diff --git a/ChangeLog b/ChangeLog index 43535f414..63d21c5b0 100755 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,11 @@ phpMyAdmin - Changelog $Id$ $Source$ +2003-01-09 Marc Delisle + * sql.php3, libraries/sqlparser.lib.php3: bug 664951, add + support for the EXTRACT ... FROM syntax which is not a real + SELECT ... FROM + 2003-01-09 Alexander M. Turek * server_privileges.php3, lang/*.inc.php3: - Forgot to implement "This host"; diff --git a/libraries/sqlparser.lib.php3 b/libraries/sqlparser.lib.php3 index 7a74fadc0..fe8b6be83 100644 --- a/libraries/sqlparser.lib.php3 +++ b/libraries/sqlparser.lib.php3 @@ -572,9 +572,14 @@ if (!defined('PMA_SQP_LIB_INCLUDED')) { 'table_ref' => array() ); $subresult_empty = $subresult; - $seek_queryend = FALSE; + $seek_queryend = FALSE; $seen_end_of_table_ref = FALSE; + // for SELECT EXTRACT(YEAR_MONTH FROM CURDATE()) + // we must not use CURDATE as a table_ref + // so we track wether we are in the EXTRACT() + $in_extract = FALSE; + /* Description of analyzer results * * lem9: db, table, column, alias @@ -663,7 +668,7 @@ if (!defined('PMA_SQP_LIB_INCLUDED')) { // loop #1 for each token: select_expr, table_ref for SELECT for ($i = 0; $i < $size; $i++) { -//echo "trace 1" . $arr[$i]['data'] . " (" . $arr[$i]['type'] . ")
"; +//echo "trace " . $arr[$i]['data'] . " (" . $arr[$i]['type'] . ")
"; // High speed seek for locating the end of the current query if ($seek_queryend == TRUE) { @@ -682,6 +687,31 @@ if (!defined('PMA_SQP_LIB_INCLUDED')) { continue; } // end if (type == punct_queryend) +// ============================================================== + if ($arr[$i]['type'] == 'punct_bracket_open_round') { + if ($in_extract) { + $number_of_brackets_in_extract++; + } + } +// ============================================================== + if ($arr[$i]['type'] == 'punct_bracket_close_round') { + if ($in_extract) { + $number_of_brackets_in_extract--; + if ($number_of_brackets_in_extract == 0) { + $in_extract = FALSE; + } + } + } +// ============================================================== + if ($arr[$i]['type'] == 'alpha_functionName') { + $upper_data = strtoupper($arr[$i]['data']); + if ($upper_data =='EXTRACT') { + $in_extract = TRUE; + $number_of_brackets_in_extract = 0; + } + } + +// ============================================================== if ($arr[$i]['type'] == 'alpha_reservedWord') { // We don't know what type of query yet, so run this if ($subresult['querytype'] == '') { @@ -704,10 +734,9 @@ if (!defined('PMA_SQP_LIB_INCLUDED')) { $previous_was_identifier = FALSE; $current_select_expr = -1; $seen_end_of_table_ref = FALSE; - //$save_table_ref = TRUE; } // end if ( data == SELECT) - if ($upper_data =='FROM') { + if ($upper_data =='FROM' && !$in_extract) { $current_table_ref = -1; $seen_from = TRUE; $previous_was_identifier = FALSE; @@ -966,6 +995,7 @@ if (!defined('PMA_SQP_LIB_INCLUDED')) { // This is a big hunk of debugging code by Marc for this. // ------------------------------------------------------- /* + if (isset($current_select_expr)) { for ($trace=0; $trace<=$current_select_expr; $trace++) { echo "
"; @@ -973,6 +1003,9 @@ if (!defined('PMA_SQP_LIB_INCLUDED')) { while (list ($key, $val) = each ($subresult['select_expr'][$trace])) echo "sel expr $trace $key => $val
\n"; } + } + + if (isset($current_table_ref)) { for ($trace=0; $trace<=$current_table_ref; $trace++) { echo "
"; @@ -980,6 +1013,7 @@ if (!defined('PMA_SQP_LIB_INCLUDED')) { while (list ($key, $val) = each ($subresult['table_ref'][$trace])) echo "table ref $trace $key => $val
\n"; } + } */ // ------------------------------------------------------- @@ -1020,22 +1054,19 @@ if (!defined('PMA_SQP_LIB_INCLUDED')) { if ($first_reserved_word=='DROP' || $first_reserved_word == 'DELETE') { $subresult['queryflags']['need_confirm'] = 1; - break; } } else { if ($upper_data=='DROP' && $first_reserved_word=='ALTER') { $subresult['queryflags']['need_confirm'] = 1; - break; - } - if ($upper_data=='FROM' && $first_reserved_word=='SELECT') { - $subresult['queryflags']['select_from'] = 1; - break; } } } } // end for $i (loop #2) + if (isset($current_table_ref) && $current_table_ref > -1) { + $subresult['queryflags']['select_from'] = 1; + } // They are naughty and didn't have a trailing semi-colon, // then still handle it properly diff --git a/sql.php3 b/sql.php3 index 70654b077..17baff9f6 100755 --- a/sql.php3 +++ b/sql.php3 @@ -94,27 +94,40 @@ $is_select = eregi('^SELECT[[:space:]]+', $sql_query); // $db and $table, to have correct page headers, links and left frame. // db and table name may be enclosed with backquotes, db is optionnal, // query may contain aliases. -// (todo: check for embedded comments...) -// (todo: if there are more than one table name in the Select: +// (TODO: if there are more than one table name in the Select: // - do not extract the first table name // - do not show a table name in the page header // - do not display the sub-pages links) -if ($is_select) { - eregi('^SELECT[[:space:]]+(.*)[[:space:]]+FROM[[:space:]]+(`[^`]+`|[A-Za-z0-9_$]+)([\.]*)(`[^`]*`|[A-Za-z0-9_$]*)', $sql_query, $tmp); +//if ($is_select) { +// eregi('^SELECT[[:space:]]+(.*)[[:space:]]+FROM[[:space:]]+(`[^`]+`|[A-Za-z0-9_$]+)([\.]*)(`[^`]*`|[A-Za-z0-9_$]*)', $sql_query, $tmp); +// +// if ($tmp[3] == '.') { +// $prev_db = $db; +// $db = str_replace('`', '', $tmp[2]); +// $reload = ($db == $prev_db) ? 0 : 1; +// $table = str_replace('`', '', $tmp[4]); +// } +// else { +// $table = str_replace('`', '', $tmp[2]); +// } +//} // end if - if ($tmp[3] == '.') { - $prev_db = $db; - $db = str_replace('`', '', $tmp[2]); - $reload = ($db == $prev_db) ? 0 : 1; - $table = str_replace('`', '', $tmp[4]); +if ($is_select) { + $prev_db = $db; + if (isset($analyzed_sql[0]['table_ref'][0]['table_true_name'])) { + $table = $analyzed_sql[0]['table_ref'][0]['table_true_name']; + } + if (isset($analyzed_sql[0]['table_ref'][0]['db']) + && !empty($analyzed_sql[0]['table_ref'][0]['db'])) { + $db = $analyzed_sql[0]['table_ref'][0]['db']; } else { - $table = str_replace('`', '', $tmp[2]); - } -} // end if - + $db = $prev_db; + } + $reload = ($db == $prev_db) ? 0 : 1; +} /** * Sets or modifies the $goto variable if required @@ -382,6 +395,7 @@ else { } // end rows total count } // end else "didn't ask to see php code" + // No rows returned -> move back to the calling page if ($num_rows < 1 || $is_affected) { if ($is_delete) {