@@ -870,18 +870,55 @@ other .
870
870
871
871
872
872
{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 )
876
891
{
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 (( unsigned char ) yytext[ 0 ]) ;
879
894
}
880
- else if (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 )
881
903
{
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
+ else if (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
+ else if (pg_strcasecmp (yytext, " end" ) == 0 )
916
+ {
917
+ if (cur_state->begin_depth > 0 )
918
+ cur_state->begin_depth --;
919
+ }
884
920
}
921
+
885
922
ECHO;
886
923
}
887
924
0 commit comments