mirror of
https://github.com/postgres/postgres.git
synced 2025-08-21 10:42:50 +03:00
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
This commit is contained in:
@@ -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
|
||||
|
Reference in New Issue
Block a user