From 0d2703ecae444499a179af7c5cb6e9001c44005d Mon Sep 17 00:00:00 2001 From: Peter Eisentraut 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]; } -<> { replication_yyerror(yyscanner, "unterminated quoted string"); } +<> { replication_yyerror(NULL, yyscanner, "unterminated quoted string"); } <> { @@ -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