packages/ztd-query-mysql/tests/Unit/Rewrite/Transformer/InsertSelectRendererTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Rewrite\Transformer;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use RuntimeException;
11use ZtdQuery\Platform\MySql\Rewrite\Transformer\InsertSelectRenderer;
12use ZtdQuery\Platform\MySql\Rewrite\Transformer\MySqlSelectListAliaser;
13use ZtdQuery\Platform\MySql\Sql\MySqlIdentifierQuoter;
14
15#[UsesClass(\ZtdQuery\Platform\MySql\Rewrite\Transformer\Select\ExpressionAliaser::class)]
16#[CoversClass(InsertSelectRenderer::class)]
17#[UsesClass(MySqlIdentifierQuoter::class)]
18#[UsesClass(MySqlSelectListAliaser::class)]
19#[UsesClass(\ZtdQuery\Platform\MySql\Sql\MySqlLexerProfile::class)]
20final class InsertSelectRendererTest extends TestCase
21{
22    public function testRendersMySqlProjectionFromDialectNeutralPlan(): void
23    {
24        $sql = (new InsertSelectRenderer())->render(
25            'SELECT DISTINCT name, COUNT(*) FROM users GROUP BY name',
26            ['id', 'name', 'count', 'status'],
27            ['name', 'count'],
28            ['status' => "'active'"],
29            ['id' => 8],
30        );
31
32        self::assertSame(
33            'WITH `__ztd_insert_source` (`__ztd_insert_0`, `__ztd_insert_1`) AS ('
34            . 'SELECT DISTINCT name AS `__ztd_insert_0`, COUNT(*) AS `__ztd_insert_1` FROM users GROUP BY name) '
35            . 'SELECT 8 + ROW_NUMBER() OVER () - 1 AS `id`, `__ztd_insert_0` AS `name`, '
36            . '`__ztd_insert_1` AS `count`, \'active\' AS `status` FROM `__ztd_insert_source`',
37            $sql,
38        );
39    }
40
41    public function testRejectsKnownMySqlProjectionCountMismatch(): void
42    {
43        $this->expectException(RuntimeException::class);
44        $this->expectExceptionMessage('INSERT column count does not match SELECT column count.');
45
46        (new InsertSelectRenderer())->render('SELECT id, name FROM users', ['id'], ['id'], []);
47    }
48
49    public function testAllowsMySqlWildcardWithSchemaDependentProjectionCount(): void
50    {
51        $result = (new InsertSelectRenderer())->render(
52            'SELECT source.* FROM source',
53            ['id', 'name'],
54            ['id', 'name'],
55            [],
56        );
57
58        self::assertStringContainsString('SELECT source.* FROM source', $result);
59    }
60
61    public function testRenderGeneratedIdentityRendersGeneratedIdentityWithMySqlDialectSyntax(): void
62    {
63        self::assertSame(
64            '8 + ROW_NUMBER() OVER () - 1',
65            (new InsertSelectRenderer())->renderGeneratedIdentity(8),
66        );
67    }
68
69    public function testAcceptsMinimumGeneratedIdentityStart(): void
70    {
71        self::assertSame(
72            '1 + ROW_NUMBER() OVER () - 1',
73            (new InsertSelectRenderer())->renderGeneratedIdentity(1),
74        );
75    }
76
77
78}
79