Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0780ce6

Browse files
committed
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'thave any future use for it. Now it's needed to support disambiguatingWITH CHECK OPTION from WITH TIME ZONE. As proof of concept, add stubgrammar productions for WITH CHECK OPTION.
1 parent51b40f0 commit0780ce6

File tree

4 files changed

+131
-9
lines changed

4 files changed

+131
-9
lines changed

‎src/backend/parser/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#
33
# Makefile for parser
44
#
5-
# $PostgreSQL: pgsql/src/backend/parser/Makefile,v 1.43 2006/03/07 01:00:17 tgl Exp $
5+
# $PostgreSQL: pgsql/src/backend/parser/Makefile,v 1.44 2006/05/27 17:38:45 tgl Exp $
66
#
77
#-------------------------------------------------------------------------
88

@@ -57,7 +57,7 @@ endif
5757

5858

5959
# Force these dependencies to be known even without dependency info built:
60-
gram.okeywords.o:$(srcdir)/parse.h
60+
gram.okeywords.oparser.o:$(srcdir)/parse.h
6161

6262

6363
# gram.c, parse.h, and scan.c are in the distribution tarball, so they

‎src/backend/parser/gram.y

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.544 2006/04/30 18:30:39 tgl Exp $
14+
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.545 2006/05/27 17:38:45 tgl Exp $
1515
*
1616
* HISTORY
1717
* AUTHORDATEMAJOR EVENT
@@ -70,6 +70,12 @@
7070
(Current) = (Rhs)[0]; \
7171
}while (0)
7272

73+
/*
74+
* The %name-prefix option below will make bison call base_yylex, but we
75+
* really want it to call filtered_base_yylex (see parser.c).
76+
*/
77+
#definebase_yylex filtered_base_yylex
78+
7379
extern List *parsetree;/* final parse result is delivered here*/
7480

7581
staticbool QueryIsRule =FALSE;
@@ -339,6 +345,7 @@ static void doNegateFloat(Value *v);
339345
%type<list>constraints_set_list
340346
%type<boolean>constraints_set_mode
341347
%type<str>OptTableSpaceOptConsTableSpaceOptTableSpaceOwner
348+
%type<list>opt_check_option
342349

343350

344351
/*
@@ -356,7 +363,7 @@ static void doNegateFloat(Value *v);
356363
BACKWARD BEFORE BEGIN_P BETWEEN BIGINT BINARY BIT
357364
BOOLEAN_P BOTH BY
358365

359-
CACHE CALLED CASCADE CASE CAST CHAIN CHAR_P
366+
CACHE CALLED CASCADECASCADEDCASE CAST CHAIN CHAR_P
360367
CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
361368
CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
362369
COMMITTED CONNECTION CONSTRAINT CONSTRAINTS CONVERSION_P CONVERT COPY CREATE CREATEDB
@@ -431,6 +438,12 @@ static void doNegateFloat(Value *v);
431438

432439
ZONE
433440

441+
/* The grammar thinks these are keywords, but they are not in the keywords.c
442+
* list and so can never be entered directly. The filter in parser.c
443+
* creates these tokens when required.
444+
*/
445+
%tokenWITH_CASCADEDWITH_LOCALWITH_CHECK
446+
434447
/* Special token types, not actually keywords - see the "lex" file*/
435448
%token<str>IDENTFCONSTSCONSTBCONSTXCONSTOp
436449
%token<ival>ICONSTPARAM
@@ -4618,12 +4631,13 @@ transaction_mode_list_or_empty:
46184631
/*****************************************************************************
46194632
*
46204633
*QUERY:
4621-
*CREATE [ OR REPLACE ] [ TEMP ] VIEW <viewname> '('target-list ')' AS <query>
4634+
*CREATE [ OR REPLACE ] [ TEMP ] VIEW <viewname> '('target-list ')'
4635+
*AS <query> [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
46224636
*
46234637
*****************************************************************************/
46244638

46254639
ViewStmt: CREATE OptTemp VIEW qualified_name opt_column_list
4626-
AS SelectStmt
4640+
AS SelectStmt opt_check_option
46274641
{
46284642
ViewStmt *n = makeNode(ViewStmt);
46294643
n->replace =false;
@@ -4634,7 +4648,7 @@ ViewStmt: CREATE OptTemp VIEW qualified_name opt_column_list
46344648
$$ = (Node *) n;
46354649
}
46364650
| CREATE OR REPLACE OptTemp VIEW qualified_name opt_column_list
4637-
AS SelectStmt
4651+
AS SelectStmt opt_check_option
46384652
{
46394653
ViewStmt *n = makeNode(ViewStmt);
46404654
n->replace =true;
@@ -4646,6 +4660,32 @@ ViewStmt: CREATE OptTemp VIEW qualified_name opt_column_list
46464660
}
46474661
;
46484662

