8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 23:23:04 +01:00

Fix problem in non-reserved Inserting/Updating/Deleting implementation found by Dmitry Emanov

This commit is contained in:
skidder 2003-07-07 23:49:29 +00:00
parent 88a38bc5ac
commit 659e44cc45

View File

@ -193,7 +193,7 @@ struct LexerState {
TEXT *last_token_bk, *line_start_bk; TEXT *last_token_bk, *line_start_bk;
SSHORT lines, att_charset; SSHORT lines, att_charset;
SSHORT lines_bk; SSHORT lines_bk;
int prev_keyword; int prev_keyword, prev_prev_keyword;
USHORT param_number; USHORT param_number;
/* Fields to handle FIRST/SKIP as non-reserved keywords */ /* Fields to handle FIRST/SKIP as non-reserved keywords */
bool limit_clause; /* We are inside of limit clause. Need to detect SKIP after FIRST */ bool limit_clause; /* We are inside of limit clause. Need to detect SKIP after FIRST */
@ -4085,6 +4085,7 @@ void LEX_string (
lex.lines_bk = lex.lines; lex.lines_bk = lex.lines;
lex.param_number = 1; lex.param_number = 1;
lex.prev_keyword = -1; lex.prev_keyword = -1;
lex.prev_prev_keyword = -1;
lex.limit_clause = false; lex.limit_clause = false;
lex.first_detection = false; lex.first_detection = false;
lex.brace_analysis = false; lex.brace_analysis = false;
@ -4563,6 +4564,7 @@ inline static int yylex (
BOOLEAN *stmt_ambiguous) BOOLEAN *stmt_ambiguous)
{ {
int temp = lex.yylex(client_dialect, db_dialect, parser_version, stmt_ambiguous); int temp = lex.yylex(client_dialect, db_dialect, parser_version, stmt_ambiguous);
lex.prev_prev_keyword = lex.prev_keyword;
lex.prev_keyword = temp; lex.prev_keyword = temp;
return temp; return temp;
} }
@ -4965,7 +4967,12 @@ if (tok_class & CHR_LETTER)
(sym->sym_keyword == INSERTING || (sym->sym_keyword == INSERTING ||
sym->sym_keyword == UPDATING || sym->sym_keyword == UPDATING ||
sym->sym_keyword == DELETING sym->sym_keyword == DELETING
)) ) &&
/* Produce special_trigger_action_predicate only where we can handle it -
in search conditions */
(prev_prev_keyword=='(' || prev_prev_keyword==NOT || prev_prev_keyword==AND ||
prev_prev_keyword==OR || prev_prev_keyword==ON || prev_prev_keyword==HAVING ||
prev_prev_keyword==WHERE || prev_prev_keyword==WHEN) )
{ {
LexerState savedState = lex; LexerState savedState = lex;
int nextToken = yylex(client_dialect,db_dialect,parser_version,stmt_ambiguous); int nextToken = yylex(client_dialect,db_dialect,parser_version,stmt_ambiguous);
@ -5035,7 +5042,15 @@ if (last_token + 1 < end)
/* We need to swallow braces around INSERTING/UPDATING/DELETING keywords */ /* We need to swallow braces around INSERTING/UPDATING/DELETING keywords */
/* This algorithm is not perfect, but it is ok for now. /* This algorithm is not perfect, but it is ok for now.
It should be dropped when BOOLEAN datatype is introduced in Firebird */ It should be dropped when BOOLEAN datatype is introduced in Firebird */
if ( c == '(' && !brace_analysis ) { if ( c == '(' && !brace_analysis &&
/* 1) We need to swallow braces in all boolean expressions
2) We may swallow braces in ordinary expressions
3) We should not swallow braces after special tokens
like IF, FIRST, SKIP, VALUES and 30 more other
*/
(prev_keyword=='(' || prev_keyword==NOT || prev_keyword==AND || prev_keyword==OR ||
prev_keyword==ON || prev_keyword==HAVING || prev_keyword==WHERE || prev_keyword==WHEN) )
{
LexerState savedState = lex; LexerState savedState = lex;
brace_analysis = true; brace_analysis = true;
int openCount = 0; int openCount = 0;
@ -5063,7 +5078,13 @@ if ( c == '(' && !brace_analysis ) {
brace_analysis = false; brace_analysis = false;
yylval = temp_val; yylval = temp_val;
/* Check if we need to handle LR(2) grammar case */ /* Check if we need to handle LR(2) grammar case */
if (prev_keyword == '(') { if (prev_keyword == '(' &&
/* Produce special_trigger_action_predicate only where we can handle it -
in search conditions */
(prev_prev_keyword=='(' || prev_prev_keyword==NOT || prev_prev_keyword==AND ||
prev_prev_keyword==OR || prev_prev_keyword==ON || prev_prev_keyword==HAVING ||
prev_prev_keyword==WHERE || prev_prev_keyword==WHEN) )
{
savedState = lex; savedState = lex;
int token = yylex(client_dialect,db_dialect,parser_version,stmt_ambiguous); int token = yylex(client_dialect,db_dialect,parser_version,stmt_ambiguous);
lex = savedState; lex = savedState;