Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit029c5ac

Browse files
committed
psql: Refine lexing of BEGIN...END blocks in CREATE FUNCTION statements
Only track BEGIN...END blocks if they are in a CREATE [OR REPLACE]{FUNCTION|PROCEDURE} statement. Ignore if in parentheses.Reviewed-by: Laurenz Albe <laurenz.albe@cybertec.at>Discussion:https://www.postgresql.org/message-id/cee01d26fe55bc086b3bcf10bfe4e8d450e2f608.camel@cybertec.at
1 parent25593d7 commit029c5ac

File tree

2 files changed

+52
-9
lines changed

2 files changed

+52
-9
lines changed

‎src/fe_utils/psqlscan.l

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -870,18 +870,55 @@ other.
870870

871871

872872
{identifier}{
873-
cur_state->identifier_count++;
874-
if (pg_strcasecmp(yytext,"begin") ==0
875-
||pg_strcasecmp(yytext,"case") ==0)
873+
/*
874+
* We need to track if we are inside a BEGIN .. END block
875+
* in a function definition, so that semicolons contained
876+
* therein don't terminate the whole statement. Short of
877+
* writing a full parser here, the following heuristic
878+
* should work. First, we track whether the beginning of
879+
* the statement matches CREATE [OR REPLACE]
880+
* {FUNCTION|PROCEDURE}
881+
*/
882+
883+
if (cur_state->identifier_count ==0)
884+
memset(cur_state->identifiers,0,sizeof(cur_state->identifiers));
885+
886+
if (pg_strcasecmp(yytext,"create") ==0 ||
887+
pg_strcasecmp(yytext,"function") ==0 ||
888+
pg_strcasecmp(yytext,"procedure") ==0 ||
889+
pg_strcasecmp(yytext,"or") ==0 ||
890+
pg_strcasecmp(yytext,"replace") ==0)
876891
{
877-
if (cur_state->identifier_count>1)
878-
cur_state->begin_depth++;
892+
if (cur_state->identifier_count<sizeof(cur_state->identifiers))
893+
cur_state->identifiers[cur_state->identifier_count] =pg_tolower((unsignedchar) yytext[0]);
879894
}
880-
elseif (pg_strcasecmp(yytext,"end") ==0)
895+
896+
cur_state->identifier_count++;
897+
898+
if (cur_state->identifiers[0] =='c' &&
899+
(cur_state->identifiers[1] =='f' || cur_state->identifiers[1] =='p' ||
900+
(cur_state->identifiers[1] =='o' && cur_state->identifiers[2] =='r' &&
901+
(cur_state->identifiers[3] =='f' || cur_state->identifiers[3] =='p'))) &&
902+
cur_state->paren_depth ==0)
881903
{
882-
if (cur_state->begin_depth >0)
883-
cur_state->begin_depth--;
904+
if (pg_strcasecmp(yytext,"begin") ==0)
905+
cur_state->begin_depth++;
906+
elseif (pg_strcasecmp(yytext,"case") ==0)
907+
{
908+
/*
909+
* CASE also ends with END. We only need to track
910+
* this if we are already inside a BEGIN.
911+
*/
912+
if (cur_state->begin_depth >=1)
913+
cur_state->begin_depth++;
914+
}
915+
elseif (pg_strcasecmp(yytext,"end") ==0)
916+
{
917+
if (cur_state->begin_depth >0)
918+
cur_state->begin_depth--;
919+
}
884920
}
921+
885922
ECHO;
886923
}
887924

‎src/include/fe_utils/psqlscan_int.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,14 @@ typedef struct PsqlScanStateData
114114
intparen_depth;/* depth of nesting in parentheses */
115115
intxcdepth;/* depth of nesting in slash-star comments */
116116
char*dolqstart;/* current $foo$ quote start string */
117+
118+
/*
119+
* State to track boundaries of BEGIN ... END blocks in function
120+
* definitions, so that semicolons do not send query too early.
121+
*/
117122
intidentifier_count;/* identifiers since start of statement */
118-
intbegin_depth;/* depth of begin/end routine body blocks */
123+
charidentifiers[4];/* records the first few identifiers */
124+
intbegin_depth;/* depth of begin/end pairs */
119125

120126
/*
121127
* Callback functions provided by the program making use of the lexer,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp