@@ -106,7 +106,6 @@ class AlterOperation extends Component
106106        'MODIFY '  => 1 ,
107107        'OPTIMIZE '  => 1 ,
108108        'ORDER '  => 1 ,
109-         'PARTITION '  => 1 ,
110109        'REBUILD '  => 1 ,
111110        'REMOVE '  => 1 ,
112111        'RENAME '  => 1 ,
@@ -123,6 +122,8 @@ class AlterOperation extends Component
123122        'FULLTEXT '  => 2 ,
124123        'KEY '  => 2 ,
125124        'KEYS '  => 2 ,
125+         'PARTITION '  => 2 ,
126+         'PARTITION BY '  => 2 ,
126127        'PARTITIONING '  => 2 ,
127128        'PRIMARY KEY '  => 2 ,
128129        'SPATIAL '  => 2 ,
@@ -191,10 +192,17 @@ class AlterOperation extends Component
191192    /** 
192193     * The altered field. 
193194     * 
194-      * @var Expression 
195+      * @var Expression|string|null  
195196     */ 
196197    public  $ field ;
197198
199+     /** 
200+      * The partitions. 
201+      * 
202+      * @var Component[]|ArrayObj|null 
203+      */ 
204+     public  $ partitions ;
205+ 
198206    /** 
199207     * Unparsed tokens. 
200208     * 
@@ -203,15 +211,18 @@ class AlterOperation extends Component
203211    public  $ unknown  = [];
204212
205213    /** 
206-      * @param OptionsArray $options options of alter operation 
207-      * @param Expression   $field   altered field 
208-      * @param Token[]      $unknown unparsed tokens found at the end of operation 
214+      * @param OptionsArray              $options    options of alter operation 
215+      * @param Expression|string|null    $field      altered field 
216+      * @param Component[]|ArrayObj|null $partitions partitions definition found in the operation 
217+      * @param Token[]                   $unknown    unparsed tokens found at the end of operation 
209218     */ 
210219    public  function  __construct (
211220        $ options  = null ,
212221        $ field  = null ,
222+         $ partitions  = null ,
213223        $ unknown  = []
214224    ) {
225+         $ this  ->partitions  = $ partitions ;
215226        $ this  ->options  = $ options ;
216227        $ this  ->field  = $ field ;
217228        $ this  ->unknown  = $ unknown ;
@@ -244,12 +255,21 @@ public static function parse(Parser $parser, TokensList $list, array $options =
244255         * 
245256         *      1 ----------------------[ field ]----------------------> 2 
246257         * 
258+          *      1 -------------[ PARTITION / PARTITION BY ]------------> 3 
259+          * 
247260         *      2 -------------------------[ , ]-----------------------> 0 
248261         * 
249262         * @var int 
250263         */ 
251264        $ state  = 0 ;
252265
266+         /** 
267+          * partition state. 
268+          * 
269+          * @var int 
270+          */ 
271+         $ partitionState  = 0 ;
272+ 
253273        for  (; $ list ->idx  < $ list ->count ; ++$ list ->idx ) {
254274            /** 
255275             * Token parsed at this moment. 
@@ -272,9 +292,8 @@ public static function parse(Parser $parser, TokensList $list, array $options =
272292                    // When parsing the unknown part, the whitespaces are 
273293                    // included to not break anything. 
274294                    $ ret ->unknown [] = $ token ;
295+                     continue ;
275296                }
276- 
277-                 continue ;
278297            }
279298
280299            if  ($ state  === 0 ) {
@@ -293,6 +312,10 @@ public static function parse(Parser $parser, TokensList $list, array $options =
293312                }
294313
295314                $ state  = 1 ;
315+                 if  ($ ret ->options ->has ('PARTITION ' ) || $ token ->value  === 'PARTITION BY ' ) {
316+                     $ state  = 3 ;
317+                     $ list ->getPrevious (); // in order to check whether it's partition or partition by. 
318+                 }
296319            } elseif  ($ state  === 1 ) {
297320                $ ret ->field  = Expression::parse (
298321                    $ parser ,
@@ -362,6 +385,46 @@ public static function parse(Parser $parser, TokensList $list, array $options =
362385                }
363386
364387                $ ret ->unknown [] = $ token ;
388+             } elseif  ($ state  === 3 ) {
389+                 if  ($ partitionState  === 0 ) {
390+                         // We want to get the next non-comment and non-space token after $token 
391+                         // therefore, the first getNext call will start with the current $idx which's $token, 
392+                         // will return it and increase $idx by 1, which's not guaranteed to be non-comment 
393+                         // and non-space, that's why we're calling getNext again. 
394+ 
395+                         $ list ->getNext ();
396+                         $ nextToken  = $ list ->getNext ();
397+                     if  (
398+                         ($ token ->type  === Token::TYPE_KEYWORD )
399+                         && (($ token ->keyword  === 'PARTITION BY ' )
400+                         || ($ token ->keyword  === 'PARTITION '  && $ nextToken  && $ nextToken ->value  !== '( ' ))
401+                     ) {
402+                         $ partitionState  = 1 ;
403+                     } elseif  (($ token ->type  === Token::TYPE_KEYWORD ) && ($ token ->keyword  === 'PARTITION ' )) {
404+                         $ partitionState  = 2 ;
405+                     }
406+ 
407+                     --$ list ->idx ; // to decrease the idx by one, because the last getNext returned and increased it. 
408+ 
409+                     // reverting the effect of the getNext 
410+                     $ list ->getPrevious ();
411+                     $ list ->getPrevious ();
412+ 
413+                     ++$ list ->idx ; // to index the idx by one, because the last getPrevious returned and decreased it. 
414+                 } elseif  ($ partitionState  === 1 ) {
415+                     // Building the expression used for partitioning. 
416+                     if  (empty ($ ret ->field )) {
417+                         $ ret ->field  = '' ;
418+                     }
419+ 
420+                     $ ret ->field  .= $ token ->type  === Token::TYPE_WHITESPACE  ? '  '  : $ token ->token ;
421+                 } elseif  ($ partitionState  === 2 ) {
422+                     $ ret ->partitions  = ArrayObj::parse (
423+                         $ parser ,
424+                         $ list ,
425+                         ['type '  => PartitionDefinition::class]
426+                     );
427+                 }
365428            }
366429        }
367430
@@ -389,6 +452,10 @@ public static function build($component, array $options = [])
389452
390453        $ ret  .= TokensList::build ($ component ->unknown );
391454
455+         if  (isset ($ component ->partitions )) {
456+             $ ret  .= PartitionDefinition::build ($ component ->partitions );
457+         }
458+ 
392459        return  $ ret ;
393460    }
394461
0 commit comments