diff options
author | Dan Ungureanu <udan1107@gmail.com> | 2015-08-15 22:43:47 +0300 |
---|---|---|
committer | Dan Ungureanu <udan1107@gmail.com> | 2015-08-15 22:43:47 +0300 |
commit | 724210044ef2606ff383dbc142ad46bf95f1f949 (patch) | |
tree | b4c52ef9c33cc5ba747350ed643f60382cc7cb82 /src | |
parent | 09a7047bf51de1d733dd95674f083c1e11c656e1 (diff) | |
download | sql-parser-724210044ef2606ff383dbc142ad46bf95f1f949.zip sql-parser-724210044ef2606ff383dbc142ad46bf95f1f949.tar.gz sql-parser-724210044ef2606ff383dbc142ad46bf95f1f949.tar.bz2 |
Initial support for partitions.
Diffstat (limited to 'src')
-rw-r--r-- | src/Components/ArrayObj.php | 12 | ||||
-rw-r--r-- | src/Contexts/ContextMySql50000.php | 12 | ||||
-rw-r--r-- | src/Contexts/ContextMySql50100.php | 6 | ||||
-rw-r--r-- | src/Contexts/ContextMySql50500.php | 6 | ||||
-rw-r--r-- | src/Contexts/ContextMySql50600.php | 6 | ||||
-rw-r--r-- | src/Contexts/ContextMySql50700.php | 6 | ||||
-rw-r--r-- | src/Statements/CreateStatement.php | 105 |
7 files changed, 135 insertions, 18 deletions
diff --git a/src/Components/ArrayObj.php b/src/Components/ArrayObj.php index ef0f79f..422c81c 100644 --- a/src/Components/ArrayObj.php +++ b/src/Components/ArrayObj.php @@ -56,11 +56,11 @@ class ArrayObj extends Component * @param TokensList $list The list of tokens that are being parsed. * @param array $options Parameters for parsing. * - * @return ArrayObj + * @return mixed */ public static function parse(Parser $parser, TokensList $list, array $options = array()) { - $ret = new ArrayObj(); + $ret = empty($options['type']) ? new ArrayObj() : array(); /** * The state of the parser. @@ -109,8 +109,12 @@ class ArrayObj extends Component // Empty array. break; } - $ret->values[] = $token->value; - $ret->raw[] = $token->token; + if (empty($options['type'])) { + $ret->values[] = $token->value; + $ret->raw[] = $token->token; + } else { + $ret[] = $options['type']::parse($parser, $list); + } $state = 2; } elseif ($state === 2) { if (($token->type !== Token::TYPE_OPERATOR) || (($token->value !== ',') && ($token->value !== ')'))) { diff --git a/src/Contexts/ContextMySql50000.php b/src/Contexts/ContextMySql50000.php index ed86320..8767398 100644 --- a/src/Contexts/ContextMySql50000.php +++ b/src/Contexts/ContextMySql50000.php @@ -77,8 +77,8 @@ class ContextMySql50000 extends Context 'VARIABLES' => 1, 'BERKELEYDB' => 1, 'COMPRESSED' => 1, 'CONCURRENT' => 1, 'CONNECTION' => 1, 'CONSISTENT' => 1, 'DEALLOCATE' => 1, 'IDENTIFIED' => 1, 'MASTER_SSL' => 1, - 'NDBCLUSTER' => 1, 'PERSISTENT' => 1, 'PRIVILEGES' => 1, 'REPEATABLE' => 1, - 'ROW_FORMAT' => 1, 'SQL_THREAD' => 1, 'TABLESPACE' => 1, + 'NDBCLUSTER' => 1, 'PARTITIONS' => 1, 'PERSISTENT' => 1, 'PRIVILEGES' => 1, + 'REPEATABLE' => 1, 'ROW_FORMAT' => 1, 'SQL_THREAD' => 1, 'TABLESPACE' => 1, 'FRAC_SECOND' => 1, 'MASTER_HOST' => 1, 'MASTER_PORT' => 1, 'MASTER_USER' => 1, 'PROCESSLIST' => 1, 'RAID_CHUNKS' => 1, 'REPLICATION' => 1, 'SQL_TSI_DAY' => 1, 'TRANSACTION' => 1, 'UNCOMMITTED' => 1, @@ -86,7 +86,7 @@ class ContextMySql50000 extends Context 'SQL_NO_CACHE' => 1, 'SQL_TSI_HOUR' => 1, 'SQL_TSI_WEEK' => 1, 'SQL_TSI_YEAR' => 1, 'INSERT_METHOD' => 1, 'MASTER_SSL_CA' => 1, 'RELAY_LOG_POS' => 1, - 'SQL_TSI_MONTH' => 1, + 'SQL_TSI_MONTH' => 1, 'SUBPARTITIONS' => 1, 'AUTO_INCREMENT' => 1, 'AVG_ROW_LENGTH' => 1, 'MASTER_LOG_POS' => 1, 'MASTER_SSL_KEY' => 1, 'RAID_CHUNKSIZE' => 1, 'RELAY_LOG_FILE' => 1, 'SQL_TSI_MINUTE' => 1, 'SQL_TSI_SECOND' => 1, 'USER_RESOURCES' => 1, @@ -145,12 +145,14 @@ class ContextMySql50000 extends Context 'GROUP BY' => 7, 'NOT NULL' => 7, 'ORDER BY' => 7, 'SET NULL' => 7, 'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7, - 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7, + 'LESS THAN' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7, 'INNER JOIN' => 7, 'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7, - 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'SQL SECURITY' => 7, + 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'PARTITION BY' => 7, + 'SQL SECURITY' => 7, 'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7, 'DATA DIRECTORY' => 7, 'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7, + 'SUBPARTITION BY' => 7, 'GENERATED ALWAYS' => 7, 'START TRANSACTION' => 7, 'SELECT TRANSACTION' => 7, diff --git a/src/Contexts/ContextMySql50100.php b/src/Contexts/ContextMySql50100.php index c71ff6c..63fcb80 100644 --- a/src/Contexts/ContextMySql50100.php +++ b/src/Contexts/ContextMySql50100.php @@ -157,12 +157,14 @@ class ContextMySql50100 extends Context 'GROUP BY' => 7, 'NOT NULL' => 7, 'ORDER BY' => 7, 'SET NULL' => 7, 'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7, - 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7, + 'LESS THAN' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7, 'INNER JOIN' => 7, 'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7, - 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'SQL SECURITY' => 7, + 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'PARTITION BY' => 7, + 'SQL SECURITY' => 7, 'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7, 'DATA DIRECTORY' => 7, 'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7, + 'SUBPARTITION BY' => 7, 'GENERATED ALWAYS' => 7, 'START TRANSACTION' => 7, 'SELECT TRANSACTION' => 7, diff --git a/src/Contexts/ContextMySql50500.php b/src/Contexts/ContextMySql50500.php index 6f6bb66..49d0df5 100644 --- a/src/Contexts/ContextMySql50500.php +++ b/src/Contexts/ContextMySql50500.php @@ -162,12 +162,14 @@ class ContextMySql50500 extends Context 'GROUP BY' => 7, 'NOT NULL' => 7, 'ORDER BY' => 7, 'SET NULL' => 7, 'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7, - 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7, + 'LESS THAN' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7, 'INNER JOIN' => 7, 'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7, - 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'SQL SECURITY' => 7, + 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'PARTITION BY' => 7, + 'SQL SECURITY' => 7, 'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7, 'DATA DIRECTORY' => 7, 'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7, + 'SUBPARTITION BY' => 7, 'GENERATED ALWAYS' => 7, 'START TRANSACTION' => 7, 'SELECT TRANSACTION' => 7, diff --git a/src/Contexts/ContextMySql50600.php b/src/Contexts/ContextMySql50600.php index 62b75ab..6bb41f1 100644 --- a/src/Contexts/ContextMySql50600.php +++ b/src/Contexts/ContextMySql50600.php @@ -167,12 +167,14 @@ class ContextMySql50600 extends Context 'GROUP BY' => 7, 'NOT NULL' => 7, 'ORDER BY' => 7, 'SET NULL' => 7, 'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7, - 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7, + 'LESS THAN' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7, 'INNER JOIN' => 7, 'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7, - 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'SQL SECURITY' => 7, + 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'PARTITION BY' => 7, + 'SQL SECURITY' => 7, 'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7, 'DATA DIRECTORY' => 7, 'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7, + 'SUBPARTITION BY' => 7, 'GENERATED ALWAYS' => 7, 'START TRANSACTION' => 7, 'SELECT TRANSACTION' => 7, diff --git a/src/Contexts/ContextMySql50700.php b/src/Contexts/ContextMySql50700.php index 8b0568b..9397c21 100644 --- a/src/Contexts/ContextMySql50700.php +++ b/src/Contexts/ContextMySql50700.php @@ -175,12 +175,14 @@ class ContextMySql50700 extends Context 'GROUP BY' => 7, 'NOT NULL' => 7, 'ORDER BY' => 7, 'SET NULL' => 7, 'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7, - 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7, + 'LESS THAN' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7, 'INNER JOIN' => 7, 'NO RELEASE' => 7, 'OR REPLACE' => 7, 'RIGHT JOIN' => 7, - 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'SQL SECURITY' => 7, + 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'PARTITION BY' => 7, + 'SQL SECURITY' => 7, 'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7, 'DATA DIRECTORY' => 7, 'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7, + 'SUBPARTITION BY' => 7, 'GENERATED ALWAYS' => 7, 'START TRANSACTION' => 7, 'SELECT TRANSACTION' => 7, diff --git a/src/Statements/CreateStatement.php b/src/Statements/CreateStatement.php index 4c0d985..2dd5775 100644 --- a/src/Statements/CreateStatement.php +++ b/src/Statements/CreateStatement.php @@ -229,11 +229,27 @@ class CreateStatement extends Statement . Expression::build($this->name) . ' ' . OptionsArray::build($this->entityOptions); } elseif ($this->options->has('TABLE')) { + $partition = ''; + + if (!empty($this->partitionBy)) { + $partition .= ' PARTITION BY ' . $this->partitionBy; + } + if (!empty($this->partitionsNum)) { + $partition .= ' PARTITIONS ' . $this->partitionsNum; + } + if (!empty($this->subpartitionBy)) { + $partition .= ' SUBPARTITION BY ' . $this->subpartitionBy; + } + if (!empty($this->subpartitionsNum)) { + $partition .= ' SUBPARTITIONS ' . $this->subpartitionsNum; + } + return 'CREATE ' . OptionsArray::build($this->options) . ' ' . Expression::build($this->name) . ' ' . $fields - . OptionsArray::build($this->entityOptions); + . OptionsArray::build($this->entityOptions) + . $partition; } elseif ($this->options->has('VIEW')) { return 'CREATE ' . OptionsArray::build($this->options) . ' ' @@ -318,6 +334,93 @@ class CreateStatement extends Statement $list, static::$TABLE_OPTIONS ); + + /** + * The field that is being filled (`partitionBy` or + * `subpartitionBy`). + * + * @var string $field + */ + $field = null; + + /** + * The number of brackets. `false` means no bracket was found + * previously. At least one bracket is required to validate the + * expression. + * + * @var int|bool + */ + $brackets = false; + + /* + * Handles partitions. + */ + for (; $list->idx < $list->count; ++$list->idx) { + + /** + * Token parsed at this moment. + * @var Token $token + */ + $token = $list->tokens[$list->idx]; + + // End of statement. + if ($token->type === Token::TYPE_DELIMITER) { + break; + } + + // Skipping comments. + if ($token->type === Token::TYPE_COMMENT) { + continue; + } + + if (($token->type === Token::TYPE_KEYWORD) && ($token->value === 'PARTITION BY')) { + $field = 'partitionBy'; + $brackets = false; + } elseif (($token->type === Token::TYPE_KEYWORD) && ($token->value === 'SUBPARTITION BY')) { + $field = 'subpartitionBy'; + $brackets = false; + } elseif (($token->type === Token::TYPE_KEYWORD) && ($token->value === 'PARTITIONS')) { + $token = $list->getNextOfType(Token::TYPE_NUMBER); + $this->partitionsNum = $token->value; + } elseif (($token->type === Token::TYPE_KEYWORD) && ($token->value === 'SUBPARTITIONS')) { + $token = $list->getNextOfType(Token::TYPE_NUMBER); + $this->subpartitionsNum = $token->value; + } elseif (!empty($field)) { + + /* + * Handling the content of `PARTITION BY` and `SUBPARTITION BY`. + */ + + // Counting brackets. + if (($token->type === Token::TYPE_OPERATOR) && ($token->value === '(')) { + // This is used instead of `++$brackets` because, + // initially, `$brackets` is `false` cannot be + // incremented. + $brackets = $brackets + 1; + } elseif (($token->type === Token::TYPE_OPERATOR) && ($token->value === ')')) { + --$brackets; + } + + // Building the expression used for partitioning. + $this->$field .= ($token->type === Token::TYPE_WHITESPACE) ? ' ' : $token->token; + + // Last bracket was read, the expression ended. + // Comparing with `0` and not `false`, because `false` means + // that no bracket was found and at least one must is + // required. + if ($brackets === 0) { + $this->$field = trim($this->$field); + $field = null; + } + } elseif (($token->type === Token::TYPE_OPERATOR) && ($token->value === '(')) { + $this->partitions = ArrayObj::parse( + $parser, + $list, + array('type' => 'SqlParser\Components\PartitionDefinition') + ); + break; + } + } } elseif (($this->options->has('PROCEDURE')) || ($this->options->has('FUNCTION')) ) { |