Skip to content

Commit 2a4660f

Browse files
committed
Update keyword lists per suggestions by Peter. There are now four
mutually exclusive keyword lists spanning all known keywords --- including AS. Moved COALESCE and a few other ColLabels into the can-be-ColId list.
1 parent 7e422ac commit 2a4660f

File tree

2 files changed

+251
-212
lines changed

2 files changed

+251
-212
lines changed

src/backend/parser/gram.y

Lines changed: 112 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.274 2001/11/12 21:04:45 tgl Exp $
14+
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.275 2001/11/16 04:08:33 tgl Exp $
1515
*
1616
* HISTORY
1717
* AUTHOR DATE MAJOR EVENT
@@ -268,7 +268,8 @@ static void doNegateFloat(Value *v);
268268
%type <ival> Iconst
269269
%type <str> Sconst, comment_text
270270
%type <str> UserId, opt_boolean, var_value, ColId_or_Sconst
271-
%type <str> ColId, TypeFuncId, ColLabel
271+
%type <str> ColId, ColLabel, type_name, func_name_keyword
272+
%type <str> col_name_keyword, unreserved_keyword, reserved_keyword
272273
%type <node> zone_value
273274

274275
%type <node> TableConstraint
@@ -296,8 +297,8 @@ static void doNegateFloat(Value *v);
296297
* This gets annoying when trying to also retain Postgres' nice
297298
* type-extensible features, but we don't really have a choice.
298299
* - thomas 1997-10-11
299-
* NOTE: Whenever possible, try to add new keywords to the ColId list,
300-
* or failing that, at least to the ColLabel list.
300+
* NOTE: don't forget to add new keywords to the appropriate one of
301+
* the reserved-or-not-so-reserved keyword lists, below.
301302
*/
302303

303304
/* Keywords (in SQL92 reserved words) */
@@ -2631,13 +2632,13 @@ func_return: func_type
26312632

