0002-pgbench-Return-parse-result-not-via-global-variable.patch

text/plain

Filename: 0002-pgbench-Return-parse-result-not-via-global-variable.patch
Type: text/plain
Part: 1
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 0002
Subject: pgbench: Return parse result not via global variable
File+
src/bin/pgbench/exprparse.y 2 3
src/bin/pgbench/exprscan.l 5 1
src/bin/pgbench/pgbench.c 1 3
src/bin/pgbench/pgbench.h 2 4
From 5925f806205ae9f868fb732da24e529ee67ea87d Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Fri, 17 Jan 2025 13:14:16 +0100
Subject: [PATCH 2/4] pgbench: 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/bin/pgbench/exprparse.y | 5 ++---
 src/bin/pgbench/exprscan.l  | 6 +++++-
 src/bin/pgbench/pgbench.c   | 4 +---
 src/bin/pgbench/pgbench.h   | 6 ++----
 4 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/src/bin/pgbench/exprparse.y b/src/bin/pgbench/exprparse.y
index 9b5ab8074eb..68a37e49e45 100644
--- a/src/bin/pgbench/exprparse.y
+++ b/src/bin/pgbench/exprparse.y
@@ -21,8 +21,6 @@
 #define PGBENCH_NARGS_HASH		(-3)
 #define PGBENCH_NARGS_PERMUTE	(-4)
 
-PgBenchExpr *expr_parse_result;
-
 static PgBenchExprList *make_elist(PgBenchExpr *expr, PgBenchExprList *list);
 static PgBenchExpr *make_null_constant(void);
 static PgBenchExpr *make_boolean_constant(bool bval);
@@ -42,6 +40,7 @@ static PgBenchExpr *make_case(yyscan_t yyscanner, PgBenchExprList *when_then_lis
 %expect 0
 %name-prefix="expr_yy"
 
+%parse-param {PgBenchExpr **expr_parse_result_p}
 %parse-param {yyscan_t yyscanner}
 %lex-param   {yyscan_t yyscanner}
 
@@ -81,7 +80,7 @@ static PgBenchExpr *make_case(yyscan_t yyscanner, PgBenchExprList *when_then_lis
 %%
 
 result: expr				{
-								expr_parse_result = $1;
+								*expr_parse_result_p = $1;
 								(void) yynerrs; /* suppress compiler warning */
 							}
 
diff --git a/src/bin/pgbench/exprscan.l b/src/bin/pgbench/exprscan.l
index 46f6ea05121..8943a52e9f0 100644
--- a/src/bin/pgbench/exprscan.l
+++ b/src/bin/pgbench/exprscan.l
@@ -296,8 +296,12 @@ expr_yyerror_more(yyscan_t yyscanner, const char *message, const char *more)
 				 message, more, error_detection_offset - expr_start_offset);
 }
 
+/*
+ * (The first argument is enforced by Bison to match the first argument of
+ * yyparse(), but it is not used here.)
+ */
 void
-expr_yyerror(yyscan_t yyscanner, const char *message)
+expr_yyerror(PgBenchExpr **expr_parse_result_p, yyscan_t yyscanner, const char *message)
 {
 	expr_yyerror_more(yyscanner, message, NULL);
 }
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index c415e0f32c1..40592e62606 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -5706,14 +5706,12 @@ process_backslash_command(PsqlScanState sstate, const char *source)
 		yyscanner = expr_scanner_init(sstate, source, lineno, start_offset,
 									  my_command->argv[0]);
 
-		if (expr_yyparse(yyscanner) != 0)
+		if (expr_yyparse(&my_command->expr, yyscanner) != 0)
 		{
 			/* dead code: exit done from syntax_error called by yyerror */
 			exit(1);
 		}
 
-		my_command->expr = expr_parse_result;
-
 		/* Save line, trimming any trailing newline */
 		my_command->first_line =
 			expr_scanner_get_substring(sstate,
diff --git a/src/bin/pgbench/pgbench.h b/src/bin/pgbench/pgbench.h
index 4b607b7ee04..f6a883611c5 100644
--- a/src/bin/pgbench/pgbench.h
+++ b/src/bin/pgbench/pgbench.h
@@ -138,11 +138,9 @@ struct PgBenchExprList
 	PgBenchExprLink *tail;
 };
 
-extern PgBenchExpr *expr_parse_result;
-
-extern int	expr_yyparse(yyscan_t yyscanner);
+extern int	expr_yyparse(PgBenchExpr **expr_parse_result_p, yyscan_t yyscanner);
 extern int	expr_yylex(union YYSTYPE *yylval_param, yyscan_t yyscanner);
-extern void expr_yyerror(yyscan_t yyscanner, const char *message) pg_attribute_noreturn();
+extern void expr_yyerror(PgBenchExpr **expr_parse_result_p, yyscan_t yyscanner, const char *message) pg_attribute_noreturn();
 extern void expr_yyerror_more(yyscan_t yyscanner, const char *message,
 							  const char *more) pg_attribute_noreturn();
 extern bool expr_lex_one_word(PsqlScanState state, PQExpBuffer word_buf,
-- 
2.47.1