Replaced more of the old parser.

Updated sql-parser library.

Signed-off-by: Dan Ungureanu <udan1107@gmail.com>
This commit is contained in:
Dan Ungureanu 2015-06-27 22:07:40 +03:00
parent ec750bec1c
commit f7689d5c7e
14 changed files with 571 additions and 211 deletions

View File

@ -80,15 +80,30 @@ if (isset($_REQUEST['submit_sql']) && ! empty($sql_query)) {
if (! preg_match('@^SELECT@i', $sql_query)) {
$message_to_display = true;
} else {
$goto = 'db_sql.php';
$goto = 'db_sql.php';
// Parse and analyze the query
include_once 'libraries/parse_analyze.inc.php';
PMA_executeQueryAndSendQueryResponse(
$analyzed_sql_results, false, $_REQUEST['db'], null, false, null, null,
false, null, null, null, $goto, $pmaThemeImage, null, null, null,
$sql_query, null, null
$analyzed_sql_results, // analyzed_sql_results
false, // is_gotofile
$_REQUEST['db'], // db
null, // table
false, // find_real_end
null, // sql_query_for_bookmark
null, // extra_data
null, // message_to_show
null, // message
null, // sql_data
$goto, // goto
$pmaThemeImage, // pmaThemeImage
null, // disp_query
null, // disp_message
null, // query_type
$sql_query, // sql_query
null, // selectedTables
null // complete_query
);
}
}

View File

@ -745,10 +745,24 @@ if ($go_sql) {
include 'libraries/parse_analyze.inc.php';
$html_output .= PMA_executeQueryAndGetQueryResponse(
$analyzed_sql_results, false, $db, $table, null,
$sql_query, null, $analyzed_sql_results['is_affected'],
null, null, null, $goto, $pmaThemeImage,
null, null, null, $sql_query, null, null
$analyzed_sql_results, // analyzed_sql_results
false, // is_gotofile
$db, // db
$table, // table
null, // find_real_end
$sql_query, // sql_query_for_bookmark
null, // extra_data
null, // message_to_show
null, // message
null, // sql_data
$goto, // goto
$pmaThemeImage, // pmaThemeImage
null, // disp_query
null, // disp_message
null, // query_type
$sql_query, // sql_query
null, // selectedTables
null // complete_query
);
}

View File

