Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 3e4bacb

Browse files
committed
bootstrap: pure parser and reentrant scanner
Use the flex %option reentrant and the bison option %pure-parser to make the generated scanner and parser pure, reentrant, and thread-safe. Make the generated scanner use palloc() etc. instead of malloc() etc. For the bootstrap scanner and parser, reentrancy and memory management aren't that important, but we make this change here anyway so that all the scanners and parsers in the backend use a similar set of options and APIs. Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi> Reviewed-by: Andreas Karlsson <andreas@proxel.se> Discussion: https://www.postgresql.org/message-id/flat/eb6faeac-2a8a-4b69-9189-c33c520e5b7b@eisentraut.org
1 parent 399d0f1 commit 3e4bacb

File tree

4 files changed

+80
-38
lines changed

4 files changed

+80
-38
lines changed

src/backend/bootstrap/bootparse.y

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@
3434

3535
#include "bootparse.h"
3636

37-
/* silence -Wmissing-variable-declarations */
38-
extern int boot_yychar;
39-
extern int boot_yynerrs;
40-
4137

4238
/*
4339
* Bison doesn't allocate anything that needs to live across parser calls,
@@ -81,6 +77,9 @@ static int num_columns_read = 0;
8177

8278
%}
8379

80+
%parse-param {yyscan_t yyscanner}
81+
%lex-param {yyscan_t yyscanner}
82+
%pure-parser
8483
%expect 0
8584
%name-prefix="boot_yy"
8685

@@ -141,6 +140,8 @@ Boot_OpenStmt:
141140
do_start();
142141
boot_openrel($2);
143142
do_end();
143+
144+
(void) yynerrs; /* suppress compiler warning */
144145
}
145146
;
146147

src/backend/bootstrap/bootscanner.l

Lines changed: 61 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,19 @@ fprintf_to_ereport(const char *fmt, const char *msg)
3939
ereport(ERROR, (errmsg_internal("%s", msg)));
4040
}
4141

42-
43-
static int yyline = 1; /* line number for error reporting */
44-
4542
%}
4643

44+
%option reentrant
45+
%option bison-bridge
4746
%option 8bit
4847
%option never-interactive
4948
%option nodefault
5049
%option noinput
5150
%option nounput
5251
%option noyywrap
52+
%option noyyalloc
53+
%option noyyrealloc
54+
%option noyyfree
5355
%option warn
5456
%option prefix="boot_yy"
5557

@@ -58,31 +60,31 @@ id [-A-Za-z0-9_]+
5860
sid \'([^']|\'\')*\'
5961

6062
/*
61-
* Keyword tokens return the keyword text (as a constant string) in boot_yylval.kw,
63+
* Keyword tokens return the keyword text (as a constant string) in yylval->kw,
6264
* just in case that's needed because we want to treat the keyword as an
6365
* unreserved identifier. Note that _null_ is not treated as a keyword
6466
* for this purpose; it's the one "reserved word" in the bootstrap syntax.
6567
*
6668
* Notice that all the keywords are case-sensitive, and for historical
6769
* reasons some must be upper case.
6870
*
69-
* String tokens return a palloc'd string in boot_yylval.str.
71+
* String tokens return a palloc'd string in yylval->str.
7072
*/
7173

7274
%%
7375

74-
open { boot_yylval.kw = "open"; return OPEN; }
76+
open { yylval->kw = "open"; return OPEN; }
7577

76-
close { boot_yylval.kw = "close"; return XCLOSE; }
78+
close { yylval->kw = "close"; return XCLOSE; }
7779

78-
create { boot_yylval.kw = "create"; return XCREATE; }
80+
create { yylval->kw = "create"; return XCREATE; }
7981

80-
OID { boot_yylval.kw = "OID"; return OBJ_ID; }
81-
bootstrap { boot_yylval.kw = "bootstrap"; return XBOOTSTRAP; }
82-
shared_relation { boot_yylval.kw = "shared_relation"; return XSHARED_RELATION; }
83-
rowtype_oid { boot_yylval.kw = "rowtype_oid"; return XROWTYPE_OID; }
82+
OID { yylval->kw = "OID"; return OBJ_ID; }
83+
bootstrap { yylval->kw = "bootstrap"; return XBOOTSTRAP; }
84+
shared_relation { yylval->kw = "shared_relation"; return XSHARED_RELATION; }
85+
rowtype_oid { yylval->kw = "rowtype_oid"; return XROWTYPE_OID; }
8486

85-
insert { boot_yylval.kw = "insert"; return INSERT_TUPLE; }
87+
insert { yylval->kw = "insert"; return INSERT_TUPLE; }
8688

8789
_null_ { return NULLVAL; }
8890

@@ -91,43 +93,72 @@ _null_ { return NULLVAL; }
9193
"(" { return LPAREN; }
9294
")" { return RPAREN; }
9395

94-
[\n] { yyline++; }
96+
[\n] { yylineno++; }
9597
[\r\t ] ;
9698

9799
^\#[^\n]* ; /* drop everything after "#" for comments */
98100

