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

Commit7b27f5f

Browse files
committed
plpgsql: pure parser and reentrant scanner
The plpgsql scanner is a wrapper around the core scanner, whichalready uses the flex %option reentrant. This patch only pushes up afew levels the place where the scanner handle is allocated. Before,it was allocated in pl_scanner.c in a global variable, so to theoutside the scanner was not reentrant. Now, it is allocated inpl_comp.c and is passed as an argument to yyparse(), similar to how itis handled in other reentrant scanners.Also use flex yyextra to handle context information, instead of globalvariables. Again, this uses the existing yyextra support in the corescanner. This complements the other changes to make the scannerreentrant.The bison option %pure-parser is used to make the generated parserpure. This happens in the usual way, since plpgsql has its own bisonparser definition.Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>Discussion:https://www.postgresql.org/message-id/flat/eb6faeac-2a8a-4b69-9189-c33c520e5b7b@eisentraut.org
1 parentb18464f commit7b27f5f

File tree

5 files changed

+598
-537
lines changed

5 files changed

+598
-537
lines changed

‎src/pl/plpgsql/src/nls.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ GETTEXT_FILES = pl_comp.c \
66
pl_funcs.c\
77
pl_handler.c\
88
pl_scanner.c
9-
GETTEXT_TRIGGERS =$(BACKEND_COMMON_GETTEXT_TRIGGERS) yyerror plpgsql_yyerror
9+
GETTEXT_TRIGGERS =$(BACKEND_COMMON_GETTEXT_TRIGGERS) yyerror:3 plpgsql_yyerror:3
1010
GETTEXT_FLAGS =$(BACKEND_COMMON_GETTEXT_FLAGS)

‎src/pl/plpgsql/src/pl_comp.c

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,12 @@ plpgsql_compile(FunctionCallInfo fcinfo, bool forValidator)
237237
returnfunction;
238238
}
239239

240+
structcompile_error_callback_arg
241+
{
242+
constchar*proc_source;
243+
yyscan_tyyscanner;
244+
};
245+
240246
/*
241247
* This is the slow part of plpgsql_compile().
242248
*
@@ -269,13 +275,15 @@ do_compile(FunctionCallInfo fcinfo,
269275
Form_pg_procprocStruct= (Form_pg_proc)GETSTRUCT(procTup);
270276
boolis_dml_trigger=CALLED_AS_TRIGGER(fcinfo);
271277
boolis_event_trigger=CALLED_AS_EVENT_TRIGGER(fcinfo);
278+
yyscan_tscanner;
272279
Datumprosrcdatum;
273280
char*proc_source;
274281
HeapTupletypeTup;
275282
Form_pg_typetypeStruct;
276283
PLpgSQL_variable*var;
277284
PLpgSQL_rec*rec;
278285
inti;
286+
structcompile_error_callback_argcbarg;
279287
ErrorContextCallbackplerrcontext;
280288
intparse_rc;
281289
Oidrettypeid;
@@ -290,21 +298,21 @@ do_compile(FunctionCallInfo fcinfo,
290298
MemoryContextfunc_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,
841849
PLpgSQL_function*
842850
plpgsql_compile_inline(char*proc_source)
843851
{
852+
yyscan_tscanner;
844853
char*func_name="inline_code_block";
845854
PLpgSQL_function*function;
855+
structcompile_error_callback_argcbarg;
846856
ErrorContextCallbackplerrcontext;
847857
PLpgSQL_variable*var;
848858
intparse_rc;
849859
MemoryContextfunc_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)
978988
staticvoid
979989
plpgsql_compile_error_callback(void*arg)
980990
{
981-
if (arg)
991+
structcompile_error_callback_arg*cbarg= (structcompile_error_callback_arg*)arg;
992+
yyscan_tyyscanner=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((constchar*)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

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp