summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDan Ungureanu <udan1107@gmail.com>2015-08-15 22:43:47 +0300
committerDan Ungureanu <udan1107@gmail.com>2015-08-15 22:43:47 +0300
commit724210044ef2606ff383dbc142ad46bf95f1f949 (patch)
treeb4c52ef9c33cc5ba747350ed643f60382cc7cb82 /src
parent09a7047bf51de1d733dd95674f083c1e11c656e1 (diff)
downloadsql-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.php12
-rw-r--r--src/Contexts/ContextMySql50000.php12
-rw-r--r--src/Contexts/ContextMySql50100.php6
-rw-r--r--src/Contexts/ContextMySql50500.php6
-rw-r--r--src/Contexts/ContextMySql50600.php6
-rw-r--r--src/Contexts/ContextMySql50700.php6
-rw-r--r--src/Statements/CreateStatement.php105
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'))
) {