v1-0016-bootstrap-pure-parser-and-reentrant-scanner.patch

text/plain

Filename: v1-0016-bootstrap-pure-parser-and-reentrant-scanner.patch
Type: text/plain
Part: 15
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 v1-0016
Subject: bootstrap: pure parser and reentrant scanner
File+
src/backend/bootstrap/bootparse.y 5 4
src/backend/bootstrap/bootscanner.l 31 30
src/backend/bootstrap/bootstrap.c 5 1
src/include/bootstrap/bootstrap.h 6 3
From ab6e50ec0ac5e7ef79a373cccf9319ba9a985782 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter@eisentraut.org>
Date: Tue, 3 Dec 2024 15:23:36 +0100
Subject: [PATCH v1 16/19] bootstrap: pure parser and reentrant scanner

---
 src/backend/bootstrap/bootparse.y   |  9 +++--
 src/backend/bootstrap/bootscanner.l | 61 +++++++++++++++--------------
 src/backend/bootstrap/bootstrap.c   |  6 ++-
 src/include/bootstrap/bootstrap.h   |  9 +++--
 4 files changed, 47 insertions(+), 38 deletions(-)

diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y
index 73a7592fb71..05ef26c07d0 100644
--- a/src/backend/bootstrap/bootparse.y
+++ b/src/backend/bootstrap/bootparse.y
@@ -34,10 +34,6 @@
 
 #include "bootparse.h"
 
-/* silence -Wmissing-variable-declarations */
-extern int boot_yychar;
-extern int boot_yynerrs;
-
 
 /*
  * Bison doesn't allocate anything that needs to live across parser calls,
@@ -81,6 +77,9 @@ static int num_columns_read = 0;
 
 %}
 
+%parse-param {yyscan_t yyscanner}
+%lex-param   {yyscan_t yyscanner}
+%pure-parser
 %expect 0
 %name-prefix="boot_yy"
 
@@ -141,6 +140,8 @@ Boot_OpenStmt:
 					do_start();
 					boot_openrel($2);
 					do_end();
+
+					(void) yynerrs; /* suppress compiler warning */
 				}
 		;
 
diff --git a/src/backend/bootstrap/bootscanner.l b/src/backend/bootstrap/bootscanner.l
index 31d63ff3015..c4e7139fa41 100644
--- a/src/backend/bootstrap/bootscanner.l
+++ b/src/backend/bootstrap/bootscanner.l
@@ -39,11 +39,10 @@ fprintf_to_ereport(const char *fmt, const char *msg)
 	ereport(ERROR, (errmsg_internal("%s", msg)));
 }
 
-
-static int	yyline = 1;			/* line number for error reporting */
-
 %}
 
+%option reentrant
+%option bison-bridge
 %option 8bit
 %option never-interactive
 %option nodefault
@@ -58,7 +57,7 @@ id		[-A-Za-z0-9_]+
 sid		\'([^']|\'\')*\'
 
 /*
- * Keyword tokens return the keyword text (as a constant string) in boot_yylval.kw,
+ * Keyword tokens return the keyword text (as a constant string) in yylval->kw,
  * just in case that's needed because we want to treat the keyword as an
  * unreserved identifier.  Note that _null_ is not treated as a keyword
  * for this purpose; it's the one "reserved word" in the bootstrap syntax.
@@ -66,23 +65,23 @@ sid		\'([^']|\'\')*\'
  * Notice that all the keywords are case-sensitive, and for historical
  * reasons some must be upper case.
  *
- * String tokens return a palloc'd string in boot_yylval.str.
+ * String tokens return a palloc'd string in yylval->str.
  */
 
 %%
 
-open			{ boot_yylval.kw = "open"; return OPEN; }
+open			{ yylval->kw = "open"; return OPEN; }
 
-close			{ boot_yylval.kw = "close"; return XCLOSE; }
+close			{ yylval->kw = "close"; return XCLOSE; }
 
-create			{ boot_yylval.kw = "create"; return XCREATE; }
+create			{ yylval->kw = "create"; return XCREATE; }
 
-OID				{ boot_yylval.kw = "OID"; return OBJ_ID; }
-bootstrap		{ boot_yylval.kw = "bootstrap"; return XBOOTSTRAP; }
-shared_relation	{ boot_yylval.kw = "shared_relation"; return XSHARED_RELATION; }
-rowtype_oid		{ boot_yylval.kw = "rowtype_oid"; return XROWTYPE_OID; }
+OID				{ yylval->kw = "OID"; return OBJ_ID; }
+bootstrap		{ yylval->kw = "bootstrap"; return XBOOTSTRAP; }
+shared_relation	{ yylval->kw = "shared_relation"; return XSHARED_RELATION; }
+rowtype_oid		{ yylval->kw = "rowtype_oid"; return XROWTYPE_OID; }
 
-insert			{ boot_yylval.kw = "insert"; return INSERT_TUPLE; }
+insert			{ yylval->kw = "insert"; return INSERT_TUPLE; }
 
 _null_			{ return NULLVAL; }
 
