packages/ztd-query-mysql/tests/Unit/Schema/Partition/PredicateCompilerTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Schema\Partition;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9use ZtdQuery\Platform\MySql\Schema\Partition\PredicateCompiler;
10
11#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\MySqlLexerProfile::class)]
12#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\MySqlParser::class)]
13#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\MySql\Sql\OptionalInsertIntoNormalizer::class)]
14#[CoversClass(PredicateCompiler::class)]
15final class PredicateCompilerTest extends TestCase
16{
17    public function testPartitionExpressionCase1(): void
18    {
19        $compiler = new PredicateCompiler();
20        self::assertSame(['RANGE', 'YEAR(created_at)'], $compiler->partitionExpression('RANGE (YEAR(created_at))'));
21        self::assertSame(['LIST', 'id'], $compiler->partitionExpression('LIST (id)'));
22        $sql = 'HASH(id)';
23        self::assertNull($compiler->partitionExpression($sql));
24    }
25
26    public function testPartitionExpressionCase2(): void
27    {
28        $compiler = new PredicateCompiler();
29        self::assertSame(['RANGE', 'YEAR(created_at)'], $compiler->partitionExpression('RANGE (YEAR(created_at))'));
30        self::assertSame(['LIST', 'id'], $compiler->partitionExpression('LIST (id)'));
31        $sql = '';
32        self::assertNull($compiler->partitionExpression($sql));
33    }
34
35    public function testPartitionExpressionCase3(): void
36    {
37        $compiler = new PredicateCompiler();
38        self::assertSame(['RANGE', 'YEAR(created_at)'], $compiler->partitionExpression('RANGE (YEAR(created_at))'));
39        self::assertSame(['LIST', 'id'], $compiler->partitionExpression('LIST (id)'));
40        $sql = 'RANGE';
41        self::assertNull($compiler->partitionExpression($sql));
42    }
43
44    public function testPartitionExpressionCase4(): void
45    {
46        $compiler = new PredicateCompiler();
47        self::assertSame(['RANGE', 'YEAR(created_at)'], $compiler->partitionExpression('RANGE (YEAR(created_at))'));
48        self::assertSame(['LIST', 'id'], $compiler->partitionExpression('LIST (id)'));
49        $sql = 'RANGE ()';
50        self::assertNull($compiler->partitionExpression($sql));
51    }
52
53    public function testPartitionExpressionCase5(): void
54    {
55        $compiler = new PredicateCompiler();
56        self::assertSame(['RANGE', 'YEAR(created_at)'], $compiler->partitionExpression('RANGE (YEAR(created_at))'));
57        self::assertSame(['LIST', 'id'], $compiler->partitionExpression('LIST (id)'));
58        $sql = 'RANGE COLUMNS (id)';
59        self::assertNull($compiler->partitionExpression($sql));
60    }
61
62    public function testRangePredicates(): void
63    {
64        $sql = 'CREATE TABLE t (id INT) PARTITION BY RANGE (id) (PARTITION p0 VALUES LESS THAN (10), PARTITION p1 VALUES LESS THAN (20), PARTITION p2 VALUES LESS THAN MAXVALUE)';
65        $statement = (new \ZtdQuery\Platform\MySql\Sql\MySqlParser())->parseSingleLogicalStatement($sql);
66        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\CreateStatement::class, $statement);
67        $partitions = $statement->partitions;
68        self::assertNotNull($partitions);
69        self::assertSame(['p0' => '(id) IS NULL OR (id) < 10', 'p1' => '(id) >= 10 AND (id) < 20', 'p2' => '(id) >= 20'], (new PredicateCompiler())->rangePredicates('id', $partitions));
70    }
71
72    public function testListPredicates(): void
73    {
74        $sql = 'CREATE TABLE t (id INT) PARTITION BY LIST (id) (PARTITION p0 VALUES IN (1, 2, NULL), PARTITION p1 VALUES IN (3))';
75        $statement = (new \ZtdQuery\Platform\MySql\Sql\MySqlParser())->parseSingleLogicalStatement($sql);
76        self::assertInstanceOf(\PhpMyAdmin\SqlParser\Statements\CreateStatement::class, $statement);
77        $partitions = $statement->partitions;
78        self::assertNotNull($partitions);
79        self::assertSame(['p0' => '((id) IN (1, 2) OR (id) IS NULL)', 'p1' => '(id) IN (3)'], (new PredicateCompiler())->listPredicates('id', $partitions));
80    }
81
82    public function testPartitionValue(): void
83    {
84        $partition = new \PhpMyAdmin\SqlParser\Components\PartitionDefinition();
85        $partition->type = 'LESS THAN';
86        $partition->expr = 'MAXVALUE';
87        $compiler = new PredicateCompiler();
88        self::assertSame('MAXVALUE', $compiler->partitionValue($partition, 'LESS THAN'));
89        self::assertNull($compiler->partitionValue($partition, 'IN'));
90    }
91
92}
93