analyzer: clauses

This commit is contained in:
Marc Delisle
2003-02-16 11:06:46 +00:00
parent eb723c5a68
commit ed17265db2

View File

@@ -19,12 +19,9 @@
*
* If you want to extract data from it then, you just need to run
* $sql_info = PMA_SQP_analyze($parsed_sql);
* (returned structure of this function is being rewritten presently);
*
* lem9: Currently the analyzer can interpret db, table, column, alias
* for SELECTs;
* see comments in PMA_SQP_analyze for the new returned info
* (select_expr and table_ref)
* lem9: See comments in PMA_SQP_analyze for the returned info
* from the analyzer.
*
* If you want a pretty-printed version of the query, do:
* $string = PMA_SQP_formatHtml($parsed_sql);
@@ -636,6 +633,12 @@ if (!defined('PMA_SQP_LIB_INCLUDED')) {
$size = $arr['len'];
$subresult = array(
'querytype' => '',
'select_expr_clause'=> '', // the whole stuff between SELECT and FROM , except DISTINCT
'from_clause'=> '',
'group_by_clause'=> '',
'order_by_clause'=> '',
'having_clause' => '',
'where_clause' => '',
'queryflags' => array(),
'select_expr' => array(),
'table_ref' => array()
@@ -685,6 +688,17 @@ if (!defined('PMA_SQP_LIB_INCLUDED')) {
*
* ['queryflags']['need_confirm'] = 1; if the query needs confirmation
* ['queryflags']['select_from'] = 1; if this is a real SELECT...FROM
*
* lem9: query clauses
* -------------
*
* The select is splitted in those clauses:
* ['select_expr_clause']
* ['from_clause']
* ['group_by_clause']
* ['order_by_clause']
* ['having_clause']
* ['where_clause']
*/
// must be sorted
// TODO: current logic checks for only one word, so I put only the
@@ -714,6 +728,18 @@ if (!defined('PMA_SQP_LIB_INCLUDED')) {
);
$words_ending_table_ref_cnt = 9; //count($words_ending_table_ref);
$words_ending_clauses = array(
'FOR',
'LIMIT',
'LOCK',
'PROCEDURE',
'UNION'
);
$words_ending_clauses_cnt = 5; //count($words_ending_clauses);
// must be sorted
$supported_query_types = array(
'SELECT'
@@ -980,6 +1006,10 @@ if (!defined('PMA_SQP_LIB_INCLUDED')) {
. '.' . $subresult['table_ref'][$current_table_ref]['expr'];
} // end if ($size_chain > 1)
// add the table alias into the whole expression
$subresult['table_ref'][$current_table_ref]['expr']
.= ' ' . $subresult['table_ref'][$current_table_ref]['table_alias'];
unset($chain);
$previous_was_identifier = TRUE;
//continue;
@@ -1088,16 +1118,30 @@ if (!defined('PMA_SQP_LIB_INCLUDED')) {
// loop #2: for queryflags
// and querytype (for queries != 'SELECT')
// ,querytype (for queries != 'SELECT')
//
// This is not in the loop 1 to keep logic simple
// we will also need this queryflag in loop 2
// so set it here
if (isset($current_table_ref) && $current_table_ref > -1) {
$subresult['queryflags']['select_from'] = 1;
}
$seen_reserved_word = FALSE;
$seen_group = FALSE;
$seen_order = FALSE;
$in_group_by = FALSE; // true when we are into the GROUP BY clause
$in_order_by = FALSE; // true when we are into the ORDER BY clause
$in_having = FALSE; // true when we are into the HAVING clause
$in_select_expr = FALSE; // true when we are into the select expr clause
$in_where = FALSE; // true when we are into the WHERE clause
$in_from = FALSE;
for ($i = 0; $i < $size; $i++) {
//echo "trace 2<b>" . $arr[$i]['data'] . "</b> (" . $arr[$i]['type'] . ")<br>";
//echo "trace loop2 <b>" . $arr[$i]['data'] . "</b> (" . $arr[$i]['type'] . ")<br>";
// c o n f i r m a t i o n r e q u e s t s (need_confirm)
// need_confirm
//
// check for reserved words that will have to generate
// a confirmation request later in sql.php3
@@ -1129,13 +1173,143 @@ if (!defined('PMA_SQP_LIB_INCLUDED')) {
$subresult['queryflags']['need_confirm'] = 1;
}
}
if ($upper_data == 'SELECT') {
$in_select_expr = TRUE;
$select_expr_clause = '';
}
// if this is a real SELECT...FROM
if ($upper_data == 'FROM' && isset($subresult['queryflags']['select_from']) && $subresult['queryflags']['select_from'] == 1) {
$in_from = TRUE;
$from_clause = '';
$in_select_expr = FALSE;
}
// (we could have less resetting of variables to FALSE
// if we trust that the query respects the standard
// MySQL order for clauses)
// we use $seen_group and $seen_order because we are looking
// for the BY
if ($upper_data == 'GROUP') {
$seen_group = TRUE;
$seen_order = FALSE;
$in_having = FALSE;
$in_order_by = FALSE;
$in_where = FALSE;
$in_select_expr = FALSE;
$in_from = FALSE;
}
if ($upper_data == 'ORDER') {
$seen_order = TRUE;
$seen_group = FALSE;
$in_having = FALSE;
$in_group_by = FALSE;
$in_where = FALSE;
$in_select_expr = FALSE;
$in_from = FALSE;
}
if ($upper_data == 'HAVING') {
$in_having = TRUE;
$having_clause = '';
$seen_group = FALSE;
$seen_order = FALSE;
$in_group_by = FALSE;
$in_order_by = FALSE;
$in_where = FALSE;
$in_select_expr = FALSE;
$in_from = FALSE;
}
if ($upper_data == 'WHERE') {
$in_where = TRUE;
$where_clause = '';
$seen_group = FALSE;
$seen_order = FALSE;
$in_group_by = FALSE;
$in_order_by = FALSE;
$in_having = FALSE;
$in_select_expr = FALSE;
$in_from = FALSE;
}
if ($upper_data == 'BY') {
if ($seen_group) {
$in_group_by = TRUE;
$group_by_clause = '';
}
if ($seen_order) {
$in_order_by = TRUE;
$order_by_clause = '';
}
}
// if we find one of the words that could end the clause
if (PMA_STR_binarySearchInArr($upper_data, $words_ending_clauses, $words_ending_clauses_cnt)) {
$in_group_by = FALSE;
$in_order_by = FALSE;
$in_having = FALSE;
$in_where = FALSE;
$in_select_expr = FALSE;
$in_from = FALSE;
}
} // endif (reservedWord)
// do not add a blank after a function name
$sep=' ';
if ($arr[$i]['type'] == 'alpha_functionName') {
$sep='';
}
if ($in_select_expr && $upper_data != 'SELECT' && $upper_data != 'DISTINCT') {
$select_expr_clause .= $arr[$i]['data'] . $sep;
}
if ($in_from && $upper_data != 'FROM') {
$from_clause .= $arr[$i]['data'] . $sep;
}
if ($in_group_by && $upper_data != 'GROUP' && $upper_data != 'BY') {
$group_by_clause .= $arr[$i]['data'] . $sep;
}
if ($in_order_by && $upper_data != 'ORDER' && $upper_data != 'BY') {
$order_by_clause .= $arr[$i]['data'] . $sep;
}
if ($in_having && $upper_data != 'HAVING') {
$having_clause .= $arr[$i]['data'] . $sep;
}
if ($in_where && $upper_data != 'WHERE') {
$where_clause .= $arr[$i]['data'] . $sep;
}
// clear $upper_data for next iteration
$upper_data='';
} // end for $i (loop #2)
if (isset($current_table_ref) && $current_table_ref > -1) {
$subresult['queryflags']['select_from'] = 1;
if (isset($select_expr_clause)) {
$subresult['select_expr_clause'] = $select_expr_clause;
}
if (isset($from_clause)) {
$subresult['from_clause'] = $from_clause;
}
if (isset($group_by_clause)) {
$subresult['group_by_clause'] = $group_by_clause;
}
if (isset($order_by_clause)) {
$subresult['order_by_clause'] = $order_by_clause;
}
if (isset($having_clause)) {
$subresult['having_clause'] = $having_clause;
}
if (isset($where_clause)) {
$subresult['where_clause'] = $where_clause;
}
// They are naughty and didn't have a trailing semi-colon,
// then still handle it properly