Test Failed
Pull Request — master (#291)
by William
12:25
created

CreateStatement::build()   D

Complexity

Conditions 19
Paths 160

Size

Total Lines 85

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 59
CRAP Score 19

Importance

Changes 0
Metric Value
dl 0
loc 85
ccs 59
cts 59
cp 1
rs 4.0166
c 0
b 0
f 0
cc 19
nc 160
nop 0
crap 19

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * `CREATE` statement.
5
 */
6
7
namespace PhpMyAdmin\SqlParser\Statements;
8
9
use PhpMyAdmin\SqlParser\Components\ArrayObj;
10
use PhpMyAdmin\SqlParser\Components\CreateDefinition;
11
use PhpMyAdmin\SqlParser\Components\DataType;
12
use PhpMyAdmin\SqlParser\Components\Expression;
13
use PhpMyAdmin\SqlParser\Components\OptionsArray;
14
use PhpMyAdmin\SqlParser\Components\ParameterDefinition;
15
use PhpMyAdmin\SqlParser\Components\PartitionDefinition;
16
use PhpMyAdmin\SqlParser\Parser;
17
use PhpMyAdmin\SqlParser\Statement;
18
use PhpMyAdmin\SqlParser\Token;
19
use PhpMyAdmin\SqlParser\TokensList;
20
21
/**
22
 * `CREATE` statement.
23
 *
24
 * @category   Statements
25
 *
26
 * @license    https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+
27
 */
28
class CreateStatement extends Statement
29
{
30
    /**
31
     * Options for `CREATE` statements.
32
     *
33
     * @var array
34
     */
35
    public static $OPTIONS = array(
36
        // CREATE TABLE
37
        'TEMPORARY' => 1,
38
39
        // CREATE VIEW
40
        'OR REPLACE' => 2,
41
        'ALGORITHM' => array(
42
            3,
43
            'var=',
44
        ),
45
        // `DEFINER` is also used for `CREATE FUNCTION / PROCEDURE`
46
        'DEFINER' => array(
47
            4,
48
            'expr=',
49
        ),
50
        'SQL SECURITY' => array(
51
            5,
52
            'var',
53
        ),
54
55
        'DATABASE' => 6,
56
        'EVENT' => 6,
57
        'FUNCTION' => 6,
58
        'INDEX' => 6,
59
        'UNIQUE INDEX' => 6,
60
        'FULLTEXT INDEX' => 6,
61
        'SPATIAL INDEX' => 6,
62
        'PROCEDURE' => 6,
63
        'SERVER' => 6,
64
        'TABLE' => 6,
65
        'TABLESPACE' => 6,
66
        'TRIGGER' => 6,
67
        'USER' => 6,
68
        'VIEW' => 6,
69
        'SCHEMA' => 6,
70
71
        // CREATE TABLE
72
        'IF NOT EXISTS' => 7
73
    );
74
75
    /**
76
     * All database options.
77
     *
78
     * @var array
79
     */
80
    public static $DB_OPTIONS = array(
81
        'CHARACTER SET' => array(
82
            1,
83
            'var=',
84
        ),
85
        'CHARSET' => array(
86
            1,
87
            'var=',
88
        ),
89
        'DEFAULT CHARACTER SET' => array(
90
            1,
91
            'var=',
92
        ),
93
        'DEFAULT CHARSET' => array(
94
            1,
95
            'var=',
96
        ),
97
        'DEFAULT COLLATE' => array(
98
            2,
99
            'var=',
100
        ),
101
        'COLLATE' => array(
102
            2,
103
            'var=',
104
        )
105
    );
106
107
    /**
108
     * All table options.
109
     *
110
     * @var array
111
     */
112
    public static $TABLE_OPTIONS = array(
113
        'ENGINE' => array(
114
            1,
115
            'var=',
116
        ),
117
        'AUTO_INCREMENT' => array(
118
            2,
119
            'var=',
120
        ),
121
        'AVG_ROW_LENGTH' => array(
122
            3,
123
            'var',
124
        ),
125
        'CHARACTER SET' => array(
126
            4,
127
            'var=',
128
        ),
129
        'CHARSET' => array(
130
            4,
131
            'var=',
132
        ),
133
        'DEFAULT CHARACTER SET' => array(
134
            4,
135
            'var=',
136
        ),
137
        'DEFAULT CHARSET' => array(
138
            4,
139
            'var=',
140
        ),
141
        'CHECKSUM' => array(
142
            5,
143
            'var',
144
        ),
145
        'DEFAULT COLLATE' => array(
146
            6,
147
            'var=',
148
        ),
149
        'COLLATE' => array(
150
            6,
151
            'var=',
152
        ),
153
        'COMMENT' => array(
154
            7,
155
            'var=',
156
        ),
157
        'CONNECTION' => array(
158
            8,
159
            'var',
160
        ),
161
        'DATA DIRECTORY' => array(
162
            9,
163
            'var',
164
        ),
165
        'DELAY_KEY_WRITE' => array(
166
            10,
167
            'var',
168
        ),
169
        'INDEX DIRECTORY' => array(
170
            11,
171
            'var',
172
        ),
173
        'INSERT_METHOD' => array(
174
            12,
175
            'var',
176
        ),
177
        'KEY_BLOCK_SIZE' => array(
178
            13,
179
            'var',
180
        ),
181
        'MAX_ROWS' => array(
182
            14,
183
            'var',
184
        ),
185
        'MIN_ROWS' => array(
186
            15,
187
            'var',
188
        ),
189
        'PACK_KEYS' => array(
190
            16,
191
            'var',
192
        ),
193
        'PASSWORD' => array(
194
            17,
195
            'var',
196
        ),
197
        'ROW_FORMAT' => array(
198
            18,
199
            'var',
200
        ),
201
        'TABLESPACE' => array(
202
            19,
203
            'var',
204
        ),
205
        'STORAGE' => array(
206
            20,
207
            'var',
208
        ),
209
        'UNION' => array(
210
            21,
211
            'var',
212
        )
213
    );
214
215
    /**
216
     * All function options.
217
     *
218
     * @var array
219
     */
220
    public static $FUNC_OPTIONS = array(
221
        'COMMENT' => array(
222
            1,
223
            'var=',
224
        ),
225
        'LANGUAGE SQL' => 2,
226
        'DETERMINISTIC' => 3,
227
        'NOT DETERMINISTIC' => 3,
228
        'CONTAINS SQL' => 4,
229
        'NO SQL' => 4,
230
        'READS SQL DATA' => 4,
231
        'MODIFIES SQL DATA' => 4,
232
        'SQL SECURITY DEFINER' => array(
233
            5,
234
            'var',
235
        )
236
    );
237
238
    /**
239
     * All trigger options.
240
     *
241
     * @var array
242
     */
243
    public static $TRIGGER_OPTIONS = array(
244
        'BEFORE' => 1,
245
        'AFTER' => 1,
246
        'INSERT' => 2,
247
        'UPDATE' => 2,
248
        'DELETE' => 2
249
    );
250
251
    /**
252
     * The name of the entity that is created.
253
     *
254
     * Used by all `CREATE` statements.
255
     *
256
     * @var Expression
257
     */
258
    public $name;
259
260
    /**
261
     * The options of the entity (table, procedure, function, etc.).
262
     *
263
     * Used by `CREATE TABLE`, `CREATE FUNCTION` and `CREATE PROCEDURE`.
264
     *
265
     * @var OptionsArray
266
     *
267
     * @see static::$TABLE_OPTIONS
268
     * @see static::$FUNC_OPTIONS
269
     * @see static::$TRIGGER_OPTIONS
270
     */
271
    public $entityOptions;
272
273
    /**
274
     * If `CREATE TABLE`, a list of columns and keys.
275
     * If `CREATE VIEW`, a list of columns.
276
     *
277
     * Used by `CREATE TABLE` and `CREATE VIEW`.
278
     *
279
     * @var CreateDefinition[]|ArrayObj
280
     */
281
    public $fields;
282
283
    /**
284
     * If `CREATE TABLE ... SELECT`.
285
     *
286
     * Used by `CREATE TABLE`
287
     *
288
     * @var SelectStatement
289
     */
290
    public $select;
291
292
    /**
293
     * If `CREATE TABLE ... LIKE`.
294
     *
295
     * Used by `CREATE TABLE`
296
     *
297
     * @var Expression
298
     */
299
    public $like;
300
301
    /**
302
     * Expression used for partitioning.
303
     *
304
     * @var string
305
     */
306
    public $partitionBy;
307
308
    /**
309
     * The number of partitions.
310
     *
311
     * @var int
312
     */
313
    public $partitionsNum;
314
315
    /**
316
     * Expression used for subpartitioning.
317
     *
318
     * @var string
319
     */
320
    public $subpartitionBy;
321
322
    /**
323
     * The number of subpartitions.
324
     *
325
     * @var int
326
     */
327
    public $subpartitionsNum;
328
329
    /**
330
     * The partition of the new table.
331
     *
332
     * @var PartitionDefinition[]
333
     */
334
    public $partitions;
335
336
    /**
337
     * If `CREATE TRIGGER` the name of the table.
338
     *
339
     * Used by `CREATE TRIGGER`.
340
     *
341
     * @var Expression
342
     */
343
    public $table;
344
345
    /**
346
     * The return data type of this routine.
347
     *
348
     * Used by `CREATE FUNCTION`.
349
     *
350
     * @var DataType
351
     */
352
    public $return;
353
354
    /**
355
     * The parameters of this routine.
356
     *
357
     * Used by `CREATE FUNCTION` and `CREATE PROCEDURE`.
358
     *
359
     * @var ParameterDefinition[]
360
     */
361
    public $parameters;
362
363
    /**
364
     * The body of this function or procedure. For views, it is the select
365
     * statement that gets the.
366
     *
367
     * Used by `CREATE FUNCTION`, `CREATE PROCEDURE` and `CREATE VIEW`.
368
     *
369
     * @var Token[]|string
370
     */
371
    public $body = array();
372
373
    /**
374
     * @return string
375
     */
376 13
    public function build()
377
    {
378 13
        $fields = '';
379 13
        if (! empty($this->fields)) {
380 8
            if (is_array($this->fields)) {
381 7
                $fields = CreateDefinition::build($this->fields) . ' ';
382 1
            } elseif ($this->fields instanceof ArrayObj) {
383 1
                $fields = ArrayObj::build($this->fields);
384
            }
385
        }
386 13
        if ($this->options->has('DATABASE') || $this->options->has('SCHEMA')) {
387
            return 'CREATE '
388 1
                . OptionsArray::build($this->options) . ' '
389 1
                . Expression::build($this->name) . ' '
390 1
                . OptionsArray::build($this->entityOptions);
391 12
        } elseif ($this->options->has('TABLE')) {
392 8
            if (! is_null($this->select)) {
393
                return 'CREATE '
394 1
                    . OptionsArray::build($this->options) . ' '
395 1
                    . Expression::build($this->name) . ' '
396 1
                    . $this->select->build();
397 7
            } elseif (! is_null($this->like)) {
398
                return 'CREATE '
399 1
                    . OptionsArray::build($this->options) . ' '
400 1
                    . Expression::build($this->name) . ' LIKE '
401 1
                    . Expression::build($this->like);
402
            } else {
403 7
                $partition = '';
404
405 7
                if (! empty($this->partitionBy)) {
406 3
                    $partition .= "\nPARTITION BY " . $this->partitionBy;
407
                }
408 7
                if (! empty($this->partitionsNum)) {
409 1
                    $partition .= "\nPARTITIONS " . $this->partitionsNum;
410
                }
411 7
                if (! empty($this->subpartitionBy)) {
412 2
                    $partition .= "\nSUBPARTITION BY " . $this->subpartitionBy;
413
                }
414 7
                if (! empty($this->subpartitionsNum)) {
415 1
                    $partition .= "\nSUBPARTITIONS " . $this->subpartitionsNum;
416
                }
417 7
                if (! empty($this->partitions)) {
418 3
                    $partition .= "\n" . PartitionDefinition::build($this->partitions);
419
                }
420
421
                return 'CREATE '
422 7
                    . OptionsArray::build($this->options) . ' '
423 7
                    . Expression::build($this->name) . ' '
424 7
                    . $fields
425 7
                    . OptionsArray::build($this->entityOptions)
426 7
                    . $partition;
427
            }
428 4
        } elseif ($this->options->has('VIEW')) {
429
            return 'CREATE '
430 1
                . OptionsArray::build($this->options) . ' '
431 1
                . Expression::build($this->name) . ' '
432 1
                . $fields . ' AS ' . TokensList::build($this->body) . ' '
433 1
                . OptionsArray::build($this->entityOptions);
434 3
        } elseif ($this->options->has('TRIGGER')) {
435
            return 'CREATE '
436 1
                . OptionsArray::build($this->options) . ' '
437 1
                . Expression::build($this->name) . ' '
438 1
                . OptionsArray::build($this->entityOptions) . ' '
439 1
                . 'ON ' . Expression::build($this->table) . ' '
440 1
                . 'FOR EACH ROW ' . TokensList::build($this->body);
441 2
        } elseif ($this->options->has('PROCEDURE')
442 2
            || $this->options->has('FUNCTION')
443
        ) {
444 1
            $tmp = '';
445 1
            if ($this->options->has('FUNCTION')) {
446 1
                $tmp = 'RETURNS ' . DataType::build($this->return);
447
            }
448
449
            return 'CREATE '
450 1
                . OptionsArray::build($this->options) . ' '
451 1
                . Expression::build($this->name) . ' '
452 1
                . ParameterDefinition::build($this->parameters) . ' '
453 1
                . $tmp . ' ' . TokensList::build($this->body);
454
        }
455
456
        return 'CREATE '
457 1
            . OptionsArray::build($this->options) . ' '
458 1
            . Expression::build($this->name) . ' '
459 1
            . TokensList::build($this->body);
460
    }
461
462
    /**
463
     * @param Parser     $parser the instance that requests parsing
464
     * @param TokensList $list   the list of tokens to be parsed
465
     */
466 63
    public function parse(Parser $parser, TokensList $list)
467
    {
468 63
        ++$list->idx; // Skipping `CREATE`.
469
470
        // Parsing options.
471 63
        $this->options = OptionsArray::parse($parser, $list, static::$OPTIONS);
472 63
        ++$list->idx; // Skipping last option.
473
474 63
        $isDatabase = $this->options->has('DATABASE') || $this->options->has('SCHEMA');
475 63
        $fieldName = $isDatabase ? 'database' : 'table';
476
477
        // Parsing the field name.
478 63
        $this->name = Expression::parse(
479 63
            $parser,
480 63
            $list,
481
            array(
482 63
                'parseField' => $fieldName,
483
                'breakOnAlias' => true
484
            )
485
        );
486
487 63
        if (! isset($this->name) || ($this->name === '')) {
488 1
            $parser->error(
489 1
                'The name of the entity was expected.',
490 1
                $list->tokens[$list->idx]
491
            );
492
        } else {
493 62
            ++$list->idx; // Skipping field.
494
        }
495
496
        /**
497
         * Token parsed at this moment.
498
         *
499
         * @var Token
500
         */
501 63
        $token = $list->tokens[$list->idx];
502 63
        $nextidx = $list->idx + 1;
503 63
        while ($nextidx < $list->count && $list->tokens[$nextidx]->type === Token::TYPE_WHITESPACE) {
504 35
            ++$nextidx;
505
        }
506
507 63
        if ($isDatabase) {
508 5
            $this->entityOptions = OptionsArray::parse(
509 5
                $parser,
510 5
                $list,
511 5
                static::$DB_OPTIONS
512
            );
513 58
        } elseif ($this->options->has('TABLE')) {
514 37
            if (($token->type === Token::TYPE_KEYWORD)
515 37
             && ($token->keyword === 'SELECT')) {
516
                /* CREATE TABLE ... SELECT */
517 2
                $this->select = new SelectStatement($parser, $list);
518 35
            } elseif (($token->type === Token::TYPE_KEYWORD) && ($token->keyword === 'AS')
519 35
                && ($list->tokens[$nextidx]->type === Token::TYPE_KEYWORD)
520 35
                && ($list->tokens[$nextidx]->value === 'SELECT')) {
521
                /* CREATE TABLE ... AS SELECT */
522 1
                $list->idx = $nextidx;
523 1
                $this->select = new SelectStatement($parser, $list);
524 34
            } elseif ($token->type === Token::TYPE_KEYWORD
525 34
                && $token->keyword === 'LIKE') {
526
                /* CREATE TABLE `new_tbl` LIKE 'orig_tbl' */
527 3
                $list->idx = $nextidx;
528 3
                $this->like = Expression::parse(
529 3
                    $parser,
530 3
                    $list,
531
                    array(
532 3
                        'parseField' => 'table',
533
                        'breakOnAlias' => true
534
                    )
535
                );
536
                // The 'LIKE' keyword was found, but no table_name was found next to it
537 3
                if (is_null($this->like)) {
538 1
                    $parser->error(
539 1
                        'A table name was expected.',
540 3
                        $list->tokens[$list->idx]
541
                    );
542
                }
543
            } else {
544 32
                $this->fields = CreateDefinition::parse($parser, $list);
545 32
                if (empty($this->fields)) {
546 3
                    $parser->error(
547 3
                        'At least one column definition was expected.',
548 3
                        $list->tokens[$list->idx]
549
                    );
550
                }
551 32
                ++$list->idx;
552
553 32
                $this->entityOptions = OptionsArray::parse(
554 32
                    $parser,
555 32
                    $list,
556 32
                    static::$TABLE_OPTIONS
557
                );
558
559
                /**
560
                 * The field that is being filled (`partitionBy` or
561
                 * `subpartitionBy`).
562
                 *
563
                 * @var string
564
                 */
565 32
                $field = null;
566
567
                /**
568
                 * The number of brackets. `false` means no bracket was found
569
                 * previously. At least one bracket is required to validate the
570
                 * expression.
571
                 *
572
                 * @var int|bool
573
                 */
574 32
                $brackets = false;
575
576
                /*
577
                 * Handles partitions.
578
                 */
579 37
                for (; $list->idx < $list->count; ++$list->idx) {
580
                    /**
581
                     * Token parsed at this moment.
582
                     *
583
                     * @var Token
584
                     */
585 32
                    $token = $list->tokens[$list->idx];
586
587
                    // End of statement.
588 32
                    if ($token->type === Token::TYPE_DELIMITER) {
589 24
                        break;
590
                    }
591
592
                    // Skipping comments.
593 32
                    if ($token->type === Token::TYPE_COMMENT) {
594 1
                        continue;
595
                    }
596
597 32
                    if (($token->type === Token::TYPE_KEYWORD) && ($token->keyword === 'PARTITION BY')) {
598 5
                        $field = 'partitionBy';
599 5
                        $brackets = false;
600 32
                    } elseif (($token->type === Token::TYPE_KEYWORD) && ($token->keyword === 'SUBPARTITION BY')) {
601 4
                        $field = 'subpartitionBy';
602 4
                        $brackets = false;
603 32
                    } elseif (($token->type === Token::TYPE_KEYWORD) && ($token->keyword === 'PARTITIONS')) {
604 2
                        $token = $list->getNextOfType(Token::TYPE_NUMBER);
605 2
                        --$list->idx; // `getNextOfType` also advances one position.
606 2
                        $this->partitionsNum = $token->value;
607 32
                    } elseif (($token->type === Token::TYPE_KEYWORD) && ($token->keyword === 'SUBPARTITIONS')) {
608 2
                        $token = $list->getNextOfType(Token::TYPE_NUMBER);
609 2
                        --$list->idx; // `getNextOfType` also advances one position.
610 2
                        $this->subpartitionsNum = $token->value;
611 32
                    } elseif (! empty($field)) {
612
                        /*
613
                         * Handling the content of `PARTITION BY` and `SUBPARTITION BY`.
614
                         */
615
616
                        // Counting brackets.
617 5 View Code Duplication
                        if ($token->type === Token::TYPE_OPERATOR) {
618 5
                            if ($token->value === '(') {
619
                                // This is used instead of `++$brackets` because,
620
                                // initially, `$brackets` is `false` cannot be
621
                                // incremented.
622 5
                                $brackets = $brackets + 1;
623 5
                            } elseif ($token->value === ')') {
624 5
                                --$brackets;
625
                            }
626
                        }
627
628
                        // Building the expression used for partitioning.
629 5
                        $this->$field .= ($token->type === Token::TYPE_WHITESPACE) ? ' ' : $token->token;
630
631
                        // Last bracket was read, the expression ended.
632
                        // Comparing with `0` and not `false`, because `false` means
633
                        // that no bracket was found and at least one must is
634
                        // required.
635 5
                        if ($brackets === 0) {
636 5
                            $this->$field = trim($this->$field);
637 5
                            $field = null;
638
                        }
639 32
                    } elseif (($token->type === Token::TYPE_OPERATOR) && ($token->value === '(')) {
640 8
                        if (! empty($this->partitionBy)) {
641 5
                            $this->partitions = ArrayObj::parse(
0 ignored issues
show
Documentation Bug introduced by
It seems like \PhpMyAdmin\SqlParser\Co...\PartitionDefinition')) can also be of type object<PhpMyAdmin\SqlParser\Components\ArrayObj>. However, the property $partitions is declared as type array<integer,object<Php...s\PartitionDefinition>>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
642 5
                                $parser,
643 5
                                $list,
644
                                array(
645 5
                                    'type' => 'PhpMyAdmin\\SqlParser\\Components\\PartitionDefinition'
646
                                )
647
                            );
648
                        }
649 8
                        break;
650
                    }
651
                }
652
            }
653 21
        } elseif ($this->options->has('PROCEDURE')
654 21
            || $this->options->has('FUNCTION')
655
        ) {
656 11
            $this->parameters = ParameterDefinition::parse($parser, $list);
657 11
            if ($this->options->has('FUNCTION')) {
658 6
                $prev_token = $token;
659 6
                $token = $list->getNextOfType(Token::TYPE_KEYWORD);
660 6
                if (is_null($token) || $token->keyword !== 'RETURNS') {
661 3
                    $parser->error(
662 3
                        'A "RETURNS" keyword was expected.',
663 3
                        is_null($token) ? $prev_token : $token
664
                    );
665
                } else {
666 3
                    ++$list->idx;
667 3
                    $this->return = DataType::parse(
668 3
                        $parser,
669 3
                        $list
670
                    );
671
                }
672
            }
673 11
            ++$list->idx;
674
675 11
            $this->entityOptions = OptionsArray::parse(
676 11
                $parser,
677 11
                $list,
678 11
                static::$FUNC_OPTIONS
679
            );
680 11
            ++$list->idx;
681
682 11 View Code Duplication
            for (; $list->idx < $list->count; ++$list->idx) {
683 9
                $token = $list->tokens[$list->idx];
684 9
                $this->body[] = $token;
685
            }
686 10
        } elseif ($this->options->has('VIEW')) {
687 5
            $token = $list->getNext(); // Skipping whitespaces and comments.
688
689
            // Parsing columns list.
690 5
            if (($token->type === Token::TYPE_OPERATOR) && ($token->value === '(')) {
691 2
                --$list->idx; // getNext() also goes forward one field.
692 2
                $this->fields = ArrayObj::parse($parser, $list);
693 2
                ++$list->idx; // Skipping last token from the array.
694 2
                $list->getNext();
695
            }
696
697
            // Parsing the `AS` keyword.
698 5 View Code Duplication
            for (; $list->idx < $list->count; ++$list->idx) {
699 5
                $token = $list->tokens[$list->idx];
700 5
                if ($token->type === Token::TYPE_DELIMITER) {
701 5
                    break;
702
                }
703 5
                $this->body[] = $token;
704
            }
705 5
        } elseif ($this->options->has('TRIGGER')) {
706
            // Parsing the time and the event.
707 1
            $this->entityOptions = OptionsArray::parse(
708 1
                $parser,
709 1
                $list,
710 1
                static::$TRIGGER_OPTIONS
711
            );
712 1
            ++$list->idx;
713
714 1
            $list->getNextOfTypeAndValue(Token::TYPE_KEYWORD, 'ON');
715 1
            ++$list->idx; // Skipping `ON`.
716
717
            // Parsing the name of the table.
718 1
            $this->table = Expression::parse(
719 1
                $parser,
720 1
                $list,
721
                array(
722 1
                    'parseField' => 'table',
723
                    'breakOnAlias' => true
724
                )
725
            );
726 1
            ++$list->idx;
727
728 1
            $list->getNextOfTypeAndValue(Token::TYPE_KEYWORD, 'FOR EACH ROW');
729 1
            ++$list->idx; // Skipping `FOR EACH ROW`.
730
731 1 View Code Duplication
            for (; $list->idx < $list->count; ++$list->idx) {
732 1
                $token = $list->tokens[$list->idx];
733 1
                $this->body[] = $token;
734
            }
735
        } else {
736 4 View Code Duplication
            for (; $list->idx < $list->count; ++$list->idx) {
737 4
                $token = $list->tokens[$list->idx];
738 4
                if ($token->type === Token::TYPE_DELIMITER) {
739 4
                    break;
740
                }
741 1
                $this->body[] = $token;
742
            }
743
        }
744 63
    }
745
}
746