1 /*-------------------------------------------------------------------------
4 * Main entry point/driver for PostgreSQL grammar
6 * Note that the grammar is not allowed to perform any table access
7 * (since we need to be able to do basic parsing even while inside an
8 * aborted transaction). Therefore, the data structures returned by
9 * the grammar are "raw" parsetrees that still need to be analyzed by
10 * analyze.c and related files.
13 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
14 * Portions Copyright (c) 1994, Regents of the University of California
19 *-------------------------------------------------------------------------
24 #include "parser/gramparse.h" /* required before parser/gram.h! */
25 #include "parser/gram.h"
26 #include "parser/parser.h"
29 List
*parsetree
; /* result of parsing is left here */
31 static bool have_lookahead
; /* is lookahead info valid? */
32 static int lookahead_token
; /* one-token lookahead */
33 static YYSTYPE lookahead_yylval
; /* yylval for lookahead token */
34 static YYLTYPE lookahead_yylloc
; /* yylloc for lookahead token */
39 * Given a query in string form, do lexical and grammatical analysis.
41 * Returns a list of raw (un-analyzed) parse trees.
44 raw_parser(const char *str
)
48 parsetree
= NIL
; /* in case grammar forgets to set it */
49 have_lookahead
= false;
54 yyresult
= base_yyparse();
58 if (yyresult
) /* error */
66 * pg_parse_string_token - get the value represented by a string literal
68 * Given the textual form of a SQL string literal, produce the represented
69 * value as a palloc'd string. It is caller's responsibility that the
70 * passed string does represent one single string literal.
72 * We export this function to avoid having plpgsql depend on internal details
73 * of the core grammar (such as the token code assigned to SCONST). Note
74 * that since the scanner isn't presently re-entrant, this cannot be used
75 * during use of the main parser/scanner.
78 pg_parse_string_token(const char *token
)
84 ctoken
= base_yylex();
86 if (ctoken
!= SCONST
) /* caller error */
87 elog(ERROR
, "expected string constant, got token code %d", ctoken
);
91 return base_yylval
.str
;
96 * Intermediate filter between parser and base lexer (base_yylex in scan.l).
98 * The filter is needed because in some cases the standard SQL grammar
99 * requires more than one token lookahead. We reduce these cases to one-token
100 * lookahead by combining tokens here, in order to keep the grammar LALR(1).
102 * Using a filter is simpler than trying to recognize multiword tokens
103 * directly in scan.l, because we'd have to allow for comments between the
104 * words. Furthermore it's not clear how to do it without re-introducing
105 * scanner backtrack, which would cost more performance than this filter
109 filtered_base_yylex(void)
116 /* Get next token --- we might already have it */
119 cur_token
= lookahead_token
;
120 base_yylval
= lookahead_yylval
;
121 base_yylloc
= lookahead_yylloc
;
122 have_lookahead
= false;
125 cur_token
= base_yylex();
127 /* Do we need to look ahead for a possible multiword token? */
133 * NULLS FIRST and NULLS LAST must be reduced to one token
135 cur_yylval
= base_yylval
;
136 cur_yylloc
= base_yylloc
;
137 next_token
= base_yylex();
141 cur_token
= NULLS_FIRST
;
144 cur_token
= NULLS_LAST
;
147 /* save the lookahead token for next time */
148 lookahead_token
= next_token
;
149 lookahead_yylval
= base_yylval
;
150 lookahead_yylloc
= base_yylloc
;
151 have_lookahead
= true;
152 /* and back up the output info to cur_token */
153 base_yylval
= cur_yylval
;
154 base_yylloc
= cur_yylloc
;
162 * WITH TIME must be reduced to one token
164 cur_yylval
= base_yylval
;
165 cur_yylloc
= base_yylloc
;
166 next_token
= base_yylex();
170 cur_token
= WITH_TIME
;
173 /* save the lookahead token for next time */
174 lookahead_token
= next_token
;
175 lookahead_yylval
= base_yylval
;
176 lookahead_yylloc
= base_yylloc
;
177 have_lookahead
= true;
178 /* and back up the output info to cur_token */
179 base_yylval
= cur_yylval
;
180 base_yylloc
= cur_yylloc
;