diff options
-rw-r--r-- | db_qbe.php | 23 | ||||
-rw-r--r-- | import.php | 22 | ||||
-rw-r--r-- | libraries/mult_submits.inc.php | 22 | ||||
-rw-r--r-- | libraries/sql-parser/src/Lexer.php | 14 | ||||
-rw-r--r-- | libraries/sql-parser/src/Parser.php | 2 | ||||
-rw-r--r-- | libraries/sql-parser/src/Statement.php | 4 | ||||
-rw-r--r-- | libraries/sql-parser/src/Statements/SelectStatement.php | 14 | ||||
-rw-r--r-- | libraries/sql-parser/src/Utils/Query.php | 320 | ||||
-rw-r--r-- | libraries/sql-parser/src/Utils/Routine.php | 4 | ||||
-rw-r--r-- | libraries/sql.lib.php | 258 | ||||
-rw-r--r-- | libraries/structure.lib.php | 21 | ||||
-rw-r--r-- | sql.php | 37 | ||||
-rw-r--r-- | tbl_row_action.php | 21 | ||||
-rw-r--r-- | tbl_select.php | 22 |
14 files changed, 572 insertions, 212 deletions
diff --git a/db_qbe.php b/db_qbe.php index 2d6b499106..b57fd31027 100644 --- a/db_qbe.php +++ b/db_qbe.php @@ -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 ); } } diff --git a/import.php b/import.php index 0576cc8626..38d0d5c48d 100644 --- a/import.php +++ b/import.php @@ -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 ); } diff --git a/libraries/mult_submits.inc.php b/libraries/mult_submits.inc.php index 6020c83b76..6500e0221c 100644 --- a/libraries/mult_submits.inc.php +++ b/libraries/mult_submits.inc.php @@ -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); diff --git a/libraries/sql-parser/src/Lexer.php b/libraries/sql-parser/src/Lexer.php index d6814259d5..b91db8bf2a 100644 --- a/libraries/sql-parser/src/Lexer.php +++ b/libraries/sql-parser/src/Lexer.php @@ -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; } /** diff --git a/libraries/sql-parser/src/Parser.php b/libraries/sql-parser/src/Parser.php index a2f7ef768d..0a876b7ab1 100644 --- a/libraries/sql-parser/src/Parser.php +++ b/libraries/sql-parser/src/Parser.php @@ -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; } diff --git a/libraries/sql-parser/src/Statement.php b/libraries/sql-parser/src/Statement.php index a813fff2db..74b2cc3a6a 100644 --- a/libraries/sql-parser/src/Statement.php +++ b/libraries/sql-parser/src/Statement.php @@ -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. } /** diff --git a/libraries/sql-parser/src/Statements/SelectStatement.php b/libraries/sql-parser/src/Statements/SelectStatement.php index 8cdee820e5..0c4c354f19 100644 --- a/libraries/sql-parser/src/Statements/SelectStatement.php +++ b/libraries/sql-parser/src/Statements/SelectStatement.php @@ -68,6 +68,20 @@ class SelectStatement extends Statement ); /** + * 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. * * @var FieldFragment[] diff --git a/libraries/sql-parser/src/Utils/Query.php b/libraries/sql-parser/src/Utils/Query.php index b1a95b155c..8cb9dfd4fd 100644 --- a/libraries/sql-parser/src/Utils/Query.php +++ b/libraries/sql-parser/src/Utils/Query.php @@ -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; + } + } diff --git a/libraries/sql-parser/src/Utils/Routine.php b/libraries/sql-parser/src/Utils/Routine.php index 4b9b21daef..8298d8d73f 100644 --- a/libraries/sql-parser/src/Utils/Routine.php +++ b/libraries/sql-parser/src/Utils/Routine.php @@ -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('', '', '', '', ''); diff --git a/libraries/sql.lib.php b/libraries/sql.lib.php index f8959946b0..206da97d60 100644 --- a/libraries/sql.lib.php +++ b/libraries/sql.lib.php @@ -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, diff --git a/libraries/structure.lib.php b/libraries/structure.lib.php index 1e896e3755..982b0b79a9 100644 --- a/libraries/structure.lib.php +++ b/libraries/structure.lib.php @@ -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 ); } @@ -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 ); diff --git a/tbl_row_action.php b/tbl_row_action.php index 70423e141e..38ccef9b74 100644 --- a/tbl_row_action.php +++ b/tbl_row_action.php @@ -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 ); } } diff --git a/tbl_select.php b/tbl_select.php index 914b547157..84d82784b1 100644 --- a/tbl_select.php +++ b/tbl_select.php @@ -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 ); } |