diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 63465c916861ce5d257989489aa753b7edd2282e..6c6b7e359c9d9a19e2790926ed4796510555eaf8 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.272 2001/11/05 05:00:14 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.273 2001/11/10 22:31:49 tgl Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -257,8 +257,8 @@ static void doNegateFloat(Value *v);
 %type <paramno> ParamNo
 
 %type <typnam>	Typename, SimpleTypename, ConstTypename
-				GenericType, Numeric, Geometric, Character, ConstDatetime, ConstInterval, Bit
-%type <str>		character, datetime, bit
+				GenericType, Numeric, Character, ConstDatetime, ConstInterval, Bit
+%type <str>		character, bit
 %type <str>		extract_arg
 %type <str>		opt_charset, opt_collate
 %type <str>		opt_float
@@ -268,7 +268,7 @@ static void doNegateFloat(Value *v);
 %type <ival>	Iconst
 %type <str>		Sconst, comment_text
 %type <str>		UserId, opt_boolean, var_value, ColId_or_Sconst
-%type <str>		ColId, ColLabel, TokenId
+%type <str>		ColId, TypeFuncId, ColLabel
 %type <node>	zone_value
 
 %type <node>	TableConstraint
@@ -1007,11 +1007,11 @@ constraints_set_list:	ALL
 		;
 
 
-constraints_set_namelist:	IDENT
+constraints_set_namelist:	ColId
 				{
 					$$ = makeList1($1);
 				}
-		| constraints_set_namelist ',' IDENT
+		| constraints_set_namelist ',' ColId
 				{
 					$$ = lappend($1, $3);
 				}
@@ -2007,8 +2007,8 @@ def_elem:  ColLabel '=' def_arg
 				}
 		;
 
+/* Note: any simple identifier will be returned as a type name! */
 def_arg:  func_return  					{  $$ = (Node *)$1; }
-		| TokenId						{  $$ = (Node *)makeString($1); }
 		| all_Op						{  $$ = (Node *)makeString($1); }
 		| NumericOnly					{  $$ = (Node *)$1; }
 		| Sconst						{  $$ = (Node *)makeString($1); }
@@ -2629,11 +2629,15 @@ 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.
+ */
 func_type:	Typename
 				{
 					$$ = $1;
 				}