@ -244,15 +244,31 @@ if (!empty($submit_mult) && !empty($what)) {
}
if ($use_sql) {
/**
* Parse and analyze the query
*/
include_once 'libraries/parse_analyze.inc.php';
PMA_executeQueryAndSendQueryResponse(
$analyzed_sql_results, false, $db, $table, null, null, null,
false, null, null, null, $goto, $pmaThemeImage, null, null,
$query_type, $sql_query, $selected, null
$analyzed_sql_results, // analyzed_sql_results
false, // is_gotofile
$db, // db
$table, // table
null, // find_real_end
null, // sql_query_for_bookmark
null, // extra_data
null, // message_to_show
null, // message
null, // sql_data
$goto, // goto
$pmaThemeImage, // pmaThemeImage
null, // disp_query
null, // disp_message
$query_type, // query_type
$sql_query, // sql_query
$selected, // selectedTables
null // complete_query
);
} elseif (!$run_parts) {
$GLOBALS['dbi']->selectDb($db);

View File

@ -100,7 +100,7 @@ class Lexer
*
* @var TokensList
*/
public $tokens;
public $list;
/**
* Statements delimiter.
@ -164,7 +164,7 @@ class Lexer
// context and compare again with `false`.
// Another example is `parseComment`.
$tokens = new TokensList();
$list = new TokensList();
$lastToken = null;
for ($this->last = 0, $lastIdx = 0; $this->last < $this->len; $lastIdx = ++$this->last) {
@ -203,7 +203,7 @@ class Lexer
}
$token->position = $lastIdx;
$tokens->tokens[$tokens->count++] = $token;
$list->tokens[$list->count++] = $token;
// Handling delimiters.
if (($token->type === Token::TYPE_NONE) && ($token->value === 'DELIMITER')) {
@ -217,7 +217,7 @@ class Lexer
$pos = ++$this->last;
if (($token = $this->parseWhitespace()) !== null) {
$token->position = $pos;
$tokens->tokens[$tokens->count++] = $token;
$list->tokens[$list->count++] = $token;
}
// Preparing the token that holds the new delimiter.
@ -238,17 +238,17 @@ class Lexer
$this->delimiterLen = strlen($this->delimiter);
$token = new Token($this->delimiter, Token::TYPE_DELIMITER);
$token->position = $pos;
$tokens->tokens[$tokens->count++] = $token;
$list->tokens[$list->count++] = $token;
}
$lastToken = $token;
}
// Adding a final delimite at the end to mark the ending.
$tokens->tokens[$tokens->count++] = new Token(null, Token::TYPE_DELIMITER);
$list->tokens[$list->count++] = new Token(null, Token::TYPE_DELIMITER);
// Saving the tokens list.
$this->tokens = $tokens;
$this->list = $list;
}
/**

View File

@ -225,7 +225,7 @@ class Parser
{
if ((is_string($list)) || ($list instanceof UtfString)) {
$lexer = new Lexer($list, $strict);
$this->list = $lexer->tokens;
$this->list = $lexer->list;
} elseif ($list instanceof TokensList) {
$this->list = $list;
}

View File

@ -59,6 +59,8 @@ abstract class Statement
*/
public function parse(Parser $parser, TokensList $list)
{
$this->first = $list->idx;
/**
* Whether options were parsed or not.
* For statements that do not have any options this is set to `true` by
@ -134,7 +136,7 @@ abstract class Statement
$this->after($parser, $list, $token);
}
$this->last = --$list->idx; // Go back to last used token.
$this->last = $list->idx--; // Go back to last used token.
}
/**

View File

@ -67,6 +67,20 @@ class SelectStatement extends Statement
'SQL_CALC_FOUND_ROWS' => 9,
);
/**
* The sections of this statement, in order.
*
* Used by the query builder to arrange the clauses.
*
* @var array
*/
public static $SECTIONS = array(
'SELECT' => 0, '%OPTIONS' => 1,'FROM' => 2, 'PARTITION' => 3,
'WHERE' => 4, 'GROUP BY' => 5, 'HAVING' => 6, 'ORDER BY' => 7,
'LIMIT' => 8, 'PROCEDURE' => 9, 'INTO' => 10, 'UNION' => 11,
'JOIN' => 12, '%OPTIONS' => 13
);
/**
* Expressions that are being selected by this statement.
*

View File

@ -10,6 +10,7 @@ namespace SqlParser\Utils;
use SqlParser\Parser;
use SqlParser\Statement;
use SqlParser\Token;
use SqlParser\Statements\AlterStatement;
use SqlParser\Statements\AnalyzeStatement;
use SqlParser\Statements\CallStatement;
@ -61,49 +62,193 @@ class Query
$flags = array();
if ($all) {
$flags = array(
/**
* select ... DISTINCT ...
*/
'distinct' => false,
/**
* drop ... DATABASE ...
*/
'drop_database' => false,
/**
* ... GROUP BY ...
*/
'group' => false,
/**
* ... HAVING ...
*/
'having' => false,
/**
* INSERT ...
* or
* REPLACE ...
* or
* DELETE ...
*/
'is_affected' => false,
/**
* select ... PROCEDURE ANALYSE( ... ) ...
*/
'is_analyse' => false,
/**
* select COUNT( ... ) ...
*/
'is_count' => false,
'is_delete' => false,
'is_explain' => false,
/**
* DELETE ...
*/
'is_delete' => false, // @deprecated; use `querytype`
/**
* EXPLAIN ...
*/
'is_explain' => false, // @deprecated; use `querytype`
/**
* select ... INTO OUTFILE ...
*/
'is_export' => false,
/**
* select FUNC( ... ) ...
*/
'is_func' => false,
/**
* select ... GROUP BY ...
* or
* select ... HAVING ...
*/
'is_group' => false,
/**
* INSERT ...
* or
* REPLACE ...
* or
* TODO: LOAD DATA ...
*/
'is_insert' => false,
/**
* ANALYZE ...
* or
* CHECK ...
* or
* CHECKSUM ...
* or
* OPTIMIZE ...
* or
* REPAIR ...
*/
'is_maint' => false,
/**
* CALL ...
*/
'is_procedure' => false,
'is_replace' => false,
'is_select' => false,
'is_show' => false,
/**
* REPLACE ...
*/
'is_replace' => false, // @deprecated; use `querytype`
/**
* SELECT ...
*/
'is_select' => false, // @deprecated; use `querytype`
/**
* SHOW ...
*/
'is_show' => false, // @deprecated; use `querytype`
/**
* Contains a subquery.
*/
'is_subquery' => false,
/**
* ... JOIN ...
*/
'join' => false,
/**
* ... LIMIT ...
*/
'limit' => false,
/**
* TODO
*/
'offset' => false,
/**
* ... ORDER ...
*/
'order' => false,
/**
* The type of the query (which is usually the first keyword of
* the statement).
*/
'querytype' => false,
/**
* Whether a page reload is required.
*/
'reload' => false,
/**
* SELECT ... FROM ...
*/
'select_from' => false,
/**
* ... UNION ...
*/
'union' => false
);
}
// TODO: 'union', 'join', 'offset'
if (($statement instanceof AlterStatement)
|| ($statement instanceof CreateStatement)
) {
if ($statement instanceof AlterStatement) {
$flags['querytype'] = 'ALTER';
$flags['reload'] = true;
} else if (($statement instanceof AnalyzeStatement)
|| ($statement instanceof CheckStatement)
|| ($statement instanceof ChecksumStatement)
|| ($statement instanceof OptimizeStatement)
|| ($statement instanceof RepairStatement)
) {
} else if ($statement instanceof CreateStatement) {
$flags['querytype'] = 'CREATE';
$flags['reload'] = true;
} else if ($statement instanceof AnalyzeStatement) {
$flags['querytype'] = 'ANALYZE';
$flags['is_maint'] = true;
} else if ($statement instanceof CheckStatement) {
$flags['querytype'] = 'CHECK';
$flags['is_maint'] = true;
} else if ($statement instanceof ChecksumStatement) {
$flags['querytype'] = 'CHECKSUM';
$flags['is_maint'] = true;
} else if ($statement instanceof OptimizeStatement) {
$flags['querytype'] = 'OPTIMIZE';
$flags['is_maint'] = true;
} else if ($statement instanceof RepairStatement) {
$flags['querytype'] = 'REPAIR';
$flags['is_maint'] = true;
} else if ($statement instanceof CallStatement) {
$flags['querytype'] = 'CALL';
$flags['is_procedure'] = true;
} else if ($statement instanceof DeleteStatement) {
$flags['querytype'] = 'DELETE';
$flags['is_delete'] = true;
$flags['is_affected'] = true;
} else if ($statement instanceof DropStatement) {
$flags['querytype'] = 'DROP';
$flags['reload'] = true;
if (($statement->options->has('DATABASE')
@ -112,14 +257,19 @@ class Query
$flags['drop_database'] = true;
}
} else if ($statement instanceof ExplainStatement) {
$flags['querytype'] = 'EXPLAIN';
$flags['is_explain'] = true;
} else if ($statement instanceof InsertStatement) {
$flags['querytype'] = 'INSERT';
$flags['is_affected'] = true;
$flags['is_insert'] = true;
} else if ($statement instanceof ReplaceStatement) {
$flags['querytype'] = 'REPLACE';
$flags['is_affected'] = true;
$flags['is_replace'] = true;
$flags['is_insert'] = true;
} else if ($statement instanceof SelectStatement) {
$flags['querytype'] = 'SELECT';
$flags['is_select'] = true;
if (!empty($statement->from)) {
@ -158,12 +308,43 @@ class Query
) {
$flags['is_analyse'] = true;
}
if (!empty($statement->group)) {
$flags['group'] = true;
}
if (!empty($statement->having)) {
$flags['having'] = true;
}
if (!empty($statement->union)) {
$flags['union'] = true;
}
if (!empty($statement->join)) {
$flags['join'] = true;
}
} else if ($statement instanceof ShowStatement) {
$flags['querytype'] = 'SHOW';
$flags['is_show'] = true;
} else if ($statement instanceof UpdateStatement) {
$flags['querytype'] = 'UPDATE';
$flags['is_affected'] = true;
}
if (($statement instanceof SelectStatement)
|| ($statement instanceof UpdateStatement)
|| ($statement instanceof DeleteStatement)
) {
if (!empty($statement->limit)) {
$flags['limit'] = true;
}
if (!empty($statement->order)) {
$flags['order'] = true;
}
}
return $flags;
}
@ -190,13 +371,16 @@ class Query
$ret['statement'] = $statement;
if ($statement instanceof SelectStatement) {
$ret['tables'] = array();
$ret['select_tables'] = array();
$ret['select_expr'] = array();
foreach ($statement->expr as $expr) {
if (!empty($expr->table)) {
$ret['tables'][] = array(
$ret['select_tables'][] = array(
$expr->table,
!empty($expr->database) ? $expr->database : null
);
} else {
$ret['select_expr'][] = $expr->expr;
}
}
}
@ -204,4 +388,106 @@ class Query
return $ret;
}
public static function getClauseType($clause)
{
$type = '';
for ($i = 0, $len = strlen($clause); $i < $len; ++$i) {
if ((empty($type)) && (ctype_space($type))) {
// Skipping whitespaces if we haven't started determining the
// type.
continue;
}
if (!ctype_alnum($clause[$i])) {
// The type contains only alphanumeric characters.
break;
}
// Adding character.
$type .= $clause[$i];
}
return $type;
}
/**
* Replaces the clause in the query. If the clause does not exist, it is
* inserted.
*
* It is a very basic version of a query builder.
*
* @param Statement $statement The parsed query that has to be modified.
* @param TokensList $list The list of tokens.
* @param string $clause The clause to be replaced.
*
* @return string
*/
public static function replaceClause($statement, $list, $clause)
{
/**
* Current location.
* @var int
*/
$currIdx = 0;
/**
* The count of brackets.
* We keep track of them so we won't insert the clause in a subquery.
* @var int
*/
$brackets = 0;
/**
* The sections before the clause
* @var string
*/
$before = '';
/**
* The sections after the clause.
* @var string
*/
$after = '';
/**
* The place where the clause should be added.
* @var int
*/
$clauseIdx = $statement::$SECTIONS[static::getClauseType($clause)];
for ($i = $statement->first; $i <= $statement->last; ++$i) {
$token = $list->tokens[$i];
if ($token->type === Token::TYPE_DELIMITER) {
break;
}
if ($token->type === Token::TYPE_OPERATOR) {
if ($token->value === '(') {
++$brackets;
} elseif ($token->value === ')') {
--$brackets;
}
}
if ($brackets == 0) {
// Checking if we changed sections.
if ($token->type === Token::TYPE_KEYWORD) {
if (isset($statement::$SECTIONS[$token->value])) {
if ($statement::$SECTIONS[$token->value] > $currIdx) {
$currIdx = $statement::$SECTIONS[$token->value];
}
}
}
}
if ($currIdx < $clauseIdx) {
$before .= $token->token;
} elseif ($currIdx > $clauseIdx) {
$after .= $token->value;
}
}
return $before . ' ' . $clause . ' ' . $after;
}
}

