Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/phpmyadmin/phpmyadmin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Ungureanu <udan1107@gmail.com>2015-07-07 03:21:38 +0300
committerDan Ungureanu <udan1107@gmail.com>2015-07-10 23:18:17 +0300
commiteeafcad986917b581292a1c7ac0c27cf98f67787 (patch)
treee5f245901869531e39daaec2e35fb4003251bbe3
parent11f42cd80ea60c44eca74ddae82414023f9cfce6 (diff)
Using the new parser to simulate queries.
Updated sql-parser library to udan11/sql-parser@e58d230. Signed-off-by: Dan Ungureanu <udan1107@gmail.com>
-rw-r--r--libraries/import.lib.php415
-rw-r--r--libraries/sql-parser/src/Contexts/ContextMySql50000.php2
-rw-r--r--libraries/sql-parser/src/Contexts/ContextMySql50100.php2
-rw-r--r--libraries/sql-parser/src/Contexts/ContextMySql50500.php2
-rw-r--r--libraries/sql-parser/src/Contexts/ContextMySql50600.php2
-rw-r--r--libraries/sql-parser/src/Contexts/ContextMySql50700.php2
-rw-r--r--libraries/sql-parser/src/Fragments/AlterFragment.php2
-rw-r--r--libraries/sql-parser/src/Fragments/FieldDefFragment.php1
-rw-r--r--libraries/sql-parser/src/Fragments/IntoKeyword.php18
-rw-r--r--libraries/sql-parser/src/Fragments/ParamDefFragment.php21
-rw-r--r--libraries/sql-parser/src/Fragments/RenameKeyword.php28
-rw-r--r--libraries/sql-parser/src/Fragments/SetKeyword.php9
-rw-r--r--libraries/sql-parser/src/Parser.php9
-rw-r--r--libraries/sql-parser/src/Statements/CheckStatement.php7
-rw-r--r--libraries/sql-parser/src/Statements/ChecksumStatement.php7
-rw-r--r--libraries/sql-parser/src/Statements/CreateStatement.php126
-rw-r--r--libraries/sql-parser/src/Statements/DeleteStatement.php18
-rw-r--r--libraries/sql-parser/src/Statements/RepairStatement.php7
-rw-r--r--libraries/sql-parser/src/Statements/RestoreStatement.php7
-rw-r--r--libraries/sql-parser/src/Statements/SelectStatement.php2
-rw-r--r--libraries/sql-parser/src/Statements/TruncateStatement.php49
-rw-r--r--libraries/sql-parser/src/Statements/UpdateStatement.php21
-rw-r--r--libraries/sql-parser/src/TokensList.php7
-rw-r--r--libraries/sql-parser/src/Utils/Query.php51
-rw-r--r--test/libraries/PMA_import_test.php41
25 files changed, 430 insertions, 426 deletions
diff --git a/libraries/import.lib.php b/libraries/import.lib.php
index 9656e97503..9f379e6026 100644
--- a/libraries/import.lib.php
+++ b/libraries/import.lib.php
@@ -1388,33 +1388,33 @@ function PMA_handleSimulateDMLRequest()
continue;
}
- // Parse and Analyze the query.
- $parsed_sql = PMA_SQP_parse($sql_query);
- $analyzed_sql = PMA_SQP_analyze($parsed_sql);
+ // Parsing the query.
+ $parser = new SqlParser\Parser($sql_query);
+
+ if (empty($parser->statements[0])) {
+ continue;
+ }
+
+ $statement = $parser->statements[0];
+
$analyzed_sql_results = array(
- 'parsed_sql' => $parsed_sql,
- 'analyzed_sql' => $analyzed_sql
+ 'query' => $sql_query,
+ 'parser' => $parser,
+ 'statement' => $statement,
);
- // Only UPDATE/DELETE queries accepted.
- $query_type = $analyzed_sql_results['analyzed_sql'][0]['querytype'];
- if ($query_type != 'UPDATE' && $query_type != 'DELETE') {
+ if ((!(($statement instanceof SqlParser\Statements\UpdateStatement) ||
+ ($statement instanceof SqlParser\Statements\DeleteStatement))) ||
+ (!empty($statement->join))
+ ) {
$error = $error_msg;
break;
}
- // Only single-table queries accepted.
- $table_references = PMA_getTableReferences($analyzed_sql_results);
- $table_references = $table_references ? $table_references : '';
- if (preg_match('/JOIN/i', $table_references)) {
+ $tables = SqlParser\Utils\Query::getTables($statement);
+ if (count($tables) > 1) {
$error = $error_msg;
break;
- } else {
- $tables = explode(',', $table_references);
- if (count($tables) > 1) {
- $error = $error_msg;
- break;
- }
}
// Get the matched rows for the query.
@@ -1444,20 +1444,18 @@ function PMA_handleSimulateDMLRequest()
*/
function PMA_getMatchedRows($analyzed_sql_results = array())
{
- // Get the query type.
- $query_type = (isset($analyzed_sql_results['analyzed_sql'][0]['querytype']))
- ? $analyzed_sql_results['analyzed_sql'][0]['querytype']
- : '';
+ $statement = $analyzed_sql_results['statement'];
$matched_row_query = '';
- if ($query_type == 'DELETE') {
+ if ($statement instanceof SqlParser\Statements\DeleteStatement) {
$matched_row_query = PMA_getSimulatedDeleteQuery($analyzed_sql_results);
- } else if ($query_type == 'UPDATE') {
+ } elseif ($statement instanceof SqlParser\Statements\UpdateStatement) {
$matched_row_query = PMA_getSimulatedUpdateQuery($analyzed_sql_results);
}
// Execute the query and get the number of matched rows.
$matched_rows = PMA_executeMatchedRowQuery($matched_row_query);
+
// URL to matched rows.
$_url_params = array(
'db' => $GLOBALS['db'],
@@ -1466,9 +1464,7 @@ function PMA_getMatchedRows($analyzed_sql_results = array())
$matched_rows_url = 'sql.php' . PMA_URL_getCommon($_url_params);
return array(
- 'sql_query' => PMA_Util::formatSql(
- $analyzed_sql_results['parsed_sql']['raw']
- ),
+ 'sql_query' => PMA_Util::formatSql($analyzed_sql_results['query']),
'matched_rows' => $matched_rows,
'matched_rows_url' => $matched_rows_url
);
@@ -1483,95 +1479,50 @@ function PMA_getMatchedRows($analyzed_sql_results = array())
*/
function PMA_getSimulatedUpdateQuery($analyzed_sql_results)
{
- $where_clause = '';
- $extra_where_clause = array();
- $target_cols = array();
-
- $prev_term = '';
- $i = 0;
- $in_function = 0;
- foreach ($analyzed_sql_results['parsed_sql'] as $key => $term) {
- if (! isset($get_set_expr)
- && preg_match(
- '/\bSET\b/i',
- isset($term['data']) ? $term['data'] : ''
- )
- ) {
- $get_set_expr = true;
- continue;
- }
-
- if (isset($get_set_expr)) {
- if (preg_match(
- '/\bWHERE\b|\bORDER BY\b|\bLIMIT\b/i',
- isset($term['data']) ? $term['data'] : ''
- )
- ) {
- break;
- }
- if (!$in_function) {
- if ($term['type'] == 'punct_listsep') {
- $extra_where_clause[] = ' OR ';
- } else if ($term['type'] == 'punct') {
- $extra_where_clause[] = ' <> ';
- } else if ($term['type'] == 'alpha_functionName') {
- array_pop($extra_where_clause);
- array_pop($extra_where_clause);
- } else {
- $extra_where_clause[] = $term['data'];
- }
- } else if ($term['type'] == 'punct_bracket_close_round') {
- $in_function--;
- }
+ $table_references = SqlParser\Utils\Query::getTables(
+ $analyzed_sql_results['statement']
+ );
- if ($term['type'] == 'alpha_functionName') {
- $in_function++;
- }
+ $where = SqlParser\Utils\Query::getClause(
+ $analyzed_sql_results['statement'],
+ $analyzed_sql_results['parser']->list,
+ 'WHERE'
+ );
- // Get columns in SET expression.
- if ($prev_term != 'punct') {
- if ($term['type'] != 'punct_listsep'
- && $term['type'] != 'punct'
- && $term['type'] != 'punct_bracket_open_round'
- && $term['type'] != 'punct_bracket_close_round'
- && !$in_function
- && isset($term['data'])
- ) {
- if (isset($target_cols[$i])) {
- $target_cols[$i] .= $term['data'];
- } else {
- $target_cols[$i] = $term['data'];
- }
- }
- } else {
- $i++;
- }
+ if (empty($where)) {
+ $where = '1';
+ }
- $prev_term = $term['type'];
- continue;
- }
+ $diff = array();
+ foreach ($analyzed_sql_results['statement']->set as $set) {
+ $columns[] = $set->column;
+ $diff[] = $set->column . ' <> ' . $set->value;
+ }
+ if (!empty($diff)) {
+ $where .= ' AND (' . implode(' OR ', $diff) . ')';
}
- // Get table_references.
- $table_references = PMA_getTableReferences($analyzed_sql_results);
- $target_cols = implode(', ', $target_cols);
+ $order_and_limit = '';
- // Get WHERE clause.
- $where_clause .= $analyzed_sql_results['analyzed_sql'][0]['where_clause'];
- if (empty($where_clause)) {
- $where_clause = (!empty($extra_where_clause) && $extra_where_clause[0])
- ? implode(' ', $extra_where_clause)
- : '1';
+ if (!empty($analyzed_sql_results['statement']->order)) {
+ $order_and_limit .= ' ORDER BY ' . SqlParser\Utils\Query::getClause(
+ $analyzed_sql_results['statement'],
+ $analyzed_sql_results['parser']->list,
+ 'ORDER BY'
+ );
}
- $matched_row_query = 'SELECT '
- . $target_cols
- . ' FROM '
- . $table_references
- . ' WHERE '
- . $where_clause;
+ if (!empty($analyzed_sql_results['statement']->limit)) {
+ $order_and_limit .= ' LIMIT ' . SqlParser\Utils\Query::getClause(
+ $analyzed_sql_results['statement'],
+ $analyzed_sql_results['parser']->list,
+ 'LIMIT'
+ );
+ }
- return $matched_row_query;
+ return 'SELECT ' . implode(', ', $columns) .
+ ' FROM ' . implode(', ', $table_references) .
+ ' WHERE ' . $where . $order_and_limit;
}
/**
@@ -1583,115 +1534,40 @@ function PMA_getSimulatedUpdateQuery($analyzed_sql_results)
*/
function PMA_getSimulatedDeleteQuery($analyzed_sql_results)
{
- $where_clause = '';
-
- $where_clause .= $analyzed_sql_results['analyzed_sql'][0]['where_clause'];
- if (empty($where_clause)) {
- $where_clause = '1';
- }
-
- // Get the table_references.
- $table_references = PMA_getTableReferences($analyzed_sql_results);
-
- $matched_row_query = 'SELECT * '
- . ' FROM '
- . $table_references
- . ' WHERE '
- . $where_clause;
-
- return $matched_row_query;
-}
-
-/**
- * Finds table_references from a given query.
- * Queries Supported: INSERT, UPDATE, DELETE, REPLACE, ALTER, DROP, TRUNCATE
- * and RENAME.
- *
- * @param array $analyzed_sql_results Analyzed SQL results from parser
- *
- * @return string table_references
- */
-function PMA_getTableReferences($analyzed_sql_results)
-{
- $table_references = '';
- foreach ($analyzed_sql_results['parsed_sql'] as $key => $term) {
- // Skip first KeyWord and other invalid keys.
- if ($key == 0 || ! isset($term['data'])) {
- continue;
- }
+ $table_references = SqlParser\Utils\Query::getTables(
+ $analyzed_sql_results['statement']
+ );
- // Get the query type.
- $query_type = (isset($analyzed_sql_results['analyzed_sql'][0]['querytype']))
- ? $analyzed_sql_results['analyzed_sql'][0]['querytype']
- : '';
-
- // Terms to 'ignore' from query for table_references.
- $ignore_re = '/';
- // Terminating condition for table_references.
- $terminate_re = '/';
-
- // Create relevant Regular Expressions.
- switch ($query_type) {
- case 'REPLACE':
- case 'INSERT':
- $ignore_re .= '\bINSERT\b|\bREPLACE\b|\bLOW_PRIORITY\b|\bDELAYED\b'
- . '|\bHIGH_PRIORITY\b|\bIGNORE\b|\bINTO\b';
- $terminate_re .= '\bPARTITION\b|\(|\bVALUE\b|\bVALUES\b|\bSELECT\b';
- break;
- case 'UPDATE':
- $ignore_re .= '\bUPDATE\b|\bLOW_PRIORITY\b|\bIGNORE\b';
- $terminate_re .= '\bSET\b|\bUSING\b';
- break;
- case 'DELETE':
- $ignore_re .= '\bDELETE\b|\bLOW_PRIORITY\b|\bQUICK\b|\bIGNORE\b'
- . '|\bFROM\b';
- $terminate_re .= '\bPARTITION\b|\bWHERE\b|\bORDER\b|\bLIMIT\b|\bUSING\b';
- break;
- case 'ALTER':
- $ignore_re .= '\bALTER\b|\bONLINE\b|\bOFFLINE\b|\bIGNORE\b|\bTABLE\b';
- $terminate_re .= '\bADD\b|\bALTER\b|\bCHANGE\b|\bMODIFY\b|\bDROP\b'
- . '|\bDISABLE\b|\bENABLE\b|\bRENAME\b|\bORDER\b|\bCONVERT\b'
- . '|\bDEFAULT\b|\bDISCARD\b|\bIMPORT\b|\bCOALESCE\b|\bREORGANIZE\b'
- . '|\bANALYZE\b|\bCHECK\b|\bOPTIMIZE\b|\bREBUILD\b|\bREPAIR\b'
- . '|\bPARTITION\b|\bREMOVE\b|\bCHARACTER\b';
- break;
- case 'DROP':
- $ignore_re .= '\bDROP\b|\bTEMPORARY\b|\bTABLE\b|\bIF\b|\bEXISTS\b';
- $terminate_re .= '\bRESTRICT\b|\bCASCADE\b';
- break;
- case 'TRUNCATE':
- $ignore_re .= '\bTRUNCATE\b|\bTABLE\b';
- $terminate_re .= '';
- break;
- case 'RENAME':
- $ignore_re .= '\bRENAME\b|\bTABLE\b';
- $terminate_re .= '\bTO\b';
- break;
- default:
- return false;
- }
+ $where = SqlParser\Utils\Query::getClause(
+ $analyzed_sql_results['statement'],
+ $analyzed_sql_results['parser']->list,
+ 'WHERE'
+ );
- // Ignore 'case' in RegEx.
- $ignore_re .= '/i';
- $terminate_re .= '/i';
+ if (empty($where)) {
+ $where = '1';
+ }
- if ($query_type != 'TRUNCATE'
- && preg_match($terminate_re, $term['data'])
- ) {
- break;
- }
+ $order_and_limit = '';
- if (preg_match($ignore_re, $term['data'])
- || ! is_numeric($key)
- || $key == 0
- ) {
- continue;
- }
+ if (!empty($analyzed_sql_results['statement']->order)) {
+ $order_and_limit .= ' ORDER BY ' . SqlParser\Utils\Query::getClause(
+ $analyzed_sql_results['statement'],
+ $analyzed_sql_results['parser']->list,
+ 'ORDER BY'
+ );
+ }
- $table_references .= ' ' . $term['data'];
+ if (!empty($analyzed_sql_results['statement']->limit)) {
+ $order_and_limit .= ' LIMIT ' . SqlParser\Utils\Query::getClause(
+ $analyzed_sql_results['statement'],
+ $analyzed_sql_results['parser']->list,
+ 'LIMIT'
+ );
}
- return $table_references;
+ return 'SELECT * FROM ' . implode(', ', $table_references) .
+ ' WHERE ' . $where . $order_and_limit;
}
/**
@@ -1713,93 +1589,6 @@ function PMA_executeMatchedRowQuery($matched_row_query)
}
/**
- * Extracts unique table names from table_references.
- *
- * @param string $table_references table_references
- *
- * @return array $table_names
- */
-function PMA_getTableNamesFromTableReferences($table_references)
-{
- $table_names = array();
- $parsed_data = PMA_SQP_parse($table_references);
-
- $prev_term = array(
- 'data' => '',
- 'type' => ''
- );
- $on_encountered = false;
- $qualifier_encountered = false;
- $i = 0;
- foreach ($parsed_data as $key => $term) {
- // To skip first 'raw' key and other invalid keys.
- if (! is_numeric($key)
- || ! isset($term['data'])
- || ! isset($term['type'])
- ) {
- continue;
- }
-
- $add_to_table_names = true;
-
- // Un-quote the data, if any.
- if ($term['type'] == 'quote_backtick') {
- $term['data'] = PMA_Util::unQuote($term['data']);
- $term['type'] = 'alpha_identifier';
- }
-
- // New table name expected after 'JOIN' keyword.
- if (preg_match('/\bJOIN\b/i', $term['data'])) {
- $on_encountered = false;
- }
-
- // If term is a qualifier, set flag.
- if ($term['type'] == 'punct_qualifier') {
- $qualifier_encountered = true;
- }
-
- // Skip the JOIN conditions after 'ON' keyword.
- if (preg_match('/\bON\b/i', $term['data'])) {
- $on_encountered = true;
- }
-
- // If the word is not an 'identifier', skip it.
- if ($term['type'] != 'alpha_identifier') {
- $add_to_table_names = false;
- }
-
- // Skip table 'alias'.
- if (preg_match('/\bAS\b/i', $prev_term['data'])
- || $prev_term['type'] == 'alpha_identifier'
- ) {
- $add_to_table_names = false;
- }
-
- // Everything fine up to now, add name to list if 'unique'.
- if ($add_to_table_names
- && ! $on_encountered
- && ! in_array($term['data'], $table_names)
- ) {
- if (! $qualifier_encountered) {
- $table_names[] = PMA_Util::backquote($term['data']);
- $i++;
- } else {
- // If qualifier encountered, concatenate DB name and table name.
- $table_names[$i-1] = $table_names[$i-1]
- . '.'
- . PMA_Util::backquote($term['data']);
- $qualifier_encountered = false;
- }
- }
-
- // Update previous term.
- $prev_term = $term;
- }
-
- return $table_names;
-}
-
-/**
* Handles request for ROLLBACK.
*
* @param string $sql_query SQL query(s)
@@ -1853,37 +1642,25 @@ function PMA_handleRollbackRequest($sql_query)
*/
function PMA_checkIfRollbackPossible($sql_query)
{
- // Supported queries.
- $supported_queries = array(
- 'INSERT',
- 'UPDATE',
- 'DELETE',
- 'REPLACE'
- );
+ $parser = new SqlParser\Parser($sql_query);
- // Parse and Analyze the query.
- $parsed_sql = PMA_SQP_parse($sql_query);
- $analyzed_sql = PMA_SQP_analyze($parsed_sql);
- $analyzed_sql_results = array(
- 'parsed_sql' => $parsed_sql,
- 'analyzed_sql' => $analyzed_sql
- );
+ if (empty($parser->statements[0])) {
+ return false;
+ }
- // Get the query type.
- $query_type = (isset($analyzed_sql_results['analyzed_sql'][0]['querytype']))
- ? $analyzed_sql_results['analyzed_sql'][0]['querytype']
- : '';
+ $statement = $parser->statements[0];
// Check if query is supported.
- if (! in_array($query_type, $supported_queries)) {
+ if (!(($statement instanceof SqlParser\Statements\InsertStatement)
+ || ($statement instanceof SqlParser\Statements\UpdateStatement)
+ || ($statement instanceof SqlParser\Statements\DeleteStatement)
+ || ($statement instanceof SqlParser\Statements\ReplaceStatement))
+ ) {
return false;
}
// Get table_references from the query.
- $table_references = PMA_getTableReferences($analyzed_sql_results);
- $table_references = $table_references ? $table_references : '';
- // Get table names from table_references.
- $tables = PMA_getTableNamesFromTableReferences($table_references);
+ $tables = SqlParser\Utils\Query::getTables($statement);
// Check if each table is 'InnoDB'.
foreach ($tables as $table) {
diff --git a/libraries/sql-parser/src/Contexts/ContextMySql50000.php b/libraries/sql-parser/src/Contexts/ContextMySql50000.php
index dc2759a30b..7db5fc3a76 100644
--- a/libraries/sql-parser/src/Contexts/ContextMySql50000.php
+++ b/libraries/sql-parser/src/Contexts/ContextMySql50000.php
@@ -146,7 +146,7 @@ class ContextMySql50000 extends Context
'GROUP BY' => 7, 'NOT NULL' => 7, 'ORDER BY' => 7, 'SET NULL' => 7,
'IF EXISTS' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7,
'OR REPLACE' => 7,
- 'SQL SECURITY' => 7,
+ 'FOR EACH ROW' => 7, 'SQL SECURITY' => 7,
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
'DATA DIRECTORY' => 7,
'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7,
diff --git a/libraries/sql-parser/src/Contexts/ContextMySql50100.php b/libraries/sql-parser/src/Contexts/ContextMySql50100.php
index 82db6843ed..a5c4bef0bf 100644
--- a/libraries/sql-parser/src/Contexts/ContextMySql50100.php
+++ b/libraries/sql-parser/src/Contexts/ContextMySql50100.php
@@ -157,7 +157,7 @@ class ContextMySql50100 extends Context
'GROUP BY' => 7, 'NOT NULL' => 7, 'ORDER BY' => 7, 'SET NULL' => 7,
'IF EXISTS' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7,
'OR REPLACE' => 7,
- 'SQL SECURITY' => 7,
+ 'FOR EACH ROW' => 7, 'SQL SECURITY' => 7,
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
'DATA DIRECTORY' => 7,
'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7,
diff --git a/libraries/sql-parser/src/Contexts/ContextMySql50500.php b/libraries/sql-parser/src/Contexts/ContextMySql50500.php
index e338232eb0..3faf785315 100644
--- a/libraries/sql-parser/src/Contexts/ContextMySql50500.php
+++ b/libraries/sql-parser/src/Contexts/ContextMySql50500.php
@@ -162,7 +162,7 @@ class ContextMySql50500 extends Context
'GROUP BY' => 7, 'NOT NULL' => 7, 'ORDER BY' => 7, 'SET NULL' => 7,
'IF EXISTS' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7,
'OR REPLACE' => 7,
- 'SQL SECURITY' => 7,
+ 'FOR EACH ROW' => 7, 'SQL SECURITY' => 7,
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
'DATA DIRECTORY' => 7,
'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7,
diff --git a/libraries/sql-parser/src/Contexts/ContextMySql50600.php b/libraries/sql-parser/src/Contexts/ContextMySql50600.php
index 780ea5208b..6a1af74921 100644
--- a/libraries/sql-parser/src/Contexts/ContextMySql50600.php
+++ b/libraries/sql-parser/src/Contexts/ContextMySql50600.php
@@ -168,7 +168,7 @@ class ContextMySql50600 extends Context
'GROUP BY' => 7, 'NOT NULL' => 7, 'ORDER BY' => 7, 'SET NULL' => 7,
'IF EXISTS' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7,
'OR REPLACE' => 7,
- 'SQL SECURITY' => 7,
+ 'FOR EACH ROW' => 7, 'SQL SECURITY' => 7,
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
'DATA DIRECTORY' => 7,
'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7,
diff --git a/libraries/sql-parser/src/Contexts/ContextMySql50700.php b/libraries/sql-parser/src/Contexts/ContextMySql50700.php
index 6a3cfd638b..ac81e8a8d8 100644
--- a/libraries/sql-parser/src/Contexts/ContextMySql50700.php
+++ b/libraries/sql-parser/src/Contexts/ContextMySql50700.php
@@ -176,7 +176,7 @@ class ContextMySql50700 extends Context
'GROUP BY' => 7, 'NOT NULL' => 7, 'ORDER BY' => 7, 'SET NULL' => 7,
'IF EXISTS' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7,
'OR REPLACE' => 7,
- 'SQL SECURITY' => 7,
+ 'FOR EACH ROW' => 7, 'SQL SECURITY' => 7,
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
'DATA DIRECTORY' => 7,
'DEFAULT COLLATE' => 7, 'INDEX DIRECTORY' => 7,
diff --git a/libraries/sql-parser/src/Fragments/AlterFragment.php b/libraries/sql-parser/src/Fragments/AlterFragment.php
index 54338f9dab..b5c66e81e9 100644
--- a/libraries/sql-parser/src/Fragments/AlterFragment.php
+++ b/libraries/sql-parser/src/Fragments/AlterFragment.php
@@ -160,7 +160,7 @@ class AlterFragment extends Fragment
);
if ($ret->field === null) {
// No field was read. We go back one token so the next
- // iteration will parse the same on, but in state 2.
+ // iteration will parse the same token, but in state 2.
--$list->idx;
}
$state = 2;
diff --git a/libraries/sql-parser/src/Fragments/FieldDefFragment.php b/libraries/sql-parser/src/Fragments/FieldDefFragment.php
index 9f43fcc2fe..a4c21d79a1 100644
--- a/libraries/sql-parser/src/Fragments/FieldDefFragment.php
+++ b/libraries/sql-parser/src/Fragments/FieldDefFragment.php
@@ -221,7 +221,6 @@ class FieldDefFragment extends Fragment
--$list->idx;
return $ret;
-
}
/**
diff --git a/libraries/sql-parser/src/Fragments/IntoKeyword.php b/libraries/sql-parser/src/Fragments/IntoKeyword.php
index 0b515319e3..cf65da6e5a 100644
--- a/libraries/sql-parser/src/Fragments/IntoKeyword.php
+++ b/libraries/sql-parser/src/Fragments/IntoKeyword.php
@@ -33,11 +33,11 @@ class IntoKeyword extends Fragment
public $type;
/**
- * The name of the table or file.
+ * The destination, which can be a table or a file.
*
- * @var string
+ * @var string|FieldFragment
*/
- public $name;
+ public $dest;
/**
* The name of the columns.
@@ -102,7 +102,15 @@ class IntoKeyword extends Fragment
}
if ($state === 0) {
- $ret->name = $token->value;
+ $ret->dest = FieldFragment::parse(
+ $parser,
+ $list,
+ array(
+ 'noAlias' => true,
+ 'noBrackets' => true,
+ 'skipColumn' => true,
+ )
+ );
$state = 1;
} elseif ($state === 1) {
if (($token->type === Token::TYPE_OPERATOR) && ($token->value === '(')) {
@@ -111,7 +119,7 @@ class IntoKeyword extends Fragment
}
break;
} elseif ($state === 2) {
- $ret->name = $token->value;
+ $ret->dest = $token->value;
++$list->idx;
break;
}
diff --git a/libraries/sql-parser/src/Fragments/ParamDefFragment.php b/libraries/sql-parser/src/Fragments/ParamDefFragment.php
index 583c3abbcd..23b84e3220 100644
--- a/libraries/sql-parser/src/Fragments/ParamDefFragment.php
+++ b/libraries/sql-parser/src/Fragments/ParamDefFragment.php
@@ -135,6 +135,27 @@ class ParamDefFragment extends Fragment
--$list->idx;
return $ret;
+ }
+ /**
+ * @param ParamDefFragment[] $fragment The fragment to be built.
+ *
+ * @return string
+ */
+ public static function build($fragment)
+ {
+ $ret = array();
+ foreach ($fragment as $f) {
+ $tmp = '';
+ if (!empty($f->inOut)) {
+ $tmp .= $f->inOut . ' ';
+ }
+
+ $ret[] = trim(
+ $tmp . Context::escape($f->name) . ' ' .
+ DataTypeFragment::build($f->type)
+ );
+ }
+ return '(' . implode(', ', $ret) . ')';
}
}
diff --git a/libraries/sql-parser/src/Fragments/RenameKeyword.php b/libraries/sql-parser/src/Fragments/RenameKeyword.php
index 077982aafb..de81848584 100644
--- a/libraries/sql-parser/src/Fragments/RenameKeyword.php
+++ b/libraries/sql-parser/src/Fragments/RenameKeyword.php
@@ -26,16 +26,16 @@ class RenameKeyword extends Fragment
{
/**
- * The old name.
+ * The old table name.
*
- * @var string
+ * @var FieldFragment
*/
public $old;
/**
- * The new name.
+ * The new table name.
*
- * @var string
+ * @var FieldFragment
*/
public $new;
@@ -110,10 +110,26 @@ class RenameKeyword extends Fragment
}
if ($state == 0) {
- $expr->old = $token->value;
+ $expr->old = FieldFragment::parse(
+ $parser,
+ $list,
+ array(
+ 'noAlias' => true,
+ 'noBrackets' => true,
+ 'skipColumn' => true,
+ )
+ );
$state = 1;
} elseif ($state == 2) {
- $expr->new = $token->value;
+ $expr->new = FieldFragment::parse(
+ $parser,
+ $list,
+ array(
+ 'noBrackets' => true,
+ 'skipColumn' => true,
+ 'noAlias' => true,
+ )
+ );
$state = 3;
}
diff --git a/libraries/sql-parser/src/Fragments/SetKeyword.php b/libraries/sql-parser/src/Fragments/SetKeyword.php
index bced45fb43..713a179c84 100644
--- a/libraries/sql-parser/src/Fragments/SetKeyword.php
+++ b/libraries/sql-parser/src/Fragments/SetKeyword.php
@@ -90,24 +90,29 @@ class SetKeyword extends Fragment
if ($token->type === Token::TYPE_OPERATOR) {
if ($token->value === ',') {
+ $expr->column = trim($expr->column);
+ $expr->value = trim($expr->value);
$ret[] = $expr;
$expr = new SetKeyword();
$state = 0;
continue;
} elseif ($token->value === '=') {
$state = 1;
+ continue;
}
}
if ($state === 0) {
- $expr->column .= $token->value;
+ $expr->column .= $token->token;
} else { // } else if ($state === 1) {
- $expr->value = $token->value;
+ $expr->value .= $token->token;
}
}
// Last iteration was not saved.
if (!empty($expr->column)) {
+ $expr->column = trim($expr->column);
+ $expr->value = trim($expr->value);
$ret[] = $expr;
}
diff --git a/libraries/sql-parser/src/Parser.php b/libraries/sql-parser/src/Parser.php
index ff55f5f7d1..3c574063d1 100644
--- a/libraries/sql-parser/src/Parser.php
+++ b/libraries/sql-parser/src/Parser.php
@@ -54,7 +54,7 @@ class Parser
'CREATE' => 'SqlParser\\Statements\\CreateStatement',
'DROP' => 'SqlParser\\Statements\\DropStatement',
'RENAME' => 'SqlParser\\Statements\\RenameStatement',
- 'TRUNCATE' => '',
+ 'TRUNCATE' => 'SqlParser\\Statements\\TruncateStatement',
// Data Manipulation Statements.
// https://dev.mysql.com/doc/refman/5.7/en/sql-syntax-data-manipulation.html
@@ -185,9 +185,14 @@ class Parser
'class' => 'SqlParser\\Fragments\\FieldListFragment',
'field' => 'expr',
),
+ 'TRUNCATE' => array(
+ 'class' => 'SqlParser\\Fragments\\FieldFragment',
+ 'field' => 'table',
+ 'options' => array('skipColumn' => true),
+ ),
'UPDATE' => array(
'class' => 'SqlParser\\Fragments\\FieldListFragment',
- 'field' => 'from',
+ 'field' => 'tables',
'options' => array('skipColumn' => true),
),
'VALUE' => array(
diff --git a/libraries/sql-parser/src/Statements/CheckStatement.php b/libraries/sql-parser/src/Statements/CheckStatement.php
index 38764ff869..2e0e5a37b7 100644
--- a/libraries/sql-parser/src/Statements/CheckStatement.php
+++ b/libraries/sql-parser/src/Statements/CheckStatement.php
@@ -40,11 +40,4 @@ class CheckStatement extends MaintenanceStatement
'EXTENDED' => 6,
'CHANGED' => 7,
);
-
- /**
- * Checked tables.
- *
- * @var FieldFragment[]
- */
- public $tables;
}
diff --git a/libraries/sql-parser/src/Statements/ChecksumStatement.php b/libraries/sql-parser/src/Statements/ChecksumStatement.php
index e2c6371c12..0495932702 100644
--- a/libraries/sql-parser/src/Statements/ChecksumStatement.php
+++ b/libraries/sql-parser/src/Statements/ChecksumStatement.php
@@ -36,11 +36,4 @@ class ChecksumStatement extends MaintenanceStatement
'QUICK' => 2,
'EXTENDED' => 3,
);
-
- /**
- * Checked tables.
- *
- * @var FieldFragment[]
- */
- public $tables;
}
diff --git a/libraries/sql-parser/src/Statements/CreateStatement.php b/libraries/sql-parser/src/Statements/CreateStatement.php
index 306bfebceb..71557c7e10 100644
--- a/libraries/sql-parser/src/Statements/CreateStatement.php
+++ b/libraries/sql-parser/src/Statements/CreateStatement.php
@@ -101,15 +101,28 @@ class CreateStatement extends Statement
* @var array
*/
public static $FUNC_OPTIONS = array(
- 'COMMENT' => array(1, 'var'),
- 'LANGUAGE SQL' => 2,
- 'DETERMINISTIC' => 3,
- 'NOT DETERMINISTIC' => 3,
- 'CONSTAINS SQL' => 4,
- 'NO SQL' => 4,
- 'READS SQL DATA' => 4,
- 'MODIFIES SQL DATA' => 4,
- 'SQL SEQURITY DEFINER' => array(5, 'var'),
+ 'COMMENT' => array(1, 'var'),
+ 'LANGUAGE SQL' => 2,
+ 'DETERMINISTIC' => 3,
+ 'NOT DETERMINISTIC' => 3,
+ 'CONSTAINS SQL' => 4,
+ 'NO SQL' => 4,
+ 'READS SQL DATA' => 4,
+ 'MODIFIES SQL DATA' => 4,
+ 'SQL SEQURITY DEFINER' => array(5, 'var'),
+ );
+
+ /**
+ * All trigger options.
+ *
+ * @var array
+ */
+ public static $TRIGGER_OPTIONS = array(
+ 'BEFORE' => 1,
+ 'AFTER' => 1,
+ 'INSERT' => 2,
+ 'UPDATE' => 2,
+ 'DELETE' => 2,
);
/**
@@ -130,6 +143,7 @@ class CreateStatement extends Statement
*
* @see static::$TABLE_OPTIONS
* @see static::$FUNC_OPTIONS
+ * @see static::$TRIGGER_OPTIONS
*/
public $entityOptions;
@@ -144,6 +158,15 @@ class CreateStatement extends Statement
public $fields;
/**
+ * If `CREATE TRIGGER` the name of the table.
+ *
+ * Used by `CREATE TRIGGER`.
+ *
+ * @var FieldFragment
+ */
+ public $table;
+
+ /**
* The return data type of this routine.
*
* Used by `CREATE FUNCTION`.
@@ -167,7 +190,7 @@ class CreateStatement extends Statement
*
* Used by `CREATE FUNCTION`, `CREATE PROCEDURE` and `CREATE VIEW`.
*
- * @var Token[]
+ * @var Token[]|string
*/
public $body = array();
@@ -176,20 +199,43 @@ class CreateStatement extends Statement
*/
public function build()
{
- $tmp = '';
if ($this->options->has('TABLE')) {
- $tmp = FieldDefFragment::build($this->fields);
+ return 'CREATE '
+ . OptionsFragment::build($this->options) . ' '
+ . FieldFragment::build($this->name) . ' '
+ . FieldDefFragment::build($this->fields) . ' '
+ . OptionsFragment::build($this->entityOptions);
} elseif ($this->options->has('VIEW')) {
+ $tmp = '';
if (!empty($this->fields)) {
- $tmp .= ArrayFragment::build($this->fields) . ' ';
+ $tmp = ArrayFragment::build($this->fields);
+ }
+ return 'CREATE '
+ . OptionsFragment::build($this->options) . ' '
+ . FieldFragment::build($this->name) . ' '
+ . $tmp . ' AS ' . TokensList::build($this->body) . ' '
+ . OptionsFragment::build($this->entityOptions);
+ } elseif ($this->options->has('TRIGGER')) {
+ return 'CREATE '
+ . OptionsFragment::build($this->options) . ' '
+ . FieldFragment::build($this->name) . ' '
+ . OptionsFragment::build($this->entityOptions) . ' '
+ . 'ON ' . FieldFragment::build($this->table) . ' '
+ . 'FOR EACH ROW ' . TokensList::build($this->body);
+ } elseif (($this->options->has('PROCEDURE'))
+ || ($this->options->has('FUNCTION'))
+ ) {
+ $tmp = '';
+ if ($this->options->has('FUNCTION')) {
+ $tmp = 'RETURNS ' . DataTypeFragment::build($this->return);
}
- $tmp .= 'AS ' . TokensList::build($this->body);
+ return 'CREATE '
+ . OptionsFragment::build($this->options) . ' '
+ . FieldFragment::build($this->name) . ' '
+ . ParamDefFragment::build($this->parameters) . ' '
+ . $tmp . ' ' . TokensList::build($this->body);
}
- return 'CREATE '
- . OptionsFragment::build($this->options) . ' '
- . FieldFragment::build($this->name) . ' '
- . $tmp . ' '
- . OptionsFragment::build($this->entityOptions);
+ return '';
}
/**
@@ -221,6 +267,7 @@ class CreateStatement extends Statement
if ($this->options->has('TABLE')) {
$this->fields = FieldDefFragment::parse($parser, $list);
++$list->idx;
+
$this->entityOptions = OptionsFragment::parse(
$parser,
$list,
@@ -246,13 +293,14 @@ class CreateStatement extends Statement
}
}
++$list->idx;
+
$this->entityOptions = OptionsFragment::parse(
$parser,
$list,
static::$FUNC_OPTIONS
);
++$list->idx;
- $this->body = array();
+
for (; $list->idx < $list->count; ++$list->idx) {
$token = $list->tokens[$list->idx];
$this->body[] = $token;
@@ -263,7 +311,7 @@ class CreateStatement extends Statement
}
}
} else if ($this->options->has('VIEW')) {
- $token = $list->getNext();
+ $token = $list->getNext(); // Skipping whitespaces and comments.
// Parsing columns list.
if (($token->type === Token::TYPE_OPERATOR) && ($token->value === '(')) {
@@ -281,6 +329,42 @@ class CreateStatement extends Statement
}
$this->body[] = $token;
}
+ } else if ($this->options->has('TRIGGER')) {
+ // Parsing the time and the event.
+ $this->entityOptions = OptionsFragment::parse(
+ $parser,
+ $list,
+ static::$TRIGGER_OPTIONS
+ );
+ ++$list->idx;
+
+ $list->getNextOfTypeAndValue(Token::TYPE_KEYWORD, 'ON');
+ ++$list->idx; // Skipping `ON`.
+
+ // Parsing the name of the table.
+ $this->fields = FieldFragment::parse(
+ $parser,
+ $list,
+ array(
+ 'skipColumn' => true,
+ 'noAlias' => true,
+ 'noBrackets' => true,
+ )
+ );
+ ++$list->idx;
+
+ $list->getNextOfTypeAndValue(Token::TYPE_KEYWORD, 'FOR EACH ROW');
+ ++$list->idx; // Skipping `FOR EACH ROW`.
+
+ for (; $list->idx < $list->count; ++$list->idx) {
+ $token = $list->tokens[$list->idx];
+ $this->body[] = $token;
+ if (($token->type === Token::TYPE_KEYWORD)
+ && ($token->value === 'END')
+ ) {
+ break;
+ }
+ }
}
}
}
diff --git a/libraries/sql-parser/src/Statements/DeleteStatement.php b/libraries/sql-parser/src/Statements/DeleteStatement.php
index 9016da37de..04208fc094 100644
--- a/libraries/sql-parser/src/Statements/DeleteStatement.php
+++ b/libraries/sql-parser/src/Statements/DeleteStatement.php
@@ -40,6 +40,24 @@ class DeleteStatement extends Statement
);
/**
+ * The clauses of this statement, in order.
+ *
+ * @see Statement::$CLAUSES
+ *
+ * @var array
+ */
+ public static $CLAUSES = array(
+ 'DELETE' => array('DELETE', 2),
+ // Used for options.
+ '_OPTIONS' => array('_OPTIONS', 1),
+ 'FROM' => array('FROM', 3),
+ 'PARTITION' => array('PARTITION', 3),
+ 'WHERE' => array('WHERE', 3),
+ 'ORDER BY' => array('ORDER BY', 3),
+ 'LIMIT' => array('LIMIT', 3),
+ );
+
+ /**
* Tables used as sources for this statement.
*
* @var FieldFragment[]
diff --git a/libraries/sql-parser/src/Statements/RepairStatement.php b/libraries/sql-parser/src/Statements/RepairStatement.php
index 933d2c0d08..e340dd12e0 100644
--- a/libraries/sql-parser/src/Statements/RepairStatement.php
+++ b/libraries/sql-parser/src/Statements/RepairStatement.php
@@ -42,11 +42,4 @@ class RepairStatement extends MaintenanceStatement
'EXTENDED' => 5,
'USE_FRM' => 6,
);
-
- /**
- * Repaired tables.
- *
- * @var FieldFragment[]
- */
- public $tables;
}
diff --git a/libraries/sql-parser/src/Statements/RestoreStatement.php b/libraries/sql-parser/src/Statements/RestoreStatement.php
index 996b41eb0b..1c03e29df1 100644
--- a/libraries/sql-parser/src/Statements/RestoreStatement.php
+++ b/libraries/sql-parser/src/Statements/RestoreStatement.php
@@ -35,11 +35,4 @@ class RestoreStatement extends MaintenanceStatement
'FROM' => array(2, 'var'),
);
-
- /**
- * Restored tables.
- *
- * @var FieldFragment[]
- */
- public $tables;
}
diff --git a/libraries/sql-parser/src/Statements/SelectStatement.php b/libraries/sql-parser/src/Statements/SelectStatement.php
index e376b47a0a..b5d0b0a840 100644
--- a/libraries/sql-parser/src/Statements/SelectStatement.php
+++ b/libraries/sql-parser/src/Statements/SelectStatement.php
@@ -78,7 +78,7 @@ class SelectStatement extends Statement
'SELECT' => array('SELECT', 2),
// Used for options.
'_OPTIONS' => array('_OPTIONS', 1),
- // Used for select expressions.
+ // Used for selected expressions.
'_SELECT' => array('SELECT', 1),
'FROM' => array('FROM', 3),
'PARTITION' => array('PARTITION', 3),
diff --git a/libraries/sql-parser/src/Statements/TruncateStatement.php b/libraries/sql-parser/src/Statements/TruncateStatement.php
new file mode 100644
index 0000000000..9313204b5e
--- /dev/null
+++ b/libraries/sql-parser/src/Statements/TruncateStatement.php
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * `TRUNCATE` statement.
+ *
+ * @package SqlParser
+ * @subpackage Statements
+ */
+namespace SqlParser\Statements;
+
+use SqlParser\Parser;
+use SqlParser\Statement;
+use SqlParser\Token;
+use SqlParser\TokensList;
+use SqlParser\Fragments\ArrayFragment;
+use SqlParser\Fragments\DataTypeFragment;
+use SqlParser\Fragments\FieldDefFragment;
+use SqlParser\Fragments\FieldFragment;
+use SqlParser\Fragments\OptionsFragment;
+use SqlParser\Fragments\ParamDefFragment;
+
+/**
+ * `TRUNCATE` statement.
+ *
+ * @category Statements
+ * @package SqlParser
+ * @subpackage Statements
+ * @author Dan Ungureanu <udan1107@gmail.com>
+ * @license http://opensource.org/licenses/GPL-2.0 GNU Public License
+ */
+class TruncateStatement extends Statement
+{
+
+ /**
+ * Options for `TRUNCATE` statements.
+ *
+ * @var array
+ */
+ public static $OPTIONS = array(
+ 'TABLE' => 1,
+ );
+
+ /**
+ * The name of the truncated table.
+ *
+ * @var FieldFragment
+ */
+ public $table;
+}
diff --git a/libraries/sql-parser/src/Statements/UpdateStatement.php b/libraries/sql-parser/src/Statements/UpdateStatement.php
index d100560b30..ab445dc34a 100644
--- a/libraries/sql-parser/src/Statements/UpdateStatement.php
+++ b/libraries/sql-parser/src/Statements/UpdateStatement.php
@@ -45,11 +45,30 @@ class UpdateStatement extends Statement
);
/**
+ * The clauses of this statement, in order.
+ *
+ * @see Statement::$CLAUSES
+ *
+ * @var array
+ */
+ public static $CLAUSES = array(
+ 'UPDATE' => array('UPDATE', 2),
+ // Used for options.
+ '_OPTIONS' => array('_OPTIONS', 1),
+ // Used for updated tables.
+ '_UPDATE' => array('UPDATE', 1),
+ 'SET' => array('SET', 3),
+ 'WHERE' => array('WHERE', 3),
+ 'ORDER BY' => array('ORDER BY', 3),
+ 'LIMIT' => array('LIMIT', 3),
+ );
+
+ /**
* Tables used as sources for this statement.
*
* @var FieldFragment[]
*/
- public $from;
+ public $tables;
/**
* The updated values.
diff --git a/libraries/sql-parser/src/TokensList.php b/libraries/sql-parser/src/TokensList.php
index 229bebcec4..be9124c0de 100644
--- a/libraries/sql-parser/src/TokensList.php
+++ b/libraries/sql-parser/src/TokensList.php
@@ -57,15 +57,20 @@ class TokensList implements \ArrayAccess
/**
* Builds an array of tokens by merging their raw value.
*
- * @param array $tokens
+ * @param string|array|TokensList $tokens
*
* @return string
*/
public static function build($list)
{
+ if (is_string($list)) {
+ return $list;
+ }
+
if ($list instanceof TokensList) {
$list = $list->tokens;
}
+
$ret = '';
if (is_array($list)) {
foreach ($list as $tok) {
diff --git a/libraries/sql-parser/src/Utils/Query.php b/libraries/sql-parser/src/Utils/Query.php
index 5c4553d2ab..d4c01afa64 100644
--- a/libraries/sql-parser/src/Utils/Query.php
+++ b/libraries/sql-parser/src/Utils/Query.php
@@ -12,6 +12,7 @@ use SqlParser\Lexer;
use SqlParser\Parser;
use SqlParser\Statement;
use SqlParser\Token;
+use SqlParser\Fragments\FieldFragment;
use SqlParser\Statements\AlterStatement;
use SqlParser\Statements\AnalyzeStatement;
use SqlParser\Statements\CallStatement;
@@ -23,10 +24,12 @@ use SqlParser\Statements\DropStatement;
use SqlParser\Statements\ExplainStatement;
use SqlParser\Statements\InsertStatement;
use SqlParser\Statements\OptimizeStatement;
+use SqlParser\Statements\RenameStatement;
use SqlParser\Statements\RepairStatement;
use SqlParser\Statements\ReplaceStatement;
use SqlParser\Statements\SelectStatement;
use SqlParser\Statements\ShowStatement;
+use SqlParser\Statements\TruncateStatement;
use SqlParser\Statements\UpdateStatement;
/**
@@ -437,6 +440,54 @@ class Query
}
/**
+ * Gets a list of all tables used in this statement.
+ *
+ * @param Statement $statement Statement to be scanned.
+ *
+ * @return array
+ */
+ public static function getTables($statement)
+ {
+ $fields = array();
+
+ if (($statement instanceof InsertStatement)
+ || ($statement instanceof ReplaceStatement)
+ ) {
+ $fields = array($statement->into->dest);
+ } elseif ($statement instanceof UpdateStatement) {
+ $fields = $statement->tables;
+ } elseif (($statement instanceof SelectStatement)
+ || ($statement instanceof DeleteStatement)
+ ) {
+ $fields = $statement->from;
+ } elseif (($statement instanceof AlterStatement)
+ || ($statement instanceof TruncateStatement)
+ ) {
+ $fields = array($statement->table);
+ } elseif ($statement instanceof DropStatement) {
+ if (!$statement->options->has('TABLE')) {
+ // No tables are dropped.
+ return array();
+ }
+ $fields = $statement->fields;
+ } elseif ($statement instanceof RenameStatement) {
+ foreach ($statement->renames as $rename) {
+ $fields[] = $rename->old;
+ }
+ }
+
+ $ret = array();
+ foreach ($fields as $field) {
+ if (!empty($field->table)) {
+ $field->expr = null; // Force rebuild.
+ $field->alias = null; // Aliases are not required.
+ $ret[] = FieldFragment::build($field);
+ }
+ }
+ return $ret;
+ }
+
+ /**
* Gets a specific clause.
*
* @param Statement $statement The parsed query that has to be modified.
diff --git a/test/libraries/PMA_import_test.php b/test/libraries/PMA_import_test.php
index d47e11caa6..96472e08e2 100644
--- a/test/libraries/PMA_import_test.php
+++ b/test/libraries/PMA_import_test.php
@@ -329,32 +329,6 @@ class PMA_Import_Test extends PHPUnit_Framework_TestCase
}
/**
- * Test for PMA_getTableReferences
- *
- * @return void
- */
- function testPMAGetTableReferences()
- {
- $sql_query = 'UPDATE `table_1` AS t1, `table_2` t2, `table_3` AS t3 '
- . 'SET `table_1`.`id` = `table_2`.`id` '
- . 'WHERE 1';
-
- $parsed_sql = PMA_SQP_parse($sql_query);
- $analyzed_sql = PMA_SQP_analyze($parsed_sql);
- $analyzed_sql_results = array(
- 'parsed_sql' => $parsed_sql,
- 'analyzed_sql' => $analyzed_sql
- );
-
- $table_references = PMA_getTableReferences($analyzed_sql_results);
-
- $this->assertEquals(
- ' `table_1` AS t1 , `table_2` t2 , `table_3` AS t3',
- $table_references
- );
- }
-
- /**
* Test for PMA_getMatchedRows.
*
* @return void
@@ -370,10 +344,11 @@ class PMA_Import_Test extends PHPUnit_Framework_TestCase
$update_query = 'UPDATE `table_1` '
. 'SET `id` = 20 '
. 'WHERE `id` > 10';
- $simulated_update_query = 'SELECT `id` FROM `table_1` WHERE `id` > 10 ';
+ $simulated_update_query = 'SELECT `id` FROM `table_1` WHERE `id` > 10 AND (`id` <> 20)';
+
$delete_query = 'DELETE FROM `table_1` '
. 'WHERE `id` > 10';
- $simulated_delete_query = 'SELECT * FROM `table_1` WHERE `id` > 10 ';
+ $simulated_delete_query = 'SELECT * FROM `table_1` WHERE `id` > 10';
$dbi->expects($this->any())
->method('numRows')
@@ -411,11 +386,11 @@ class PMA_Import_Test extends PHPUnit_Framework_TestCase
*/
function simulatedQueryTest($sql_query, $simulated_query)
{
- $parsed_sql = PMA_SQP_parse($sql_query);
- $analyzed_sql = PMA_SQP_analyze($parsed_sql);
+ $parser = new SqlParser\Parser($sql_query);
$analyzed_sql_results = array(
- 'parsed_sql' => $parsed_sql,
- 'analyzed_sql' => $analyzed_sql
+ 'query' => $sql_query,
+ 'parser' => $parser,
+ 'statement' => $parser->statements[0],
);
$simulated_data = PMA_getMatchedRows($analyzed_sql_results);
@@ -430,7 +405,7 @@ class PMA_Import_Test extends PHPUnit_Framework_TestCase
$this->assertEquals(
array(
'sql_query' => PMA_Util::formatSql(
- $analyzed_sql_results['parsed_sql']['raw']
+ $analyzed_sql_results['query']
),
'matched_rows' => 2,
'matched_rows_url' => $matched_rows_url