📄 sqlparser.lib.php
字号:
// - section_before_limit, section_after_limit // // 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; } $collect_section_before_limit = TRUE; $section_before_limit = ''; $section_after_limit = ''; $seen_reserved_word = FALSE; $seen_group = FALSE; $seen_order = FALSE; $in_group_by = FALSE; // true when we are inside the GROUP BY clause $in_order_by = FALSE; // true when we are inside the ORDER BY clause $in_having = FALSE; // true when we are inside the HAVING clause $in_select_expr = FALSE; // true when we are inside the select expr clause $in_where = FALSE; // true when we are inside the WHERE clause $in_from = FALSE; $in_group_concat = FALSE; $unsorted_query = ''; $first_reserved_word = ''; $current_identifier = ''; for ($i = 0; $i < $size; $i++) {//DEBUG echo "trace loop2 <b>" . $arr[$i]['data'] . "</b> (" . $arr[$i]['type'] . ")<br />"; // need_confirm // // check for reserved words that will have to generate // a confirmation request later in sql.php // the cases are: // DROP TABLE // DROP DATABASE // ALTER TABLE... DROP // DELETE FROM... // // this code is not used for confirmations coming from functions.js // 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) { $first_reserved_word = $upper_data; $subresult['querytype'] = $upper_data; $seen_reserved_word = TRUE; // if the first reserved word is DROP or DELETE, // we know this is a query that needs to be confirmed if ($first_reserved_word=='DROP' || $first_reserved_word == 'DELETE' || $first_reserved_word == 'TRUNCATE') { $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; } } 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 = ''; } if ($upper_data == 'DISTINCT' && !$in_group_concat) { $subresult['queryflags']['distinct'] = 1; } if ($upper_data == 'UNION') { $subresult['queryflags']['union'] = 1; } if ($upper_data == 'JOIN') { $subresult['queryflags']['join'] = 1; } if ($upper_data == 'OFFSET') { $subresult['queryflags']['offset'] = 1; } // 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' && !$in_group_concat) { $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 = ''; $where_clause_identifiers = array(); $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 // TODO: can we combine loop 2 and loop 1? // some code is repeated here... $sep=' '; if ($arr[$i]['type'] == 'alpha_functionName') { $sep=''; $upper_data = strtoupper($arr[$i]['data']); if ($upper_data =='GROUP_CONCAT') { $in_group_concat = TRUE; $number_of_brackets_in_group_concat = 0; } } if ($arr[$i]['type'] == 'punct_bracket_open_round') { if ($in_group_concat) { $number_of_brackets_in_group_concat++; } } if ($arr[$i]['type'] == 'punct_bracket_close_round') { if ($in_group_concat) { $number_of_brackets_in_group_concat--; if ($number_of_brackets_in_group_concat == 0) { $in_group_concat = FALSE; } } } 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; if (($arr[$i]['type'] == 'quote_backtick') || ($arr[$i]['type'] == 'alpha_identifier')) { $where_clause_identifiers[] = $arr[$i]['data']; } } if (isset($subresult['queryflags']['select_from']) && $subresult['queryflags']['select_from'] == 1 && !$seen_order) { $unsorted_query .= $arr[$i]['data']; if ($arr[$i]['type'] != 'punct_bracket_open_round' && $arr[$i]['type'] != 'punct_bracket_close_round' && $arr[$i]['type'] != 'punct') { $unsorted_query .= $sep; } } // clear $upper_data for next iteration $upper_data=''; if ($collect_section_before_limit && $arr[$i]['type'] != 'punct_queryend') { $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) // (for now, identifiers are assumed to be backquoted) // If we find that we are dealing with a CREATE TABLE query, // we look for the next punct_bracket_open_round, which // introduces the fields list. Then, when we find a // quote_backtick, it must be a field, so we put it into // the create_table_fields array. Even if this field is // not a timestamp, it will be useful when logic has been // added for complete field attributes analysis. $seen_foreign = FALSE; $seen_references = FALSE; $seen_constraint = FALSE; $foreign_key_number = -1; $seen_create_table = FALSE; $seen_create = FALSE; $in_create_table_fields = FALSE; $brackets_level = 0; $in_timestamp_options = FALSE; $seen_default = FALSE; for ($i = 0; $i < $size; $i++) { // DEBUG echo "<b>" . $arr[$i]['data'] . "</b> " . $arr[$i]['type'] . "<br />"; if ($arr[$i]['type'] == 'alpha_reservedWord') { $upper_data = strtoupper($arr[$i]['data']); if ($upper_data == 'NOT' && $in_timestamp_options) { $create_table_fields[$current_identifier]['timestamp_not_null'] = TRUE; } if ($upper_data == 'CREATE') { $seen_create = TRUE; } if ($upper_data == 'TABLE' && $seen_create) { $seen_create_table = TRUE; $create_table_fields = array(); } if ($upper_data == 'CURRENT_TIMESTAMP') { if ($in_timestamp_options) { if ($seen_default) { $create_table_fields[$current_identifier]['default_current_timestamp'] = TRUE; } } } if ($upper_data == 'CONSTRAINT') { $foreign_key_number++; $seen_foreign = FALSE; $seen_references = FALSE; $seen_constraint = TRUE; } if ($upper_data == 'FOREIGN') { $seen_foreign = TRUE; $seen_references = FALSE; $seen_constraint = FALSE; } if ($upper_data == 'REFERENCES') { $seen_foreign = FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -