@@ -237,6 +237,12 @@ plpgsql_compile(FunctionCallInfo fcinfo, bool forValidator)
237
237
return function ;
238
238
}
239
239
240
+ struct compile_error_callback_arg
241
+ {
242
+ const char * proc_source ;
243
+ yyscan_t yyscanner ;
244
+ };
245
+
240
246
/*
241
247
* This is the slow part of plpgsql_compile().
242
248
*
@@ -269,13 +275,15 @@ do_compile(FunctionCallInfo fcinfo,
269
275
Form_pg_proc procStruct = (Form_pg_proc ) GETSTRUCT (procTup );
270
276
bool is_dml_trigger = CALLED_AS_TRIGGER (fcinfo );
271
277
bool is_event_trigger = CALLED_AS_EVENT_TRIGGER (fcinfo );
278
+ yyscan_t scanner ;
272
279
Datum prosrcdatum ;
273
280
char * proc_source ;
274
281
HeapTuple typeTup ;
275
282
Form_pg_type typeStruct ;
276
283
PLpgSQL_variable * var ;
277
284
PLpgSQL_rec * rec ;
278
285
int i ;
286
+ struct compile_error_callback_arg cbarg ;
279
287
ErrorContextCallback plerrcontext ;
280
288
int parse_rc ;
281
289
Oid rettypeid ;
@@ -290,21 +298,21 @@ do_compile(FunctionCallInfo fcinfo,
290
298
MemoryContext func_cxt ;
291
299
292
300
/*
293
- * Setup the scanner input and error info. We assume that this function
294
- * cannot be invoked recursively, so there's no need to save and restore
295
- * the static variables used here.
301
+ * Setup the scanner input and error info.
296
302
*/
297
303
prosrcdatum = SysCacheGetAttrNotNull (PROCOID , procTup , Anum_pg_proc_prosrc );
298
304
proc_source = TextDatumGetCString (prosrcdatum );
299
- plpgsql_scanner_init (proc_source );
305
+ scanner = plpgsql_scanner_init (proc_source );
300
306
301
307
plpgsql_error_funcname = pstrdup (NameStr (procStruct -> proname ));
302
308
303
309
/*
304
310
* Setup error traceback support for ereport()
305
311
*/
312
+ cbarg .proc_source = forValidator ? proc_source : NULL ;
313
+ cbarg .yyscanner = scanner ;
306
314
plerrcontext .callback = plpgsql_compile_error_callback ;
307
- plerrcontext .arg = forValidator ? proc_source : NULL ;
315
+ plerrcontext .arg = & cbarg ;
308
316
plerrcontext .previous = error_context_stack ;
309
317
error_context_stack = & plerrcontext ;
310
318
@@ -779,12 +787,12 @@ do_compile(FunctionCallInfo fcinfo,
779
787
/*
780
788
* Now parse the function's text
781
789
*/
782
- parse_rc = plpgsql_yyparse ();
790
+ parse_rc = plpgsql_yyparse (scanner );
783
791
if (parse_rc != 0 )
784
792
elog (ERROR , "plpgsql parser returned %d" , parse_rc );
785
793
function -> action = plpgsql_parse_result ;
786
794
787
- plpgsql_scanner_finish ();
795
+ plpgsql_scanner_finish (scanner );
788
796
pfree (proc_source );
789
797
790
798
/*
@@ -841,27 +849,29 @@ do_compile(FunctionCallInfo fcinfo,
841
849
PLpgSQL_function *
842
850
plpgsql_compile_inline (char * proc_source )
843
851
{
852
+ yyscan_t scanner ;
844
853
char * func_name = "inline_code_block" ;
845
854
PLpgSQL_function * function ;
855
+ struct compile_error_callback_arg cbarg ;
846
856
ErrorContextCallback plerrcontext ;
847
857
PLpgSQL_variable * var ;
848
858
int parse_rc ;
849
859
MemoryContext func_cxt ;
850
860
851
861
/*
852
- * Setup the scanner input and error info. We assume that this function
853
- * cannot be invoked recursively, so there's no need to save and restore
854
- * the static variables used here.
862
+ * Setup the scanner input and error info.
855
863
*/
856
- plpgsql_scanner_init (proc_source );
864
+ scanner = plpgsql_scanner_init (proc_source );
857
865
858
866
plpgsql_error_funcname = func_name ;
859
867
860
868
/*
861
869
* Setup error traceback support for ereport()
862
870
*/
871
+ cbarg .proc_source = proc_source ;
872
+ cbarg .yyscanner = scanner ;
863
873
plerrcontext .callback = plpgsql_compile_error_callback ;
864
- plerrcontext .arg = proc_source ;
874
+ plerrcontext .arg = & cbarg ;
865
875
plerrcontext .previous = error_context_stack ;
866
876
error_context_stack = & plerrcontext ;
867
877
@@ -935,12 +945,12 @@ plpgsql_compile_inline(char *proc_source)
935
945
/*
936
946
* Now parse the function's text
937
947
*/
938
- parse_rc = plpgsql_yyparse ();
948
+ parse_rc = plpgsql_yyparse (scanner );
939
949
if (parse_rc != 0 )
940
950
elog (ERROR , "plpgsql parser returned %d" , parse_rc );
941
951
function -> action = plpgsql_parse_result ;
942
952
943
- plpgsql_scanner_finish ();
953
+ plpgsql_scanner_finish (scanner );
944
954
945
955
/*
946
956
* If it returns VOID (always true at the moment), we allow control to
@@ -978,13 +988,16 @@ plpgsql_compile_inline(char *proc_source)
978
988
static void
979
989
plpgsql_compile_error_callback (void * arg )
980
990
{
981
- if (arg )
991
+ struct compile_error_callback_arg * cbarg = (struct compile_error_callback_arg * ) arg ;
992
+ yyscan_t yyscanner = cbarg -> yyscanner ;
993
+
994
+ if (cbarg -> proc_source )
982
995
{
983
996
/*
984
997
* Try to convert syntax error position to reference text of original
985
998
* CREATE FUNCTION or DO command.
986
999
*/
987
- if (function_parse_error_transpose (( const char * ) arg ))
1000
+ if (function_parse_error_transpose (cbarg -> proc_source ))
988
1001
return ;
989
1002
990
1003
/*
@@ -995,7 +1008,7 @@ plpgsql_compile_error_callback(void *arg)
995
1008
996
1009
if (plpgsql_error_funcname )
997
1010
errcontext ("compilation of PL/pgSQL function \"%s\" near line %d" ,
998
- plpgsql_error_funcname , plpgsql_latest_lineno ());
1011
+ plpgsql_error_funcname , plpgsql_latest_lineno (yyscanner ));
999
1012
}
1000
1013
1001
1014
0 commit comments