|
|
|
@ -870,18 +870,55 @@ other . |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{identifier} { |
|
|
|
|
cur_state->identifier_count++; |
|
|
|
|
if (pg_strcasecmp(yytext, "begin") == 0 |
|
|
|
|
|| pg_strcasecmp(yytext, "case") == 0) |
|
|
|
|
/* |
|
|
|
|
* We need to track if we are inside a BEGIN .. END block |
|
|
|
|
* in a function definition, so that semicolons contained |
|
|
|
|
* therein don't terminate the whole statement. Short of |
|
|
|
|
* writing a full parser here, the following heuristic |
|
|
|
|
* should work. First, we track whether the beginning of |
|
|
|
|
* the statement matches CREATE [OR REPLACE] |
|
|
|
|
* {FUNCTION|PROCEDURE} |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
if (cur_state->identifier_count == 0) |
|
|
|
|
memset(cur_state->identifiers, 0, sizeof(cur_state->identifiers)); |
|
|
|
|
|
|
|
|
|
if (pg_strcasecmp(yytext, "create") == 0 || |
|
|
|
|
pg_strcasecmp(yytext, "function") == 0 || |
|
|
|
|
pg_strcasecmp(yytext, "procedure") == 0 || |
|
|
|
|
pg_strcasecmp(yytext, "or") == 0 || |
|
|
|
|
pg_strcasecmp(yytext, "replace") == 0) |
|
|
|
|
{ |
|
|
|
|
if (cur_state->identifier_count > 1) |
|
|
|
|
cur_state->begin_depth++; |
|
|
|
|
if (cur_state->identifier_count < sizeof(cur_state->identifiers)) |
|
|
|
|
cur_state->identifiers[cur_state->identifier_count] = pg_tolower((unsigned char) yytext[0]); |
|
|
|
|
} |
|
|
|
|
else if (pg_strcasecmp(yytext, "end") == 0) |
|
|
|
|
|
|
|
|
|
cur_state->identifier_count++; |
|
|
|
|
|
|
|
|
|
if (cur_state->identifiers[0] == 'c' && |
|
|
|
|
(cur_state->identifiers[1] == 'f' || cur_state->identifiers[1] == 'p' || |
|
|
|
|
(cur_state->identifiers[1] == 'o' && cur_state->identifiers[2] == 'r' && |
|
|
|
|
(cur_state->identifiers[3] == 'f' || cur_state->identifiers[3] == 'p'))) && |
|
|
|
|
cur_state->paren_depth == 0) |
|
|
|
|
{ |
|
|
|
|
if (cur_state->begin_depth > 0) |
|
|
|
|
cur_state->begin_depth--; |
|
|
|
|
if (pg_strcasecmp(yytext, "begin") == 0) |
|
|
|
|
cur_state->begin_depth++; |
|
|
|
|
else if (pg_strcasecmp(yytext, "case") == 0) |
|
|
|
|
{ |
|
|
|
|
/* |
|
|
|
|
* CASE also ends with END. We only need to track |
|
|
|
|
* this if we are already inside a BEGIN. |
|
|
|
|
*/ |
|
|
|
|
if (cur_state->begin_depth >= 1) |
|
|
|
|
cur_state->begin_depth++; |
|
|
|
|
} |
|
|
|
|
else if (pg_strcasecmp(yytext, "end") == 0) |
|
|
|
|
{ |
|
|
|
|
if (cur_state->begin_depth > 0) |
|
|
|
|
cur_state->begin_depth--; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ECHO; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|