packages/ztd-query-mysql/tests/Unit/Rewrite/StatementRewriterTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Rewrite;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9use ZtdQuery\Platform\MySql\Rewrite\StatementRewriter;
10
11#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Dml\DmlWhereClauseExtractor::class)]
12#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Dml\InsertSelectSourceExtractor::class)]
13#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\AlterTableMutation::class)]
14#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\Alter\ColumnAction::class)]
15#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\Alter\ColumnAlteration::class)]
16#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\Alter\ColumnDefinitionParser::class)]
17#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\Alter\CreateTableRenderer::class)]
18#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\Alter\OperationApplier::class)]
19#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\Alter\PrimaryKeyAlteration::class)]
20#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\Alter\StoredColumns::class)]
21#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\Alter\UnsupportedKeyword::class)]
22#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Row\RowMutationResolver::class)]
23#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Table\TableMutationResolver::class)]
24#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Dml\TargetName::class)]
25#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Value\MySqlCastRenderer::class)]
26#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Schema\MySqlColumnTypeMapper::class)]
27#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Cte\MySqlCteShadowComposer::class)]
28#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Schema\Key\MySqlForeignKeyDefinitionParser::class)]
29#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\FullText\MySqlFullTextSearchRewriter::class)]
30#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\GeneratedColumn\MySqlGeneratedColumnProjector::class)]
31#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\MySqlIdentifierQuoter::class)]
32#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\MySqlLexerProfile::class)]
33#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\MySqlMutationResolver::class)]
34#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Upsert\MySqlNativeUpsertProjector::class)]
35#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\MySqlParser::class)]
36#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Partition\MySqlPartitionSelectionRewriter::class)]
37#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Schema\Partition\MySqlPartitioningParser::class)]
38#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\MySqlQueryGuard::class)]
39#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Diagnostic\MySqlReadOnlyDiagnosticStatement::class)]
40#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Schema\MySqlSchemaParser::class)]
41#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Relation\MySqlSelectRelationParser::class)]
42#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Type\MySqlTypeSemantics::class)]
43#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Upsert\MySqlUpsertAssignmentExtractor::class)]
44#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Upsert\MySqlUpsertExpressionParser::class)]
45#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Value\MySqlValueRenderer::class)]
46#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\View\MySqlViewShadowRenderer::class)]
47#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Alter\OptionList::class)]
48#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Dml\AssignmentExpression::class)]
49#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Cte\HeaderParser::class)]
50#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Cte\IdentifierReferences::class)]
51#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Diagnostic\DiagnosticKeywords::class)]
52#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\OptionalInsertIntoNormalizer::class)]
53#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Relation\ExpressionNames::class)]
54#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Relation\ReferenceReader::class)]
55#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Upsert\AssignmentReader::class)]
56#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Upsert\ExpressionReader::class)]
57#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Upsert\LiteralReader::class)]
58#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Shadow\Mutation\Upsert\StringLiteral::class)]
59#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\FullText\ExpressionEditor::class)]
60#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Partition\SelectionReader::class)]
61#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Partition\SourceProjection::class)]
62#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Upsert\ConflictPredicate::class)]
63#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Upsert\ExpressionBinder::class)]
64#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Upsert\MetadataColumns::class)]
65#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Upsert\QualifiedColumn::class)]
66#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Classification\CteStatementKind::class)]
67#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Context\TableContext::class)]
68#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Validation\AlterTableGuard::class)]
69#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Validation\ReplaceColumns::class)]
70#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Schema\DefinitionBuilder::class)]
71#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Schema\Key\DefinitionReader::class)]
72#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Schema\Key\TokenReader::class)]
73#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Schema\Partition\PredicateCompiler::class)]
74#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\DeleteTransformer::class)]
75#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\Delete\ResultSelect::class)]
76#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\Delete\TargetProjection::class)]
77#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\InsertRowRenderer::class)]
78#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\InsertSelectRenderer::class)]
79#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\InsertTransformer::class)]
80#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\Insert\InsertTarget::class)]
81#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\Insert\ReplaceStatementConverter::class)]
82#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\Insert\ResultProjection::class)]
83#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\MySqlSelectListAliaser::class)]
84#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\MySqlTransformer::class)]
85#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\ReplaceTransformer::class)]
86#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\SelectTransformer::class)]
87#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\Select\ExpressionAliaser::class)]
88#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\Set\OrderRewriter::class)]
89#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\Set\ValueNormalizer::class)]
90#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\Shadow\CteRows::class)]
91#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\UpdateTransformer::class)]
92#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\Update\ResultSelect::class)]
93#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\Update\TargetProjection::class)]
94#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Value\CastTypeResolver::class)]
95#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Type\RankEdits::class)]
96#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Value\ScalarExpression::class)]
97#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Value\StringCoercion::class)]
98#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Dml\UpdateAssignmentExtractor::class)]
99#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\Dml\UpdateSourceExtractor::class)]
100#[CoversClass(StatementRewriter::class)]
101final class StatementRewriterTest extends TestCase
102{
103 public function testRewriteStatement(): void
104 {
105 $parser = new \ZtdQuery\Platform\MySql\Sql\MySqlParser();
106 $store = new \ZtdQuery\Shadow\ShadowStore();
107 $registry = new \ZtdQuery\Schema\TableDefinitionRegistry();
108 $select = new \ZtdQuery\Platform\MySql\Rewrite\Transformer\SelectTransformer();
109 $insert = new \ZtdQuery\Platform\MySql\Rewrite\Transformer\InsertTransformer($parser, $select);
110 $update = new \ZtdQuery\Platform\MySql\Rewrite\Transformer\UpdateTransformer($parser, $select);
111 $delete = new \ZtdQuery\Platform\MySql\Rewrite\Transformer\DeleteTransformer($parser, $select);
112 $replace = new \ZtdQuery\Platform\MySql\Rewrite\Transformer\ReplaceTransformer($parser, $select);
113 $transformer = new \ZtdQuery\Platform\MySql\Rewrite\Transformer\MySqlTransformer($parser, $select, $insert, $update, $delete, $replace);
114 $resolver = new \ZtdQuery\Platform\MySql\Shadow\MySqlMutationResolver($store, $registry, new \ZtdQuery\Platform\MySql\Schema\MySqlSchemaParser($parser), $update, $delete);
115 $rewriter = new StatementRewriter(new \ZtdQuery\Platform\MySql\Rewrite\Cte\MySqlCteShadowComposer(), new \ZtdQuery\Platform\MySql\Rewrite\MySqlQueryGuard($parser), $resolver, $parser, $registry, $store, $transformer, new \ZtdQuery\Schema\ViewDefinitionSet());
116 $statement = (new \PhpMyAdmin\SqlParser\Parser('SELECT 1'))->statements[0];
117 self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\SelectStatement::class, $statement);
118 $plan = $rewriter->rewriteStatement($statement, 'SELECT 1');
119 self::assertSame('SELECT 1', $plan->sql());
120 self::assertSame(\ZtdQuery\Rewrite\QueryKind::READ, $plan->kind());
121 self::assertNull($plan->mutation());
122 }
123
124 public function testMutationStatement(): void
125 {
126 $parser = new \ZtdQuery\Platform\MySql\Sql\MySqlParser();
127 $store = new \ZtdQuery\Shadow\ShadowStore();
128 $registry = new \ZtdQuery\Schema\TableDefinitionRegistry();
129 $select = new \ZtdQuery\Platform\MySql\Rewrite\Transformer\SelectTransformer();
130 $insert = new \ZtdQuery\Platform\MySql\Rewrite\Transformer\InsertTransformer($parser, $select);
131 $update = new \ZtdQuery\Platform\MySql\Rewrite\Transformer\UpdateTransformer($parser, $select);
132 $delete = new \ZtdQuery\Platform\MySql\Rewrite\Transformer\DeleteTransformer($parser, $select);
133 $replace = new \ZtdQuery\Platform\MySql\Rewrite\Transformer\ReplaceTransformer($parser, $select);
134 $transformer = new \ZtdQuery\Platform\MySql\Rewrite\Transformer\MySqlTransformer($parser, $select, $insert, $update, $delete, $replace);
135 $resolver = new \ZtdQuery\Platform\MySql\Shadow\MySqlMutationResolver($store, $registry, new \ZtdQuery\Platform\MySql\Schema\MySqlSchemaParser($parser), $update, $delete);
136 $rewriter = new StatementRewriter(new \ZtdQuery\Platform\MySql\Rewrite\Cte\MySqlCteShadowComposer(), new \ZtdQuery\Platform\MySql\Rewrite\MySqlQueryGuard($parser), $resolver, $parser, $registry, $store, $transformer, new \ZtdQuery\Schema\ViewDefinitionSet());
137 $statement = (new \PhpMyAdmin\SqlParser\Parser('WITH c AS (SELECT 1) UPDATE users SET id = 2'))->statements[0];
138 self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\WithStatement::class, $statement);
139 $mutation = $rewriter->mutationStatement($statement, 'WITH c AS (SELECT 1) UPDATE users SET id = 2');
140 self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\UpdateStatement::class, $mutation);
141 self::assertSame('UPDATE users SET id = 2', $mutation->build());
142 }
143
144}
145