packages/ztd-query-postgres/tests/Unit/Sql/Diagnostic/PgSqlReadOnlyDiagnosticStatementTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Sql\Diagnostic;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\DataProvider;
9use PHPUnit\Framework\Attributes\UsesClass;
10use PHPUnit\Framework\TestCase;
11use ZtdQuery\Platform\Postgres\Sql\Diagnostic\PgSqlReadOnlyDiagnosticStatement;
12
13#[CoversClass(PgSqlReadOnlyDiagnosticStatement::class)]
14#[UsesClass(\ZtdQuery\Platform\Postgres\Sql\PgSqlLexerProfile::class)]
15#[CoversClass(\ZtdQuery\Platform\Postgres\Sql\Diagnostic\KeywordSearch::class)]
16final class PgSqlReadOnlyDiagnosticStatementTest extends TestCase
17{
18 #[DataProvider('providerStatement')]
19 public function testIsSafeClassifiesOnlySafePostgreSqlDiagnostics(string $sql, bool $expected): void
20 {
21 self::assertSame($expected, PgSqlReadOnlyDiagnosticStatement::isSafe($sql));
22 }
23
24 /**
25 * @return iterable<string, array{string, bool}>
26 */
27 public static function providerStatement(): iterable
28 {
29 yield 'explain select' => ['EXPLAIN SELECT * FROM users', true];
30 yield 'non-executing update' => ['EXPLAIN UPDATE users SET active = FALSE', true];
31 yield 'analyze select' => ['EXPLAIN (ANALYZE TRUE, FORMAT JSON) SELECT * FROM users', true];
32 yield 'analyse select' => ['EXPLAIN ANALYSE SELECT * FROM users', true];
33 yield 'executing update' => ['EXPLAIN ANALYZE UPDATE users SET active = FALSE', false];
34 yield 'data-modifying cte' => ['EXPLAIN ANALYZE WITH d AS (DELETE FROM users RETURNING id) SELECT * FROM d', false];
35 yield 'show setting' => ['SHOW server_version', true];
36 yield 'show without setting' => ['SHOW', false];
37 yield 'mysql describe' => ['DESCRIBE users', false];
38 yield 'multiple statements' => ['EXPLAIN SELECT 1; DELETE FROM users', false];
39 yield 'empty explain' => ['EXPLAIN', false];
40 }
41}
42