summaryrefslogtreecommitdiff
path: root/src/backend/parser/parser.c
diff options
context:
space:
mode:
authorTom Lane2006-05-27 17:38:46 +0000
committerTom Lane2006-05-27 17:38:46 +0000
commit0780ce6a93c1403e8d354906cdc49cd1cd21b364 (patch)
tree7d576ff5c8eb91fbdfe7cf82c2779cf9cbd75c6c /src/backend/parser/parser.c
parent51b40f03a4001eaa0fe42df8f6567abe4bd32d21 (diff)
Re-introduce the yylex filter function formerly used to support UNION
JOIN, which I removed in a recent fit of over-optimism that we wouldn't have any future use for it. Now it's needed to support disambiguating WITH CHECK OPTION from WITH TIME ZONE. As proof of concept, add stub grammar productions for WITH CHECK OPTION.
Diffstat (limited to 'src/backend/parser/parser.c')
-rw-r--r--src/backend/parser/parser.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/src/backend/parser/parser.c b/src/backend/parser/parser.c
index 6c331ad338d..de40e64fa8a 100644
--- a/src/backend/parser/parser.c
+++ b/src/backend/parser/parser.c
@@ -14,7 +14,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parser.c,v 1.65 2006/03/07 01:00:17 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parser.c,v 1.66 2006/05/27 17:38:46 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -22,11 +22,15 @@
#include "postgres.h"
#include "parser/gramparse.h"
+#include "parser/parse.h"
#include "parser/parser.h"
List *parsetree; /* result of parsing is left here */
+static int lookahead_token; /* one-token lookahead */
+static bool have_lookahead; /* lookahead_token set? */
+
/*
* raw_parser
@@ -40,6 +44,7 @@ raw_parser(const char *str)
int yyresult;
parsetree = NIL; /* in case grammar forgets to set it */
+ have_lookahead = false;
scanner_init(str);
parser_init();
@@ -53,3 +58,70 @@ raw_parser(const char *str)
return parsetree;
}
+
+
+/*
+ * Intermediate filter between parser and base lexer (base_yylex in scan.l).
+ *
+ * The filter is needed because in some cases the standard SQL grammar
+ * requires more than one token lookahead. We reduce these cases to one-token
+ * lookahead by combining tokens here, in order to keep the grammar LALR(1).
+ *
+ * Using a filter is simpler than trying to recognize multiword tokens
+ * directly in scan.l, because we'd have to allow for comments between the
+ * words. Furthermore it's not clear how to do it without re-introducing
+ * scanner backtrack, which would cost more performance than this filter
+ * layer does.
+ */
+int
+filtered_base_yylex(void)
+{
+ int cur_token;
+
+ /* Get next token --- we might already have it */
+ if (have_lookahead)
+ {
+ cur_token = lookahead_token;
+ have_lookahead = false;
+ }
+ else
+ cur_token = base_yylex();
+
+ /* Do we need to look ahead for a possible multiword token? */
+ switch (cur_token)
+ {
+ case WITH:
+ /*
+ * WITH CASCADED, LOCAL, or CHECK must be reduced to one token
+ *
+ * XXX an alternative way is to recognize just WITH_TIME and
+ * put the ugliness into the datetime datatype productions
+ * instead of WITH CHECK OPTION. However that requires promoting
+ * WITH to a fully reserved word. If we ever have to do that
+ * anyway (perhaps for SQL99 recursive queries), come back and
+ * simplify this code.
+ */
+ lookahead_token = base_yylex();
+ switch (lookahead_token)
+ {
+ case CASCADED:
+ cur_token = WITH_CASCADED;
+ break;
+ case LOCAL:
+ cur_token = WITH_LOCAL;
+ break;
+ case CHECK:
+ cur_token = WITH_CHECK;
+ break;
+ default:
+ have_lookahead = true;
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return cur_token;
+}