0003-replication-parser-Return-parse-result-not-via-globa.patch

text/plain

Filename: 0003-replication-parser-Return-parse-result-not-via-globa.patch
Type: text/plain
Part: 2
Message: Re: pure parsers and reentrant scanners

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 0003
Subject: replication parser: Return parse result not via global variable
File+
src/backend/nls.mk 1 1
src/backend/replication/repl_gram.y 2 5
src/backend/replication/repl_scanner.l 7 3
src/backend/replication/walsender.c 1 3
src/include/replication/walsender_private.h 2 4
From 0d2703ecae444499a179af7c5cb6e9001c44005d Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 17 Jan 2025 13:18:38 +0100
Subject: [PATCH 3/4] replication parser: Return parse result not via global
 variable

Instead of passing the parse result from yyparse() via a global
variable, pass it via a function output argument.
---
 src/backend/nls.mk                          |  2 +-
 src/backend/replication/repl_gram.y         |  7 ++-----
 src/backend/replication/repl_scanner.l      | 10 +++++++---
 src/backend/replication/walsender.c         |  4 +---
 src/include/replication/walsender_private.h |  6 ++----
 5 files changed, 13 insertions(+), 16 deletions(-)

diff --git a/src/backend/nls.mk b/src/backend/nls.mk
index 5a5298b33f7..210893c7b72 100644
--- a/src/backend/nls.mk
+++ b/src/backend/nls.mk
@@ -9,7 +9,7 @@ GETTEXT_TRIGGERS = $(BACKEND_COMMON_GETTEXT_TRIGGERS) \
                    yyerror \
                    jsonpath_yyerror:4 \
                    parser_yyerror \
-                   replication_yyerror:2 \
+                   replication_yyerror:3 \
                    scanner_yyerror \
                    syncrep_yyerror:2 \
                    report_invalid_record:2 \
diff --git a/src/backend/replication/repl_gram.y b/src/backend/replication/repl_gram.y
index 61e68d0727a..7440aae5a1a 100644
--- a/src/backend/replication/repl_gram.y
+++ b/src/backend/replication/repl_gram.y
@@ -25,10 +25,6 @@
 #include "repl_gram.h"
 
 
-/* Result of the parsing is returned here */
-Node *replication_parse_result;
-
-
 /*
  * Bison doesn't allocate anything that needs to live across parser calls,
  * so we can easily have it use palloc instead of malloc.  This prevents
@@ -39,6 +35,7 @@ Node *replication_parse_result;
 
 %}
 
+%parse-param {Node **replication_parse_result_p}
 %parse-param {yyscan_t yyscanner}
 %lex-param   {yyscan_t yyscanner}
 %pure-parser
@@ -104,7 +101,7 @@ Node *replication_parse_result;
 
 firstcmd: command opt_semicolon
 				{
-					replication_parse_result = $1;
+					*replication_parse_result_p = $1;
 
 					(void) yynerrs; /* suppress compiler warning */
 				}
diff --git a/src/backend/replication/repl_scanner.l b/src/backend/replication/repl_scanner.l
index de10cb5abd1..014ea8d25c6 100644
--- a/src/backend/replication/repl_scanner.l
+++ b/src/backend/replication/repl_scanner.l
@@ -156,7 +156,7 @@ UPLOAD_MANIFEST		{ return K_UPLOAD_MANIFEST; }
 					uint32	hi,
 							lo;
 					if (sscanf(yytext, "%X/%X", &hi, &lo) != 2)
-						replication_yyerror(yyscanner, "invalid streaming start location");
+						replication_yyerror(NULL, yyscanner, "invalid streaming start location");
 					yylval->recptr = ((uint64) hi) << 32 | lo;
 					return RECPTR;
 				}
@@ -213,7 +213,7 @@ UPLOAD_MANIFEST		{ return K_UPLOAD_MANIFEST; }
 					return yytext[0];
 				}
 
-<xq,xd><<EOF>>	{ replication_yyerror(yyscanner, "unterminated quoted string"); }
+<xq,xd><<EOF>>	{ replication_yyerror(NULL, yyscanner, "unterminated quoted string"); }
 
 
 <<EOF>>			{
@@ -252,8 +252,12 @@ addlitchar(unsigned char ychar, yyscan_t yyscanner)
 	appendStringInfoChar(&yyextra->litbuf, ychar);
 }
 
+/*
+  * (The first argument is enforced by Bison to match the first argument of
+  * yyparse(), but it is not used here.)
+  */
 void
-replication_yyerror(yyscan_t yyscanner, const char *message)
+replication_yyerror(Node **replication_parse_result_p, yyscan_t yyscanner, const char *message)
 {
 	ereport(ERROR,
 			(errcode(ERRCODE_SYNTAX_ERROR),
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index a0782b1bbf6..bac504b554e 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -2017,7 +2017,7 @@ exec_replication_command(const char *cmd_string)
 	/*
 	 * Looks like a WalSender command, so parse it.
 	 */
-	parse_rc = replication_yyparse(scanner);
+	parse_rc = replication_yyparse(&cmd_node, scanner);
 	if (parse_rc != 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_SYNTAX_ERROR),
@@ -2025,8 +2025,6 @@ exec_replication_command(const char *cmd_string)
 								 parse_rc)));
 	replication_scanner_finish(scanner);
 
-	cmd_node = replication_parse_result;
-
 	/*
 	 * Report query to various monitoring facilities.  For this purpose, we
 	 * report replication commands just like SQL commands.
diff --git a/src/include/replication/walsender_private.h b/src/include/replication/walsender_private.h
index 5ab96ed5f7d..814b812432a 100644
--- a/src/include/replication/walsender_private.h
+++ b/src/include/replication/walsender_private.h
@@ -130,13 +130,11 @@ union YYSTYPE;
 #define YY_TYPEDEF_YY_SCANNER_T
 typedef void *yyscan_t;
 #endif
-extern int	replication_yyparse(yyscan_t yyscanner);
+extern int	replication_yyparse(Node **replication_parse_result_p, yyscan_t yyscanner);
 extern int	replication_yylex(union YYSTYPE *yylval_param, yyscan_t yyscanner);
-extern void replication_yyerror(yyscan_t yyscanner, const char *message) pg_attribute_noreturn();
+extern void replication_yyerror(Node **replication_parse_result_p, yyscan_t yyscanner, const char *message) pg_attribute_noreturn();
 extern void replication_scanner_init(const char *str, yyscan_t *yyscannerp);
 extern void replication_scanner_finish(yyscan_t yyscanner);
 extern bool replication_scanner_is_replication_command(yyscan_t yyscanner);
 
-extern PGDLLIMPORT Node *replication_parse_result;
-
 #endif							/* _WALSENDER_PRIVATE_H */
-- 
2.47.1