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
17 * $PostgreSQL: pgsql/src/backend/parser/parser.c,v 1.79 2009/07/12 17:12:34 tgl Exp $
19 *-------------------------------------------------------------------------
24 #include "parser/gramparse.h"
25 #include "parser/parser.h"
28 List *parsetree; /* result of parsing is left here */
30 static bool have_lookahead; /* is lookahead info valid? */
31 static int lookahead_token; /* one-token lookahead */
32 static YYSTYPE lookahead_yylval; /* yylval for lookahead token */
33 static YYLTYPE lookahead_yylloc; /* yylloc for lookahead token */
38 * Given a query in string form, do lexical and grammatical analysis.
40 * Returns a list of raw (un-analyzed) parse trees.
43 raw_parser(const char *str)
47 parsetree = NIL; /* in case grammar forgets to set it */
48 have_lookahead = false;
53 yyresult = base_yyparse();
57 if (yyresult) /* error */
65 * pg_parse_string_token - get the value represented by a string literal
67 * Given the textual form of a SQL string literal, produce the represented
68 * value as a palloc'd string. It is caller's responsibility that the
69 * passed string does represent one single string literal.
71 * We export this function to avoid having plpgsql depend on internal details
72 * of the core grammar (such as the token code assigned to SCONST). Note
73 * that since the scanner isn't presently re-entrant, this cannot be used
74 * during use of the main parser/scanner.
77 pg_parse_string_token(const char *token)
83 ctoken = base_yylex();
85 if (ctoken != SCONST) /* caller error */
86 elog(ERROR, "expected string constant, got token code %d", ctoken);
90 return base_yylval.str;
95 * Intermediate filter between parser and base lexer (base_yylex in scan.l).
97 * The filter is needed because in some cases the standard SQL grammar
98 * requires more than one token lookahead. We reduce these cases to one-token
99 * lookahead by combining tokens here, in order to keep the grammar LALR(1).
101 * Using a filter is simpler than trying to recognize multiword tokens
102 * directly in scan.l, because we'd have to allow for comments between the
103 * words. Furthermore it's not clear how to do it without re-introducing
104 * scanner backtrack, which would cost more performance than this filter
108 filtered_base_yylex(void)
115 /* Get next token --- we might already have it */
118 cur_token = lookahead_token;
119 base_yylval = lookahead_yylval;
120 base_yylloc = lookahead_yylloc;
121 have_lookahead = false;
124 cur_token = base_yylex();
126 /* Do we need to look ahead for a possible multiword token? */
132 * NULLS FIRST and NULLS LAST must be reduced to one token
134 cur_yylval = base_yylval;
135 cur_yylloc = base_yylloc;
136 next_token = base_yylex();
140 cur_token = NULLS_FIRST;
143 cur_token = NULLS_LAST;
146 /* save the lookahead token for next time */
147 lookahead_token = next_token;
148 lookahead_yylval = base_yylval;
149 lookahead_yylloc = base_yylloc;
150 have_lookahead = true;
151 /* and back up the output info to cur_token */
152 base_yylval = cur_yylval;
153 base_yylloc = cur_yylloc;
161 * WITH TIME must be reduced to one token
163 cur_yylval = base_yylval;
164 cur_yylloc = base_yylloc;
165 next_token = base_yylex();
169 cur_token = WITH_TIME;
172 /* save the lookahead token for next time */
173 lookahead_token = next_token;
174 lookahead_yylval = base_yylval;
175 lookahead_yylloc = base_yylloc;
176 have_lookahead = true;
177 /* and back up the output info to cur_token */
178 base_yylval = cur_yylval;
179 base_yylloc = cur_yylloc;