aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parser.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2021-01-04 11:03:22 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2021-01-04 11:03:22 -0500
commit844fe9f159a948377907a63d0ef3fb16dc51ce50 (patch)
tree5f2ac3f159f7a4795a01330044fd76049ed5bff6 /src/backend/parser/parser.c
parentb49154b3b7a45523ce4081fdae8d65049342fcec (diff)
downloadpostgresql-844fe9f159a948377907a63d0ef3fb16dc51ce50.tar.gz
postgresql-844fe9f159a948377907a63d0ef3fb16dc51ce50.zip
Add the ability for the core grammar to have more than one parse target.
This patch essentially allows gram.y to implement a family of related syntax trees, rather than necessarily always parsing a list of SQL statements. raw_parser() gains a new argument, enum RawParseMode, to say what to do. As proof of concept, add a mode that just parses a TypeName without any other decoration, and use that to greatly simplify typeStringToTypeName(). In addition, invent a new SPI entry point SPI_prepare_extended() to allow SPI users (particularly plpgsql) to get at this new functionality. In hopes of making this the last variant of SPI_prepare(), set up its additional arguments as a struct rather than direct arguments, and promise that future additions to the struct can default to zero. SPI_prepare_cursor() and SPI_prepare_params() can perhaps go away at some point. Discussion: https://postgr.es/m/4165684.1607707277@sss.pgh.pa.us
Diffstat (limited to 'src/backend/parser/parser.c')
-rw-r--r--src/backend/parser/parser.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/src/backend/parser/parser.c b/src/backend/parser/parser.c
index b897a5160a2..8eb8feb372e 100644
--- a/src/backend/parser/parser.c
+++ b/src/backend/parser/parser.c
@@ -35,11 +35,11 @@ static char *str_udeescape(const char *str, char escape,
* raw_parser
* Given a query in string form, do lexical and grammatical analysis.
*
- * Returns a list of raw (un-analyzed) parse trees. The immediate elements
- * of the list are always RawStmt nodes.
+ * Returns a list of raw (un-analyzed) parse trees. The contents of the
+ * list have the form required by the specified RawParseMode.
*/
List *
-raw_parser(const char *str)
+raw_parser(const char *str, RawParseMode mode)
{
core_yyscan_t yyscanner;
base_yy_extra_type yyextra;
@@ -49,8 +49,22 @@ raw_parser(const char *str)
yyscanner = scanner_init(str, &yyextra.core_yy_extra,
&ScanKeywords, ScanKeywordTokens);
- /* base_yylex() only needs this much initialization */
- yyextra.have_lookahead = false;
+ /* base_yylex() only needs us to initialize the lookahead token, if any */
+ if (mode == RAW_PARSE_DEFAULT)
+ yyextra.have_lookahead = false;
+ else
+ {
+ /* this array is indexed by RawParseMode enum */
+ static const int mode_token[] = {
+ 0, /* RAW_PARSE_DEFAULT */
+ MODE_TYPE_NAME /* RAW_PARSE_TYPE_NAME */
+ };
+
+ yyextra.have_lookahead = true;
+ yyextra.lookahead_token = mode_token[mode];
+ yyextra.lookahead_yylloc = 0;
+ yyextra.lookahead_end = NULL;
+ }
/* initialize the bison parser */
parser_init(&yyextra);
@@ -104,7 +118,8 @@ base_yylex(YYSTYPE *lvalp, YYLTYPE *llocp, core_yyscan_t yyscanner)
cur_token = yyextra->lookahead_token;
lvalp->core_yystype = yyextra->lookahead_yylval;
*llocp = yyextra->lookahead_yylloc;
- *(yyextra->lookahead_end) = yyextra->lookahead_hold_char;
+ if (yyextra->lookahead_end)
+ *(yyextra->lookahead_end) = yyextra->lookahead_hold_char;
yyextra->have_lookahead = false;
}
else