From 2a4660f5aa325b1e3876f9a8759beb6228f7dbb6 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 16 Nov 2001 04:08:33 +0000 Subject: [PATCH] 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. --- src/backend/parser/gram.y | 204 +++++++++++--------- src/interfaces/ecpg/preproc/preproc.y | 259 ++++++++++++++------------ 2 files changed, 251 insertions(+), 212 deletions(-) diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 5a2324de20..b3b09c068f 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.274 2001/11/12 21:04:45 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.275 2001/11/16 04:08:33 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -268,7 +268,8 @@ static void doNegateFloat(Value *v); %type Iconst %type Sconst, comment_text %type UserId, opt_boolean, var_value, ColId_or_Sconst -%type ColId, TypeFuncId, ColLabel +%type ColId, ColLabel, type_name, func_name_keyword +%type col_name_keyword, unreserved_keyword, reserved_keyword %type zone_value %type TableConstraint @@ -296,8 +297,8 @@ static void doNegateFloat(Value *v); * This gets annoying when trying to also retain Postgres' nice * type-extensible features, but we don't really have a choice. * - thomas 1997-10-11 - * NOTE: Whenever possible, try to add new keywords to the ColId list, - * or failing that, at least to the ColLabel list. + * NOTE: don't forget to add new keywords to the appropriate one of + * the reserved-or-not-so-reserved keyword lists, below. */ /* Keywords (in SQL92 reserved words) */ @@ -2631,13 +2632,13 @@ func_return: func_type /* * We would like to make the second production here be ColId '.' ColId etc, - * but that causes reduce/reduce conflicts. TypeFuncId is next best choice. + * but that causes reduce/reduce conflicts. type_name is next best choice. */ func_type: Typename { $$ = $1; } - | TypeFuncId '.' ColId '%' TYPE_P + | type_name '.' ColId '%' TYPE_P { $$ = makeNode(TypeName); $$->name = $1; @@ -4073,7 +4074,7 @@ ConstTypename: GenericType | ConstDatetime ; -GenericType: TypeFuncId +GenericType: type_name { $$ = makeNode(TypeName); $$->name = xlateSqlType($1); @@ -5658,22 +5659,61 @@ Iconst: ICONST { $$ = $1; }; Sconst: SCONST { $$ = $1; }; UserId: ColId { $$ = $1; }; +/* + * Name classification hierarchy. + * + * IDENT is the lexeme returned by the lexer for identifiers that match + * no known keyword. In most cases, we can accept certain keywords as + * names, not only IDENTs. We prefer to accept as many such keywords + * as possible to minimize the impact of "reserved words" on programmers. + * So, we divide names into several possible classes. The classification + * is chosen in part to make keywords acceptable as names wherever possible. + */ + +/* Column identifier --- names that can be column, table, etc names. + */ +ColId: IDENT { $$ = $1; } + | unreserved_keyword { $$ = $1; } + | col_name_keyword { $$ = $1; } + ; + +/* Type identifier --- names that can be type names. + */ +type_name: IDENT { $$ = $1; } + | unreserved_keyword { $$ = $1; } + ; + +/* Function identifier --- names that can be function names. + */ +func_name: IDENT { $$ = xlateSqlFunc($1); } + | unreserved_keyword { $$ = xlateSqlFunc($1); } + | func_name_keyword { $$ = xlateSqlFunc($1); } + ; + +/* Column label --- allowed labels in "AS" clauses. + * This presently includes *all* Postgres keywords. + */ +ColLabel: IDENT { $$ = $1; } + | unreserved_keyword { $$ = $1; } + | col_name_keyword { $$ = $1; } + | func_name_keyword { $$ = $1; } + | reserved_keyword { $$ = $1; } + ; + + /* * Keyword classification lists. Generally, every keyword present in - * the Postgres grammar should be in one of these lists. (Presently, - * "AS" is the sole exception: it is our only completely-reserved word.) + * the Postgres grammar should appear in exactly one of these lists. * - * Put a new keyword into the earliest list (of TypeFuncId, ColId, ColLabel) - * that it can go into without creating shift or reduce conflicts. The - * earlier lists define "less reserved" categories of keywords. Notice that - * each list includes by reference the ones before it. + * Put a new keyword into the first list that it can go into without causing + * shift or reduce conflicts. The earlier lists define "less reserved" + * categories of keywords. */ -/* Type/func identifier --- names that can be type and function names - * (as well as ColIds --- ie, these are completely unreserved keywords). +/* "Unreserved" keywords --- available for use as any kind of name. */ -TypeFuncId: IDENT { $$ = $1; } - | ABORT_TRANS { $$ = "abort"; } +unreserved_keyword: + ABORT_TRANS { $$ = "abort"; } | ABSOLUTE { $$ = "absolute"; } | ACCESS { $$ = "access"; } | ACTION { $$ = "action"; } @@ -5829,58 +5869,94 @@ TypeFuncId: IDENT { $$ = $1; } | ZONE { $$ = "zone"; } ; -/* Column identifier --- names that can be column, table, etc names. +/* Column identifier --- keywords that can be column, table, etc names. * - * This contains the TypeFuncId list plus those keywords that conflict - * only with typename productions, not with other uses. Note that - * most of these keywords will in fact be recognized as type names too; - * they just have to have special productions for the purpose. + * Many of these keywords will in fact be recognized as type or function + * names too; but they have special productions for the purpose, and so + * can't be treated as "generic" type or function names. * - * Most of these cannot be in TypeFuncId (ie, are not also usable as function - * names) because they can be followed by '(' in typename productions, which - * looks too much like a function call for a LALR(1) parser. + * The type names appearing here are not usable as function names + * because they can be followed by '(' in typename productions, which + * looks too much like a function call for an LR(1) parser. */ -ColId: TypeFuncId { $$ = $1; } - | BIT { $$ = "bit"; } +col_name_keyword: + BIT { $$ = "bit"; } | CHAR { $$ = "char"; } | CHARACTER { $$ = "character"; } + | COALESCE { $$ = "coalesce"; } | DEC { $$ = "dec"; } | DECIMAL { $$ = "decimal"; } + | EXISTS { $$ = "exists"; } + | EXTRACT { $$ = "extract"; } | FLOAT { $$ = "float"; } | INTERVAL { $$ = "interval"; } | NCHAR { $$ = "nchar"; } | NONE { $$ = "none"; } + | NULLIF { $$ = "nullif"; } | NUMERIC { $$ = "numeric"; } + | POSITION { $$ = "position"; } | SETOF { $$ = "setof"; } + | SUBSTRING { $$ = "substring"; } | TIME { $$ = "time"; } | TIMESTAMP { $$ = "timestamp"; } + | TRIM { $$ = "trim"; } | VARCHAR { $$ = "varchar"; } ; -/* Column label --- allowed labels in "AS" clauses. +/* Function identifier --- keywords that can be function names. + * + * Most of these are keywords that are used as operators in expressions; + * in general such keywords can't be column names because they would be + * ambiguous with variables, but they are unambiguous as function identifiers. + * + * Do not include POSITION, SUBSTRING, etc here since they have explicit + * productions in a_expr to support the goofy SQL9x argument syntax. + * - thomas 2000-11-28 + */ +func_name_keyword: + BETWEEN { $$ = "between"; } + | BINARY { $$ = "binary"; } + | CROSS { $$ = "cross"; } + | FREEZE { $$ = "freeze"; } + | FULL { $$ = "full"; } + | ILIKE { $$ = "ilike"; } + | IN { $$ = "in"; } + | INNER_P { $$ = "inner"; } + | IS { $$ = "is"; } + | ISNULL { $$ = "isnull"; } + | JOIN { $$ = "join"; } + | LEFT { $$ = "left"; } + | LIKE { $$ = "like"; } + | NATURAL { $$ = "natural"; } + | NOTNULL { $$ = "notnull"; } + | OUTER_P { $$ = "outer"; } + | OVERLAPS { $$ = "overlaps"; } + | PUBLIC { $$ = "public"; } + | RIGHT { $$ = "right"; } + | VERBOSE { $$ = "verbose"; } + ; + +/* Reserved keyword --- these keywords are usable only as a ColLabel. * * Keywords appear here if they could not be distinguished from variable, - * type, or function names in some contexts. - * When adding a ColLabel, consider whether it can be added to func_name. + * type, or function names in some contexts. Don't put things here unless + * forced to. */ -ColLabel: ColId { $$ = $1; } - | ALL { $$ = "all"; } +reserved_keyword: + ALL { $$ = "all"; } | ANALYSE { $$ = "analyse"; } /* British */ | ANALYZE { $$ = "analyze"; } | AND { $$ = "and"; } | ANY { $$ = "any"; } + | AS { $$ = "as"; } | ASC { $$ = "asc"; } - | BETWEEN { $$ = "between"; } - | BINARY { $$ = "binary"; } | BOTH { $$ = "both"; } | CASE { $$ = "case"; } | CAST { $$ = "cast"; } | CHECK { $$ = "check"; } - | COALESCE { $$ = "coalesce"; } | COLLATE { $$ = "collate"; } | COLUMN { $$ = "column"; } | CONSTRAINT { $$ = "constraint"; } - | CROSS { $$ = "cross"; } | CURRENT_DATE { $$ = "current_date"; } | CURRENT_TIME { $$ = "current_time"; } | CURRENT_TIMESTAMP { $$ = "current_timestamp"; } @@ -5893,34 +5969,19 @@ ColLabel: ColId { $$ = $1; } | ELSE { $$ = "else"; } | END_TRANS { $$ = "end"; } | EXCEPT { $$ = "except"; } - | EXISTS { $$ = "exists"; } - | EXTRACT { $$ = "extract"; } | FALSE_P { $$ = "false"; } | FOR { $$ = "for"; } | FOREIGN { $$ = "foreign"; } - | FREEZE { $$ = "freeze"; } | FROM { $$ = "from"; } - | FULL { $$ = "full"; } | GROUP { $$ = "group"; } | HAVING { $$ = "having"; } - | ILIKE { $$ = "ilike"; } - | IN { $$ = "in"; } | INITIALLY { $$ = "initially"; } - | INNER_P { $$ = "inner"; } | INTERSECT { $$ = "intersect"; } | INTO { $$ = "into"; } - | IS { $$ = "is"; } - | ISNULL { $$ = "isnull"; } - | JOIN { $$ = "join"; } | LEADING { $$ = "leading"; } - | LEFT { $$ = "left"; } - | LIKE { $$ = "like"; } | LIMIT { $$ = "limit"; } - | NATURAL { $$ = "natural"; } | NEW { $$ = "new"; } | NOT { $$ = "not"; } - | NOTNULL { $$ = "notnull"; } - | NULLIF { $$ = "nullif"; } | NULL_P { $$ = "null"; } | OFF { $$ = "off"; } | OFFSET { $$ = "offset"; } @@ -5929,65 +5990,24 @@ ColLabel: ColId { $$ = $1; } | ONLY { $$ = "only"; } | OR { $$ = "or"; } | ORDER { $$ = "order"; } - | OUTER_P { $$ = "outer"; } - | OVERLAPS { $$ = "overlaps"; } - | POSITION { $$ = "position"; } | PRIMARY { $$ = "primary"; } - | PUBLIC { $$ = "public"; } | REFERENCES { $$ = "references"; } - | RIGHT { $$ = "right"; } | SELECT { $$ = "select"; } | SESSION_USER { $$ = "session_user"; } | SOME { $$ = "some"; } - | SUBSTRING { $$ = "substring"; } | TABLE { $$ = "table"; } | THEN { $$ = "then"; } | TO { $$ = "to"; } | TRAILING { $$ = "trailing"; } - | TRIM { $$ = "trim"; } | TRUE_P { $$ = "true"; } | UNION { $$ = "union"; } | UNIQUE { $$ = "unique"; } | USER { $$ = "user"; } | USING { $$ = "using"; } - | VERBOSE { $$ = "verbose"; } | WHEN { $$ = "when"; } | WHERE { $$ = "where"; } ; -/* Function identifier --- names that can be function names. - * - * This contains the TypeFuncId list plus some ColLabel keywords - * that are used as operators in expressions; in general such keywords - * can't be ColId because they would be ambiguous with variable names, - * but they are unambiguous as function identifiers. - * - * Do not include POSITION, SUBSTRING, etc here since they have explicit - * productions in a_expr to support the goofy SQL9x argument syntax. - * - thomas 2000-11-28 - */ -func_name: TypeFuncId { $$ = xlateSqlFunc($1); } - | BETWEEN { $$ = xlateSqlFunc("between"); } - | BINARY { $$ = xlateSqlFunc("binary"); } - | CROSS { $$ = xlateSqlFunc("cross"); } - | FREEZE { $$ = xlateSqlFunc("freeze"); } - | FULL { $$ = xlateSqlFunc("full"); } - | ILIKE { $$ = xlateSqlFunc("ilike"); } - | IN { $$ = xlateSqlFunc("in"); } - | INNER_P { $$ = xlateSqlFunc("inner"); } - | IS { $$ = xlateSqlFunc("is"); } - | ISNULL { $$ = xlateSqlFunc("isnull"); } - | JOIN { $$ = xlateSqlFunc("join"); } - | LEFT { $$ = xlateSqlFunc("left"); } - | LIKE { $$ = xlateSqlFunc("like"); } - | NATURAL { $$ = xlateSqlFunc("natural"); } - | NOTNULL { $$ = xlateSqlFunc("notnull"); } - | OUTER_P { $$ = xlateSqlFunc("outer"); } - | OVERLAPS { $$ = xlateSqlFunc("overlaps"); } - | PUBLIC { $$ = xlateSqlFunc("public"); } - | RIGHT { $$ = xlateSqlFunc("right"); } - | VERBOSE { $$ = xlateSqlFunc("verbose"); } - ; SpecialRuleRelation: OLD { diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y index 04296d42aa..edb8941de8 100644 --- a/src/interfaces/ecpg/preproc/preproc.y +++ b/src/interfaces/ecpg/preproc/preproc.y @@ -279,7 +279,7 @@ make_name(void) %type key_match ColLabel SpecialRuleRelation ColId columnDef %type ColConstraint ColConstraintElem drop_type Bitconst %type OptTableElementList OptTableElement TableConstraint -%type ConstraintElem key_actions ColQualList TypeFuncId DropSchemaStmt +%type ConstraintElem key_actions ColQualList type_name DropSchemaStmt %type target_list target_el update_target_list alias_clause %type update_target_el opt_id relation_name database_name %type access_method attr_name class index_name name func_name @@ -357,7 +357,9 @@ make_name(void) %type struct_type s_struct declaration declarations variable_declarations %type s_union union_type ECPGSetAutocommit on_off %type ECPGAllocateDescr ECPGDeallocateDescr symbol opt_symbol -%type ECPGGetDescriptorHeader ECPGTypeFuncId ECPGColId ECPGColLabel +%type ECPGGetDescriptorHeader ECPGColLabel +%type reserved_keyword unreserved_keyword +%type col_name_keyword func_name_keyword %type ECPGTypeName variablelist cvariable %type ECPGGetDescriptor @@ -1964,7 +1966,7 @@ func_type: Typename { $$ = $1; } - | TypeFuncId '.' ColId '%' TYPE_P + | type_name '.' ColId '%' TYPE_P { $$ = cat_str(4, $1, make_str("."), $3, make_str("% type")); } @@ -2978,8 +2980,7 @@ ConstTypename: Generic { $$ = $1; } | Character { $$ = $1; } ; -Generic: TypeFuncId { $$ = $1; } - | ECPGTypeName { $$ = $1; } +Generic: type_name { $$ = $1; } ; /* SQL92 numeric data types @@ -4874,48 +4875,48 @@ action : SQL_CONTINUE /* some other stuff for ecpg */ -/* additional ColId entries */ -ECPGKeywords: SQL_BREAK { $$ = make_str("break"); } - | SQL_CALL { $$ = make_str("call"); } - | SQL_CARDINALITY { $$ = make_str("cardinality"); } +/* additional unreserved keywords */ +ECPGKeywords: SQL_BREAK { $$ = make_str("break"); } + | SQL_CALL { $$ = make_str("call"); } + | SQL_CARDINALITY { $$ = make_str("cardinality"); } | SQL_CONNECT { $$ = make_str("connect"); } | SQL_CONTINUE { $$ = make_str("continue"); } - | SQL_COUNT { $$ = make_str("count"); } - | SQL_DATA { $$ = make_str("data"); } + | SQL_COUNT { $$ = make_str("count"); } + | SQL_DATA { $$ = make_str("data"); } | SQL_DATETIME_INTERVAL_CODE { $$ = make_str("datetime_interval_code"); } | SQL_DATETIME_INTERVAL_PRECISION { $$ = make_str("datetime_interval_precision"); } | SQL_DEALLOCATE { $$ = make_str("deallocate"); } | SQL_DISCONNECT { $$ = make_str("disconnect"); } - | SQL_FOUND { $$ = make_str("found"); } - | SQL_GO { $$ = make_str("go"); } - | SQL_GOTO { $$ = make_str("goto"); } + | SQL_FOUND { $$ = make_str("found"); } + | SQL_GO { $$ = make_str("go"); } + | SQL_GOTO { $$ = make_str("goto"); } | SQL_IDENTIFIED { $$ = make_str("identified"); } | SQL_INDICATOR { $$ = make_str("indicator"); } | SQL_KEY_MEMBER { $$ = make_str("key_member"); } | SQL_LENGTH { $$ = make_str("length"); } - | SQL_NAME { $$ = make_str("name"); } + | SQL_NAME { $$ = make_str("name"); } | SQL_NULLABLE { $$ = make_str("nullable"); } | SQL_OCTET_LENGTH { $$ = make_str("octet_length"); } - | SQL_OPEN { $$ = make_str("open"); } + | SQL_OPEN { $$ = make_str("open"); } | SQL_PREPARE { $$ = make_str("prepare"); } | SQL_RELEASE { $$ = make_str("release"); } | SQL_RETURNED_LENGTH { $$ = make_str("returned_length"); } | SQL_RETURNED_OCTET_LENGTH { $$ = make_str("returned_octet_length"); } - | SQL_SCALE { $$ = make_str("scale"); } + | SQL_SCALE { $$ = make_str("scale"); } | SQL_SECTION { $$ = make_str("section"); } | SQL_SQLERROR { $$ = make_str("sqlerror"); } | SQL_SQLPRINT { $$ = make_str("sqlprint"); } | SQL_SQLWARNING { $$ = make_str("sqlwarning"); } - | SQL_STOP { $$ = make_str("stop"); } - | SQL_VAR { $$ = make_str("var"); } + | SQL_STOP { $$ = make_str("stop"); } + | SQL_VAR { $$ = make_str("var"); } | SQL_WHENEVER { $$ = make_str("whenever"); } -/* | ECPGTypeName { $$ = $1 }*/ ; -ECPGTypeName: SQL_BOOL { $$ = make_str("bool"); } - | SQL_INT { $$ = make_str("int"); } - | SQL_LONG { $$ = make_str("long"); } - | SQL_SHORT { $$ = make_str("short"); } +/* additional keywords that can be SQL type names (but not ECPGColLabels) */ +ECPGTypeName: SQL_BOOL { $$ = make_str("bool"); } + | SQL_INT { $$ = make_str("int"); } + | SQL_LONG { $$ = make_str("long"); } + | SQL_SHORT { $$ = make_str("short"); } | SQL_STRUCT { $$ = make_str("struct"); } | SQL_SIGNED { $$ = make_str("signed"); } | SQL_UNSIGNED { $$ = make_str("unsigned"); } @@ -4928,25 +4929,72 @@ opt_symbol: symbol { $$ = $1; } symbol: ColLabel { $$ = $1; }; /* - * Keyword classification lists. Generally, every keyword present in - * the Postgres grammar should be in one of these lists. (Presently, - * "AS" is the sole exception: it is our only completely-reserved word.) - * - * Put a new keyword into the earliest list (of TypeFuncId, ColId, ColLabel) - * that it can go into without creating shift or reduce conflicts. The - * earlier lists define "less reserved" categories of keywords. Notice that - * each list includes by reference the ones before it. + * Name classification hierarchy. + * + * IDENT is the lexeme returned by the lexer for identifiers that match + * no known keyword. In most cases, we can accept certain keywords as + * names, not only IDENTs. We prefer to accept as many such keywords + * as possible to minimize the impact of "reserved words" on programmers. + * So, we divide names into several possible classes. The classification + * is chosen in part to make keywords acceptable as names wherever possible. + */ + +/* Column identifier --- names that can be column, table, etc names. + */ +ColId: ident { $$ = $1; } + | unreserved_keyword { $$ = $1; } + | col_name_keyword { $$ = $1; } + | ECPGKeywords { $$ = $1; } + | CHAR { $$ = make_str("char"); } + ; + +/* Type identifier --- names that can be type names. + */ +type_name: ident { $$ = $1; } + | unreserved_keyword { $$ = $1; } + | ECPGKeywords { $$ = $1; } + | ECPGTypeName { $$ = $1; } + ; + +/* Function identifier --- names that can be function names. */ +func_name: ident { $$ = $1; } + | unreserved_keyword { $$ = $1; } + | func_name_keyword { $$ = $1; } + | ECPGKeywords { $$ = $1; } + ; -/* Type/func identifier --- names that can be type and function names - * (as well as ColIds --- ie, these are completely unreserved keywords). +/* Column label --- allowed labels in "AS" clauses. + * This presently includes *all* Postgres keywords. */ -TypeFuncId: ECPGTypeFuncId { $$ = $1; } +ColLabel: ECPGColLabel { $$ = $1; } + | ECPGTypeName { $$ = $1; } + | CHAR { $$ = make_str("char"); } + | UNION { $$ = make_str("union"); } + ; + +ECPGColLabel: ident { $$ = $1; } + | unreserved_keyword { $$ = $1; } + | col_name_keyword { $$ = $1; } + | func_name_keyword { $$ = $1; } + | reserved_keyword { $$ = $1; } | ECPGKeywords { $$ = $1; } ; -ECPGTypeFuncId: ident { $$ = $1; } - | ABORT_TRANS { $$ = make_str("abort"); } + +/* + * Keyword classification lists. Generally, every keyword present in + * the Postgres grammar should appear in exactly one of these lists. + * + * Put a new keyword into the first list that it can go into without causing + * shift or reduce conflicts. The earlier lists define "less reserved" + * categories of keywords. + */ + +/* "Unreserved" keywords --- available for use as any kind of name. + */ +unreserved_keyword: + ABORT_TRANS { $$ = make_str("abort"); } | ABSOLUTE { $$ = make_str("absolute"); } | ACCESS { $$ = make_str("access"); } | ACTION { $$ = make_str("action"); } @@ -5102,69 +5150,96 @@ ECPGTypeFuncId: ident { $$ = $1; } | ZONE { $$ = make_str("zone"); } ; -/* Column identifier --- names that can be column, table, etc names. +/* Column identifier --- keywords that can be column, table, etc names. * - * This contains the TypeFuncId list plus those keywords that conflict - * only with typename productions, not with other uses. Note that - * most of these keywords will in fact be recognized as type names too; - * they just have to have special productions for the purpose. + * Many of these keywords will in fact be recognized as type or function + * names too; but they have special productions for the purpose, and so + * can't be treated as "generic" type or function names. * - * Most of these cannot be in TypeFuncId (ie, are not also usable as function - * names) because they can be followed by '(' in typename productions, which - * looks too much like a function call for a LALR(1) parser. + * The type names appearing here are not usable as function names + * because they can be followed by '(' in typename productions, which + * looks too much like a function call for an LR(1) parser. */ -ColId: ECPGColId { $$ = $1; } - | CHAR { $$ = make_str("char"); } - ; - -ECPGColId: TypeFuncId { $$ = $1; } - | BIT { $$ = make_str("bit"); } +col_name_keyword: + BIT { $$ = make_str("bit"); } /* CHAR must be excluded from ECPGColLabel because of conflict with UNSIGNED | CHAR { $$ = make_str("char"); } */ | CHARACTER { $$ = make_str("character"); } + | COALESCE { $$ = make_str("coalesce"); } | DEC { $$ = make_str("dec"); } | DECIMAL { $$ = make_str("decimal"); } + | EXISTS { $$ = make_str("exists"); } + | EXTRACT { $$ = make_str("extract"); } | FLOAT { $$ = make_str("float"); } | INTERVAL { $$ = make_str("interval"); } | NCHAR { $$ = make_str("nchar"); } | NONE { $$ = make_str("none"); } + | NULLIF { $$ = make_str("nullif"); } | NUMERIC { $$ = make_str("numeric"); } + | POSITION { $$ = make_str("position"); } | SETOF { $$ = make_str("setof"); } + | SUBSTRING { $$ = make_str("substring"); } | TIME { $$ = make_str("time"); } | TIMESTAMP { $$ = make_str("timestamp"); } + | TRIM { $$ = make_str("trim"); } | VARCHAR { $$ = make_str("varchar"); } ; -/* Column label --- allowed labels in "AS" clauses. +/* Function identifier --- keywords that can be function names. * - * Keywords appear here if they could not be distinguished from variable, - * type, or function names in some contexts. - * When adding a ColLabel, consider whether it can be added to func_name. + * Most of these are keywords that are used as operators in expressions; + * in general such keywords can't be column names because they would be + * ambiguous with variables, but they are unambiguous as function identifiers. + * + * Do not include POSITION, SUBSTRING, etc here since they have explicit + * productions in a_expr to support the goofy SQL9x argument syntax. + * - thomas 2000-11-28 */ -ColLabel: ECPGColLabel { $$ = $1; } - | CHAR { $$ = make_str("char"); } - | UNION { $$ = make_str("union"); } +func_name_keyword: + BETWEEN { $$ = make_str("between"); } + | BINARY { $$ = make_str("binary"); } + | CROSS { $$ = make_str("cross"); } + | FREEZE { $$ = make_str("freeze"); } + | FULL { $$ = make_str("full"); } + | ILIKE { $$ = make_str("ilike"); } + | IN { $$ = make_str("in"); } + | INNER_P { $$ = make_str("inner"); } + | IS { $$ = make_str("is"); } + | ISNULL { $$ = make_str("isnull"); } + | JOIN { $$ = make_str("join"); } + | LEFT { $$ = make_str("left"); } + | LIKE { $$ = make_str("like"); } + | NATURAL { $$ = make_str("natural"); } + | NOTNULL { $$ = make_str("notnull"); } + | OUTER_P { $$ = make_str("outer"); } + | OVERLAPS { $$ = make_str("overlaps"); } + | PUBLIC { $$ = make_str("public"); } + | RIGHT { $$ = make_str("right"); } + | VERBOSE { $$ = make_str("verbose"); } ; -ECPGColLabel: ECPGColId { $$ = $1; } - | ALL { $$ = make_str("all"); } +/* Reserved keyword --- these keywords are usable only as a ColLabel. + * + * Keywords appear here if they could not be distinguished from variable, + * type, or function names in some contexts. Don't put things here unless + * forced to. + */ +reserved_keyword: + ALL { $$ = make_str("all"); } | ANALYSE { $$ = make_str("analyse"); } /* British */ | ANALYZE { $$ = make_str("analyze"); } | AND { $$ = make_str("and"); } | ANY { $$ = make_str("any"); } + | AS { $$ = make_str("as"); } | ASC { $$ = make_str("asc"); } - | BETWEEN { $$ = make_str("between"); } - | BINARY { $$ = make_str("binary"); } | BOTH { $$ = make_str("both"); } | CASE { $$ = make_str("case"); } | CAST { $$ = make_str("cast"); } | CHECK { $$ = make_str("check"); } - | COALESCE { $$ = make_str("coalesce"); } | COLLATE { $$ = make_str("collate"); } | COLUMN { $$ = make_str("column"); } | CONSTRAINT { $$ = make_str("constraint"); } - | CROSS { $$ = make_str("cross"); } | CURRENT_DATE { $$ = make_str("current_date"); } | CURRENT_TIME { $$ = make_str("current_time"); } | CURRENT_TIMESTAMP { $$ = make_str("current_timestamp"); } @@ -5177,34 +5252,19 @@ ECPGColLabel: ECPGColId { $$ = $1; } | ELSE { $$ = make_str("else"); } | END_TRANS { $$ = make_str("end"); } | EXCEPT { $$ = make_str("except"); } - | EXISTS { $$ = make_str("exists"); } - | EXTRACT { $$ = make_str("extract"); } | FALSE_P { $$ = make_str("false"); } | FOR { $$ = make_str("for"); } | FOREIGN { $$ = make_str("foreign"); } - | FREEZE { $$ = make_str("freeze"); } | FROM { $$ = make_str("from"); } - | FULL { $$ = make_str("full"); } | GROUP { $$ = make_str("group"); } | HAVING { $$ = make_str("having"); } - | ILIKE { $$ = make_str("ilike"); } - | IN { $$ = make_str("in"); } | INITIALLY { $$ = make_str("initially"); } - | INNER_P { $$ = make_str("inner"); } | INTERSECT { $$ = make_str("intersect"); } | INTO { $$ = make_str("into"); } - | IS { $$ = make_str("is"); } - | ISNULL { $$ = make_str("isnull"); } - | JOIN { $$ = make_str("join"); } | LEADING { $$ = make_str("leading"); } - | LEFT { $$ = make_str("left"); } - | LIKE { $$ = make_str("like"); } | LIMIT { $$ = make_str("limit"); } - | NATURAL { $$ = make_str("natural"); } | NEW { $$ = make_str("new"); } | NOT { $$ = make_str("not"); } - | NOTNULL { $$ = make_str("notnull"); } - | NULLIF { $$ = make_str("nullif"); } | NULL_P { $$ = make_str("null"); } | OFF { $$ = make_str("off"); } | OFFSET { $$ = make_str("offset"); } @@ -5213,22 +5273,15 @@ ECPGColLabel: ECPGColId { $$ = $1; } | ONLY { $$ = make_str("only"); } | OR { $$ = make_str("or"); } | ORDER { $$ = make_str("order"); } - | OUTER_P { $$ = make_str("outer"); } - | OVERLAPS { $$ = make_str("overlaps"); } - | POSITION { $$ = make_str("position"); } | PRIMARY { $$ = make_str("primary"); } - | PUBLIC { $$ = make_str("public"); } | REFERENCES { $$ = make_str("references"); } - | RIGHT { $$ = make_str("right"); } | SELECT { $$ = make_str("select"); } | SESSION_USER { $$ = make_str("session_user"); } | SOME { $$ = make_str("some"); } - | SUBSTRING { $$ = make_str("substring"); } | TABLE { $$ = make_str("table"); } | THEN { $$ = make_str("then"); } | TO { $$ = make_str("to"); } | TRAILING { $$ = make_str("trailing"); } - | TRIM { $$ = make_str("trim"); } | TRUE_P { $$ = make_str("true"); } /* UNION must be excluded from ECPGColLabel because of conflict with s_union | UNION { $$ = make_str("union"); } @@ -5236,44 +5289,10 @@ ECPGColLabel: ECPGColId { $$ = $1; } | UNIQUE { $$ = make_str("unique"); } | USER { $$ = make_str("user"); } | USING { $$ = make_str("using"); } - | VERBOSE { $$ = make_str("verbose"); } | WHEN { $$ = make_str("when"); } | WHERE { $$ = make_str("where"); } ; -/* Function identifier --- names that can be function names. - * - * This contains the TypeFuncId list plus some ColLabel keywords - * that are used as operators in expressions; in general such keywords - * can't be ColId because they would be ambiguous with variable names, - * but they are unambiguous as function identifiers. - * - * Do not include POSITION, SUBSTRING, etc here since they have explicit - * productions in a_expr to support the goofy SQL9x argument syntax. - * - thomas 2000-11-28 - */ -func_name: TypeFuncId { $$ = $1; } - | BETWEEN { $$ = make_str("between"); } - | BINARY { $$ = make_str("binary"); } - | CROSS { $$ = make_str("cross"); } - | FREEZE { $$ = make_str("freeze"); } - | FULL { $$ = make_str("full"); } - | ILIKE { $$ = make_str("ilike"); } - | IN { $$ = make_str("in"); } - | INNER_P { $$ = make_str("inner"); } - | IS { $$ = make_str("is"); } - | ISNULL { $$ = make_str("isnull"); } - | JOIN { $$ = make_str("join"); } - | LEFT { $$ = make_str("left"); } - | LIKE { $$ = make_str("like"); } - | NATURAL { $$ = make_str("natural"); } - | NOTNULL { $$ = make_str("notnull"); } - | OUTER_P { $$ = make_str("outer"); } - | OVERLAPS { $$ = make_str("overlaps"); } - | PUBLIC { $$ = make_str("public"); } - | RIGHT { $$ = make_str("right"); } - | VERBOSE { $$ = make_str("verbose"); } - ; into_list : coutputvariable | into_list ',' coutputvariable; -- 2.40.0