4663+
/*
4664+
* We use merged tokens here to avoid creating shift/reduce conflicts against
4665+
* a whole lot of other uses of WITH.
4666+
*/
4667+
opt_check_option:
4668+
WITH_CHECK OPTION
4669+
{
4670+
ereport(ERROR,
4671+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4672+
errmsg("WITH CHECK OPTION is not implemented")));
4673+
}
4674+
| WITH_CASCADED CHECK OPTION
4675+
{
4676+
ereport(ERROR,
4677+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4678+
errmsg("WITH CHECK OPTION is not implemented")));
4679+
}
4680+
| WITH_LOCAL CHECK OPTION
4681+
{
4682+
ereport(ERROR,
4683+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4684+
errmsg("WITH CHECK OPTION is not implemented")));
4685+
}
4686+
|/* EMPTY*/{$$ = NIL; }
4687+
;
4688+
46494689
/*****************************************************************************
46504690
*
46514691
*QUERY:
@@ -8319,6 +8359,7 @@ unreserved_keyword:
83198359
| CACHE
83208360
| CALLED
83218361
| CASCADE
8362+
| CASCADED
83228363
| CHAIN
83238364
| CHARACTERISTICS
83248365
| CHECKPOINT
@@ -9139,4 +9180,10 @@ doNegateFloat(Value *v)
91399180
}
91409181
}
91419182

9183+
/*
9184+
* Must undefine base_yylex before including scan.c, since we want it
9185+
* to create the function base_yylex not filtered_base_yylex.
9186+
*/
9187+
#undef base_yylex
9188+
91429189
#include "scan.c"

‎src/backend/parser/parser.c

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,23 @@
1414
* Portions Copyright (c) 1994, Regents of the University of California
1515
*
1616
* IDENTIFICATION
17-
* $PostgreSQL: pgsql/src/backend/parser/parser.c,v 1.65 2006/03/07 01:00:17 tgl Exp $
17+
* $PostgreSQL: pgsql/src/backend/parser/parser.c,v 1.66 2006/05/27 17:38:46 tgl Exp $
1818
*
1919
*-------------------------------------------------------------------------
2020
*/
2121

2222
#include"postgres.h"
2323

2424
#include"parser/gramparse.h"
25+
#include"parser/parse.h"
2526
#include"parser/parser.h"
2627

2728

2829
List*parsetree;/* result of parsing is left here */
2930

31+
staticintlookahead_token;/* one-token lookahead */
32+
staticboolhave_lookahead;/* lookahead_token set? */
33+
3034

3135
/*
3236
* raw_parser
@@ -40,6 +44,7 @@ raw_parser(const char *str)
4044
intyyresult;
4145

4246
parsetree=NIL;/* in case grammar forgets to set it */
47+
have_lookahead= false;
4348

4449
scanner_init(str);
4550
parser_init();
@@ -53,3 +58,70 @@ raw_parser(const char *str)
5358

5459
returnparsetree;
5560
}
61+
62+
63+
/*
64+
* Intermediate filter between parser and base lexer (base_yylex in scan.l).
65+
*
66+
* The filter is needed because in some cases the standard SQL grammar
67+
* requires more than one token lookahead. We reduce these cases to one-token
68+
* lookahead by combining tokens here, in order to keep the grammar LALR(1).
69+
*
70+
* Using a filter is simpler than trying to recognize multiword tokens
71+
* directly in scan.l, because we'd have to allow for comments between the
72+
* words. Furthermore it's not clear how to do it without re-introducing
73+
* scanner backtrack, which would cost more performance than this filter
74+
* layer does.
75+
*/
76+
int
77+
filtered_base_yylex(void)
78+
{
79+
intcur_token;
80+
81+
/* Get next token --- we might already have it */
82+
if (have_lookahead)
83+
{
84+
cur_token=lookahead_token;
85+
have_lookahead= false;
86+
}
87+
else
88+
cur_token=base_yylex();
89+
90+
/* Do we need to look ahead for a possible multiword token? */
91+
switch (cur_token)
92+
{
93+
caseWITH:
94+
/*
95+
* WITH CASCADED, LOCAL, or CHECK must be reduced to one token
96+
*
97+
* XXX an alternative way is to recognize just WITH_TIME and
98+
* put the ugliness into the datetime datatype productions
99+
* instead of WITH CHECK OPTION. However that requires promoting
100+
* WITH to a fully reserved word. If we ever have to do that
101+
* anyway (perhaps for SQL99 recursive queries), come back and
102+
* simplify this code.
103+
*/
104+
lookahead_token=base_yylex();
105+
switch (lookahead_token)
106+
{
107+
caseCASCADED:
108+
cur_token=WITH_CASCADED;
109+
break;
110+
caseLOCAL:
111+
cur_token=WITH_LOCAL;
112+
break;
113+
caseCHECK:
114+
cur_token=WITH_CHECK;
115+
break;
116+
default:
117+
have_lookahead= true;
118+
break;
119+
}
120+
break;
121+
122+
default:
123+
break;
124+
}
125+
126+
returncur_token;
127+
}

‎src/include/parser/gramparse.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/parser/gramparse.h,v 1.36 2006/05/21 20:10:42 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/parser/gramparse.h,v 1.37 2006/05/27 17:38:46 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -40,6 +40,9 @@ extern bool escape_string_warning;
4040
externboolstandard_conforming_strings;
4141

4242

43+
/* from parser.c */
44+
externintfiltered_base_yylex(void);
45+
4346
/* from scan.l */
4447
externvoidscanner_init(constchar*str);
4548
externvoidscanner_finish(void);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp