@@ -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 ' => 'PhpMyAdmin \\SqlParser \\Components \\PartitionDefinition ' ]
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