From cb1d20eb9275691ec57be4e914e8bc9ddc3e63f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Sat, 19 Mar 2016 18:20:39 +0100 Subject: [PATCH] Udate SQL parser to 9d8ae92 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - issue #12109 Fixed parsing of CREATE TABLE [AS] SELECT Signed-off-by: Michal Čihař --- ChangeLog | 1 + .../src/Statements/CreateStatement.php | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3e0a921d82..d8ebf81ea0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -62,6 +62,7 @@ phpMyAdmin - ChangeLog - issue #12098 Fix login after logout with http authentication - issue #12074 Fixed possible invalid SQL export - issue #12026 Fixed parsing of UNION SELECT with brackets +- issue #12109 Fixed parsing of CREATE TABLE [AS] SELECT 4.5.5.1 (2016-02-29) - issue #11971 CREATE UNIQUE INDEX index type is not recognized by parser. diff --git a/libraries/sql-parser/src/Statements/CreateStatement.php b/libraries/sql-parser/src/Statements/CreateStatement.php index 83c856c352..3ccf78f7dc 100644 --- a/libraries/sql-parser/src/Statements/CreateStatement.php +++ b/libraries/sql-parser/src/Statements/CreateStatement.php @@ -19,6 +19,7 @@ use SqlParser\Components\PartitionDefinition; use SqlParser\Components\Expression; use SqlParser\Components\OptionsArray; use SqlParser\Components\ParameterDefinition; +use SqlParser\Statements\SelectStatement; /** * `CREATE` statement. @@ -177,6 +178,15 @@ class CreateStatement extends Statement */ public $fields; + /** + * If `CREATE TABLE ... SELECT` + * + * Used by `CREATE TABLE` + * + * @var SelectStatement + */ + public $select; + /** * Expression used for partitioning. * @@ -267,6 +277,11 @@ class CreateStatement extends Statement . OptionsArray::build($this->options) . ' ' . Expression::build($this->name) . ' ' . OptionsArray::build($this->entityOptions); + } elseif ($this->options->has('TABLE') && !is_null($this->select)) { + return 'CREATE ' + . OptionsArray::build($this->options) . ' ' + . Expression::build($this->name) . ' ' + . $this->select->build(); } elseif ($this->options->has('TABLE')) { $partition = ''; @@ -357,12 +372,34 @@ class CreateStatement extends Statement ++$list->idx; // Skipping field. } + /** + * Token parsed at this moment. + * + * @var Token $token + */ + $token = $list->tokens[$list->idx]; + $nextidx = $list->idx + 1; + while ($nextidx < $list->count && $list->tokens[$nextidx]->type == Token::TYPE_WHITESPACE) { + $nextidx++; + } + if ($this->options->has('DATABASE')) { $this->entityOptions = OptionsArray::parse( $parser, $list, static::$DB_OPTIONS ); + } elseif ($this->options->has('TABLE') && ($token->type == Token::TYPE_KEYWORD) && ($token->value == 'SELECT')) { + /* CREATE TABLE ... SELECT */ + $this->select = new SelectStatement($parser, $list); + } elseif ( + $this->options->has('TABLE') && + ($token->type == Token::TYPE_KEYWORD) && ($token->value == 'AS') && + ($list->tokens[$nextidx]->type == Token::TYPE_KEYWORD) && ($list->tokens[$nextidx]->value == 'SELECT') + ) { + /* CREATE TABLE ... AS SELECT */ + $list->idx = $nextidx; + $this->select = new SelectStatement($parser, $list); } elseif ($this->options->has('TABLE')) { $this->fields = CreateDefinition::parse($parser, $list); if (empty($this->fields)) {