diff --git a/ChangeLog b/ChangeLog index 6bfda6cd8..ef4066c58 100755 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,10 @@ phpMyAdmin - Changelog $Id$ $Source$ +2005-05-15 Marc Delisle + * sql.php, libraries/sqlparser.lib.php: bug #1120434, comment at the end + of query is applied to appended LIMIT as well + 2005-05-13 Marc Delisle * tbl_printview.php: bug #1178760, header not sent when displaying print view of multi tables, thanks to Hrvoje Novosel - interghost diff --git a/libraries/sqlparser.lib.php b/libraries/sqlparser.lib.php index bed6abda6..359cd927e 100644 --- a/libraries/sqlparser.lib.php +++ b/libraries/sqlparser.lib.php @@ -807,6 +807,14 @@ if ($is_minimum_common == FALSE) { * ['default_current_timestamp'] boolean * ['on_update_current_timestamp'] boolean * + * section_before_limit, section_after_limit + * ----------------------------------------- + * + * Marks the point of the query where we can insert a LIMIT clause; + * so the section_before_limit will contain the left part before + * a possible LIMIT clause + * + * * End of description of analyzer results */ @@ -1263,8 +1271,9 @@ if ($is_minimum_common == FALSE) { // ------------------------------------------------------- - // loop #2: for queryflags - // ,querytype (for queries != 'SELECT') + // loop #2: - queryflags + // - querytype (for queries != 'SELECT') + // - section_before_limit, section_after_limit // // we will also need this queryflag in loop 2 // so set it here @@ -1272,6 +1281,9 @@ if ($is_minimum_common == FALSE) { $subresult['queryflags']['select_from'] = 1; } + $collect_section_before_limit = TRUE; + $section_before_limit = ''; + $section_after_limit = ''; $seen_reserved_word = FALSE; $seen_group = FALSE; $seen_order = FALSE; @@ -1301,6 +1313,12 @@ if ($is_minimum_common == FALSE) { // TODO: check for punct_queryend + + // TODO: verify C-style comments? + if ($arr[$i]['type'] == 'comment_ansi') { + $collect_section_before_limit = FALSE; + } + if ($arr[$i]['type'] == 'alpha_reservedWord') { $upper_data = strtoupper($arr[$i]['data']); if (!$seen_reserved_word) { @@ -1326,6 +1344,13 @@ if ($is_minimum_common == FALSE) { } } + if ($upper_data == 'PROCEDURE') { + $collect_section_before_limit = FALSE; + } + // TODO: set also to FALSE if we find + // FOR UPDATE + // LOCK IN SHARE MODE + if ($upper_data == 'SELECT') { $in_select_expr = TRUE; $select_expr_clause = ''; @@ -1495,8 +1520,16 @@ if ($is_minimum_common == FALSE) { // clear $upper_data for next iteration $upper_data=''; + if ($collect_section_before_limit) { + $section_before_limit .= $arr[$i]['data'] . $sep; + } else { + $section_after_limit .= $arr[$i]['data'] . $sep; + } + + } // end for $i (loop #2) + // ----------------------------------------------------- // loop #3: foreign keys and MySQL 4.1.2+ TIMESTAMP options // (for now, check only the first query) @@ -1753,6 +1786,8 @@ if ($is_minimum_common == FALSE) { if (isset($position_of_first_select)) { $subresult['position_of_first_select'] = $position_of_first_select; + $subresult['section_before_limit'] = $section_before_limit; + $subresult['section_after_limit'] = $section_after_limit; } // They are naughty and didn't have a trailing semi-colon, diff --git a/sql.php b/sql.php index dfe4c36df..c69ef656a 100644 --- a/sql.php +++ b/sql.php @@ -327,20 +327,34 @@ else { && isset($analyzed_sql[0]['queryflags']['select_from']) && !isset($analyzed_sql[0]['queryflags']['offset']) && !preg_match('@[[:space:]]LIMIT[[:space:]0-9,-]+$@i', $sql_query)) { - $sql_limit_to_append = " LIMIT $pos, ".$cfg['MaxRows']; - if (preg_match('@(.*)([[:space:]](PROCEDURE[[:space:]](.*)|FOR[[:space:]]+UPDATE|LOCK[[:space:]]+IN[[:space:]]+SHARE[[:space:]]+MODE))$@i', $sql_query, $regs)) { - $full_sql_query = $regs[1] . $sql_limit_to_append . $regs[2]; - } else { - $full_sql_query = $sql_query . $sql_limit_to_append; - } + $sql_limit_to_append = " LIMIT $pos, ".$cfg['MaxRows'] . " "; + +// if (preg_match('@(.*)([[:space:]](PROCEDURE[[:space:]](.*)|FOR[[:space:]]+UPDATE|LOCK[[:space:]]+IN[[:space:]]+SHARE[[:space:]]+MODE))$@i', $sql_query, $regs)) { +// $full_sql_query = $regs[1] . $sql_limit_to_append . $regs[2]; +// } else { +// $full_sql_query = $sql_query . $sql_limit_to_append; +// } + + $full_sql_query = $analyzed_sql[0]['section_before_limit'] . $sql_limit_to_append . $analyzed_sql[0]['section_after_limit']; + // FIXME: pretty printing of this modified query if (isset($display_query)) { - if (preg_match('@((.|\n)*)(([[:space:]](PROCEDURE[[:space:]](.*)|FOR[[:space:]]+UPDATE|LOCK[[:space:]]+IN[[:space:]]+SHARE[[:space:]]+MODE))|;)[[:space:]]*$@i', $display_query, $regs)) { - $display_query = $regs[1] . $sql_limit_to_append . $regs[3]; - } else { - $display_query = $display_query . $sql_limit_to_append; +// if (preg_match('@((.|\n)*)(([[:space:]](PROCEDURE[[:space:]](.*)|FOR[[:space:]]+UPDATE|LOCK[[:space:]]+IN[[:space:]]+SHARE[[:space:]]+MODE))|;)[[:space:]]*$@i', $display_query, $regs)) { +// $display_query = $regs[1] . $sql_limit_to_append . $regs[3]; +// } else { +// $display_query = $display_query . $sql_limit_to_append; +// } + + // if the analysis of the original query revealed that we found + // a section_after_limit, we now have to analyze $display_query + // to display it correctly + + if (!empty($analyzed_sql[0]['section_after_limit'])) { + $analyzed_display_query = PMA_SQP_analyze(PMA_SQP_parse($display_query)); + $display_query = $analyzed_display_query[0]['section_before_limit'] . $sql_limit_to_append . $analyzed_display_query[0]['section_after_limit']; } } + } else { $full_sql_query = $sql_query; } // end if...else