From 5df539dda3589ff8764ed1d0efd391964666337b Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 2 Dec 2024 10:35:37 +0100 Subject: [PATCH v2 08/11] syncrep parser: Use flex yyextra Use flex yyextra to handle context information, instead of global variables. This complements the earlier patch to make the scanner reentrant. --- src/backend/replication/syncrep_scanner.l | 24 +++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/backend/replication/syncrep_scanner.l b/src/backend/replication/syncrep_scanner.l index 9eac11229c6..42e6852ea15 100644 --- a/src/backend/replication/syncrep_scanner.l +++ b/src/backend/replication/syncrep_scanner.l @@ -37,7 +37,11 @@ fprintf_to_ereport(const char *fmt, const char *msg) ereport(ERROR, (errmsg_internal("%s", msg))); } -static StringInfoData xdbuf; /* FIXME */ +struct syncrep_yy_extra_type +{ + StringInfoData xdbuf; +}; +#define YY_EXTRA_TYPE struct syncrep_yy_extra_type * /* LCOV_EXCL_START */ @@ -84,18 +88,18 @@ xdinside [^"]+ [Ff][Ii][Rr][Ss][Tt] { return FIRST; } {xdstart} { - initStringInfo(&xdbuf); + initStringInfo(&yyextra->xdbuf); BEGIN(xd); } {xddouble} { - appendStringInfoChar(&xdbuf, '"'); + appendStringInfoChar(&yyextra->xdbuf, '"'); } {xdinside} { - appendStringInfoString(&xdbuf, yytext); + appendStringInfoString(&yyextra->xdbuf, yytext); } {xdstop} { - yylval->str = xdbuf.data; - xdbuf.data = NULL; + yylval->str = yyextra->xdbuf.data; + yyextra->xdbuf.data = NULL; BEGIN(INITIAL); return NAME; } @@ -128,6 +132,10 @@ xdinside [^"]+ /* LCOV_EXCL_STOP */ +/* see scan.l */ +#undef yyextra +#define yyextra (((struct yyguts_t *) yyscanner)->yyextra_r) + /* Needs to be here for access to yytext */ void syncrep_yyerror(yyscan_t yyscanner, const char *message) @@ -149,18 +157,22 @@ void syncrep_scanner_init(const char *str, yyscan_t *yyscannerp) { yyscan_t yyscanner; + struct syncrep_yy_extra_type *yyext = palloc0_object(struct syncrep_yy_extra_type); if (yylex_init(yyscannerp) != 0) elog(ERROR, "yylex_init() failed: %m"); yyscanner = *yyscannerp; + yyset_extra(yyext, yyscanner); + yy_scan_string(str, yyscanner); } void syncrep_scanner_finish(yyscan_t yyscanner) { + pfree(yyextra); yylex_destroy(yyscanner); } -- 2.47.1