@@ -91,35 +90,35 @@ _null_			{ return NULLVAL; }
 "("				{ return LPAREN; }
 ")"				{ return RPAREN; }
 
-[\n]			{ yyline++; }
+[\n]			{ yylineno++; }
 [\r\t ]			;
 
 ^\#[^\n]*		;		/* drop everything after "#" for comments */
 
-declare			{ boot_yylval.kw = "declare"; return XDECLARE; }
-build			{ boot_yylval.kw = "build"; return XBUILD; }
-indices			{ boot_yylval.kw = "indices"; return INDICES; }
-unique			{ boot_yylval.kw = "unique"; return UNIQUE; }
-index			{ boot_yylval.kw = "index"; return INDEX; }
-on				{ boot_yylval.kw = "on"; return ON; }
-using			{ boot_yylval.kw = "using"; return USING; }
-toast			{ boot_yylval.kw = "toast"; return XTOAST; }
-FORCE			{ boot_yylval.kw = "FORCE"; return XFORCE; }
-NOT				{ boot_yylval.kw = "NOT"; return XNOT; }
-NULL			{ boot_yylval.kw = "NULL"; return XNULL; }
+declare			{ yylval->kw = "declare"; return XDECLARE; }
+build			{ yylval->kw = "build"; return XBUILD; }
+indices			{ yylval->kw = "indices"; return INDICES; }
+unique			{ yylval->kw = "unique"; return UNIQUE; }
+index			{ yylval->kw = "index"; return INDEX; }
+on				{ yylval->kw = "on"; return ON; }
+using			{ yylval->kw = "using"; return USING; }
+toast			{ yylval->kw = "toast"; return XTOAST; }
+FORCE			{ yylval->kw = "FORCE"; return XFORCE; }
+NOT				{ yylval->kw = "NOT"; return XNOT; }
+NULL			{ yylval->kw = "NULL"; return XNULL; }
 
 {id}			{
-					boot_yylval.str = pstrdup(yytext);
+					yylval->str = pstrdup(yytext);
 					return ID;
 				}
 {sid}			{
 					/* strip quotes and escapes */
-					boot_yylval.str = DeescapeQuotedString(yytext);
+					yylval->str = DeescapeQuotedString(yytext);
 					return ID;
 				}
 
 .				{
-					elog(ERROR, "syntax error at line %d: unexpected character \"%s\"", yyline, yytext);
+					elog(ERROR, "syntax error at line %d: unexpected character \"%s\"", yylineno, yytext);
 				}
 
 %%
@@ -127,7 +126,9 @@ NULL			{ boot_yylval.kw = "NULL"; return XNULL; }
 /* LCOV_EXCL_STOP */
 
 void
-boot_yyerror(const char *message)
+boot_yyerror(yyscan_t yyscanner, const char *message)
 {
-	elog(ERROR, "%s at line %d", message, yyline);
+	struct yyguts_t * yyg = (struct yyguts_t *) yyscanner;	/* needed for yylineno macro */
+
+	elog(ERROR, "%s at line %d", message, yylineno);
 }
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index a5217773ffc..388458a5724 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -202,6 +202,7 @@ BootstrapModeMain(int argc, char *argv[], bool check_only)
 	int			flag;
 	char	   *userDoption = NULL;
 	uint32		bootstrap_data_checksum_version = 0;	/* No checksum */
+	yyscan_t	scanner;
 
 	Assert(!IsUnderPostmaster);
 
@@ -372,11 +373,14 @@ BootstrapModeMain(int argc, char *argv[], bool check_only)
 		Nulls[i] = false;
 	}
 
+	if (boot_yylex_init(&scanner) != 0)
+		elog(ERROR, "yylex_init() failed: %m");
+
 	/*
 	 * Process bootstrap input.
 	 */
 	StartTransactionCommand();
-	boot_yyparse();
+	boot_yyparse(scanner);
 	CommitTransactionCommand();
 
 	/*
diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h
index 73b78b31335..ccec9415acb 100644
--- a/src/include/bootstrap/bootstrap.h
+++ b/src/include/bootstrap/bootstrap.h
@@ -55,9 +55,12 @@ extern void boot_get_type_io_data(Oid typid,
 								  Oid *typinput,
 								  Oid *typoutput);
 
-extern int	boot_yyparse(void);
+union YYSTYPE;
+typedef void *yyscan_t;
 
-extern int	boot_yylex(void);
-extern void boot_yyerror(const char *message) pg_attribute_noreturn();
+extern int	boot_yyparse(yyscan_t yyscanner);
+extern int	boot_yylex_init(yyscan_t *yyscannerp);
+extern int	boot_yylex(union YYSTYPE *yylval_param, yyscan_t yyscanner);
+extern void boot_yyerror(yyscan_t yyscanner, const char *message) pg_attribute_noreturn();
 
 #endif							/* BOOTSTRAP_H */
-- 
2.47.1