View File

@ -39,7 +39,7 @@ class Routine
$lexer = new Lexer($param);
// A dummy parser is used for error reporting.
$type = DataTypeFragment::parse(new Parser(), $lexer->tokens);
$type = DataTypeFragment::parse(new Parser(), $lexer->list);
if ($type === null) {
return array('', '', '', '', '');
@ -71,7 +71,7 @@ class Routine
$lexer = new Lexer('(' . $param . ')');
// A dummy parser is used for error reporting.
$param = ParamDefFragment::parse(new Parser(), $lexer->tokens);
$param = ParamDefFragment::parse(new Parser(), $lexer->list);
if (empty($param[0])) {
return array('', '', '', '', '');

View File

@ -60,7 +60,6 @@ function PMA_getTableNameBySQL($sql, $tables)
return trim($table);
}
/**
* Handle remembered sorting order, only for single table query
*
@ -75,31 +74,29 @@ function PMA_handleSortOrder(
$db, $table, &$analyzed_sql_results, &$full_sql_query
) {
$pmatable = new PMA_Table($table, $db);
if (empty($analyzed_sql_results['analyzed_sql'][0]['order_by_clause'])) {
$sorted_col = $pmatable->getUiProp(PMA_Table::PROP_SORTED_COLUMN);
if ($sorted_col) {
//remove the tablename from retrieved preference
//to get just the column name and the sort order
$sorted_col = str_replace(
PMA_Util::backquote($table) . '.', '', $sorted_col
);
// retrieve the remembered sorting order for current table
$sql_order_to_append = ' ORDER BY ' . $sorted_col . ' ';
$full_sql_query
= $analyzed_sql_results['analyzed_sql'][0]['section_before_limit']
. $sql_order_to_append
. $analyzed_sql_results['analyzed_sql'][0]['limit_clause']
. ' '
. $analyzed_sql_results['analyzed_sql'][0]['section_after_limit'];
// update the $analyzed_sql
$analyzed_sql_results['analyzed_sql'][0]['section_before_limit']
.= $sql_order_to_append;
$analyzed_sql_results['analyzed_sql'][0]['order_by_clause']
= $sorted_col;
if (empty($analyzed_sql_results['order'])) {
// Retrieving the name of the column we should sort after.
$sortCol = $pmatable->getUiProp(PMA_Table::PROP_SORTED_COLUMN);
if (empty($sortCol)) {
return;
}
// Remove the name of the the table from the retrieved field name.
$sortCol = str_replace(PMA_Util::backquote($table) . '.', '', $sortCol);
// Create the new query.
$full_sql_query = SqlParser\Utils\Query::replaceClause(
$analyzed_sql_results['statement'],
$analyzed_sql_results['parser']->list,
'ORDER BY ' . $sortCol
);
// TODO: Avoid reparsing the query.
$analyzed_sql_results = SqlParser\Utils\Query::getAll($full_sql_query);
} else {
// store the remembered table into session
// Store the remembered table into session.
$pmatable->setUiProp(
PMA_Table::PROP_SORTED_COLUMN,
$analyzed_sql_results['analyzed_sql'][0]['order_by_clause']
@ -110,16 +107,18 @@ function PMA_handleSortOrder(
/**
* Append limit clause to SQL query
*
* @param array $analyzed_sql the analyzed query
* @param string $sql_limit_to_append clause to append
* @param array &$analyzed_sql_results the analyzed query results
*
* @return string limit clause appended SQL query
*/
function PMA_getSqlWithLimitClause($analyzed_sql,
$sql_limit_to_append
) {
return $analyzed_sql[0]['section_before_limit'] . "\n"
. $sql_limit_to_append . $analyzed_sql[0]['section_after_limit'];
function PMA_getSqlWithLimitClause(&$analyzed_sql_results)
{
return SqlParser\Utils\Query::replaceClause(
$analyzed_sql_results['statement'],
$analyzed_sql_results['parser']->list,
'LIMIT ' . $_SESSION['tmpval']['pos'] . ', '
. $_SESSION['tmpval']['max_rows']
);
}
@ -617,23 +616,15 @@ function PMA_getHtmlForBookmark($displayParts, $cfgBookmark, $sql_query, $db,
*/
function PMA_isRememberSortingOrder($analyzed_sql_results)
{
$select_from = isset(
$analyzed_sql_results['analyzed_sql'][0]['queryflags']['select_from']
);
if ($GLOBALS['cfg']['RememberSorting']
return $GLOBALS['cfg']['RememberSorting']
&& ! ($analyzed_sql_results['is_count']
|| $analyzed_sql_results['is_export']
|| $analyzed_sql_results['is_func']
|| $analyzed_sql_results['is_analyse'])
&& isset($analyzed_sql_results['analyzed_sql'][0]['select_expr'])
&& (count($analyzed_sql_results['analyzed_sql'][0]['select_expr']) == 0)
&& $select_from
&& count($analyzed_sql_results['analyzed_sql'][0]['table_ref']) == 1
) {
return true;
} else {
return false;
}
|| $analyzed_sql_results['is_export']
|| $analyzed_sql_results['is_func']
|| $analyzed_sql_results['is_analyse'])
&& $analyzed_sql_results['select_from']
&& empty($analyzed_sql_results['select_expr'])
&& count($analyzed_sql_results['analyzed_sql']['select_expr']) == 0
&& count($analyzed_sql_results['analyzed_sql']['select_tables']) == 1;
}
/**
@ -646,20 +637,12 @@ function PMA_isRememberSortingOrder($analyzed_sql_results)
*/
function PMA_isAppendLimitClause($analyzed_sql_results)
{
$select_from = isset(
$analyzed_sql_results['analyzed_sql'][0]['queryflags']['select_from']
);
if (($_SESSION['tmpval']['max_rows'] != 'all')
return ($_SESSION['tmpval']['max_rows'] != 'all')
&& ! ($analyzed_sql_results['is_export']
|| $analyzed_sql_results['is_analyse'])
&& ($select_from || $analyzed_sql_results['is_subquery'])
&& ! isset($analyzed_sql_results['analyzed_sql'][0]['queryflags']['offset'])
&& empty($analyzed_sql_results['analyzed_sql'][0]['limit_clause'])
) {
return true;
} else {
return false;
}
&& ($analyzed_sql_results['select_from']
|| $analyzed_sql_results['is_subquery'])
&& empty($analyzed_sql_results['limit']);
}
/**
@ -673,29 +656,18 @@ function PMA_isAppendLimitClause($analyzed_sql_results)
*/
function PMA_isJustBrowsing($analyzed_sql_results, $find_real_end)
{
$distinct = isset(
$analyzed_sql_results['analyzed_sql'][0]['queryflags']['distinct']
);
$table_name = isset(
$analyzed_sql_results['analyzed_sql'][0]['table_ref'][1]['table_name']
);
if (! $analyzed_sql_results['is_group']
return ! $analyzed_sql_results['is_group']
&& ! $analyzed_sql_results['is_func']
&& ! isset($analyzed_sql_results['analyzed_sql'][0]['queryflags']['union'])
&& ! $distinct
&& ! $table_name
&& (empty($analyzed_sql_results['analyzed_sql'][0]['where_clause'])
|| $analyzed_sql_results['analyzed_sql'][0]['where_clause'] == '1 ')
&& empty($analyzed_sql_results['analyzed_sql'][0]['group_by_clause'])
&& empty($analyzed_sql_results['union'])
&& empty($analyzed_sql_results['distinct'])
&& count($analyzed_sql_results['select_tables'] <= 1)
&& (empty($analyzed_sql_results['statement']->where)
|| (count($analyzed_sql_results['statement']->where) == 1
&& $analyzed_sql_results['statement']->where->expr ==='1'))
&& empty($analyzed_sql_results['group'])
&& ! isset($find_real_end)
&& !$analyzed_sql_results['is_subquery']
&& empty($analyzed_sql_results['analyzed_sql'][0]['having_clause'])
) {
return true;
} else {
return false;
}
&& ! $analyzed_sql_results['is_subquery']
&& empty($analyzed_sql_results['having']);
}
/**
@ -708,14 +680,9 @@ function PMA_isJustBrowsing($analyzed_sql_results, $find_real_end)
*/
function PMA_isDeleteTransformationInfo($analyzed_sql_results)
{
if (!empty($analyzed_sql_results['analyzed_sql'][0]['querytype'])
&& (($analyzed_sql_results['analyzed_sql'][0]['querytype'] == 'ALTER')
|| ($analyzed_sql_results['analyzed_sql'][0]['querytype'] == 'DROP'))
) {
return true;
} else {
return false;
}
return !empty($analyzed_sql_results['querytype'])
&& (($analyzed_sql_results['querytype'] == 'ALTER')
|| ($analyzed_sql_results['querytype'] == 'DROP'));
}
/**
@ -1099,18 +1066,13 @@ function PMA_getNumberOfRowsAffectedOrChanged($is_affected, $result)
*/
function PMA_hasCurrentDbChanged($db)
{
// Checks if the current database has changed
// This could happen if the user sends a query like "USE `database`;"
$reload = 0;
if (/*overload*/mb_strlen($db)) {
$current_db = $GLOBALS['dbi']->fetchValue('SELECT DATABASE()');
// $current_db is false, except when a USE statement was sent
if ($current_db != false && $db !== $current_db) {
$reload = 1;
}
return ($current_db != false) && ($db !== $current_db);
}
return $reload;
return false;
}
/**
@ -1154,26 +1116,25 @@ function PMA_cleanupRelations($db, $table, $dropped_column, $purge, $extra_data)
* the 'LIMIT' clause that may have been programatically added
*
* @param int $num_rows number of rows affected/changed by the query
* @param bool $is_select whether the query is SELECT or not
* @param bool $justBrowsing whether just browsing or not
* @param string $db the current database
* @param string $table the current table
* @param array $parsed_sql parsed sql
* @param array $analyzed_sql_results the analyzed query and other variables set
* after analyzing the query
*
* @return int $unlim_num_rows unlimited number of rows
*/
function PMA_countQueryResults(
$num_rows, $is_select, $justBrowsing,
$db, $table, $parsed_sql, $analyzed_sql_results
$num_rows, $justBrowsing, $db, $table, $analyzed_sql_results
) {
if (!PMA_isAppendLimitClause($analyzed_sql_results)) {
// if we did not append a limit, set this to get a correct
// "Showing rows..." message
// $_SESSION['tmpval']['max_rows'] = 'all';
$unlim_num_rows = $num_rows;
} elseif ($is_select || $analyzed_sql_results['is_subquery']) {
} elseif ($analyzed_sql_results['querytype'] == 'SELECT'
|| $analyzed_sql_results['is_subquery']
) {
// c o u n t q u e r y
// If we are "just browsing", there is only one table,
@ -1219,10 +1180,12 @@ function PMA_countQueryResults(
// SELECT
// (SELECT
// TODO: Replace PMA_SQP_
$analyzed_sql = $analyzed_sql_results['analyzed_sql'];
$count_query = PMA_SQP_format(
$parsed_sql,
$analyzed_sql_results['parsed_sql'],
'query_only',
0,
$analyzed_sql[0]['position_of_first_select'] + 1
@ -1230,7 +1193,7 @@ function PMA_countQueryResults(
$count_query .= ' SQL_CALC_FOUND_ROWS ';
// add everything that was after the first SELECT
$count_query .= PMA_SQP_format(
$parsed_sql,
$analyzed_sql_results['parsed_sql'],
'query_only',
$analyzed_sql[0]['position_of_first_select'] + 1
);
@ -1341,8 +1304,7 @@ function PMA_executeTheQuery($analyzed_sql_results, $full_sql_query, $is_gotofil
);
$unlim_num_rows = PMA_countQueryResults(
$num_rows, $analyzed_sql_results['is_select'], $justBrowsing, $db,
$table, $analyzed_sql_results['parsed_sql'], $analyzed_sql_results
$num_rows, $justBrowsing, $db, $table, $analyzed_sql_results
);
$extra_data = PMA_cleanupRelations(
@ -1365,23 +1327,23 @@ function PMA_executeTheQuery($analyzed_sql_results, $full_sql_query, $is_gotofil
/**
* Delete related tranformatioinformationn information
*
* @param String $db current database
* @param String $table current table
* @param array $analyzed_sql analyzed sql query
* @param String $db current database
* @param String $table current table
* @param array $analyzed_sql_results analyzed sql results
*
* @return void
*/
function PMA_deleteTransformationInfo($db, $table, $analyzed_sql)
function PMA_deleteTransformationInfo($db, $table, $analyzed_sql_results)
{
include_once 'libraries/transformations.lib.php';
if ($analyzed_sql[0]['querytype'] == 'ALTER') {
if ($analyzed_sql_results['querytype'] == 'ALTER') {
$posDrop = /*overload*/mb_stripos(
$analyzed_sql[0]['unsorted_query'],
$analyzed_sql_results['analyzed_sql'][0]['unsorted_query'],
'DROP'
);
if ($posDrop !== false) {
$drop_column = PMA_getColumnNameInColumnDropSql(
$analyzed_sql[0]['unsorted_query']
$analyzed_sql_results['analyzed_sql'][0]['unsorted_query']
);
if ($drop_column != '') {
@ -1389,7 +1351,7 @@ function PMA_deleteTransformationInfo($db, $table, $analyzed_sql)
}
}
} else if (($analyzed_sql[0]['querytype'] == 'DROP') && ($table != '')) {
} else if (($analyzed_sql_results['querytype'] == 'DROP') && ($table != '')) {
PMA_clearTransformations($db, $table);
}
}
@ -1403,14 +1365,14 @@ function PMA_deleteTransformationInfo($db, $table, $analyzed_sql)
*
* @return string $message
*/
function PMA_getMessageForNoRowsReturned($message_to_show, $analyzed_sql_results,
$num_rows
function PMA_getMessageForNoRowsReturned($message_to_show,
$analyzed_sql_results, $num_rows
) {
if ($analyzed_sql_results['is_delete']) {
if ($analyzed_sql_results['querytype'] == 'DELETE"') {
$message = PMA_Message::getMessageForDeletedRows($num_rows);
} elseif ($analyzed_sql_results['is_insert']) {
if ($analyzed_sql_results['is_replace']) {
// For replace we get DELETED + INSERTED row count,
if ($analyzed_sql_results['querytype'] == 'REPLACE') {
// For REPLACE we get DELETED + INSERTED row count,
// so we have to call it affected
$message = PMA_Message::getMessageForAffectedRows($num_rows);
} else {
@ -1438,7 +1400,9 @@ function PMA_getMessageForNoRowsReturned($message_to_show, $analyzed_sql_results
// fact that $message_to_show is sent for every case.
// The $message_to_show containing a success message and sent with
// the form should not have priority over errors
} elseif (! empty($message_to_show) && ! $analyzed_sql_results['is_select']) {
} elseif (! empty($message_to_show)
&& $analyzed_sql_results['querytype'] != 'SELECT'
) {
$message = PMA_Message::rawSuccess(htmlspecialchars($message_to_show));
} elseif (! empty($GLOBALS['show_as_php'])) {
$message = PMA_Message::success(__('Showing as PHP code'));
@ -1492,14 +1456,12 @@ function PMA_getQueryResponseForNoResultsReturned($analyzed_sql_results, $db,
$table, $message_to_show, $num_rows, $displayResultsObject, $extra_data
) {
if (PMA_isDeleteTransformationInfo($analyzed_sql_results)) {
PMA_deleteTransformationInfo(
$db, $table, $analyzed_sql_results['analyzed_sql']
);
PMA_deleteTransformationInfo($db, $table, $analyzed_sql_results);
}
$message = PMA_getMessageForNoRowsReturned(
isset($message_to_show) ? $message_to_show : null, $analyzed_sql_results,
$num_rows
isset($message_to_show) ? $message_to_show : null,
$analyzed_sql_results, $num_rows
);
$html_output = '';
@ -1526,8 +1488,7 @@ function PMA_getQueryResponseForNoResultsReturned($analyzed_sql_results, $db,
$response = PMA_Response::getInstance();
$response->addJSON(isset($extra_data) ? $extra_data : array());
$query_type = PMA_DisplayResults::QUERY_TYPE_SELECT;
if ($analyzed_sql_results['analyzed_sql'][0]['querytype'] == $query_type) {
if (!empty($analyzed_sql_results['is_select'])) {
$html_output .= $displayResultsObject->getCreateViewQueryResultOp(
$analyzed_sql_results['analyzed_sql']
);
@ -2029,7 +1990,6 @@ function PMA_getQueryResponseForResultsReturned($result,
* @param bool|null $find_real_end whether to find real end or not
* @param string $sql_query_for_bookmark the sql query to be stored as bookmark
* @param array|null $extra_data extra data
* @param bool $is_affected whether affected or not
* @param string $message_to_show message to show
* @param string $message message
* @param array|null $sql_data sql data
@ -2049,16 +2009,29 @@ function PMA_getQueryResponseForResultsReturned($result,
*/
function PMA_executeQueryAndSendQueryResponse($analyzed_sql_results,
$is_gotofile, $db, $table, $find_real_end, $sql_query_for_bookmark,
$extra_data, $is_affected, $message_to_show, $message,
$sql_data, $goto, $pmaThemeImage, $disp_query, $disp_message,
$query_type, $sql_query, $selectedTables, $complete_query
$extra_data, $message_to_show, $message, $sql_data, $goto, $pmaThemeImage,
$disp_query, $disp_message, $query_type, $sql_query, $selectedTables,
$complete_query
) {
$html_output = PMA_executeQueryAndGetQueryResponse(
$analyzed_sql_results, $is_gotofile, $db, $table,
$find_real_end, $sql_query_for_bookmark,
$extra_data, $is_affected, $message_to_show, $message,
$sql_data, $goto, $pmaThemeImage, $disp_query, $disp_message,
$query_type, $sql_query, $selectedTables, $complete_query
$analyzed_sql_results, // analyzed_sql_results
$is_gotofile, // is_gotofile
$db, // db
$table, // table
$find_real_end, // find_real_end
$sql_query_for_bookmark, // sql_query_for_bookmark
$extra_data, // extra_data
$message_to_show, // message_to_show
$message, // message
$sql_data, // sql_data
$goto, // goto
$pmaThemeImage, // pmaThemeImage
$disp_query, // disp_query
$disp_message, // disp_message
$query_type, // query_type
$sql_query, // sql_query
$selectedTables, // selectedTables
$complete_query // complete_query
);
$response = PMA_Response::getInstance();
@ -2075,7 +2048,6 @@ function PMA_executeQueryAndSendQueryResponse($analyzed_sql_results,
* @param bool|null $find_real_end whether to find real end or not
* @param string $sql_query_for_bookmark the sql query to be stored as bookmark
* @param array|null $extra_data extra data
* @param bool $is_affected whether affected or not
* @param string $message_to_show message to show
* @param string $message message
* @param array|null $sql_data sql data
@ -2095,9 +2067,9 @@ function PMA_executeQueryAndSendQueryResponse($analyzed_sql_results,
*/
function PMA_executeQueryAndGetQueryResponse($analyzed_sql_results,
$is_gotofile, $db, $table, $find_real_end, $sql_query_for_bookmark,
$extra_data, $is_affected, $message_to_show, $message,
$sql_data, $goto, $pmaThemeImage, $disp_query, $disp_message,
$query_type, $sql_query, $selectedTables, $complete_query
$extra_data, $message_to_show, $message, $sql_data, $goto, $pmaThemeImage,
$disp_query, $disp_message, $query_type, $sql_query, $selectedTables,
$complete_query
) {
// Include PMA_Index class for use in PMA_DisplayResults class
include_once './libraries/Index.class.php';
@ -2111,7 +2083,7 @@ function PMA_executeQueryAndGetQueryResponse($analyzed_sql_results,
// Handling is not required when it's a union query
// (the parser never sets the 'union' key to 0)
if (PMA_isRememberSortingOrder($analyzed_sql_results)
&& ! isset($analyzed_sql_results['analyzed_sql'][0]['queryflags']['union'])
&& empty($analyzed_sql_results['union'])
) {
if (! isset($_SESSION['sql_from_query_box'])) {
PMA_handleSortOrder($db, $table, $analyzed_sql_results, $sql_query);
@ -2131,11 +2103,7 @@ function PMA_executeQueryAndGetQueryResponse($analyzed_sql_results,
// Do append a "LIMIT" clause?
if (PMA_isAppendLimitClause($analyzed_sql_results)) {
$full_sql_query = PMA_getSqlWithLimitClause(
$analyzed_sql_results['analyzed_sql'],
' LIMIT ' . $_SESSION['tmpval']['pos']
. ', ' . $_SESSION['tmpval']['max_rows'] . " "
);
$full_sql_query = PMA_getSqlWithLimitClause($analyzed_sql_results);
}
$GLOBALS['reload'] = PMA_hasCurrentDbChanged($db);
@ -2155,7 +2123,7 @@ function PMA_executeQueryAndGetQueryResponse($analyzed_sql_results,
);
// No rows returned -> move back to the calling page
if ((0 == $num_rows && 0 == $unlim_num_rows) || $is_affected) {
if ((0 == $num_rows && 0 == $unlim_num_rows) || $analyzed_sql_results['is_affected']) {
$html_output = PMA_getQueryResponseForNoResultsReturned(
$analyzed_sql_results, $db, $table,
isset($message_to_show) ? $message_to_show : null,

View File

@ -3004,9 +3004,24 @@ function PMA_displayTableBrowseForSelectedColumns($db, $table, $goto,
include_once 'libraries/sql.lib.php';
PMA_executeQueryAndSendQueryResponse(
$analyzed_sql_results, false, $db, $table, null, null, null, false,
null, null, null, $goto, $pmaThemeImage, null, null,
null, $sql_query, null, null
$analyzed_sql_results, // analyzed_sql_results
false, // is_gotofile
$db, // db
$table, // table
null, // find_real_end
null, // sql_query_for_bookmark
null, // extra_data
null, // message_to_show
null, // message
null, // sql_data
$goto, // goto
$pmaThemeImage, // pmaThemeImage
null, // disp_query
null, // disp_message
null, // query_type
$sql_query, // sql_query
null, // selectedTables
null // complete_query
);
}

37
sql.php
View File

@ -197,23 +197,22 @@ if ($goto == 'sql.php') {
} // end if
PMA_executeQueryAndSendQueryResponse(
$analyzed_sql_results,
$is_gotofile,
$db,
$table,
isset($find_real_end) ? $find_real_end : null,
isset($import_text) ? $import_text : null,
isset($extra_data) ? $extra_data : null,
$is_affected,
isset($message_to_show) ? $message_to_show : null,
isset($message) ? $message : null,
isset($sql_data) ? $sql_data : null,
$goto,
$pmaThemeImage,
isset($disp_query) ? $display_query : null,
isset($disp_message) ? $disp_message : null,
isset($query_type) ? $query_type : null,
$sql_query,
isset($selected) ? $selected : null,
isset($complete_query) ? $complete_query : null
$analyzed_sql_results, // analyzed_sql_results
$is_gotofile, // is_gotofile
$db, // db
$table, // table
isset($find_real_end) ? $find_real_end : null, // find_real_end
isset($import_text) ? $import_text : null, // sql_query_for_bookmark
isset($extra_data) ? $extra_data : null, // extra_data
isset($message_to_show) ? $message_to_show : null, // message_to_show
isset($message) ? $message : null, // message
isset($sql_data) ? $sql_data : null, // sql_data
$goto, // goto
$pmaThemeImage, // pmaThemeImage
isset($disp_query) ? $display_query : null, // disp_query
isset($disp_message) ? $disp_message : null, // disp_message
isset($query_type) ? $query_type : null, // query_type
$sql_query, // sql_query
isset($selected) ? $selected : null, // selectedTables
isset($complete_query) ? $complete_query : null // complete_query
);

View File

@ -145,9 +145,24 @@ if (!empty($submit_mult)) {
include_once 'libraries/parse_analyze.inc.php';
PMA_executeQueryAndSendQueryResponse(
$analyzed_sql_results, false, $db, $table, null, null, null, false, null,
null, null, $goto, $pmaThemeImage, null, null, null, $sql_query,
null, null
$analyzed_sql_results, // analyzed_sql_results
false, // is_gotofile
$db, // db
$table, // table
null, // find_real_end
null, // sql_query_for_bookmark
null, // extra_data
null, // message_to_show
null, // message
null, // sql_data
$goto, // goto
$pmaThemeImage, // pmaThemeImage
null, // disp_query
null, // disp_message
null, // query_type
$sql_query, // sql_query
null, // selectedTables
null // complete_query
);
}
}

View File

@ -64,6 +64,7 @@ if (! isset($_POST['columnsToDisplay']) && ! isset($_POST['displayAllColumns']))
$response->addHTML($table_search->getSelectionForm($goto));
} else {
/**
* Selection criteria have been submitted -> do the work
*/
@ -75,8 +76,23 @@ if (! isset($_POST['columnsToDisplay']) && ! isset($_POST['displayAllColumns']))
include_once 'libraries/parse_analyze.inc.php';
PMA_executeQueryAndSendQueryResponse(
$analyzed_sql_results, false, $db, $table, null, null, null, false,
null, null, null, $GLOBALS['goto'], $pmaThemeImage, null,
null, null, $sql_query, null, null
$analyzed_sql_results, // analyzed_sql_results
false, // is_gotofile
$db, // db
$table, // table
null, // find_real_end
null, // sql_query_for_bookmark
null, // extra_data
null, // message_to_show
null, // message
null, // sql_data
$GLOBALS['goto'], // goto
$pmaThemeImage, // pmaThemeImage
null, // disp_query
null, // disp_message
null, // query_type
$sql_query, // sql_query
null, // selectedTables
null // complete_query
);
}