From 6081dca310c6b45f40a1172aea0eab981fffb9c5 Mon Sep 17 00:00:00 2001 From: Marc Delisle Date: Tue, 8 Jul 2003 14:24:41 +0000 Subject: [PATCH] bug 762213 row count and subqueries --- ChangeLog | 4 +++ libraries/sqlparser.lib.php3 | 25 +++++++++++++--- sql.php3 | 58 +++++++++++++++++++----------------- 3 files changed, 56 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7b3e1eef4..91e87521e 100755 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,10 @@ phpMyAdmin - Changelog $Id$ $Source$ +2003-07-08 Marc Delisle + * libraries/sqlparser.lib.php3, sql.php3: bug 762213, + incorrect row count for MySQL 4.1 subqueries + 2003-07-08 Michal Cihar * config.inc.php3, tbl_properties_operations.php3, libraries/config_import.lib.php3, libraries/display_export.lib.php3, diff --git a/libraries/sqlparser.lib.php3 b/libraries/sqlparser.lib.php3 index 158dcdde9..ec1296bf5 100644 --- a/libraries/sqlparser.lib.php3 +++ b/libraries/sqlparser.lib.php3 @@ -655,6 +655,7 @@ if (!defined('PMA_SQP_LIB_INCLUDED')) { $subresult = array( 'querytype' => '', 'select_expr_clause'=> '', // the whole stuff between SELECT and FROM , except DISTINCT + 'position_of_first_select' => '', // the array index 'from_clause'=> '', 'group_by_clause'=> '', 'order_by_clause'=> '', @@ -732,6 +733,12 @@ if (!defined('PMA_SQP_LIB_INCLUDED')) { * The CREATE TABLE may contain FOREIGN KEY clauses, so they get * analyzed and ['foreign_keys'] is an array filled with the index list, * the REFERENCES table name and REFERENCES index list. + * + * lem9: position_of_first_select + * ------------------------ + * + * The array index of the first SELECT we find. Will be used to + * insert a SQL_CALC_FOUND_ROWS. */ // must be sorted @@ -1204,6 +1211,11 @@ if (!defined('PMA_SQP_LIB_INCLUDED')) { || $first_reserved_word == 'DELETE') { $subresult['queryflags']['need_confirm'] = 1; } + + if ($first_reserved_word=='SELECT'){ + $position_of_first_select = $i; + } + } else { if ($upper_data=='DROP' && $first_reserved_word=='ALTER') { $subresult['queryflags']['need_confirm'] = 1; @@ -1418,6 +1430,10 @@ if (!defined('PMA_SQP_LIB_INCLUDED')) { $subresult['where_clause_identifiers'] = $where_clause_identifiers; } + if (isset($position_of_first_select)) { + $subresult['position_of_first_select'] = $position_of_first_select; + } + // They are naughty and didn't have a trailing semi-colon, // then still handle it properly @@ -1464,7 +1480,7 @@ if (!defined('PMA_SQP_LIB_INCLUDED')) { * * @access public */ - function PMA_SQP_formatHtml($arr, $mode='color') + function PMA_SQP_formatHtml($arr, $mode='color', $start_token=0) { // first check for the SQL parser having hit an error if (PMA_SQP_isError()) { @@ -1550,12 +1566,13 @@ if (!defined('PMA_SQP_LIB_INCLUDED')) { $typearr[0] = ''; $typearr[1] = ''; $typearr[2] = ''; - $typearr[3] = $arr[0]['type']; + //$typearr[3] = $arr[0]['type']; + $typearr[3] = $arr[$start_token]['type']; } $in_priv_list = FALSE; - for ($i = 0; $i < $arraysize; $i++) { - //DEBUG echo "" . $arr[$i]['data'] . " " . $arr[$i]['type'] . "
"; + for ($i = $start_token; $i < $arraysize; $i++) { +// DEBUG echo "" . $arr[$i]['data'] . " " . $arr[$i]['type'] . "
"; $before = ''; $after = ''; $indent = 0; diff --git a/sql.php3 b/sql.php3 index de7e675ea..4f03afc93 100755 --- a/sql.php3 +++ b/sql.php3 @@ -349,7 +349,7 @@ else { // c o u n t q u e r y - // If we are just browsing, there is only one table, + // If we are "just browsing", there is only one table, // and no where clause (or just 'WHERE 1 '), // so we do a quick count (which uses MaxExactCount) // because SQL_CALC_FOUND_ROWS @@ -359,9 +359,10 @@ else { && (empty($analyzed_sql[0]['where_clause']) || $analyzed_sql[0]['where_clause'] == '1 ')) { - // "just browsing" + // "j u s t b r o w s i n g" $unlim_num_rows = PMA_countRecords($db, $table, TRUE); - } else { // not "just browsing" + + } else { // n o t " j u s t b r o w s i n g " if (PMA_MYSQL_INT_VERSION < 40000) { if (eregi('DISTINCT(.*)', $sql_query)) { @@ -387,28 +388,29 @@ else { // add select expression after the SQL_CALC_FOUND_ROWS if (PMA_MYSQL_INT_VERSION >= 40000) { - if (eregi('DISTINCT(.*)', $sql_query)) { - $count_query .= 'DISTINCT ' . $analyzed_sql[0]['select_expr_clause']; - } else { - $count_query .= $analyzed_sql[0]['select_expr_clause']; +// if (eregi('DISTINCT(.*)', $sql_query)) { +// $count_query .= 'DISTINCT ' . $analyzed_sql[0]['select_expr_clause']; +// } else { + //$count_query .= $analyzed_sql[0]['select_expr_clause']; + + // add everything that was after the first SELECT + $count_query .= PMA_SQP_formatHtml($parsed_sql, 'query_only', $analyzed_sql[0]['position_of_first_select']+1); +// } + } else { // PMA_MYSQL_INT_VERSION < 40000 + + if (!empty($analyzed_sql[0]['from_clause'])) { + $count_query .= ' FROM ' . $analyzed_sql[0]['from_clause']; } - } - - - if (!empty($analyzed_sql[0]['from_clause'])) { - $count_query .= ' FROM ' . $analyzed_sql[0]['from_clause']; - } - - if (!empty($analyzed_sql[0]['where_clause'])) { - $count_query .= ' WHERE ' . $analyzed_sql[0]['where_clause']; - } - if (!empty($analyzed_sql[0]['group_by_clause'])) { - $count_query .= ' GROUP BY ' . $analyzed_sql[0]['group_by_clause']; - } - - if (!empty($analyzed_sql[0]['having_clause'])) { - $count_query .= ' HAVING ' . $analyzed_sql[0]['having_clause']; - } + if (!empty($analyzed_sql[0]['where_clause'])) { + $count_query .= ' WHERE ' . $analyzed_sql[0]['where_clause']; + } + if (!empty($analyzed_sql[0]['group_by_clause'])) { + $count_query .= ' GROUP BY ' . $analyzed_sql[0]['group_by_clause']; + } + if (!empty($analyzed_sql[0]['having_clause'])) { + $count_query .= ' HAVING ' . $analyzed_sql[0]['having_clause']; + } + } // end if // if using SQL_CALC_FOUND_ROWS, add a LIMIT to avoid // long delays. Returned count will be complete anyway. @@ -417,12 +419,13 @@ else { $count_query .= ' LIMIT 1'; } - // do not put the order_by_clause, it interferes // run the count query +//echo "trace cq=" . $count_query . "
"; + if (PMA_MYSQL_INT_VERSION < 40000) { if ($cnt_all_result = PMA_mysql_query($count_query)) { - //if ($is_group) { - if ($count_what == '*') { + if ($is_group) { +// if ($count_what == '*') { $unlim_num_rows = @mysql_num_rows($cnt_all_result); } else { $unlim_num_rows = PMA_mysql_result($cnt_all_result, 0, 'count'); @@ -430,6 +433,7 @@ else { mysql_free_result($cnt_all_result); } else { if (mysql_error()) { + // there are some cases where the generated // count_query (for MySQL 3) is wrong, // so we get here.