-		| IDENT '.' ColId '%' TYPE_P
+		| TypeFuncId '.' ColId '%' TYPE_P
 				{
 					$$ = makeNode(TypeName);
 					$$->name = $1;
@@ -4064,13 +4068,12 @@ SimpleTypename:  ConstTypename
 
 ConstTypename:  GenericType
 		| Numeric
-		| Geometric
 		| Bit
 		| Character
 		| ConstDatetime
 		;
 
-GenericType:  IDENT
+GenericType:  TypeFuncId
 				{
 					$$ = makeNode(TypeName);
 					$$->name = xlateSqlType($1);
@@ -4086,7 +4089,7 @@ GenericType:  IDENT
 Numeric:  FLOAT opt_float
 				{
 					$$ = makeNode(TypeName);
-					$$->name = xlateSqlType($2);
+					$$->name = $2; /* already xlated */
 					$$->typmod = -1;
 				}
 		| DOUBLE PRECISION
@@ -4115,14 +4118,6 @@ Numeric:  FLOAT opt_float
 				}
 		;
 
-Geometric:  PATH_P
-				{
-					$$ = makeNode(TypeName);
-					$$->name = xlateSqlType("path");
-					$$->typmod = -1;
-				}
-		;
-
 opt_float:  '(' Iconst ')'
 				{
 					if ($2 < 1)
@@ -4299,13 +4294,7 @@ opt_collate:  COLLATE ColId						{ $$ = $2; }
 		| /*EMPTY*/								{ $$ = NULL; }
 		;
 
-ConstDatetime:  datetime
-				{
-					$$ = makeNode(TypeName);
-					$$->name = xlateSqlType($1);
-					$$->typmod = -1;
-				}
-		| TIMESTAMP '(' Iconst ')' opt_timezone_x
+ConstDatetime:  TIMESTAMP '(' Iconst ')' opt_timezone_x
 				{
 					$$ = makeNode(TypeName);
 					if ($5)
@@ -4371,14 +4360,6 @@ ConstInterval:  INTERVAL
 				}
 		;
 
-datetime:  YEAR_P								{ $$ = "year"; }
-		| MONTH_P								{ $$ = "month"; }
-		| DAY_P									{ $$ = "day"; }
-		| HOUR_P								{ $$ = "hour"; }
-		| MINUTE_P								{ $$ = "minute"; }
-		| SECOND_P								{ $$ = "second"; }
-		;
-
 /* XXX Make the default be WITH TIME ZONE for 7.2 to help with database upgrades
  * but revert this back to WITHOUT TIME ZONE for 7.3.
  * Do this by simply reverting opt_timezone_x to opt_timezone - thomas 2001-09-06
@@ -5270,9 +5251,14 @@ extract_list:  extract_arg FROM a_expr
  * - thomas 2001-04-12
  */
 
-extract_arg:  datetime						{ $$ = $1; }
-		| SCONST							{ $$ = $1; }
-		| IDENT								{ $$ = $1; }
+extract_arg:  IDENT						{ $$ = $1; }
+		| YEAR_P						{ $$ = "year"; }
+		| MONTH_P						{ $$ = "month"; }
+		| DAY_P							{ $$ = "day"; }
+		| HOUR_P						{ $$ = "hour"; }
+		| MINUTE_P						{ $$ = "minute"; }
+		| SECOND_P						{ $$ = "second"; }
+		| SCONST						{ $$ = $1; }
 		;
 
 /* position_list uses b_expr not a_expr to avoid conflict with general IN */
@@ -5555,32 +5541,6 @@ access_method:			ColId			{ $$ = $1; };
 attr_name:				ColId			{ $$ = $1; };
 class:					ColId			{ $$ = $1; };
 index_name:				ColId			{ $$ = $1; };
-
-/* Functions
- * Include date/time keywords as SQL92 extension.
- * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
- * Any tokens which show up as operators will screw up the parsing if
- * allowed as identifiers, but are acceptable as ColLabels:
- *  BETWEEN, IN, IS, ISNULL, NOTNULL, OVERLAPS
- * Thanks to Tom Lane for pointing this out. - thomas 2000-03-29
- * We need OVERLAPS allowed as a function name to enable the implementation
- *  of argument type variations on the underlying implementation. These
- *  variations are done as SQL-language entries in the pg_proc catalog.
- * Do not include SUBSTRING here since it has explicit productions
- *  in a_expr to support the goofy SQL9x argument syntax.
- *  - thomas 2000-11-28
- */
-func_name:  ColId						{ $$ = xlateSqlFunc($1); }
-		| BETWEEN						{ $$ = xlateSqlFunc("between"); }
-		| ILIKE							{ $$ = xlateSqlFunc("ilike"); }
-		| IN							{ $$ = xlateSqlFunc("in"); }
-		| IS							{ $$ = xlateSqlFunc("is"); }
-		| ISNULL						{ $$ = xlateSqlFunc("isnull"); }
-		| LIKE							{ $$ = xlateSqlFunc("like"); }
-		| NOTNULL						{ $$ = xlateSqlFunc("notnull"); }
-		| OVERLAPS						{ $$ = xlateSqlFunc("overlaps"); }
-		;
-
 file_name:				Sconst			{ $$ = $1; };
 
 /* Constants
@@ -5692,27 +5652,23 @@ Iconst:  ICONST							{ $$ = $1; };
 Sconst:  SCONST							{ $$ = $1; };
 UserId:  ColId							{ $$ = $1; };
 
-/* Column identifier
- * Include date/time keywords as SQL92 extension.
- * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
- * Add other keywords. Note that as the syntax expands,
- *  some of these keywords will have to be removed from this
- *  list due to shift/reduce conflicts in yacc. If so, move
- *  down to the ColLabel entity. - thomas 1997-11-06
+/*
+ * 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.
  */
-ColId:  IDENT							{ $$ = $1; }
-		| datetime						{ $$ = $1; }
-		| TokenId						{ $$ = $1; }
-		| NATIONAL						{ $$ = "national"; }
-		| NONE							{ $$ = "none"; }
-		| PATH_P						{ $$ = "path"; }
-		;
 
-/* Parser tokens to be used as identifiers.
- * Tokens involving data types should appear in ColId only,
- * since they will conflict with real TypeName productions.
+/* Type/func identifier --- names that can be type and function names
+ * (as well as ColIds --- ie, these are completely unreserved keywords).
  */
-TokenId:  ABSOLUTE						{ $$ = "absolute"; }
+TypeFuncId:  IDENT						{ $$ = $1; }
+		| ABORT_TRANS					{ $$ = "abort"; }
+		| ABSOLUTE						{ $$ = "absolute"; }
 		| ACCESS						{ $$ = "access"; }
 		| ACTION						{ $$ = "action"; }
 		| ADD							{ $$ = "add"; }
@@ -5731,16 +5687,19 @@ TokenId:  ABSOLUTE						{ $$ = "absolute"; }
 		| CHARACTERISTICS				{ $$ = "characteristics"; }
 		| CHECKPOINT					{ $$ = "checkpoint"; }
 		| CLOSE							{ $$ = "close"; }
+		| CLUSTER						{ $$ = "cluster"; }
 		| COMMENT						{ $$ = "comment"; }
 		| COMMIT						{ $$ = "commit"; }
 		| COMMITTED						{ $$ = "committed"; }
 		| CONSTRAINTS					{ $$ = "constraints"; }
+		| COPY							{ $$ = "copy"; }
 		| CREATE						{ $$ = "create"; }
 		| CREATEDB						{ $$ = "createdb"; }
 		| CREATEUSER					{ $$ = "createuser"; }
 		| CURSOR						{ $$ = "cursor"; }
 		| CYCLE							{ $$ = "cycle"; }
 		| DATABASE						{ $$ = "database"; }
+		| DAY_P							{ $$ = "day"; }
 		| DECLARE						{ $$ = "declare"; }
 		| DEFERRED						{ $$ = "deferred"; }
 		| DELETE						{ $$ = "delete"; }
@@ -5753,16 +5712,20 @@ TokenId:  ABSOLUTE						{ $$ = "absolute"; }
 		| ESCAPE						{ $$ = "escape"; }
 		| EXCLUSIVE						{ $$ = "exclusive"; }
 		| EXECUTE						{ $$ = "execute"; }
+		| EXPLAIN						{ $$ = "explain"; }
 		| FETCH							{ $$ = "fetch"; }
 		| FORCE							{ $$ = "force"; }
 		| FORWARD						{ $$ = "forward"; }
 		| FUNCTION						{ $$ = "function"; }
+		| GLOBAL						{ $$ = "global"; }
 		| GRANT							{ $$ = "grant"; }
 		| HANDLER						{ $$ = "handler"; }
+		| HOUR_P						{ $$ = "hour"; }
 		| IMMEDIATE						{ $$ = "immediate"; }
 		| INCREMENT						{ $$ = "increment"; }
 		| INDEX							{ $$ = "index"; }
 		| INHERITS						{ $$ = "inherits"; }
+		| INOUT							{ $$ = "inout"; }
 		| INSENSITIVE					{ $$ = "insensitive"; }
 		| INSERT						{ $$ = "insert"; }
 		| INSTEAD						{ $$ = "instead"; }
@@ -5771,12 +5734,20 @@ TokenId:  ABSOLUTE						{ $$ = "absolute"; }
 		| LANGUAGE						{ $$ = "language"; }
 		| LANCOMPILER					{ $$ = "lancompiler"; }
 		| LEVEL							{ $$ = "level"; }
+		| LISTEN						{ $$ = "listen"; }
+		| LOAD							{ $$ = "load"; }
+		| LOCAL							{ $$ = "local"; }
 		| LOCATION						{ $$ = "location"; }
+		| LOCK_P						{ $$ = "lock"; }
 		| MATCH							{ $$ = "match"; }
 		| MAXVALUE						{ $$ = "maxvalue"; }
+		| MINUTE_P						{ $$ = "minute"; }
 		| MINVALUE						{ $$ = "minvalue"; }
 		| MODE							{ $$ = "mode"; }
+		| MONTH_P						{ $$ = "month"; }
+		| MOVE							{ $$ = "move"; }
 		| NAMES							{ $$ = "names"; }
+		| NATIONAL						{ $$ = "national"; }
 		| NEXT							{ $$ = "next"; }
 		| NO							{ $$ = "no"; }
 		| NOCREATEDB					{ $$ = "nocreatedb"; }
@@ -5787,10 +5758,13 @@ TokenId:  ABSOLUTE						{ $$ = "absolute"; }
 		| OIDS							{ $$ = "oids"; }
 		| OPERATOR						{ $$ = "operator"; }
 		| OPTION						{ $$ = "option"; }
+		| OUT							{ $$ = "out"; }
 		| OWNER							{ $$ = "owner"; }
 		| PARTIAL						{ $$ = "partial"; }
 		| PASSWORD						{ $$ = "password"; }
+		| PATH_P						{ $$ = "path"; }
 		| PENDANT						{ $$ = "pendant"; }
+		| PRECISION						{ $$ = "precision"; }
 		| PRIOR							{ $$ = "prior"; }
 		| PRIVILEGES					{ $$ = "privileges"; }
 		| PROCEDURAL					{ $$ = "procedural"; }
@@ -5800,6 +5774,7 @@ TokenId:  ABSOLUTE						{ $$ = "absolute"; }
 		| RELATIVE						{ $$ = "relative"; }
 		| RENAME						{ $$ = "rename"; }
 		| REPLACE						{ $$ = "replace"; }
+		| RESET							{ $$ = "reset"; }
 		| RESTRICT						{ $$ = "restrict"; }
 		| RETURNS						{ $$ = "returns"; }
 		| REVOKE						{ $$ = "revoke"; }
@@ -5808,11 +5783,13 @@ TokenId:  ABSOLUTE						{ $$ = "absolute"; }
 		| RULE							{ $$ = "rule"; }
 		| SCHEMA						{ $$ = "schema"; }
 		| SCROLL						{ $$ = "scroll"; }
+		| SECOND_P						{ $$ = "second"; }
 		| SESSION						{ $$ = "session"; }
 		| SEQUENCE						{ $$ = "sequence"; }
 		| SERIALIZABLE					{ $$ = "serializable"; }
 		| SET							{ $$ = "set"; }
 		| SHARE							{ $$ = "share"; }
+		| SHOW							{ $$ = "show"; }
 		| START							{ $$ = "start"; }
 		| STATEMENT						{ $$ = "statement"; }
 		| STATISTICS					{ $$ = "statistics"; }
@@ -5823,14 +5800,17 @@ TokenId:  ABSOLUTE						{ $$ = "absolute"; }
 		| TEMPLATE						{ $$ = "template"; }
 		| TEMPORARY						{ $$ = "temporary"; }
 		| TOAST							{ $$ = "toast"; }
+		| TRANSACTION					{ $$ = "transaction"; }
 		| TRIGGER						{ $$ = "trigger"; }
 		| TRUNCATE						{ $$ = "truncate"; }
 		| TRUSTED						{ $$ = "trusted"; }
 		| TYPE_P						{ $$ = "type"; }
 		| UNENCRYPTED					{ $$ = "unencrypted"; }
+		| UNKNOWN						{ $$ = "unknown"; }
 		| UNLISTEN						{ $$ = "unlisten"; }
 		| UNTIL							{ $$ = "until"; }
 		| UPDATE						{ $$ = "update"; }
+		| VACUUM						{ $$ = "vacuum"; }
 		| VALID							{ $$ = "valid"; }
 		| VALUES						{ $$ = "values"; }
 		| VARYING						{ $$ = "varying"; }
@@ -5839,21 +5819,45 @@ TokenId:  ABSOLUTE						{ $$ = "absolute"; }
 		| WITH							{ $$ = "with"; }
 		| WITHOUT						{ $$ = "without"; }
 		| WORK							{ $$ = "work"; }
+		| YEAR_P						{ $$ = "year"; }
 		| ZONE							{ $$ = "zone"; }
 		;
 
-/* Column label
- * Allowed labels in "AS" clauses.
- * Include TRUE/FALSE SQL3 reserved words for Postgres backward
- *  compatibility. Cannot allow this for column names since the
- *  syntax would not distinguish between the constant value and
- *  a column name. - thomas 1997-10-24
- * Add other keywords to this list. Note that they appear here
- *  rather than in ColId if there was a shift/reduce conflict
- *  when used as a full identifier. - thomas 1997-11-06
+/* Column identifier --- names 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.
+ *
+ * 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.
+ */
+ColId:  TypeFuncId						{ $$ = $1; }
+		| BIT							{ $$ = "bit"; }
+		| CHAR							{ $$ = "char"; }
+		| CHARACTER						{ $$ = "character"; }
+		| DEC							{ $$ = "dec"; }
+		| DECIMAL						{ $$ = "decimal"; }
+		| FLOAT							{ $$ = "float"; }
+		| INTERVAL						{ $$ = "interval"; }
+		| NCHAR							{ $$ = "nchar"; }
+		| NONE							{ $$ = "none"; }
+		| NUMERIC						{ $$ = "numeric"; }
+		| SETOF							{ $$ = "setof"; }
+		| TIME							{ $$ = "time"; }
+		| TIMESTAMP						{ $$ = "timestamp"; }
+		| VARCHAR						{ $$ = "varchar"; }
+		;
+
+/* Column label --- allowed labels in "AS" clauses.
+ *
+ * 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.
  */
 ColLabel:  ColId						{ $$ = $1; }
-		| ABORT_TRANS					{ $$ = "abort"; }
 		| ALL							{ $$ = "all"; }
 		| ANALYSE						{ $$ = "analyse"; } /* British */
 		| ANALYZE						{ $$ = "analyze"; }
@@ -5862,26 +5866,19 @@ ColLabel:  ColId						{ $$ = $1; }
 		| ASC							{ $$ = "asc"; }
 		| BETWEEN						{ $$ = "between"; }
 		| BINARY						{ $$ = "binary"; }
-		| BIT							{ $$ = "bit"; }
 		| BOTH							{ $$ = "both"; }
 		| CASE							{ $$ = "case"; }
 		| CAST							{ $$ = "cast"; }
-		| CHAR							{ $$ = "char"; }
-		| CHARACTER						{ $$ = "character"; }
 		| CHECK							{ $$ = "check"; }
-		| CLUSTER						{ $$ = "cluster"; }
 		| COALESCE						{ $$ = "coalesce"; }
 		| COLLATE						{ $$ = "collate"; }
 		| COLUMN						{ $$ = "column"; }
 		| CONSTRAINT					{ $$ = "constraint"; }
-		| COPY							{ $$ = "copy"; }
 		| CROSS							{ $$ = "cross"; }
 		| CURRENT_DATE					{ $$ = "current_date"; }
 		| CURRENT_TIME					{ $$ = "current_time"; }
 		| CURRENT_TIMESTAMP				{ $$ = "current_timestamp"; }
 		| CURRENT_USER					{ $$ = "current_user"; }
-		| DEC							{ $$ = "dec"; }
-		| DECIMAL						{ $$ = "decimal"; }
 		| DEFAULT						{ $$ = "default"; }
 		| DEFERRABLE					{ $$ = "deferrable"; }
 		| DESC							{ $$ = "desc"; }
@@ -5891,25 +5888,20 @@ ColLabel:  ColId						{ $$ = $1; }
 		| END_TRANS						{ $$ = "end"; }
 		| EXCEPT						{ $$ = "except"; }
 		| EXISTS						{ $$ = "exists"; }
-		| EXPLAIN						{ $$ = "explain"; }
 		| EXTRACT						{ $$ = "extract"; }
 		| FALSE_P						{ $$ = "false"; }
-		| FLOAT							{ $$ = "float"; }
 		| FOR							{ $$ = "for"; }
 		| FOREIGN						{ $$ = "foreign"; }
 		| FREEZE						{ $$ = "freeze"; }
 		| FROM							{ $$ = "from"; }
 		| FULL							{ $$ = "full"; }
-		| GLOBAL						{ $$ = "global"; }
 		| GROUP							{ $$ = "group"; }
 		| HAVING						{ $$ = "having"; }
 		| ILIKE							{ $$ = "ilike"; }
 		| IN							{ $$ = "in"; }
 		| INITIALLY						{ $$ = "initially"; }
 		| INNER_P						{ $$ = "inner"; }
-		| INOUT							{ $$ = "inout"; }
 		| INTERSECT						{ $$ = "intersect"; }
-		| INTERVAL						{ $$ = "interval"; }
 		| INTO							{ $$ = "into"; }
 		| IS							{ $$ = "is"; }
 		| ISNULL						{ $$ = "isnull"; }
@@ -5918,19 +5910,12 @@ ColLabel:  ColId						{ $$ = $1; }
 		| LEFT							{ $$ = "left"; }
 		| LIKE							{ $$ = "like"; }
 		| LIMIT							{ $$ = "limit"; }
-		| LISTEN						{ $$ = "listen"; }
-		| LOAD							{ $$ = "load"; }
-		| LOCAL							{ $$ = "local"; }
-		| LOCK_P						{ $$ = "lock"; }
-		| MOVE							{ $$ = "move"; }
 		| NATURAL						{ $$ = "natural"; }
-		| NCHAR							{ $$ = "nchar"; }
 		| NEW							{ $$ = "new"; }
 		| NOT							{ $$ = "not"; }
 		| NOTNULL						{ $$ = "notnull"; }
 		| NULLIF						{ $$ = "nullif"; }
 		| NULL_P						{ $$ = "null"; }
-		| NUMERIC						{ $$ = "numeric"; }
 		| OFF							{ $$ = "off"; }
 		| OFFSET						{ $$ = "offset"; }
 		| OLD							{ $$ = "old"; }
@@ -5938,43 +5923,66 @@ ColLabel:  ColId						{ $$ = $1; }
 		| ONLY							{ $$ = "only"; }
 		| OR							{ $$ = "or"; }
 		| ORDER							{ $$ = "order"; }
-		| OUT							{ $$ = "out"; }
 		| OUTER_P						{ $$ = "outer"; }
 		| OVERLAPS						{ $$ = "overlaps"; }
 		| POSITION						{ $$ = "position"; }
-		| PRECISION						{ $$ = "precision"; }
 		| PRIMARY						{ $$ = "primary"; }
 		| PUBLIC						{ $$ = "public"; }
 		| REFERENCES					{ $$ = "references"; }
-		| RESET							{ $$ = "reset"; }
 		| RIGHT							{ $$ = "right"; }
 		| SELECT						{ $$ = "select"; }
 		| SESSION_USER					{ $$ = "session_user"; }
-		| SETOF							{ $$ = "setof"; }
-		| SHOW							{ $$ = "show"; }
 		| SOME							{ $$ = "some"; }
 		| SUBSTRING						{ $$ = "substring"; }
 		| TABLE							{ $$ = "table"; }
 		| THEN							{ $$ = "then"; }
-		| TIME							{ $$ = "time"; }
-		| TIMESTAMP						{ $$ = "timestamp"; }
 		| TO							{ $$ = "to"; }
 		| TRAILING						{ $$ = "trailing"; }
-		| TRANSACTION					{ $$ = "transaction"; }
 		| TRIM							{ $$ = "trim"; }
 		| TRUE_P						{ $$ = "true"; }
 		| UNION							{ $$ = "union"; }
 		| UNIQUE						{ $$ = "unique"; }
-		| UNKNOWN						{ $$ = "unknown"; }
 		| USER							{ $$ = "user"; }
 		| USING							{ $$ = "using"; }
-		| VACUUM						{ $$ = "vacuum"; }
-		| VARCHAR						{ $$ = "varchar"; }
 		| 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
 				{
 					if (QueryIsRule)
diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index dfa16e119a1614a98dd0100e29fcc61b7f16c5e1..04296d42aab8d865301b1a455321b4401032540a 100644
--- a/src/interfaces/ecpg/preproc/preproc.y
+++ b/src/interfaces/ecpg/preproc/preproc.y
@@ -88,7 +88,7 @@ cat_str(int count, ...)
 char *
 make_str(const char *str)
 {
-        char * res_str = (char *)mm_alloc(strlen(str) + 1);
+	char * res_str = (char *)mm_alloc(strlen(str) + 1);
 
 	strcpy(res_str, str);
 	return res_str;
@@ -279,7 +279,7 @@ make_name(void)
 %type  <str>    key_match ColLabel SpecialRuleRelation ColId columnDef
 %type  <str>    ColConstraint ColConstraintElem drop_type Bitconst
 %type  <str>    OptTableElementList OptTableElement TableConstraint
-%type  <str>    ConstraintElem key_actions ColQualList TokenId DropSchemaStmt
+%type  <str>    ConstraintElem key_actions ColQualList TypeFuncId DropSchemaStmt
 %type  <str>    target_list target_el update_target_list alias_clause
 %type  <str>    update_target_el opt_id relation_name database_name
 %type  <str>    access_method attr_name class index_name name func_name
@@ -288,9 +288,9 @@ make_name(void)
 %type  <str> 	opt_indirection expr_list extract_list extract_arg
 %type  <str>	position_list substr_list substr_from alter_column_default
 %type  <str>	trim_list in_expr substr_for attr attrs drop_behavior
-%type  <str>	Typename SimpleTypename Generic Numeric generic opt_float opt_numeric
+%type  <str>	Typename SimpleTypename Generic Numeric opt_float opt_numeric
 %type  <str> 	opt_decimal Character character opt_varying opt_charset
-%type  <str>	opt_collate datetime opt_timezone opt_interval table_ref
+%type  <str>	opt_collate opt_timezone opt_interval table_ref
 %type  <str>	row_expr row_descriptor row_list ConstDatetime opt_chain
 %type  <str>	SelectStmt into_clause OptTemp ConstraintAttributeSpec
 %type  <str>	opt_table opt_all sort_clause sortby_list ConstraintAttr 
@@ -324,7 +324,7 @@ make_name(void)
 %type  <str>    TriggerActionTime CreateTrigStmt DropPLangStmt 
 %type  <str>    CreatePLangStmt TriggerFuncArgs TriggerFuncArg simple_select
 %type  <str>    ViewStmt LoadStmt CreatedbStmt createdb_opt_item
-%type  <str>	createdb_opt_list opt_encoding OptInherit Geometric
+%type  <str>	createdb_opt_list opt_encoding OptInherit
 %type  <str>    DropdbStmt ClusterStmt grantee RevokeStmt Bit bit
 %type  <str>	GrantStmt privileges operation_commalist operation PosAllConst
 %type  <str>	opt_with_grant opt_cursor ConstraintsSetStmt AllConst
@@ -357,12 +357,12 @@ make_name(void)
 %type  <str>    struct_type s_struct declaration declarations variable_declarations
 %type  <str>    s_union union_type ECPGSetAutocommit on_off
 %type  <str>	ECPGAllocateDescr ECPGDeallocateDescr symbol opt_symbol
-%type  <str>	ECPGGetDescriptorHeader ECPGColLabel ECPGTypeName
-%type  <str>	ECPGLabelTypeName ECPGColId variablelist cvariable
+%type  <str>	ECPGGetDescriptorHeader ECPGTypeFuncId ECPGColId ECPGColLabel
+%type  <str>	ECPGTypeName variablelist cvariable
 
 %type  <descriptor> ECPGGetDescriptor
 
-%type  <type_enum> simple_type signed_type unsigned_type varchar_type
+%type  <type_enum> simple_type signed_type unsigned_type
 
 %type  <dtype_enum> descriptor_item desc_header_item
 
@@ -913,11 +913,11 @@ constraints_set_list:  ALL
                ;
 
 
-constraints_set_namelist:      IDENT
+constraints_set_namelist:      ColId
                                {
                                        $$ = $1;
                                }
-               | constraints_set_namelist ',' IDENT
+               | constraints_set_namelist ',' ColId
                                {
                                        $$ = cat_str(3, $1, make_str(","), $3);
                                }
@@ -1529,8 +1529,8 @@ def_elem:  ColLabel '=' def_arg	{
 				}
 		;
 
+/* Note: any simple identifier will be returned as a type name! */
 def_arg:  func_return		{  $$ = $1; }
-		| TokenId	{  $$ = $1; }
 		| all_Op	{  $$ = $1; }
 		| AllConst	{  $$ = $1; }
 		;
@@ -1964,7 +1964,7 @@ func_type:	Typename
 				{
 					$$ = $1;
 				}
-		| IDENT '.' ColId '%' TYPE_P   
+		| TypeFuncId '.' ColId '%' TYPE_P   
 				{
 					$$ = cat_str(4, $1, make_str("."), $3, make_str("% type"));
 				}
@@ -2974,20 +2974,11 @@ SimpleTypename:  ConstTypename					{ $$ = $1; }
 ConstTypename:  Generic	{ $$ = $1; }
 		| ConstDatetime	{ $$ = $1; }
 		| Numeric	{ $$ = $1; }
-		| Geometric	{ $$ = $1; }
 		| Bit		{ $$ = $1; }
 		| Character	{ $$ = $1; }
 		;
 
-Generic:  generic
-				{
-					$$ = $1;
-				}
-		;
-
-generic:  ident					{ $$ = $1; }
-		| TYPE_P			{ $$ = make_str("type"); }
-		| ECPGKeywords			{ $$ = $1; }
+Generic:  TypeFuncId			{ $$ = $1; }
 		| ECPGTypeName			{ $$ = $1; }
 		;
 
@@ -3018,8 +3009,6 @@ Numeric:  FLOAT opt_float
 				}
 		;
 
-Geometric:  PATH_P 	{ $$ = make_str("path"); };
-
 opt_float:  '(' PosIntConst ')'
 				{
 					$$ = cat_str(3, make_str("("), $2, make_str(")"));
@@ -3115,11 +3104,7 @@ opt_collate:  COLLATE ColId		{ $$ = cat2_str(make_str("collate"), $2); }
 		| /*EMPTY*/					{ $$ = EMPTY; }
 		;
 
-ConstDatetime:  datetime
-				{
-					$$ = $1;
-				}
-		| TIMESTAMP '(' PosIntConst ')' opt_timezone
+ConstDatetime:  TIMESTAMP '(' PosIntConst ')' opt_timezone
 				{
 					$$ = cat_str(4, make_str("timestamp("), $3, make_str(")"), $5);
 				}
@@ -3143,14 +3128,6 @@ ConstInterval:	INTERVAL
 				}
 		;
 
-datetime:  YEAR_P								{ $$ = make_str("year"); }
-		| MONTH_P								{ $$ = make_str("month"); }
-		| DAY_P									{ $$ = make_str("day"); }
-		| HOUR_P								{ $$ = make_str("hour"); }
-		| MINUTE_P								{ $$ = make_str("minute"); }
-		| SECOND_P								{ $$ = make_str("second"); }
-		;
-
 opt_timezone:  WITH TIME ZONE				{ $$ = make_str("with time zone"); }
 		| WITHOUT TIME ZONE				{ $$ = make_str("without time zone"); }
 		| /*EMPTY*/					{ $$ = EMPTY; }
@@ -3544,9 +3521,14 @@ extract_list:  extract_arg FROM a_expr
  * - thomas 2001-04-12
  */
 
-extract_arg:  datetime		{ $$ = $1; }
-	| StringConst				{ $$ = $1; }
-	| IDENT					{ $$ = $1; }
+extract_arg:  IDENT						{ $$ = $1; }
+		| YEAR_P						{ $$ = make_str("year"); }
+		| MONTH_P						{ $$ = make_str("month"); }
+		| DAY_P							{ $$ = make_str("day"); }
+		| HOUR_P						{ $$ = make_str("hour"); }
+		| MINUTE_P						{ $$ = make_str("minute"); }
+		| SECOND_P						{ $$ = make_str("second"); }
+		| StringConst					{ $$ = $1; }
 		;
 
 /* position_list uses b_expr not a_expr to avoid conflict with general IN */
@@ -3750,22 +3732,6 @@ attr_name:				ColId			{ $$ = $1; };
 class:					ColId			{ $$ = $1; };
 index_name:				ColId			{ $$ = $1; };
 
-/* Functions
- * Include date/time keywords as SQL92 extension.
- * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
- */
-func_name:	ColId			{ $$ = $1; };
-		| BETWEEN 		{ $$ = make_str("between");}
-		| ILIKE			{ $$ = make_str("ilike");}
-		| IN			{ $$ = make_str("in");}
-		| IS			{ $$ = make_str("is");}
-		| ISNULL		{ $$ = make_str("isnull");}
-		| LIKE			{ $$ = make_str("like");}
-		| NOTNULL		{ $$ = make_str("notnull");}
-		| OVERLAPS		{ $$ = make_str("overlaps");}
-		;
-
-
 file_name:				StringConst			{ $$ = $1; };
 
 /* Constants
@@ -3859,26 +3825,6 @@ PosAllConst:	Sconst  	{ $$ = $1; }
 
 UserId:  ColId                                  { $$ = $1;};
 
-/* Column identifier
- */
-ColId:	ECPGColId			{ $$ = $1; }
-/*	| ECPGTypeName                  { $$ = $1; }*/
-	;
-
-/* Column label
- * Allowed labels in "AS" clauses.
- * Include TRUE/FALSE SQL3 reserved words for Postgres backward
- *  compatibility. Cannot allow this for column names since the
- *  syntax would not distinguish between the constant value and
- *  a column name. - thomas 1997-10-24
- * Add other keywords to this list. Note that they appear here
- *  rather than in ColId if there was a shift/reduce conflict
- *  when used as a full identifier. - thomas 1997-11-06
- */
-ColLabel:  ECPGLabelTypeName			{ $$ = $1; }
-	| ECPGColLabel                  { $$ = $1; }
-	;
-
 SpecialRuleRelation:  OLD
 				{
 					if (!QueryIsRule)
@@ -4220,13 +4166,6 @@ type: simple_type
 			$$.type_dimension = -1;
   			$$.type_index = -1;
 		}
-	| varchar_type
-		{
-			$$.type_enum = ECPGt_varchar;
-			$$.type_str = make_str("varchar");;
-			$$.type_dimension = -1;
-  			$$.type_index = -1;
-		}
 	| struct_type
 		{
 			$$.type_enum = ECPGt_struct;
@@ -4250,14 +4189,42 @@ type: simple_type
 		}
 	| ECPGColLabel
 		{
-			/* this is for typedef'ed types */
-			struct typedefs *this = get_typedef($1);
-
-			$$.type_str = (this->type->type_enum == ECPGt_varchar) ? EMPTY : mm_strdup(this->name);
-                        $$.type_enum = this->type->type_enum;
-			$$.type_dimension = this->type->type_dimension;
-  			$$.type_index = this->type->type_index;
-			struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
+			/*
+			 * Check for type names that the SQL grammar treats as
+			 * unreserved keywords
+			 */
+			if (strcmp($1, "varchar") == 0)
+			{
+				$$.type_enum = ECPGt_varchar;
+				$$.type_str = make_str("varchar");
+				$$.type_dimension = -1;
+				$$.type_index = -1;
+			}
+			else if (strcmp($1, "float") == 0)
+			{
+				$$.type_enum = ECPGt_float;
+				$$.type_str = make_str("float");
+				$$.type_dimension = -1;
+				$$.type_index = -1;
+			}
+			else if (strcmp($1, "double") == 0)
+			{
+				$$.type_enum = ECPGt_double;
+				$$.type_str = make_str("double");
+				$$.type_dimension = -1;
+				$$.type_index = -1;
+			}
+			else
+			{
+				/* this is for typedef'ed types */
+				struct typedefs *this = get_typedef($1);
+
+				$$.type_str = (this->type->type_enum == ECPGt_varchar) ? EMPTY : mm_strdup(this->name);
+				$$.type_enum = this->type->type_enum;
+				$$.type_dimension = this->type->type_dimension;
+				$$.type_index = this->type->type_index;
+				struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
+			}
 		}
 	;
 
@@ -4359,9 +4326,7 @@ signed_type: SQL_SHORT          	{ $$ = ECPGt_short; }
 								  $$ = ECPGt_long;
 #endif
 								}
-           | SQL_BOOL   		{ $$ = ECPGt_bool; };
-           | FLOAT 	        	{ $$ = ECPGt_float; }
-           | DOUBLE 		        { $$ = ECPGt_double; }
+           | SQL_BOOL   		{ $$ = ECPGt_bool; }
            | CHAR            		{ $$ = ECPGt_char; }
 	   ;
 
@@ -4369,8 +4334,6 @@ opt_signed:	SQL_SIGNED
 	|	/* EMPTY */
 	;
 
-varchar_type:  VARCHAR		{ $$ = ECPGt_varchar; };
-
 variable_list: variable 
 	{
 		$$ = $1;
@@ -4686,7 +4649,7 @@ ECPGSetConnection:  SET SQL_CONNECTION to_equal connection_object
 /*
  * define a new type for embedded SQL
  */
-ECPGTypedef: TYPE_P ECPGColLabel IS type opt_type_array_bounds opt_reference
+ECPGTypedef: TYPE_P ColLabel IS type opt_type_array_bounds opt_reference
 	{
 		/* add entry to list */
 		struct typedefs *ptr, *this;
@@ -4779,7 +4742,7 @@ opt_reference: SQL_REFERENCE { $$ = make_str("reference"); }
 /*
  * define the type of one variable for embedded SQL
  */
-ECPGVar: SQL_VAR ECPGColLabel IS type opt_type_array_bounds opt_reference
+ECPGVar: SQL_VAR ColLabel IS type opt_type_array_bounds opt_reference
 	{
 		struct variable *p = find_variable($2);
 		int dimension = $5.index1;
@@ -4956,16 +4919,6 @@ ECPGTypeName:	  SQL_BOOL		{ $$ = make_str("bool"); }
 		| SQL_STRUCT		{ $$ = make_str("struct"); }
 		| SQL_SIGNED		{ $$ = make_str("signed"); }
 		| SQL_UNSIGNED		{ $$ = make_str("unsigned"); }
-		| DOUBLE		{ $$ = make_str("double"); }
-		;
-
-/* not needed at the moment
- * 			| UNION		{ $$ = make_str("union"); }
- */
-ECPGLabelTypeName:	  CHAR			{ $$ = make_str("char"); }
-			| FLOAT		{ $$ = make_str("float"); }
-			| VARCHAR	{ $$ = make_str("varchar"); }
-/*			| ECPGTypeName	{ $$ = $1; }*/
 		;
 
 opt_symbol:	symbol		{ $$ = $1; }
@@ -4974,258 +4927,352 @@ opt_symbol:	symbol		{ $$ = $1; }
 
 symbol:		ColLabel	{ $$ = $1; };
 
-/* Parser tokens to be used as identifiers.
- * Tokens involving data types should appear in ColId only,
- * since they will conflict with real TypeName productions.
+/*
+ * 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.
  */
-TokenId:  ABSOLUTE			{ $$ = make_str("absolute"); }
-	| ACCESS			{ $$ = make_str("access"); }
-	| ACTION			{ $$ = make_str("action"); }
-	| ADD				{ $$ = make_str("add"); }
-	| AFTER				{ $$ = make_str("after"); }
-	| AGGREGATE			{ $$ = make_str("aggregate"); }
-	| ALTER				{ $$ = make_str("alter"); }
-	| AT				{ $$ = make_str("at"); }
-	| AUTHORIZATION			{ $$ = make_str("authorization"); }
-	| BACKWARD			{ $$ = make_str("backward"); }
-	| BEFORE			{ $$ = make_str("before"); }
-	| BEGIN_TRANS			{ $$ = make_str("begin"); }
-	| CACHE				{ $$ = make_str("cache"); }
-	| CASCADE			{ $$ = make_str("cascade"); }
-	| CHAIN				{ $$ = make_str("chain"); }
-	| CHARACTERISTICS		{ $$ = make_str("characteristics"); }
-	| CHECKPOINT			{ $$ = make_str("checkpoint"); }
-	| CLOSE				{ $$ = make_str("close"); }
-	| COMMENT			{ $$ = make_str("comment"); } 
-	| COMMIT			{ $$ = make_str("commit"); }
-	| COMMITTED			{ $$ = make_str("committed"); }
-	| CONSTRAINTS			{ $$ = make_str("constraints"); }
-	| CREATEDB			{ $$ = make_str("createdb"); }
-	| CREATEUSER			{ $$ = make_str("createuser"); }
-	| CYCLE				{ $$ = make_str("cycle"); }
-	| DATABASE			{ $$ = make_str("database"); }
-	| DECLARE			{ $$ = make_str("declare"); }
-	| DEFERRED			{ $$ = make_str("deferred"); }	
-	| DELETE			{ $$ = make_str("delete"); }
-	| DELIMITERS			{ $$ = make_str("delimiters"); }
-	| DROP				{ $$ = make_str("drop"); }
-	| EACH				{ $$ = make_str("each"); }
-	| ENCODING			{ $$ = make_str("encoding"); }
-	| ENCRYPTED			{ $$ = make_str("encrypted"); }
-	| ESCAPE			{ $$ = make_str("escape"); }
-	| EXCLUSIVE			{ $$ = make_str("exclusive"); }
-	| EXECUTE			{ $$ = make_str("execute"); }
-	| FETCH				{ $$ = make_str("fetch"); }
-	| FORCE				{ $$ = make_str("force"); }
-	| FORWARD			{ $$ = make_str("forward"); }
-	| FUNCTION			{ $$ = make_str("function"); }
-	| GRANT				{ $$ = make_str("grant"); }
-	| HANDLER			{ $$ = make_str("handler"); }
-	| IMMEDIATE			{ $$ = make_str("immediate"); } 
-	| INCREMENT			{ $$ = make_str("increment"); }
-	| INDEX				{ $$ = make_str("index"); }
-	| INHERITS			{ $$ = make_str("inherits"); }
-	| INSENSITIVE			{ $$ = make_str("insensitive"); }
-	| INSERT			{ $$ = make_str("insert"); }
-	| INSTEAD			{ $$ = make_str("instead"); }
-	| ISOLATION			{ $$ = make_str("isolation"); }
-	| KEY				{ $$ = make_str("key"); }
-	| LANGUAGE			{ $$ = make_str("language"); }
-	| LANCOMPILER			{ $$ = make_str("lancompiler"); }
-	| LEVEL				{ $$ = make_str("level"); }
-	| LOCATION			{ $$ = make_str("location"); }
-	| MATCH				{ $$ = make_str("match"); }
-	| MAXVALUE			{ $$ = make_str("maxvalue"); }
-	| MINVALUE			{ $$ = make_str("minvalue"); }
-	| MODE				{ $$ = make_str("mode"); }
-	| NAMES				{ $$ = make_str("names"); }
-	| NEXT				{ $$ = make_str("next"); }
-	| NO				{ $$ = make_str("no"); }
-	| NOCREATEDB			{ $$ = make_str("nocreatedb"); }
-	| NOCREATEUSER			{ $$ = make_str("nocreateuser"); }
-	| NOTHING			{ $$ = make_str("nothing"); }
-	| NOTIFY			{ $$ = make_str("notify"); }
-	| OF				{ $$ = make_str("of"); }
-	| OIDS				{ $$ = make_str("oids"); }
-	| OPERATOR			{ $$ = make_str("operator"); }
-	| OPTION			{ $$ = make_str("option"); }
-	| OWNER				{ $$ = make_str("owner"); }
-	| PARTIAL			{ $$ = make_str("partial"); }
-	| PASSWORD			{ $$ = make_str("password"); }
-	| PENDANT			{ $$ = make_str("pendant"); }
-	| PRIOR				{ $$ = make_str("prior"); }
-	| PRIVILEGES			{ $$ = make_str("privileges"); }
-	| PROCEDURAL			{ $$ = make_str("procedural"); }
-	| PROCEDURE			{ $$ = make_str("procedure"); }
-	| READ				{ $$ = make_str("read"); }
-	| REINDEX			{ $$ = make_str("reindex"); }
-	| RELATIVE			{ $$ = make_str("relative"); }
-	| RENAME			{ $$ = make_str("rename"); }
-	| REPLACE			{ $$ = make_str("replace"); }
-	| RESTRICT			{ $$ = make_str("restrict"); }
-	| RETURNS			{ $$ = make_str("returns"); }
-	| REVOKE			{ $$ = make_str("revoke"); }
-	| ROLLBACK			{ $$ = make_str("rollback"); }
-	| ROW				{ $$ = make_str("row"); }
-	| RULE				{ $$ = make_str("rule"); }
-	| SCHEMA			{ $$ = make_str("schema"); }
-	| SCROLL			{ $$ = make_str("scroll"); }
-	| SESSION			{ $$ = make_str("session"); }
-	| SEQUENCE                      { $$ = make_str("sequence"); }
-	| SERIALIZABLE			{ $$ = make_str("serializable"); }
-	| SET				{ $$ = make_str("set"); }
-	| SHARE				{ $$ = make_str("share"); }
-	| START				{ $$ = make_str("start"); }
-	| STATEMENT			{ $$ = make_str("statement"); }
-	| STATISTICS			{ $$ = make_str("statistics"); }
-	| STDIN                         { $$ = make_str("stdin"); }
-	| STDOUT                        { $$ = make_str("stdout"); }
-	| SYSID                         { $$ = make_str("sysid"); }
-	| TEMP				{ $$ = make_str("temp"); }
-	| TEMPLATE			{ $$ = make_str("template"); }
-	| TEMPORARY			{ $$ = make_str("temporary"); }
-        | TOAST		                { $$ = make_str("toast"); }
-	| TRIGGER			{ $$ = make_str("trigger"); }
-	| TRUNCATE			{ $$ = make_str("truncate"); }
-	| TRUSTED			{ $$ = make_str("trusted"); }
-	| UNENCRYPTED			{ $$ = make_str("unencrypted"); }
-	| UNLISTEN			{ $$ = make_str("unlisten"); }
-	| UNTIL				{ $$ = make_str("until"); }
-	| UPDATE			{ $$ = make_str("update"); }
-	| VALID				{ $$ = make_str("valid"); }
-	| VALUES			{ $$ = make_str("values"); }
-	| VARYING			{ $$ = make_str("varying"); }
-	| VERSION			{ $$ = make_str("version"); }
-	| VIEW				{ $$ = make_str("view"); }
-	| WITH				{ $$ = make_str("with"); }
-	| WITHOUT			{ $$ = make_str("without"); }
-	| WORK				{ $$ = make_str("work"); }
-	| ZONE				{ $$ = make_str("zone"); }
-	;
 
-ECPGColId: ident			{ $$ = $1; }
-	| TYPE_P			{ $$ = make_str("type"); }
-	| datetime			{ $$ = $1; }
-	| TokenId			{ $$ = $1; }
-	| NATIONAL			{ $$ = make_str("national"); }
-	| NONE				{ $$ = make_str("none"); }
-	| PATH_P			{ $$ = make_str("path_p"); }
-	| ECPGKeywords                  { $$ = $1; }
-	;
+/* Type/func identifier --- names that can be type and function names
+ * (as well as ColIds --- ie, these are completely unreserved keywords).
+ */
+TypeFuncId:  ECPGTypeFuncId				{ $$ = $1; }
+		| ECPGKeywords                  { $$ = $1; }
+		;
+
+ECPGTypeFuncId:  ident					{ $$ = $1; }
+		| ABORT_TRANS					{ $$ = make_str("abort"); }
+		| ABSOLUTE						{ $$ = make_str("absolute"); }
+		| ACCESS						{ $$ = make_str("access"); }
+		| ACTION						{ $$ = make_str("action"); }
+		| ADD							{ $$ = make_str("add"); }
+		| AFTER							{ $$ = make_str("after"); }
+		| AGGREGATE						{ $$ = make_str("aggregate"); }
+		| ALTER							{ $$ = make_str("alter"); }
+		| AT							{ $$ = make_str("at"); }
+		| AUTHORIZATION					{ $$ = make_str("authorization"); }
+		| BACKWARD						{ $$ = make_str("backward"); }
+		| BEFORE						{ $$ = make_str("before"); }
+		| BEGIN_TRANS					{ $$ = make_str("begin"); }
+		| BY							{ $$ = make_str("by"); }
+		| CACHE							{ $$ = make_str("cache"); }
+		| CASCADE						{ $$ = make_str("cascade"); }
+		| CHAIN							{ $$ = make_str("chain"); }
+		| CHARACTERISTICS				{ $$ = make_str("characteristics"); }
+		| CHECKPOINT					{ $$ = make_str("checkpoint"); }
+		| CLOSE							{ $$ = make_str("close"); }
+		| CLUSTER						{ $$ = make_str("cluster"); }
+		| COMMENT						{ $$ = make_str("comment"); }
+		| COMMIT						{ $$ = make_str("commit"); }
+		| COMMITTED						{ $$ = make_str("committed"); }
+		| CONSTRAINTS					{ $$ = make_str("constraints"); }
+		| COPY							{ $$ = make_str("copy"); }
+		| CREATE						{ $$ = make_str("create"); }
+		| CREATEDB						{ $$ = make_str("createdb"); }
+		| CREATEUSER					{ $$ = make_str("createuser"); }
+		| CURSOR						{ $$ = make_str("cursor"); }
+		| CYCLE							{ $$ = make_str("cycle"); }
+		| DATABASE						{ $$ = make_str("database"); }
+		| DAY_P							{ $$ = make_str("day"); }
+		| DECLARE						{ $$ = make_str("declare"); }
+		| DEFERRED						{ $$ = make_str("deferred"); }
+		| DELETE						{ $$ = make_str("delete"); }
+		| DELIMITERS					{ $$ = make_str("delimiters"); }
+		| DOUBLE						{ $$ = make_str("double"); }
+		| DROP							{ $$ = make_str("drop"); }
+		| EACH							{ $$ = make_str("each"); }
+		| ENCODING						{ $$ = make_str("encoding"); }
+		| ENCRYPTED						{ $$ = make_str("encrypted"); }
+		| ESCAPE						{ $$ = make_str("escape"); }
+		| EXCLUSIVE						{ $$ = make_str("exclusive"); }
+		| EXECUTE						{ $$ = make_str("execute"); }
+		| EXPLAIN						{ $$ = make_str("explain"); }
+		| FETCH							{ $$ = make_str("fetch"); }
+		| FORCE							{ $$ = make_str("force"); }
+		| FORWARD						{ $$ = make_str("forward"); }
+		| FUNCTION						{ $$ = make_str("function"); }
+		| GLOBAL						{ $$ = make_str("global"); }
+		| GRANT							{ $$ = make_str("grant"); }
+		| HANDLER						{ $$ = make_str("handler"); }
+		| HOUR_P						{ $$ = make_str("hour"); }
+		| IMMEDIATE						{ $$ = make_str("immediate"); }
+		| INCREMENT						{ $$ = make_str("increment"); }
+		| INDEX							{ $$ = make_str("index"); }
+		| INHERITS						{ $$ = make_str("inherits"); }
+		| INOUT							{ $$ = make_str("inout"); }
+		| INSENSITIVE					{ $$ = make_str("insensitive"); }
+		| INSERT						{ $$ = make_str("insert"); }
+		| INSTEAD						{ $$ = make_str("instead"); }
+		| ISOLATION						{ $$ = make_str("isolation"); }
+		| KEY							{ $$ = make_str("key"); }
+		| LANGUAGE						{ $$ = make_str("language"); }
+		| LANCOMPILER					{ $$ = make_str("lancompiler"); }
+		| LEVEL							{ $$ = make_str("level"); }
+		| LISTEN						{ $$ = make_str("listen"); }
+		| LOAD							{ $$ = make_str("load"); }
+		| LOCAL							{ $$ = make_str("local"); }
+		| LOCATION						{ $$ = make_str("location"); }
+		| LOCK_P						{ $$ = make_str("lock"); }
+		| MATCH							{ $$ = make_str("match"); }
+		| MAXVALUE						{ $$ = make_str("maxvalue"); }
+		| MINUTE_P						{ $$ = make_str("minute"); }
+		| MINVALUE						{ $$ = make_str("minvalue"); }
+		| MODE							{ $$ = make_str("mode"); }
+		| MONTH_P						{ $$ = make_str("month"); }
+		| MOVE							{ $$ = make_str("move"); }
+		| NAMES							{ $$ = make_str("names"); }
+		| NATIONAL						{ $$ = make_str("national"); }
+		| NEXT							{ $$ = make_str("next"); }
+		| NO							{ $$ = make_str("no"); }
+		| NOCREATEDB					{ $$ = make_str("nocreatedb"); }
+		| NOCREATEUSER					{ $$ = make_str("nocreateuser"); }
+		| NOTHING						{ $$ = make_str("nothing"); }
+		| NOTIFY						{ $$ = make_str("notify"); }
+		| OF							{ $$ = make_str("of"); }
+		| OIDS							{ $$ = make_str("oids"); }
+		| OPERATOR						{ $$ = make_str("operator"); }
+		| OPTION						{ $$ = make_str("option"); }
+		| OUT							{ $$ = make_str("out"); }
+		| OWNER							{ $$ = make_str("owner"); }
+		| PARTIAL						{ $$ = make_str("partial"); }
+		| PASSWORD						{ $$ = make_str("password"); }
+		| PATH_P						{ $$ = make_str("path"); }
+		| PENDANT						{ $$ = make_str("pendant"); }
+		| PRECISION						{ $$ = make_str("precision"); }
+		| PRIOR							{ $$ = make_str("prior"); }
+		| PRIVILEGES					{ $$ = make_str("privileges"); }
+		| PROCEDURAL					{ $$ = make_str("procedural"); }
+		| PROCEDURE						{ $$ = make_str("procedure"); }
+		| READ							{ $$ = make_str("read"); }
+		| REINDEX						{ $$ = make_str("reindex"); }
+		| RELATIVE						{ $$ = make_str("relative"); }
+		| RENAME						{ $$ = make_str("rename"); }
+		| REPLACE						{ $$ = make_str("replace"); }
+		| RESET							{ $$ = make_str("reset"); }
+		| RESTRICT						{ $$ = make_str("restrict"); }
+		| RETURNS						{ $$ = make_str("returns"); }
+		| REVOKE						{ $$ = make_str("revoke"); }
+		| ROLLBACK						{ $$ = make_str("rollback"); }
+		| ROW							{ $$ = make_str("row"); }
+		| RULE							{ $$ = make_str("rule"); }
+		| SCHEMA						{ $$ = make_str("schema"); }
+		| SCROLL						{ $$ = make_str("scroll"); }
+		| SECOND_P						{ $$ = make_str("second"); }
+		| SESSION						{ $$ = make_str("session"); }
+		| SEQUENCE						{ $$ = make_str("sequence"); }
+		| SERIALIZABLE					{ $$ = make_str("serializable"); }
+		| SET							{ $$ = make_str("set"); }
+		| SHARE							{ $$ = make_str("share"); }
+		| SHOW							{ $$ = make_str("show"); }
+		| START							{ $$ = make_str("start"); }
+		| STATEMENT						{ $$ = make_str("statement"); }
+		| STATISTICS					{ $$ = make_str("statistics"); }
+		| STDIN							{ $$ = make_str("stdin"); }
+		| STDOUT						{ $$ = make_str("stdout"); }
+		| SYSID							{ $$ = make_str("sysid"); }
+		| TEMP							{ $$ = make_str("temp"); }
+		| TEMPLATE						{ $$ = make_str("template"); }
+		| TEMPORARY						{ $$ = make_str("temporary"); }
+		| TOAST							{ $$ = make_str("toast"); }
+		| TRANSACTION					{ $$ = make_str("transaction"); }
+		| TRIGGER						{ $$ = make_str("trigger"); }
+		| TRUNCATE						{ $$ = make_str("truncate"); }
+		| TRUSTED						{ $$ = make_str("trusted"); }
+		| TYPE_P						{ $$ = make_str("type"); }
+		| UNENCRYPTED					{ $$ = make_str("unencrypted"); }
+		| UNKNOWN						{ $$ = make_str("unknown"); }
+		| UNLISTEN						{ $$ = make_str("unlisten"); }
+		| UNTIL							{ $$ = make_str("until"); }
+		| UPDATE						{ $$ = make_str("update"); }
+		| VACUUM						{ $$ = make_str("vacuum"); }
+		| VALID							{ $$ = make_str("valid"); }
+		| VALUES						{ $$ = make_str("values"); }
+		| VARYING						{ $$ = make_str("varying"); }
+		| VERSION						{ $$ = make_str("version"); }
+		| VIEW							{ $$ = make_str("view"); }
+		| WITH							{ $$ = make_str("with"); }
+		| WITHOUT						{ $$ = make_str("without"); }
+		| WORK							{ $$ = make_str("work"); }
+		| YEAR_P						{ $$ = make_str("year"); }
+		| ZONE							{ $$ = make_str("zone"); }
+		;
+
+/* Column identifier --- names 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.
+ *
+ * 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.
+ */
+ColId:  ECPGColId						{ $$ = $1; }
+		| CHAR							{ $$ = make_str("char"); }
+		;
 
-ECPGColLabel:  ECPGColId	{ $$ = $1; }
-		| ABORT_TRANS   { $$ = make_str("abort"); }
-		| ALL		{ $$ = make_str("all"); }
-		| ANALYSE       { $$ = make_str("analyse"); }
-		| ANALYZE       { $$ = make_str("analyze"); }
-		| ANY		{ $$ = make_str("any"); }
-		| ASC		{ $$ = make_str("asc"); }
-	    	| BETWEEN       { $$ = make_str("between"); }
-		| BINARY        { $$ = make_str("binary"); }
-		| BIT	        { $$ = make_str("bit"); }
-		| BOTH		{ $$ = make_str("both"); }
-		| CASE          { $$ = make_str("case"); }
-		| CAST		{ $$ = make_str("cast"); }
-		| CHARACTER     { $$ = make_str("character"); }
-		| CHECK		{ $$ = make_str("check"); }
-		| CLUSTER	{ $$ = make_str("cluster"); }
-		| COALESCE      { $$ = make_str("coalesce"); }
-		| COLLATE	{ $$ = make_str("collate"); }
-		| COLUMN	{ $$ = make_str("column"); }
-		| CONSTRAINT	{ $$ = make_str("constraint"); }
-		| COPY		{ $$ = make_str("copy"); }
-		| CROSS		{ $$ = make_str("cross"); }
-		| CURRENT_DATE	{ $$ = make_str("current_date"); }
-		| CURRENT_TIME	{ $$ = make_str("current_time"); }
-		| CURRENT_TIMESTAMP	{ $$ = make_str("current_timestamp"); }
-		| CURRENT_USER		{ $$ = make_str("current_user"); }
-		| DEC		{ $$ = make_str("dec"); }
-		| DECIMAL	{ $$ = make_str("decimal"); }
-		| DEFAULT	{ $$ = make_str("default"); }
-		| DEFERRABLE	{ $$ = make_str("deferrable"); }
-		| DESC		{ $$ = make_str("desc"); }
-		| DISTINCT	{ $$ = make_str("distinct"); }
-		| DO		{ $$ = make_str("do"); }
-		| ELSE          { $$ = make_str("else"); }
-		| END_TRANS     { $$ = make_str("end"); }
-		| EXCEPT	{ $$ = make_str("except"); }
-		| EXISTS	{ $$ = make_str("exists"); }
-		| EXPLAIN	{ $$ = make_str("explain"); }
-		| 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"); }
-		| GLOBAL	{ $$ = make_str("global"); }
-		| 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"); }
-		| INOUT         { $$ = make_str("inout"); }
-		| INTERSECT	{ $$ = make_str("intersect"); }
-		| INTERVAL	{ $$ = make_str("interval"); }
-		| 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"); }
-		| LISTEN	{ $$ = make_str("listen"); }
-		| LOAD		{ $$ = make_str("load"); }
-		| LOCK_P	{ $$ = make_str("lock"); }
-		| MOVE		{ $$ = make_str("move"); }
-		| NATURAL	{ $$ = make_str("natural"); }
-		| NCHAR		{ $$ = make_str("nchar"); }
-		| NEW		{ $$ = make_str("new"); }
-		| NOT		{ $$ = make_str("not"); }
-		| NOTNULL   	{ $$ = make_str("notnull"); }
-		| NULLIF	{ $$ = make_str("nullif"); }
-		| NULL_P	{ $$ = make_str("null"); }
-		| NUMERIC	{ $$ = make_str("numeric"); }
-		| OFF		{ $$ = make_str("off"); }
-		| OFFSET	{ $$ = make_str("offset"); }
-		| OLD		{ $$ = make_str("old"); }
-		| ON		{ $$ = make_str("on"); }
-		| ONLY		{ $$ = make_str("only"); }
-		| OR		{ $$ = make_str("or"); }
-		| ORDER		{ $$ = make_str("order"); }
-		| OUT		{ $$ = make_str("out"); }
-		| OUTER_P	{ $$ = make_str("outer"); }
-	        | OVERLAPS      { $$ = make_str("overlaps"); }
-		| POSITION	{ $$ = make_str("position"); }
-		| PRECISION	{ $$ = make_str("precision"); }
-		| PRIMARY	{ $$ = make_str("primary"); }
-		| PUBLIC	{ $$ = make_str("public"); }
-		| REFERENCES	{ $$ = make_str("references"); }
-		| RESET		{ $$ = make_str("reset"); }
-		| RIGHT		{ $$ = make_str("right"); }
-		| SELECT	{ $$ = make_str("select"); }
-		| SESSION_USER	{ $$ = make_str("session_user"); }
-		| SETOF		{ $$ = make_str("setof"); }
-		| SHOW		{ $$ = make_str("show"); }
-		| SUBSTRING	{ $$ = make_str("substring"); }
-		| TABLE		{ $$ = make_str("table"); }
-		| THEN          { $$ = make_str("then"); }
-		| TIME		{ $$ = make_str("time"); }
-		| TIMESTAMP	{ $$ = make_str("timestamp"); }
-		| TO		{ $$ = make_str("to"); }
-		| TRANSACTION	{ $$ = make_str("transaction"); }
-		| TRIM		{ $$ = make_str("trim"); }
-		| TRUE_P	{ $$ = make_str("true"); }
-		| UNIQUE	{ $$ = make_str("unique"); }
-		| UNKNOWN	{ $$ = make_str("unknown"); }
-		| USER		{ $$ = make_str("user"); }
-		| USING		{ $$ = make_str("using"); }
-		| VACUUM	{ $$ = make_str("vacuum"); }
-		| VERBOSE	{ $$ = make_str("verbose"); }
-		| WHEN          { $$ = make_str("when"); }
-		| WHERE		{ $$ = make_str("where"); }
+ECPGColId:  TypeFuncId					{ $$ = $1; }
+		| BIT							{ $$ = make_str("bit"); }
+/* CHAR must be excluded from ECPGColLabel because of conflict with UNSIGNED
+		| CHAR							{ $$ = make_str("char"); }
+ */
+		| CHARACTER						{ $$ = make_str("character"); }
+		| DEC							{ $$ = make_str("dec"); }
+		| DECIMAL						{ $$ = make_str("decimal"); }
+		| FLOAT							{ $$ = make_str("float"); }
+		| INTERVAL						{ $$ = make_str("interval"); }
+		| NCHAR							{ $$ = make_str("nchar"); }
+		| NONE							{ $$ = make_str("none"); }
+		| NUMERIC						{ $$ = make_str("numeric"); }
+		| SETOF							{ $$ = make_str("setof"); }
+		| TIME							{ $$ = make_str("time"); }
+		| TIMESTAMP						{ $$ = make_str("timestamp"); }
+		| VARCHAR						{ $$ = make_str("varchar"); }
+		;
+
+/* Column label --- allowed labels in "AS" clauses.
+ *
+ * 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.
+ */
+ColLabel:  ECPGColLabel					{ $$ = $1; }
+		| CHAR							{ $$ = make_str("char"); }
+		| UNION							{ $$ = make_str("union"); }
+		;
+
+ECPGColLabel:  ECPGColId				{ $$ = $1; }
+		| ALL							{ $$ = make_str("all"); }
+		| ANALYSE						{ $$ = make_str("analyse"); } /* British */
+		| ANALYZE						{ $$ = make_str("analyze"); }
+		| AND							{ $$ = make_str("and"); }
+		| ANY							{ $$ = make_str("any"); }
+		| 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"); }
+		| CURRENT_USER					{ $$ = make_str("current_user"); }
+		| DEFAULT						{ $$ = make_str("default"); }
+		| DEFERRABLE					{ $$ = make_str("deferrable"); }
+		| DESC							{ $$ = make_str("desc"); }
+		| DISTINCT						{ $$ = make_str("distinct"); }
+		| DO							{ $$ = make_str("do"); }
+		| 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"); }
+		| OLD							{ $$ = make_str("old"); }
+		| ON							{ $$ = make_str("on"); }
+		| 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"); }
+ */
+		| 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;