Passed
Push — master ( 5f8f14...173a37 )
by William
09:55
created

CreateStatementTest::testBuilderPartitions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 45
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 40
nc 1
nop 0
dl 0
loc 45
rs 9.28
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpMyAdmin\SqlParser\Tests\Builder;
6
7
use PhpMyAdmin\SqlParser\Components\CreateDefinition;
8
use PhpMyAdmin\SqlParser\Components\DataType;
9
use PhpMyAdmin\SqlParser\Components\Expression;
10
use PhpMyAdmin\SqlParser\Components\Key;
11
use PhpMyAdmin\SqlParser\Components\OptionsArray;
12
use PhpMyAdmin\SqlParser\Parser;
13
use PhpMyAdmin\SqlParser\Statements\CreateStatement;
14
use PhpMyAdmin\SqlParser\Tests\TestCase;
15
16
class CreateStatementTest extends TestCase
17
{
18
    public function testBuilder(): void
19
    {
20
        $parser = new Parser(
21
            'CREATE USER "jeffrey"@"localhost" IDENTIFIED BY "mypass"'
22
        );
23
        $stmt = $parser->statements[0];
24
        $this->assertEquals(
25
            'CREATE USER "jeffrey"@"localhost" IDENTIFIED BY "mypass"',
26
            $stmt->build()
27
        );
28
    }
29
30
    public function testBuilderDatabase(): void
31
    {
32
        // CREATE DATABASE ...
33
        $parser = new Parser(
34
            'CREATE DATABASE `mydb` ' .
35
            'DEFAULT CHARACTER SET = utf8 DEFAULT COLLATE = utf8_general_ci'
36
        );
37
        $stmt = $parser->statements[0];
38
39
        $this->assertEquals(
40
            'CREATE DATABASE `mydb` ' .
41
            'DEFAULT CHARACTER SET=utf8 DEFAULT COLLATE=utf8_general_ci',
42
            $stmt->build()
43
        );
44
45
        // CREATE SCHEMA ...
46
        $parser = new Parser(
47
            'CREATE SCHEMA `mydb` ' .
48
            'DEFAULT CHARACTER SET = utf8 DEFAULT COLLATE = utf8_general_ci'
49
        );
50
        $stmt = $parser->statements[0];
51
52
        $this->assertEquals(
53
            'CREATE SCHEMA `mydb` ' .
54
            'DEFAULT CHARACTER SET=utf8 DEFAULT COLLATE=utf8_general_ci',
55
            $stmt->build()
56
        );
57
    }
58
59
    public function testBuilderDefaultInt(): void
60
    {
61
        $parser = new Parser(
62
            'CREATE TABLE IF NOT EXISTS t1 (' .
63
            " c1 int(11) NOT NULL DEFAULT '0' COMMENT 'xxx'" .
64
            ') ENGINE=MyISAM'
65
        );
66
        $stmt = $parser->statements[0];
67
68
        $this->assertEquals(
69
            "CREATE TABLE IF NOT EXISTS t1 (\n" .
70
            "  `c1` int(11) NOT NULL DEFAULT '0' COMMENT 'xxx'\n" .
71
            ') ENGINE=MyISAM',
72
            $stmt->build()
73
        );
74
    }
75
76
    public function testBuilderCollate(): void
77
    {
78
        $parser = new Parser(
79
            'CREATE TABLE IF NOT EXISTS t1 (' .
80
            " c1 varchar(11) NOT NULL DEFAULT '0' COLLATE 'utf8_czech_ci' COMMENT 'xxx'" .
81
            ') ENGINE=MyISAM'
82
        );
83
        $stmt = $parser->statements[0];
84
85
        $this->assertEquals(
86
            "CREATE TABLE IF NOT EXISTS t1 (\n" .
87
            "  `c1` varchar(11) NOT NULL DEFAULT '0' COLLATE 'utf8_czech_ci' COMMENT 'xxx'\n" .
88
            ') ENGINE=MyISAM',
89
            $stmt->build()
90
        );
91
    }
92
93
    public function testBuilderDefaultComment(): void
94
    {
95
        $parser = new Parser(
96
            'CREATE TABLE `wp_audio` (' .
97
            " `somedata` int(11) DEFAULT NULL COMMENT 'ma data', " .
98
            " `someinfo` int(11) DEFAULT NULL COMMENT 'ma info' " .
99
            ' )'
100
        );
101
        $stmt = $parser->statements[0];
102
103
        $this->assertEquals(
104
            "CREATE TABLE `wp_audio` (\n" .
105
            "  `somedata` int(11) DEFAULT NULL COMMENT 'ma data',\n" .
106
            "  `someinfo` int(11) DEFAULT NULL COMMENT 'ma info'\n" .
107
            ') ',
108
            $stmt->build()
109
        );
110
    }
111
112
    public function testBuilderTable(): void
113
    {
114
        /* Assertion 1 */
115
        $stmt = new CreateStatement();
116
117
        $stmt->name = new Expression('', 'test', '');
118
        $stmt->options = new OptionsArray(['TABLE']);
119
        $stmt->fields = [
120
            new CreateDefinition(
121
                'id',
122
                new OptionsArray(['NOT NULL', 'AUTO_INCREMENT']),
123
                new DataType('INT', [11], new OptionsArray(['UNSIGNED']))
124
            ),
125
            new CreateDefinition(
126
                '',
127
                null,
128
                new Key('', [['name' => 'id']], 'PRIMARY KEY')
129
            ),
130
        ];
131
132
        $this->assertEquals(
133
            "CREATE TABLE `test` (\n" .
134
            "  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,\n" .
135
            "  PRIMARY KEY (`id`)\n" .
136
            ') ',
137
            $stmt->build()
138
        );
139
140
        /* Assertion 2 */
141
        $query =
142
            "CREATE TABLE `jos_core_acl_aro` (\n" .
143
            "  `id` int(11) NOT NULL,\n" .
144
            "  `section_value` varchar(240) NOT NULL DEFAULT '0',\n" .
145
            "  `value` varchar(240) NOT NULL DEFAULT '',\n" .
146
            "  `order_value` int(11) NOT NULL DEFAULT '0',\n" .
147
            "  `name` varchar(255) NOT NULL DEFAULT '',\n" .
148
            "  `hidden` int(11) NOT NULL DEFAULT '0',\n" .
149
            "  PRIMARY KEY (`id`),\n" .
150
            "  UNIQUE KEY `jos_section_value_value_aro` (`section_value`(100),`value`(15)) USING BTREE,\n" .
151
            "  KEY `jos_gacl_hidden_aro` (`hidden`)\n" .
152
            ') ENGINE=InnoDB DEFAULT CHARSET=latin1';
153
        $parser = new Parser($query);
154
        $this->assertEquals($query, $parser->statements[0]->build());
155
156
        /* Assertion 3 */
157
        $query = 'CREATE TABLE `table_copy` LIKE `old_table`';
158
        $parser = new Parser($query);
159
        $this->assertEquals($query, $parser->statements[0]->build());
160
161
        /* Assertion 4 */
162
        $query =
163
            "CREATE TABLE `aa` (\n" .
164
            "  `id` int(11) NOT NULL,\n" .
165
            "  `rTime` timestamp(3) NOT NULL DEFAULT '0000-00-00 00:00:00.000' ON UPDATE CURRENT_TIMESTAMP(3),\n" .
166
            "  PRIMARY KEY (`id`)\n" .
167
            ') ENGINE=InnoDB DEFAULT CHARSET=latin1';
168
        $parser = new Parser($query);
169
        $this->assertEquals($query, $parser->statements[0]->build());
170
    }
171
172
    public function testBuilderPartitions(): void
173
    {
174
        /* Assertion 1 */
175
        $query = 'CREATE TABLE ts (' . "\n"
176
            . '  `id` int,' . "\n"
177
            . '  `purchased` date' . "\n"
178
            . ') ' . "\n"
179
            . 'PARTITION BY RANGE(YEAR(purchased))' . "\n"
180
            . 'PARTITIONS 3' . "\n"
181
            . 'SUBPARTITION BY HASH(TO_DAYS(purchased))' . "\n"
182
            . 'SUBPARTITIONS 2' . "\n"
183
            . '(' . "\n"
184
            . 'PARTITION p0 VALUES LESS THAN (1990)  (' . "\n"
185
            . 'SUBPARTITION s0,' . "\n"
186
            . 'SUBPARTITION s1' . "\n"
187
            . '),' . "\n"
188
            . 'PARTITION p1 VALUES LESS THAN (2000)  (' . "\n"
189
            . 'SUBPARTITION s2,' . "\n"
190
            . 'SUBPARTITION s3' . "\n"
191
            . '),' . "\n"
192
            . 'PARTITION p2 VALUES LESS THAN MAXVALUE  (' . "\n"
193
            . 'SUBPARTITION s4,' . "\n"
194
            . 'SUBPARTITION s5' . "\n"
195
            . ')' . "\n"
196
            . ')';
197
        $parser = new Parser($query);
198
        $this->assertEquals($query, $parser->statements[0]->build());
199
200
        /* Assertion 2 */
201
        $query = 'CREATE TABLE `pma_test` (' . "\n"
202
            . '  `test_id` int(32) NOT NULL,' . "\n"
203
            . '  `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP' . "\n"
204
            . ') ENGINE=InnoDB DEFAULT CHARSET=utf8' . "\n"
205
            . 'PARTITION BY RANGE (test_id)' . "\n"
206
            . '(' . "\n"
207
            . 'PARTITION p0 VALUES LESS THAN (250000) ENGINE=InnoDB,' . "\n"
208
            . 'PARTITION p1 VALUES LESS THAN (500000) ENGINE=InnoDB,' . "\n"
209
            . 'PARTITION p2 VALUES LESS THAN (750000) ENGINE=InnoDB,' . "\n"
210
            . 'PARTITION p3 VALUES LESS THAN (1000000) ENGINE=InnoDB,' . "\n"
211
            . 'PARTITION p4 VALUES LESS THAN (1250000) ENGINE=InnoDB,' . "\n"
212
            . 'PARTITION p5 VALUES LESS THAN (1500000) ENGINE=InnoDB,' . "\n"
213
            . 'PARTITION p6 VALUES LESS THAN MAXVALUE ENGINE=InnoDB' . "\n"
214
            . ')';
215
        $parser = new Parser($query);
216
        $this->assertEquals($query, $parser->statements[0]->build());
217
    }
218
219
    public function partitionQueriesProvider(): array
220
    {
221
        return [
222
            [
223
                'subparts' => <<<EOT
224
CREATE TABLE `ts` (
225
  `id` int(11) DEFAULT NULL,
226
  `purchased` date DEFAULT NULL
227
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
228
PARTITION BY RANGE (YEAR(purchased))
229
SUBPARTITION BY HASH (TO_DAYS(purchased))
230
(
231
PARTITION p0 VALUES LESS THAN (1990)  (
232
SUBPARTITION s0 ENGINE=InnoDB,
233
SUBPARTITION s1 ENGINE=InnoDB
234
),
235
PARTITION p1 VALUES LESS THAN (2000)  (
236
SUBPARTITION s2 ENGINE=InnoDB,
237
SUBPARTITION s3 ENGINE=InnoDB
238
),
239
PARTITION p2 VALUES LESS THAN MAXVALUE  (
240
SUBPARTITION s4 ENGINE=InnoDB,
241
SUBPARTITION s5 ENGINE=InnoDB
242
)
243
)
244
EOT
245
            ,
246
            ],
247
            [
248
                'parts' => <<<EOT
249
CREATE TABLE ptest (
250
  `event_date` date NOT NULL
251
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
252
PARTITION BY HASH (TO_DAYS(event_date))
253
(
254
PARTITION p0 ENGINE=InnoDB,
255
PARTITION p1 ENGINE=InnoDB,
256
PARTITION p2 ENGINE=InnoDB,
257
PARTITION p3 ENGINE=InnoDB,
258
PARTITION p4 ENGINE=InnoDB
259
)
260
EOT
261
            ,
262
            ],
263
        ];
264
    }
265
266
    /**
267
     * @dataProvider partitionQueriesProvider
268
     */
269
    public function testBuilderPartitionsEngine(string $query): void
270
    {
271
        $parser = new Parser($query);
272
        $stmt = $parser->statements[0];
273
274
        $this->assertEquals($query, $stmt->build());
275
    }
276
277
    public function testBuilderView(): void
278
    {
279
        $parser = new Parser(
280
            'CREATE VIEW myView (vid, vfirstname) AS ' .
281
            'SELECT id, first_name FROM employee WHERE id = 1'
282
        );
283
        $stmt = $parser->statements[0];
284
285
        $this->assertEquals(
286
            'CREATE VIEW myView (vid, vfirstname) AS  ' .
287
            'SELECT id, first_name FROM employee WHERE id = 1 ',
288
            $stmt->build()
289
        );
290
291
        $parser = new Parser(
292
            'CREATE OR REPLACE VIEW myView (vid, vfirstname) AS ' .
293
            'SELECT id, first_name FROM employee WHERE id = 1'
294
        );
295
        $stmt = $parser->statements[0];
296
297
        $this->assertEquals(
298
            'CREATE OR REPLACE VIEW myView (vid, vfirstname) AS  ' .
299
            'SELECT id, first_name FROM employee WHERE id = 1 ',
300
            $stmt->build()
301
        );
302
303
        // Assert the builder can build wrong syntax select expressions
304
        $parser = new Parser(
305
            'CREATE OR REPLACE VIEW myView (vid, vfirstname) AS ' .
306
            'SELECT id, first_name, FROMzz employee WHERE id = 1'
307
        );
308
        $stmt = $parser->statements[0];
309
        $this->assertEquals(
310
            'CREATE OR REPLACE VIEW myView (vid, vfirstname) AS  ' .
311
            'SELECT id, first_name, FROMzz employee WHERE id = 1 ',
312
            $stmt->build()
313
        );
314
    }
315
316
    public function testBuilderTrigger(): void
317
    {
318
        $stmt = new CreateStatement();
319
320
        $stmt->options = new OptionsArray(['TRIGGER']);
321
        $stmt->name = new Expression('ins_sum');
322
        $stmt->entityOptions = new OptionsArray(['BEFORE', 'INSERT']);
323
        $stmt->table = new Expression('account');
324
        $stmt->body = 'SET @sum = @sum + NEW.amount';
325
326
        $this->assertEquals(
327
            'CREATE TRIGGER ins_sum BEFORE INSERT ON account ' .
328
            'FOR EACH ROW SET @sum = @sum + NEW.amount',
329
            $stmt->build()
330
        );
331
    }
332
333
    public function testBuilderRoutine(): void
334
    {
335
        $parser = new Parser(
336
            'CREATE FUNCTION test (IN `i` INT) RETURNS VARCHAR ' .
337
            'BEGIN ' .
338
            'DECLARE name VARCHAR DEFAULT ""; ' .
339
            'SELECT name INTO name FROM employees WHERE id = i; ' .
340
            'RETURN name; ' .
341
            'END'
342
        );
343
        $stmt = $parser->statements[0];
344
345
        $this->assertEquals(
346
            'CREATE FUNCTION test (IN `i` INT) RETURNS VARCHAR ' .
347
            'BEGIN ' .
348
            'DECLARE name VARCHAR DEFAULT ""; ' .
349
            'SELECT name INTO name FROM employees WHERE id = i; ' .
350
            'RETURN name; ' .
351
            'END',
352
            $stmt->build()
353
        );
354
    }
355
356
    public function testBuildSelect(): void
357
    {
358
        $parser = new Parser(
359
            'CREATE TABLE new_tbl SELECT * FROM orig_tbl'
360
        );
361
        $this->assertEquals(
362
            'CREATE TABLE new_tbl SELECT * FROM orig_tbl',
363
            $parser->statements[0]->build()
364
        );
365
    }
366
}
367