26322633
/*
26332634
* We would like to make the second production here be ColId '.' ColId etc,
2634-
* but that causes reduce/reduce conflicts. TypeFuncId is next best choice.
2635+
* but that causes reduce/reduce conflicts. type_name is next best choice.
26352636
*/
26362637
func_type: Typename
26372638
{
26382639
$$ = $1;
26392640
}
2640-
| TypeFuncId '.' ColId '%' TYPE_P
2641+
| type_name '.' ColId '%' TYPE_P
26412642
{
26422643
$$ = makeNode(TypeName);
26432644
$$->name = $1;
@@ -4073,7 +4074,7 @@ ConstTypename: GenericType
40734074
| ConstDatetime
40744075
;
40754076

4076-
GenericType: TypeFuncId
4077+
GenericType: type_name
40774078
{
40784079
$$ = makeNode(TypeName);
40794080
$$->name = xlateSqlType($1);
@@ -5658,22 +5659,61 @@ Iconst: ICONST { $$ = $1; };
56585659
Sconst: SCONST { $$ = $1; };
56595660
UserId: ColId { $$ = $1; };
56605661

5662+
/*
5663+
* Name classification hierarchy.
5664+
*
5665+
* IDENT is the lexeme returned by the lexer for identifiers that match
5666+
* no known keyword. In most cases, we can accept certain keywords as
5667+
* names, not only IDENTs. We prefer to accept as many such keywords
5668+
* as possible to minimize the impact of "reserved words" on programmers.
5669+
* So, we divide names into several possible classes. The classification
5670+
* is chosen in part to make keywords acceptable as names wherever possible.
5671+
*/
5672+
5673+
/* Column identifier --- names that can be column, table, etc names.
5674+
*/
5675+
ColId: IDENT { $$ = $1; }
5676+
| unreserved_keyword { $$ = $1; }
5677+
| col_name_keyword { $$ = $1; }
5678+
;
5679+
5680+
/* Type identifier --- names that can be type names.
5681+
*/
5682+
type_name: IDENT { $$ = $1; }
5683+
| unreserved_keyword { $$ = $1; }
5684+
;
5685+
5686+
/* Function identifier --- names that can be function names.
5687+
*/
5688+
func_name: IDENT { $$ = xlateSqlFunc($1); }
5689+
| unreserved_keyword { $$ = xlateSqlFunc($1); }
5690+
| func_name_keyword { $$ = xlateSqlFunc($1); }
5691+
;
5692+
5693+
/* Column label --- allowed labels in "AS" clauses.
5694+
* This presently includes *all* Postgres keywords.
5695+
*/
5696+
ColLabel: IDENT { $$ = $1; }
5697+
| unreserved_keyword { $$ = $1; }
5698+
| col_name_keyword { $$ = $1; }
5699+
| func_name_keyword { $$ = $1; }
5700+
| reserved_keyword { $$ = $1; }
5701+
;
5702+
5703+
56615704
/*
56625705
* Keyword classification lists. Generally, every keyword present in
5663-
* the Postgres grammar should be in one of these lists. (Presently,
5664-
* "AS" is the sole exception: it is our only completely-reserved word.)
5706+
* the Postgres grammar should appear in exactly one of these lists.
56655707
*
5666-
* Put a new keyword into the earliest list (of TypeFuncId, ColId, ColLabel)
5667-
* that it can go into without creating shift or reduce conflicts. The
5668-
* earlier lists define "less reserved" categories of keywords. Notice that
5669-
* each list includes by reference the ones before it.
5708+
* Put a new keyword into the first list that it can go into without causing
5709+
* shift or reduce conflicts. The earlier lists define "less reserved"
5710+
* categories of keywords.
56705711
*/
56715712

5672-
/* Type/func identifier --- names that can be type and function names
5673-
* (as well as ColIds --- ie, these are completely unreserved keywords).
5713+
/* "Unreserved" keywords --- available for use as any kind of name.
56745714
*/
5675-
TypeFuncId: IDENT { $$ = $1; }
5676-
| ABORT_TRANS { $$ = "abort"; }
5715+
unreserved_keyword:
5716+
ABORT_TRANS { $$ = "abort"; }
56775717
| ABSOLUTE { $$ = "absolute"; }
56785718
| ACCESS { $$ = "access"; }
56795719
| ACTION { $$ = "action"; }
@@ -5829,58 +5869,94 @@ TypeFuncId: IDENT { $$ = $1; }
58295869
| ZONE { $$ = "zone"; }
58305870
;
58315871

5832-
/* Column identifier --- names that can be column, table, etc names.
5872+
/* Column identifier --- keywords that can be column, table, etc names.
58335873
*
5834-
* This contains the TypeFuncId list plus those keywords that conflict
5835-
* only with typename productions, not with other uses. Note that
5836-
* most of these keywords will in fact be recognized as type names too;
5837-
* they just have to have special productions for the purpose.
5874+
* Many of these keywords will in fact be recognized as type or function
5875+
* names too; but they have special productions for the purpose, and so
5876+
* can't be treated as "generic" type or function names.
58385877
*
5839-
* Most of these cannot be in TypeFuncId (ie, are not also usable as function
5840-
* names) because they can be followed by '(' in typename productions, which
5841-
* looks too much like a function call for a LALR(1) parser.
5878+
* The type names appearing here are not usable as function names
5879+
* because they can be followed by '(' in typename productions, which
5880+
* looks too much like a function call for an LR(1) parser.
58425881
*/
5843-
ColId: TypeFuncId { $$ = $1; }
5844-
| BIT { $$ = "bit"; }
5882+
col_name_keyword:
5883+
BIT { $$ = "bit"; }
58455884
| CHAR { $$ = "char"; }
58465885
| CHARACTER { $$ = "character"; }
5886+
| COALESCE { $$ = "coalesce"; }
58475887
| DEC { $$ = "dec"; }
58485888
| DECIMAL { $$ = "decimal"; }
5889+
| EXISTS { $$ = "exists"; }
5890+
| EXTRACT { $$ = "extract"; }
58495891
| FLOAT { $$ = "float"; }
58505892
| INTERVAL { $$ = "interval"; }
58515893
| NCHAR { $$ = "nchar"; }
58525894
| NONE { $$ = "none"; }
5895+
| NULLIF { $$ = "nullif"; }
58535896
| NUMERIC { $$ = "numeric"; }
5897+
| POSITION { $$ = "position"; }
58545898
| SETOF { $$ = "setof"; }
5899+
| SUBSTRING { $$ = "substring"; }
58555900
| TIME { $$ = "time"; }
58565901
| TIMESTAMP { $$ = "timestamp"; }
5902+
| TRIM { $$ = "trim"; }
58575903
| VARCHAR { $$ = "varchar"; }
58585904
;
58595905

5860-
/* Column label --- allowed labels in "AS" clauses.
5906+
/* Function identifier --- keywords that can be function names.
5907+
*
5908+
* Most of these are keywords that are used as operators in expressions;
5909+
* in general such keywords can't be column names because they would be
5910+
* ambiguous with variables, but they are unambiguous as function identifiers.
5911+
*
5912+
* Do not include POSITION, SUBSTRING, etc here since they have explicit
5913+
* productions in a_expr to support the goofy SQL9x argument syntax.
5914+
* - thomas 2000-11-28
5915+
*/
5916+
func_name_keyword:
5917+
BETWEEN { $$ = "between"; }
5918+
| BINARY { $$ = "binary"; }
5919+
| CROSS { $$ = "cross"; }
5920+
| FREEZE { $$ = "freeze"; }
5921+
| FULL { $$ = "full"; }
5922+
| ILIKE { $$ = "ilike"; }
5923+
| IN { $$ = "in"; }
5924+
| INNER_P { $$ = "inner"; }
5925+
| IS { $$ = "is"; }
5926+
| ISNULL { $$ = "isnull"; }
5927+
| JOIN { $$ = "join"; }
5928+
| LEFT { $$ = "left"; }
5929+
| LIKE { $$ = "like"; }
5930+
| NATURAL { $$ = "natural"; }
5931+
| NOTNULL { $$ = "notnull"; }
5932+
| OUTER_P { $$ = "outer"; }
5933+
| OVERLAPS { $$ = "overlaps"; }
5934+
| PUBLIC { $$ = "public"; }
5935+
| RIGHT { $$ = "right"; }
5936+
| VERBOSE { $$ = "verbose"; }
5937+
;
5938+
5939+
/* Reserved keyword --- these keywords are usable only as a ColLabel.
58615940
*
58625941
* Keywords appear here if they could not be distinguished from variable,
5863-
* type, or function names in some contexts.
5864-
* When adding a ColLabel, consider whether it can be added to func_name.
5942+
* type, or function names in some contexts. Don't put things here unless
5943+
* forced to.
58655944
*/
5866-
ColLabel: ColId { $$ = $1; }
5867-
| ALL { $$ = "all"; }
5945+
reserved_keyword:
5946+
ALL { $$ = "all"; }
58685947
| ANALYSE { $$ = "analyse"; } /* British */
58695948
| ANALYZE { $$ = "analyze"; }
58705949
| AND { $$ = "and"; }
58715950
| ANY { $$ = "any"; }
5951+
| AS { $$ = "as"; }
58725952
| ASC { $$ = "asc"; }
5873-
| BETWEEN { $$ = "between"; }
5874-
| BINARY { $$ = "binary"; }
58755953
| BOTH { $$ = "both"; }
58765954
| CASE { $$ = "case"; }
58775955
| CAST { $$ = "cast"; }
58785956
| CHECK { $$ = "check"; }
5879-
| COALESCE { $$ = "coalesce"; }
58805957
| COLLATE { $$ = "collate"; }
58815958
| COLUMN { $$ = "column"; }
58825959
| CONSTRAINT { $$ = "constraint"; }
5883-
| CROSS { $$ = "cross"; }
58845960
| CURRENT_DATE { $$ = "current_date"; }
58855961
| CURRENT_TIME { $$ = "current_time"; }
58865962
| CURRENT_TIMESTAMP { $$ = "current_timestamp"; }
@@ -5893,34 +5969,19 @@ ColLabel: ColId { $$ = $1; }
58935969
| ELSE { $$ = "else"; }
58945970
| END_TRANS { $$ = "end"; }
58955971
| EXCEPT { $$ = "except"; }
5896-
| EXISTS { $$ = "exists"; }
5897-
| EXTRACT { $$ = "extract"; }
58985972
| FALSE_P { $$ = "false"; }
58995973
| FOR { $$ = "for"; }
59005974
| FOREIGN { $$ = "foreign"; }
5901-
| FREEZE { $$ = "freeze"; }
59025975
| FROM { $$ = "from"; }
5903-
| FULL { $$ = "full"; }
59045976
| GROUP { $$ = "group"; }
59055977
| HAVING { $$ = "having"; }
5906-
| ILIKE { $$ = "ilike"; }
5907-
| IN { $$ = "in"; }
59085978
| INITIALLY { $$ = "initially"; }
5909-
| INNER_P { $$ = "inner"; }
59105979
| INTERSECT { $$ = "intersect"; }
59115980
| INTO { $$ = "into"; }
5912-
| IS { $$ = "is"; }
5913-
| ISNULL { $$ = "isnull"; }
5914-
| JOIN { $$ = "join"; }
59155981
| LEADING { $$ = "leading"; }
5916-
| LEFT { $$ = "left"; }
5917-
| LIKE { $$ = "like"; }
59185982
| LIMIT { $$ = "limit"; }
5919-
| NATURAL { $$ = "natural"; }
59205983
| NEW { $$ = "new"; }
59215984
| NOT { $$ = "not"; }
5922-
| NOTNULL { $$ = "notnull"; }
5923-
| NULLIF { $$ = "nullif"; }
59245985
| NULL_P { $$ = "null"; }
59255986
| OFF { $$ = "off"; }
59265987
| OFFSET { $$ = "offset"; }
@@ -5929,65 +5990,24 @@ ColLabel: ColId { $$ = $1; }
59295990
| ONLY { $$ = "only"; }
59305991
| OR { $$ = "or"; }
59315992
| ORDER { $$ = "order"; }
5932-
| OUTER_P { $$ = "outer"; }
5933-
| OVERLAPS { $$ = "overlaps"; }
5934-
| POSITION { $$ = "position"; }
59355993
| PRIMARY { $$ = "primary"; }
5936-
| PUBLIC { $$ = "public"; }
59375994
| REFERENCES { $$ = "references"; }
5938-
| RIGHT { $$ = "right"; }
59395995
| SELECT { $$ = "select"; }
59405996
| SESSION_USER { $$ = "session_user"; }
59415997
| SOME { $$ = "some"; }
5942-
| SUBSTRING { $$ = "substring"; }
59435998
| TABLE { $$ = "table"; }
59445999
| THEN { $$ = "then"; }
59456000
| TO { $$ = "to"; }
59466001
| TRAILING { $$ = "trailing"; }
5947-
| TRIM { $$ = "trim"; }
59486002
| TRUE_P { $$ = "true"; }
59496003
| UNION { $$ = "union"; }
59506004
| UNIQUE { $$ = "unique"; }
59516005
| USER { $$ = "user"; }
59526006
| USING { $$ = "using"; }
5953-
| VERBOSE { $$ = "verbose"; }
59546007
| WHEN { $$ = "when"; }
59556008
| WHERE { $$ = "where"; }
59566009
;
59576010

5958-
/* Function identifier --- names that can be function names.
5959-
*
5960-
* This contains the TypeFuncId list plus some ColLabel keywords
5961-
* that are used as operators in expressions; in general such keywords
5962-
* can't be ColId because they would be ambiguous with variable names,
5963-
* but they are unambiguous as function identifiers.
5964-
*
5965-
* Do not include POSITION, SUBSTRING, etc here since they have explicit
5966-
* productions in a_expr to support the goofy SQL9x argument syntax.
5967-
* - thomas 2000-11-28
5968-
*/
5969-
func_name: TypeFuncId { $$ = xlateSqlFunc($1); }
5970-
| BETWEEN { $$ = xlateSqlFunc("between"); }
5971-
| BINARY { $$ = xlateSqlFunc("binary"); }
5972-
| CROSS { $$ = xlateSqlFunc("cross"); }
5973-
| FREEZE { $$ = xlateSqlFunc("freeze"); }
5974-
| FULL { $$ = xlateSqlFunc("full"); }
5975-
| ILIKE { $$ = xlateSqlFunc("ilike"); }
5976-
| IN { $$ = xlateSqlFunc("in"); }
5977-
| INNER_P { $$ = xlateSqlFunc("inner"); }
5978-
| IS { $$ = xlateSqlFunc("is"); }
5979-
| ISNULL { $$ = xlateSqlFunc("isnull"); }
5980-
| JOIN { $$ = xlateSqlFunc("join"); }
5981-
| LEFT { $$ = xlateSqlFunc("left"); }
5982-
| LIKE { $$ = xlateSqlFunc("like"); }
5983-
| NATURAL { $$ = xlateSqlFunc("natural"); }
5984-
| NOTNULL { $$ = xlateSqlFunc("notnull"); }
5985-
| OUTER_P { $$ = xlateSqlFunc("outer"); }
5986-
| OVERLAPS { $$ = xlateSqlFunc("overlaps"); }
5987-
| PUBLIC { $$ = xlateSqlFunc("public"); }
5988-
| RIGHT { $$ = xlateSqlFunc("right"); }
5989-
| VERBOSE { $$ = xlateSqlFunc("verbose"); }
5990-
;
59916011

59926012
SpecialRuleRelation: OLD
59936013
{

0 commit comments

Comments
 (0)