@@ -237,6 +237,12 @@ plpgsql_compile(FunctionCallInfo fcinfo, bool forValidator)
237237 return function ;
238238}
239239
240+ struct compile_error_callback_arg
241+ {
242+ const char * proc_source ;
243+ yyscan_t yyscanner ;
244+ };
245+
240246/*
241247 * This is the slow part of plpgsql_compile().
242248 *
@@ -269,13 +275,15 @@ do_compile(FunctionCallInfo fcinfo,
269275 Form_pg_proc procStruct = (Form_pg_proc ) GETSTRUCT (procTup );
270276 bool is_dml_trigger = CALLED_AS_TRIGGER (fcinfo );
271277 bool is_event_trigger = CALLED_AS_EVENT_TRIGGER (fcinfo );
278+ yyscan_t scanner ;
272279 Datum prosrcdatum ;
273280 char * proc_source ;
274281 HeapTuple typeTup ;
275282 Form_pg_type typeStruct ;
276283 PLpgSQL_variable * var ;
277284 PLpgSQL_rec * rec ;
278285 int i ;
286+ struct compile_error_callback_arg cbarg ;
279287 ErrorContextCallback plerrcontext ;
280288 int parse_rc ;
281289 Oid rettypeid ;
@@ -290,21 +298,21 @@ do_compile(FunctionCallInfo fcinfo,
290298 MemoryContext func_cxt ;
291299
292300 /*
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.
296302 */
297303 prosrcdatum = SysCacheGetAttrNotNull (PROCOID , procTup , Anum_pg_proc_prosrc );
298304 proc_source = TextDatumGetCString (prosrcdatum );
299- plpgsql_scanner_init (proc_source );
305+ scanner = plpgsql_scanner_init (proc_source );
300306
301307 plpgsql_error_funcname = pstrdup (NameStr (procStruct -> proname ));
302308
303309 /*
304310 * Setup error traceback support for ereport()
305311 */
312+ cbarg .proc_source = forValidator ? proc_source : NULL ;
313+ cbarg .yyscanner = scanner ;
306314 plerrcontext .callback = plpgsql_compile_error_callback ;
307- plerrcontext .arg = forValidator ? proc_source : NULL ;
315+ plerrcontext .arg = & cbarg ;
308316 plerrcontext .previous = error_context_stack ;
309317 error_context_stack = & plerrcontext ;
310318
@@ -779,12 +787,12 @@ do_compile(FunctionCallInfo fcinfo,
779787 /*
780788 * Now parse the function's text
781789 */
782- parse_rc = plpgsql_yyparse ();
790+ parse_rc = plpgsql_yyparse (scanner );
783791 if (parse_rc != 0 )
784792 elog (ERROR , "plpgsql parser returned %d" , parse_rc );
785793 function -> action = plpgsql_parse_result ;
786794
787- plpgsql_scanner_finish ();
795+ plpgsql_scanner_finish (scanner );
788796 pfree (proc_source );
789797
790798 /*
@@ -841,27 +849,29 @@ do_compile(FunctionCallInfo fcinfo,
841849PLpgSQL_function *
842850plpgsql_compile_inline (char * proc_source )
843851{
852+ yyscan_t scanner ;
844853 char * func_name = "inline_code_block" ;
845854 PLpgSQL_function * function ;
855+ struct compile_error_callback_arg cbarg ;
846856 ErrorContextCallback plerrcontext ;
847857 PLpgSQL_variable * var ;
848858 int parse_rc ;
849859 MemoryContext func_cxt ;
850860
851861 /*
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.
855863 */
856- plpgsql_scanner_init (proc_source );
864+ scanner = plpgsql_scanner_init (proc_source );
857865
858866 plpgsql_error_funcname = func_name ;
859867
860868 /*
861869 * Setup error traceback support for ereport()
862870 */
871+ cbarg .proc_source = proc_source ;
872+ cbarg .yyscanner = scanner ;
863873 plerrcontext .callback = plpgsql_compile_error_callback ;
864- plerrcontext .arg = proc_source ;
874+ plerrcontext .arg = & cbarg ;
865875 plerrcontext .previous = error_context_stack ;
866876 error_context_stack = & plerrcontext ;
867877
@@ -935,12 +945,12 @@ plpgsql_compile_inline(char *proc_source)
935945 /*
936946 * Now parse the function's text
937947 */
938- parse_rc = plpgsql_yyparse ();
948+ parse_rc = plpgsql_yyparse (scanner );
939949 if (parse_rc != 0 )
940950 elog (ERROR , "plpgsql parser returned %d" , parse_rc );
941951 function -> action = plpgsql_parse_result ;
942952
943- plpgsql_scanner_finish ();
953+ plpgsql_scanner_finish (scanner );
944954
945955 /*
946956 * If it returns VOID (always true at the moment), we allow control to
@@ -978,13 +988,16 @@ plpgsql_compile_inline(char *proc_source)
978988static void
979989plpgsql_compile_error_callback (void * arg )
980990{
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 )
982995 {
983996 /*
984997 * Try to convert syntax error position to reference text of original
985998 * CREATE FUNCTION or DO command.
986999 */
987- if (function_parse_error_transpose (( const char * ) arg ))
1000+ if (function_parse_error_transpose (cbarg -> proc_source ))
9881001 return ;
9891002
9901003 /*
@@ -995,7 +1008,7 @@ plpgsql_compile_error_callback(void *arg)
9951008
9961009 if (plpgsql_error_funcname )
9971010 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 ));
9991012}
10001013
10011014
0 commit comments