v2-0004-replication-parser-Use-flex-yyextra.patch
text/plain
Filename: v2-0004-replication-parser-Use-flex-yyextra.patch
Type: text/plain
Part: 3
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v2-0004
Subject: replication parser: Use flex yyextra
| File | + | − |
|---|---|---|
| src/backend/replication/repl_scanner.l | 39 | 30 |
| src/backend/replication/walsender.c | 1 | 0 |
From 6c50b086029a3bf955d72e454384bb90e61debb1 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Thu, 19 Dec 2024 21:20:10 +0100
Subject: [PATCH v2 04/11] replication 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.
Co-authored-by: Andreas Karlsson <andreas@proxel.se>
---
src/backend/replication/repl_scanner.l | 69 +++++++++++++++-----------
src/backend/replication/walsender.c | 1 +
2 files changed, 40 insertions(+), 30 deletions(-)
diff --git a/src/backend/replication/repl_scanner.l b/src/backend/replication/repl_scanner.l
index 6388024a598..899114d901a 100644
--- a/src/backend/replication/repl_scanner.l
+++ b/src/backend/replication/repl_scanner.l
@@ -38,16 +38,20 @@ fprintf_to_ereport(const char *fmt, const char *msg)
ereport(ERROR, (errmsg_internal("%s", msg)));
}
-/* Pushed-back token (we only handle one) */
-static int repl_pushed_back_token; /* FIXME */
+struct replication_yy_extra_type
+{
+ /* Pushed-back token (we only handle one) */
+ int repl_pushed_back_token;
-/* Work area for collecting literals */
-static StringInfoData litbuf; /* FIXME */
+ /* Work area for collecting literals */
+ StringInfoData litbuf;
+};
+#define YY_EXTRA_TYPE struct replication_yy_extra_type *
-static void startlit(void);
-static char *litbufdup(void);
-static void addlit(char *ytext, int yleng);
-static void addlitchar(unsigned char ychar);
+static void startlit(yyscan_t yyscanner);
+static char *litbufdup(yyscan_t yyscanner);
+static void addlit(char *ytext, int yleng, yyscan_t yyscanner);
+static void addlitchar(unsigned char ychar, yyscan_t yyscanner);
/* LCOV_EXCL_START */
@@ -110,11 +114,11 @@ identifier {ident_start}{ident_cont}*
/* This code is inserted at the start of replication_yylex() */
/* If we have a pushed-back token, return that. */
- if (repl_pushed_back_token)
+ if (yyextra->repl_pushed_back_token)
{
- int result = repl_pushed_back_token;
+ int result = yyextra->repl_pushed_back_token;
- repl_pushed_back_token = 0;
+ yyextra->repl_pushed_back_token = 0;
return result;
}
%}
@@ -159,27 +163,27 @@ UPLOAD_MANIFEST { return K_UPLOAD_MANIFEST; }
{xqstart} {
BEGIN(xq);
- startlit();
+ startlit(yyscanner);
}
<xq>{quotestop} {
yyless(1);
BEGIN(INITIAL);
- yylval->str = litbufdup();
+ yylval->str = litbufdup(yyscanner);
return SCONST;
}
<xq>{xqdouble} {
- addlitchar('\'');
+ addlitchar('\'', yyscanner);
}
<xq>{xqinside} {
- addlit(yytext, yyleng);
+ addlit(yytext, yyleng, yyscanner);
}
{xdstart} {
BEGIN(xd);
- startlit();
+ startlit(yyscanner);
}
<xd>{xdstop} {
@@ -187,14 +191,14 @@ UPLOAD_MANIFEST { return K_UPLOAD_MANIFEST; }
yyless(1);
BEGIN(INITIAL);
- yylval->str = litbufdup();
+ yylval->str = litbufdup(yyscanner);
len = strlen(yylval->str);
truncate_identifier(yylval->str, len, true);
return IDENT;
}
<xd>{xdinside} {
- addlit(yytext, yyleng);
+ addlit(yytext, yyleng, yyscanner);
}
{identifier} {
@@ -220,28 +224,32 @@ UPLOAD_MANIFEST { return K_UPLOAD_MANIFEST; }
/* LCOV_EXCL_STOP */
+/* see scan.l */
+#undef yyextra
+#define yyextra (((struct yyguts_t *) yyscanner)->yyextra_r)
+
static void
-startlit(void)
+startlit(yyscan_t yyscanner)
{
- initStringInfo(&litbuf);
+ initStringInfo(&yyextra->litbuf);
}
static char *
-litbufdup(void)
+litbufdup(yyscan_t yyscanner)
{
- return litbuf.data;
+ return yyextra->litbuf.data;
}
static void
-addlit(char *ytext, int yleng)
+addlit(char *ytext, int yleng, yyscan_t yyscanner)
{
- appendBinaryStringInfo(&litbuf, ytext, yleng);
+ appendBinaryStringInfo(&yyextra->litbuf, ytext, yleng);
}
static void
-addlitchar(unsigned char ychar)
+addlitchar(unsigned char ychar, yyscan_t yyscanner)
{
- appendStringInfoChar(&litbuf, ychar);
+ appendStringInfoChar(&yyextra->litbuf, ychar);
}
void
@@ -256,21 +264,22 @@ void
replication_scanner_init(const char *str, yyscan_t *yyscannerp)
{
yyscan_t yyscanner;
+ struct replication_yy_extra_type *yyext = palloc0_object(struct replication_yy_extra_type);
if (yylex_init(yyscannerp) != 0)
elog(ERROR, "yylex_init() failed: %m");
yyscanner = *yyscannerp;
- yy_scan_string(str, yyscanner);
+ yyset_extra(yyext, yyscanner);
- /* Make sure we start in proper state */
- repl_pushed_back_token = 0;
+ yy_scan_string(str, yyscanner);
}
void
replication_scanner_finish(yyscan_t yyscanner)
{
+ pfree(yyextra);
yylex_destroy(yyscanner);
}
@@ -301,7 +310,7 @@ replication_scanner_is_replication_command(yyscan_t yyscanner)
case K_UPLOAD_MANIFEST:
case K_SHOW:
/* Yes; push back the first token so we can parse later. */
- repl_pushed_back_token = first_token;
+ yyextra->repl_pushed_back_token = first_token;
return true;
default:
/* Nope; we don't bother to push back the token. */
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index dc25dd6af91..559dba48962 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -1998,6 +1998,7 @@ exec_replication_command(const char *cmd_string)
*/
if (!replication_scanner_is_replication_command(scanner))
{
+ elog(WARNING, "CHECK1: not-repl: %s", cmd_string);
/* Nope; clean up and get out. */
replication_scanner_finish(scanner);
--
2.47.1