99-
declare { boot_yylval.kw = "declare"; return XDECLARE; }
100-
build { boot_yylval.kw = "build"; return XBUILD; }
101-
indices { boot_yylval.kw = "indices"; return INDICES; }
102-
unique { boot_yylval.kw = "unique"; return UNIQUE; }
103-
index { boot_yylval.kw = "index"; return INDEX; }
104-
on { boot_yylval.kw = "on"; return ON; }
105-
using { boot_yylval.kw = "using"; return USING; }
106-
toast { boot_yylval.kw = "toast"; return XTOAST; }
107-
FORCE { boot_yylval.kw = "FORCE"; return XFORCE; }
108-
NOT { boot_yylval.kw = "NOT"; return XNOT; }
109-
NULL { boot_yylval.kw = "NULL"; return XNULL; }
101+
declare { yylval->kw = "declare"; return XDECLARE; }
102+
build { yylval->kw = "build"; return XBUILD; }
103+
indices { yylval->kw = "indices"; return INDICES; }
104+
unique { yylval->kw = "unique"; return UNIQUE; }
105+
index { yylval->kw = "index"; return INDEX; }
106+
on { yylval->kw = "on"; return ON; }
107+
using { yylval->kw = "using"; return USING; }
108+
toast { yylval->kw = "toast"; return XTOAST; }
109+
FORCE { yylval->kw = "FORCE"; return XFORCE; }
110+
NOT { yylval->kw = "NOT"; return XNOT; }
111+
NULL { yylval->kw = "NULL"; return XNULL; }
110112

111113
{id} {
112-
boot_yylval.str = pstrdup(yytext);
114+
yylval->str = pstrdup(yytext);
113115
return ID;
114116
}
115117
{sid} {
116118
/* strip quotes and escapes */
117-
boot_yylval.str = DeescapeQuotedString(yytext);
119+
yylval->str = DeescapeQuotedString(yytext);
118120
return ID;
119121
}
120122

121123
. {
122-
elog(ERROR, "syntax error at line %d: unexpected character \"%s\"", yyline, yytext);
124+
elog(ERROR, "syntax error at line %d: unexpected character \"%s\"", yylineno, yytext);
123125
}
124126

125127
%%
126128

127129
/* LCOV_EXCL_STOP */
128130

129131
void
130-
boot_yyerror(const char *message)
132+
boot_yyerror(yyscan_t yyscanner, const char *message)
133+
{
134+
struct yyguts_t * yyg = (struct yyguts_t *) yyscanner; /* needed for yylineno macro */
135+
136+
elog(ERROR, "%s at line %d", message, yylineno);
137+
}
138+
139+
/*
140+
* Interface functions to make flex use palloc() instead of malloc().
141+
* It'd be better to make these static, but flex insists otherwise.
142+
*/
143+
144+
void *
145+
yyalloc(yy_size_t size, yyscan_t yyscanner)
146+
{
147+
return palloc(size);
148+
}
149+
150+
void *
151+
yyrealloc(void *ptr, yy_size_t size, yyscan_t yyscanner)
152+
{
153+
if (ptr)
154+
return repalloc(ptr, size);
155+
else
156+
return palloc(size);
157+
}
158+
159+
void
160+
yyfree(void *ptr, yyscan_t yyscanner)
131161
{
132-
elog(ERROR, "%s at line %d", message, yyline);
162+
if (ptr)
163+
pfree(ptr);
133164
}

src/backend/bootstrap/bootstrap.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ BootstrapModeMain(int argc, char *argv[], bool check_only)
202202
int flag;
203203
char *userDoption = NULL;
204204
uint32 bootstrap_data_checksum_version = 0; /* No checksum */
205+
yyscan_t scanner;
205206

206207
Assert(!IsUnderPostmaster);
207208

@@ -378,11 +379,14 @@ BootstrapModeMain(int argc, char *argv[], bool check_only)
378379
Nulls[i] = false;
379380
}
380381

382+
if (boot_yylex_init(&scanner) != 0)
383+
elog(ERROR, "yylex_init() failed: %m");
384+
381385
/*
382386
* Process bootstrap input.
383387
*/
384388
StartTransactionCommand();
385-
boot_yyparse();
389+
boot_yyparse(scanner);
386390
CommitTransactionCommand();
387391

388392
/*

src/include/bootstrap/bootstrap.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,15 @@ extern void boot_get_type_io_data(Oid typid,
5555
Oid *typinput,
5656
Oid *typoutput);
5757

58-
extern int boot_yyparse(void);
58+
union YYSTYPE;
59+
#ifndef YY_TYPEDEF_YY_SCANNER_T
60+
#define YY_TYPEDEF_YY_SCANNER_T
61+
typedef void *yyscan_t;
62+
#endif
5963

60-
extern int boot_yylex(void);
61-
extern void boot_yyerror(const char *message) pg_attribute_noreturn();
64+
extern int boot_yyparse(yyscan_t yyscanner);
65+
extern int boot_yylex_init(yyscan_t *yyscannerp);
66+
extern int boot_yylex(union YYSTYPE *yylval_param, yyscan_t yyscanner);
67+
extern void boot_yyerror(yyscan_t yyscanner, const char *message) pg_attribute_noreturn();
6268

6369
#endif /* BOOTSTRAP_H */

0 commit comments

Comments
 (0)