summaryrefslogtreecommitdiffstats
path: root/src/Statements
diff options
context:
space:
mode:
authorDan Ungureanu <udan1107@gmail.com>2015-07-03 21:18:10 +0300
committerDan Ungureanu <udan1107@gmail.com>2015-07-04 23:41:52 +0300
commitb3eff80030f9bd6d90e65360eb89e18a1be298b2 (patch)
treedb420fef27f24856f4cfaeee008104fdfcb77942 /src/Statements
parent4dabcc2ae266c022e44294bfbe3344b05e66e266 (diff)
downloadsql-parser-b3eff80030f9bd6d90e65360eb89e18a1be298b2.zip
sql-parser-b3eff80030f9bd6d90e65360eb89e18a1be298b2.tar.gz
sql-parser-b3eff80030f9bd6d90e65360eb89e18a1be298b2.tar.bz2
The context depends on the SQL mode.
Implemented a few more builders. Improved some fragments and statement types. Fixed the noAlias option in FieldFragment. Reordered CREATE statements's options. Updated contexts definitions. Fixed typos. Improved tests.
Diffstat (limited to 'src/Statements')
-rw-r--r--src/Statements/AlterStatement.php143
-rw-r--r--src/Statements/CreateStatement.php92
-rw-r--r--src/Statements/DropStatement.php15
-rw-r--r--src/Statements/NotImplementedStatement.php37
-rw-r--r--src/Statements/SelectStatement.php2
5 files changed, 176 insertions, 113 deletions
diff --git a/src/Statements/AlterStatement.php b/src/Statements/AlterStatement.php
index 81bca05..92f3744 100644
--- a/src/Statements/AlterStatement.php
+++ b/src/Statements/AlterStatement.php
@@ -9,11 +9,12 @@
namespace SqlParser\Statements;
use SqlParser\Parser;
+use SqlParser\Statement;
use SqlParser\Token;
use SqlParser\TokensList;
+use SqlParser\Fragments\AlterFragment;
use SqlParser\Fragments\FieldFragment;
use SqlParser\Fragments\OptionsFragment;
-use SqlParser\Statements\NotImplementedStatement;
/**
* `ALTER` statement.
@@ -24,7 +25,7 @@ use SqlParser\Statements\NotImplementedStatement;
* @author Dan Ungureanu <udan1107@gmail.com>
* @license http://opensource.org/licenses/GPL-2.0 GNU Public License
*/
-class AlterStatement extends NotImplementedStatement
+class AlterStatement extends Statement
{
/**
@@ -37,9 +38,9 @@ class AlterStatement extends NotImplementedStatement
/**
* Column affected by this statement.
*
- * @var FieldFragment
+ * @var AlterFragment[]
*/
- public $altered;
+ public $altered = array();
/**
* Options of this statement.
@@ -47,83 +48,91 @@ class AlterStatement extends NotImplementedStatement
* @var array
*/
public static $OPTIONS = array(
-
'ONLINE' => 1,
'OFFLINE' => 1,
-
'IGNORE' => 2,
-
- 'TABLE' => 3,
-
- 'ADD' => 4,
- 'ALTER' => 4,
- 'ANALYZE' => 4,
- 'CHANGE' => 4,
- 'CHECK' => 4,
- 'COALESCE' => 4,
- 'CONVERT' => 4,
- 'DISABLE' => 4,
- 'DISCARD' => 4,
- 'DROP' => 4,
- 'ENABLE' => 4,
- 'IMPORT' => 4,
- 'MODIFY' => 4,
- 'OPTIMIZE' => 4,
- 'ORDER' => 4,
- 'PARTITION' => 4,
- 'REBUILD' => 4,
- 'REMOVE' => 4,
- 'RENAME' => 4,
- 'REORGANIZE' => 4,
- 'REPAIR' => 4,
-
- 'COLUMN' => 5,
- 'CONSTRAINT' => 5,
- 'DEFAULT' => 5,
- 'TO' => 5,
- 'BY' => 5,
- 'FOREIGN' => 5,
- 'FULLTEXT' => 5,
- 'KEYS' => 5,
- 'PARTITIONING' => 5,
- 'PRIMARY KEY' => 5,
- 'SPATIAL' => 5,
- 'TABLESPACE' => 5,
- 'INDEX' => 5,
-
- 'DEFAULT CHARACTER SET' => array(6, 'var'),
-
- 'COLLATE' => array(7, 'var'),
);
/**
- * Function called after the token was processed.
- *
- * Extracts the name of affected column.
- *
* @param Parser $parser The instance that requests parsing.
* @param TokensList $list The list of tokens to be parsed.
- * @param Token $token The token that is being parsed.
*
* @return void
*/
- public function after(Parser $parser, TokensList $list, Token $token)
+ public function parse(Parser $parser, TokensList $list)
{
- // Parsing operation.
- ++$list->idx;
- $this->options->merge(
- OptionsFragment::parse(
- $parser,
- $list,
- static::$OPTIONS
- )
+ ++$list->idx; // Skipping `ALTER`.
+ $this->options = OptionsFragment::parse(
+ $parser,
+ $list,
+ static::$OPTIONS
);
- // Parsing affected field.
- ++$list->idx;
- $this->altered = FieldFragment::parse($parser, $list);
+ // Skipping `TABLE`.
+ $list->getNextOfTypeAndValue(Token::TYPE_KEYWORD, 'TABLE');
- //
- parent::after($parser, $list, $token);
+ // Parsing affected table.
+ $this->table = FieldFragment::parse(
+ $parser, $list, array(
+ 'noAlias' => true,
+ 'noBrackets' => true,
+ )
+ );
+ ++$list->idx; // Skipping field.
+
+ /**
+ * The state of the parser.
+ *
+ * Below are the states of the parser.
+ *
+ * 0 -----------------[ alter operation ]-----------------> 1
+ *
+ * 1 -------------------------[ , ]-----------------------> 0
+ *
+ * @var int
+ */
+ $state = 0;
+
+ for (; $list->idx < $list->count; ++$list->idx) {
+ /**
+ * Token parsed at this moment.
+ * @var Token
+ */
+ $token = $list->tokens[$list->idx];
+
+ // End of statement.
+ if ($token->type === Token::TYPE_DELIMITER) {
+ break;
+ }
+
+ // Skipping whitespaces and comments.
+ if (($token->type === Token::TYPE_WHITESPACE) || ($token->type === Token::TYPE_COMMENT)) {
+ continue;
+ }
+
+ if ($state === 0) {
+ $this->altered[] = AlterFragment::parse($parser, $list);
+ $state = 1;
+ } else if ($state === 1) {
+ if (($token->type === Token::TYPE_OPERATOR) && ($token->value === ',')) {
+ $state = 0;
+ }
+ }
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function build()
+ {
+ $tmp = array();
+ foreach ($this->altered as $altered) {
+ $tmp[] = $altered::build($altered);
+ }
+
+ return 'ALTER ' . OptionsFragment::build($this->options)
+ . ' TABLE ' . FieldFragment::build($this->table)
+ . ' ' . implode(', ', $tmp);
}
}
diff --git a/src/Statements/CreateStatement.php b/src/Statements/CreateStatement.php
index 7fd8ef0..306bfeb 100644
--- a/src/Statements/CreateStatement.php
+++ b/src/Statements/CreateStatement.php
@@ -38,30 +38,30 @@ class CreateStatement extends Statement
*/
public static $OPTIONS = array(
- 'DATABASE' => 1,
- 'EVENT' => 1,
- 'FUNCTION' => 1,
- 'INDEX' => 1,
- 'PROCEDURE' => 1,
- 'SERVER' => 1,
- 'TABLE' => 1,
- 'TABLESPACE' => 1,
- 'TRIGGER' => 1,
- 'USER' => 1,
- 'VIEW' => 1,
-
// CREATE TABLE
- 'TEMPORARY' => 2,
- 'IF NOT EXISTS' => 3,
+ 'TEMPORARY' => 1,
+ 'IF NOT EXISTS' => 2,
// CREATE FUNCTION / PROCEDURE and CREATE VIEW
- 'DEFINER' => array(2, 'var'),
+ 'DEFINER' => array(1, 'var='),
// CREATE VIEW
- 'OR REPLACE' => array(3, 'var'),
- 'ALGORITHM' => array(4, 'var'),
- 'DEFINER' => array(5, 'var'),
- 'SQL SECURITY' => array(6, 'var'),
+ 'OR REPLACE' => array(2, 'var='),
+ 'ALGORITHM' => array(3, 'var='),
+ 'DEFINER' => array(4, 'var='),
+ 'SQL SECURITY' => array(5, 'var'),
+
+ 'DATABASE' => 6,
+ 'EVENT' => 6,
+ 'FUNCTION' => 6,
+ 'INDEX' => 6,
+ 'PROCEDURE' => 6,
+ 'SERVER' => 6,
+ 'TABLE' => 6,
+ 'TABLESPACE' => 6,
+ 'TRIGGER' => 6,
+ 'USER' => 6,
+ 'VIEW' => 6,
);
/**
@@ -70,8 +70,8 @@ class CreateStatement extends Statement
* @var array
*/
public static $TABLE_OPTIONS = array(
- 'ENGINE' => array(1, 'var'),
- 'AUTO_INCREMENT' => array(2, 'var'),
+ 'ENGINE' => array(1, 'var='),
+ 'AUTO_INCREMENT' => array(2, 'var='),
'AVG_ROW_LENGTH' => array(3, 'var'),
'DEFAULT CHARACTER SET' => array(4, 'var'),
'CHARACTER SET' => array(4, 'var'),
@@ -144,15 +144,6 @@ class CreateStatement extends Statement
public $fields;
/**
- * The `SELECT` statement that defines this view.
- *
- * Used by `CREATE VIEW`.
- *
- * @var SelectStatement
- */
- public $select;
-
- /**
* The return data type of this routine.
*
* Used by `CREATE FUNCTION`.
@@ -170,15 +161,36 @@ class CreateStatement extends Statement
*/
public $parameters;
-
/**
- * The body of this function or procedure.
+ * The body of this function or procedure. For views, it is the select
+ * statement that gets the
*
- * Used by `CREATE FUNCTION` and `CREATE PROCEDURE`.
+ * Used by `CREATE FUNCTION`, `CREATE PROCEDURE` and `CREATE VIEW`.
*
* @var Token[]
*/
- public $body;
+ public $body = array();
+
+ /**
+ * @return string
+ */
+ public function build()
+ {
+ $tmp = '';
+ if ($this->options->has('TABLE')) {
+ $tmp = FieldDefFragment::build($this->fields);
+ } elseif ($this->options->has('VIEW')) {
+ if (!empty($this->fields)) {
+ $tmp .= ArrayFragment::build($this->fields) . ' ';
+ }
+ $tmp .= 'AS ' . TokensList::build($this->body);
+ }
+ return 'CREATE '
+ . OptionsFragment::build($this->options) . ' '
+ . FieldFragment::build($this->name) . ' '
+ . $tmp . ' '
+ . OptionsFragment::build($this->entityOptions);
+ }
/**
* @param Parser $parser The instance that requests parsing.
@@ -258,11 +270,17 @@ class CreateStatement extends Statement
--$list->idx; // getNext() also goes forward one field.
$this->fields = ArrayFragment::parse($parser, $list);
++$list->idx; // Skipping last token from the array.
- $token = $list->getNext();
+ $list->getNext();
}
- // Parsing the 'SELECT' statement.
- $this->select = new SelectStatement($parser, $list);
+ // Parsing the `AS` keyword.
+ for (; $list->idx < $list->count; ++$list->idx) {
+ $token = $list->tokens[$list->idx];
+ if ($token->type === Token::TYPE_DELIMITER) {
+ break;
+ }
+ $this->body[] = $token;
+ }
}
}
}
diff --git a/src/Statements/DropStatement.php b/src/Statements/DropStatement.php
index babf18a..f0cd1ce 100644
--- a/src/Statements/DropStatement.php
+++ b/src/Statements/DropStatement.php
@@ -46,6 +46,21 @@ class DropStatement extends Statement
);
/**
+ * The clauses of this statement, in order.
+ *
+ * @see Statement::$CLAUSES
+ *
+ * @var array
+ */
+ public static $CLAUSES = array(
+ 'DROP' => array('DROP', 2),
+ // Used for options.
+ '_OPTIONS' => array('_OPTIONS', 1),
+ // Used for select expressions.
+ 'DROP_' => array('DROP', 1),
+ );
+
+ /**
* Dropped elements.
*
* @var FieldFragment[]
diff --git a/src/Statements/NotImplementedStatement.php b/src/Statements/NotImplementedStatement.php
index b96c558..f5f8b8f 100644
--- a/src/Statements/NotImplementedStatement.php
+++ b/src/Statements/NotImplementedStatement.php
@@ -28,19 +28,40 @@ class NotImplementedStatement extends Statement
{
/**
- * Function called after the token was processed.
- *
- * Jump to the end of the delimiter.
- *
+ * The part of the statement that can't be parsed.
+ * @var Token[]
+ */
+ public $unknown = array();
+
+ /**
+ * @return string
+ */
+ public function build()
+ {
+ // Building the parsed part of the query (if any).
+ $query = parent::build() . ' ';
+
+ // Rebuilding the unknown part from tokens.
+ foreach ($this->unknown as $token) {
+ $query .= $token->token;
+ }
+
+ return $query;
+ }
+
+ /**
* @param Parser $parser The instance that requests parsing.
* @param TokensList $list The list of tokens to be parsed.
- * @param Token $token The token that is being parsed.
*
* @return void
*/
- public function after(Parser $parser, TokensList $list, Token $token)
+ public function parse(Parser $parser, TokensList $list)
{
- $list->getNextOfType(Token::TYPE_DELIMITER);
- --$list->idx;
+ for (; $list->idx < $list->count; ++$list->idx) {
+ if ($list->tokens[$list->idx]->type === Token::TYPE_DELIMITER) {
+ break;
+ }
+ $this->unknown[] = $list->tokens[$list->idx];
+ }
}
}
diff --git a/src/Statements/SelectStatement.php b/src/Statements/SelectStatement.php
index 84ec5a2..e376b47 100644
--- a/src/Statements/SelectStatement.php
+++ b/src/Statements/SelectStatement.php
@@ -57,7 +57,7 @@ class SelectStatement extends Statement
'DISTINCT' => 1,
'DISTINCTROW' => 1,
'HIGH_PRIORITY' => 2,
- 'MAX_STATEMENT_TIME' => array(3, 'var'),
+ 'MAX_STATEMENT_TIME' => array(3, 'var='),
'STRAIGHT_JOIN' => 4,
'SQL_SMALL_RESULT' => 5,
'SQL_BIG_RESULT' => 6,