]> granicus.if.org Git - postgresql/blobdiff - src/backend/parser/gram.y
Allow WITH clauses to be attached to INSERT, UPDATE, DELETE statements.
[postgresql] / src / backend / parser / gram.y
index 81d57f65fb5c20954835a6567965b84a70213090..609c4727017429e09f3679ad0bc60c4a84185a69 100644 (file)
@@ -6,12 +6,12 @@
  * gram.y
  *       POSTGRESQL BISON rules/actions
  *
- * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.678 2009/09/21 20:10:21 tgl Exp $
+ *       src/backend/parser/gram.y
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
                        (Current) = (Rhs)[0]; \
        } while (0)
 
-/*
- * The %name-prefix option below will make bison call base_yylex, but we
- * really want it to call filtered_base_yylex (see parser.c).
- */
-#define base_yylex filtered_base_yylex
-
 /*
  * Bison doesn't allocate anything that needs to live across parser calls,
  * so we can easily have it use palloc instead of malloc.  This prevents
@@ -95,6 +89,7 @@
 /* Private struct for the result of privilege_target production */
 typedef struct PrivTarget
 {
+       GrantTargetType targtype;
        GrantObjectType objtype;
        List       *objs;
 } PrivTarget;
@@ -103,10 +98,10 @@ typedef struct PrivTarget
 #define parser_yyerror(msg)  scanner_yyerror(msg, yyscanner)
 #define parser_errposition(pos)  scanner_errposition(pos, yyscanner)
 
-static void base_yyerror(YYLTYPE *yylloc, base_yyscan_t yyscanner,
+static void base_yyerror(YYLTYPE *yylloc, core_yyscan_t yyscanner,
                                                 const char *msg);
 static Node *makeColumnRef(char *colname, List *indirection,
-                                                  int location, base_yyscan_t yyscanner);
+                                                  int location, core_yyscan_t yyscanner);
 static Node *makeTypeCast(Node *arg, TypeName *typename, int location);
 static Node *makeStringConst(char *str, int location);
 static Node *makeStringConstCast(char *str, int location, TypeName *typename);
@@ -117,17 +112,17 @@ static Node *makeNullAConst(int location);
 static Node *makeAConst(Value *v, int location);
 static Node *makeBoolAConst(bool state, int location);
 static FuncCall *makeOverlaps(List *largs, List *rargs,
-                                                         int location, base_yyscan_t yyscanner);
-static void check_qualified_name(List *names, base_yyscan_t yyscanner);
-static List *check_func_name(List *names, base_yyscan_t yyscanner);
-static List *check_indirection(List *indirection, base_yyscan_t yyscanner);
+                                                         int location, core_yyscan_t yyscanner);
+static void check_qualified_name(List *names, core_yyscan_t yyscanner);
+static List *check_func_name(List *names, core_yyscan_t yyscanner);
+static List *check_indirection(List *indirection, core_yyscan_t yyscanner);
 static List *extractArgTypes(List *parameters);
 static SelectStmt *findLeftmostSelect(SelectStmt *node);
 static void insertSelectOptions(SelectStmt *stmt,
                                                                List *sortClause, List *lockingClause,
                                                                Node *limitOffset, Node *limitCount,
                                                                WithClause *withClause,
-                                                               base_yyscan_t yyscanner);
+                                                               core_yyscan_t yyscanner);
 static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg);
 static Node *doNegate(Node *n, int location);
 static void doNegateFloat(Value *v);
@@ -136,6 +131,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args,
                                                 List *args, int location);
 static List *mergeTableFuncParameters(List *func_args, List *columns);
 static TypeName *TableFuncTypeName(List *columns);
+static RangeVar *makeRangeVarFromAnyName(List *names, int position, core_yyscan_t yyscanner);
 
 %}
 
@@ -144,15 +140,18 @@ static TypeName *TableFuncTypeName(List *columns);
 %name-prefix="base_yy"
 %locations
 
-%parse-param {base_yyscan_t yyscanner}
-%lex-param   {base_yyscan_t yyscanner}
+%parse-param {core_yyscan_t yyscanner}
+%lex-param   {core_yyscan_t yyscanner}
 
 %union
 {
+       core_YYSTYPE            core_yystype;
+       /* these fields must match core_YYSTYPE: */
        int                                     ival;
-       char                            chr;
        char                            *str;
        const char                      *keyword;
+
+       char                            chr;
        bool                            boolean;
        JoinType                        jtype;
        DropBehavior            dbehavior;
@@ -161,7 +160,6 @@ static TypeName *TableFuncTypeName(List *columns);
        Node                            *node;
        Value                           *value;
        ObjectType                      objtype;
-
        TypeName                        *typnam;
        FunctionParameter   *fun_param;
        FunctionParameterMode fun_param_mode;
@@ -179,7 +177,6 @@ static TypeName *TableFuncTypeName(List *columns);
        ResTarget                       *target;
        struct PrivTarget       *privtarget;
        AccessPriv                      *accesspriv;
-
        InsertStmt                      *istmt;
        VariableSetStmt         *vsetstmt;
 }
@@ -188,7 +185,9 @@ static TypeName *TableFuncTypeName(List *columns);
                AlterDatabaseStmt AlterDatabaseSetStmt AlterDomainStmt AlterFdwStmt
                AlterForeignServerStmt AlterGroupStmt
                AlterObjectSchemaStmt AlterOwnerStmt AlterSeqStmt AlterTableStmt
-               AlterUserStmt AlterUserMappingStmt AlterUserSetStmt AlterRoleStmt AlterRoleSetStmt
+               AlterCompositeTypeStmt AlterUserStmt AlterUserMappingStmt AlterUserSetStmt
+               AlterRoleStmt AlterRoleSetStmt
+               AlterDefaultPrivilegesStmt DefACLAction
                AnalyzeStmt ClosePortalStmt ClusterStmt CommentStmt
                ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt
                CreateDomainStmt CreateGroupStmt CreateOpClassStmt
@@ -196,7 +195,7 @@ static TypeName *TableFuncTypeName(List *columns);
                CreateSchemaStmt CreateSeqStmt CreateStmt CreateTableSpaceStmt
                CreateFdwStmt CreateForeignServerStmt CreateAssertStmt CreateTrigStmt
                CreateUserStmt CreateUserMappingStmt CreateRoleStmt
-               CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt DiscardStmt
+               CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt DiscardStmt DoStmt
                DropGroupStmt DropOpClassStmt DropOpFamilyStmt DropPLangStmt DropStmt
                DropAssertStmt DropTrigStmt DropRuleStmt DropCastStmt DropRoleStmt
                DropUserStmt DropdbStmt DropTableSpaceStmt DropFdwStmt
@@ -206,7 +205,7 @@ static TypeName *TableFuncTypeName(List *columns);
                CreateFunctionStmt AlterFunctionStmt ReindexStmt RemoveAggrStmt
                RemoveFuncStmt RemoveOperStmt RenameStmt RevokeStmt RevokeRoleStmt
                RuleActionStmt RuleActionStmtOrEmpty RuleStmt
-               SelectStmt TransactionStmt TruncateStmt
+               SecLabelStmt SelectStmt TransactionStmt TruncateStmt
                UnlistenStmt UpdateStmt VacuumStmt
                VariableResetStmt VariableSetStmt VariableShowStmt
                ViewStmt CheckPointStmt CreateConversionStmt
@@ -220,8 +219,8 @@ static TypeName *TableFuncTypeName(List *columns);
 %type <node>   alter_column_default opclass_item opclass_drop alter_using
 %type <ival>   add_drop opt_asc_desc opt_nulls_order
 
-%type <node>   alter_table_cmd
-%type <list>   alter_table_cmds
+%type <node>   alter_table_cmd alter_type_cmd
+%type <list>   alter_table_cmds alter_type_cmds
 
 %type <dbehavior>      opt_drop_behavior
 
@@ -231,36 +230,39 @@ static TypeName *TableFuncTypeName(List *columns);
                                transaction_mode_item
 
 %type <ival>   opt_lock lock_type cast_context
+%type <ival>   vacuum_option_list vacuum_option_elem
 %type <boolean>        opt_force opt_or_replace
                                opt_grant_grant_option opt_grant_admin_option
                                opt_nowait opt_if_exists opt_with_data
 
-%type <list>   OptRoleList
-%type <defelt> OptRoleElem
+%type <list>   OptRoleList AlterOptRoleList
+%type <defelt> CreateOptRoleElem AlterOptRoleElem
 
 %type <str>            opt_type
 %type <str>            foreign_server_version opt_foreign_server_version
 %type <str>            auth_ident
+%type <str>            opt_in_database
 
 %type <str>            OptSchemaName
 %type <list>   OptSchemaEltList
 
-%type <boolean> TriggerActionTime TriggerForSpec opt_trusted opt_restart_seqs
-%type <str>            opt_lancompiler
-
-%type <ival>   TriggerEvents TriggerOneEvent
+%type <boolean> TriggerForSpec TriggerForType
+%type <ival>   TriggerActionTime
+%type <list>   TriggerEvents TriggerOneEvent
 %type <value>  TriggerFuncArg
+%type <node>   TriggerWhen
 
-%type <str>            relation_name copy_file_name
+%type <str>            copy_file_name
                                database_name access_method_clause access_method attr_name
-                               index_name name file_name cluster_index_specification
+                               name cursor_name file_name
+                               index_name opt_index_name cluster_index_specification
 
 %type <list>   func_name handler_name qual_Op qual_all_Op subquery_Op
-                               opt_class opt_validator validator_clause
+                               opt_class opt_inline_handler opt_validator validator_clause
 
 %type <range>  qualified_name OptConstrFromTable
 
-%type <str>            all_Op MathOp SpecialRuleRelation
+%type <str>            all_Op MathOp
 
 %type <str>            iso_level opt_encoding
 %type <node>   grantee
@@ -270,9 +272,13 @@ static TypeName *TableFuncTypeName(List *columns);
 %type <privtarget> privilege_target
 %type <funwithargs> function_with_argtypes
 %type <list>   function_with_argtypes_list
+%type <ival>   defacl_privilege_target
+%type <defelt> DefACLOption
+%type <list>   DefACLOptionList
 
 %type <list>   stmtblock stmtmulti
                                OptTableElementList TableElementList OptInherit definition
+                               OptTypedTableElementList TypedTableElementList
                                reloptions opt_reloptions
                                OptWith opt_distinct opt_definition func_args func_args_list
                                func_args_with_defaults func_args_with_defaults_list
@@ -290,22 +296,22 @@ static TypeName *TableFuncTypeName(List *columns);
                                reloption_list group_clause TriggerFuncArgs select_limit
                                opt_select_limit opclass_item_list opclass_drop_list
                                opt_opfamily transaction_mode_list_or_empty
-                               TableFuncElementList opt_type_modifiers
+                               OptTableFuncElementList TableFuncElementList opt_type_modifiers
                                prep_type_clause
                                execute_param_clause using_clause returning_clause
-                               enum_val_list table_func_column_list
+                               opt_enum_val_list enum_val_list table_func_column_list
                                create_generic_options alter_generic_options
-                               relation_expr_list
+                               relation_expr_list dostmt_opt_list
 
 %type <range>  OptTempTableName
 %type <into>   into_clause create_as_target
 
-%type <defelt> createfunc_opt_item common_func_opt_item
+%type <defelt> createfunc_opt_item common_func_opt_item dostmt_opt_item
 %type <fun_param> func_arg func_arg_with_default table_func_column
 %type <fun_param_mode> arg_class
 %type <typnam> func_return func_type
 
-%type <boolean>  TriggerForType OptTemp
+%type <boolean>  OptTemp opt_trusted opt_restart_seqs
 %type <oncommit> OnCommitOption
 
 %type <node>   for_locking_item
@@ -322,16 +328,16 @@ static TypeName *TableFuncTypeName(List *columns);
 %type <node>   overlay_placing substr_from substr_for
 
 %type <boolean> opt_instead
-%type <boolean> index_opt_unique opt_verbose opt_full
+%type <boolean> opt_unique opt_concurrently opt_verbose opt_full
 %type <boolean> opt_freeze opt_default opt_recheck
 %type <defelt> opt_binary opt_oids copy_delimiter
 
 %type <boolean> copy_from
 
 %type <ival>   opt_column event cursor_options opt_hold opt_set_data
-%type <objtype>        reindex_type drop_type comment_type
+%type <objtype>        reindex_type drop_type comment_type security_label_type
 
-%type <node>   fetch_direction limit_clause select_limit_value
+%type <node>   fetch_args limit_clause select_limit_value
                                offset_clause select_offset_value
                                select_offset_value2 opt_select_fetch_first_value
 %type <ival>   row_or_rows first_or_next
@@ -343,12 +349,16 @@ static TypeName *TableFuncTypeName(List *columns);
 
 %type <vsetstmt> set_rest SetResetClause
 
-%type <node>   TableElement ConstraintElem TableFuncElement
-%type <node>   columnDef
+%type <node>   TableElement TypedTableElement ConstraintElem TableFuncElement
+%type <node>   columnDef columnOptions
 %type <defelt> def_elem reloption_elem old_aggr_elem
 %type <node>   def_arg columnElem where_clause where_or_current_clause
                                a_expr b_expr c_expr func_expr AexprConst indirection_el
                                columnref in_expr having_clause func_table array_expr
+                               ExclusionWhereClause
+%type <list>   ExclusionConstraintList ExclusionConstraintElem
+%type <list>   func_arg_list
+%type <node>   func_arg_expr
 %type <list>   row type_list array_expr_list
 %type <node>   case_expr case_arg when_clause case_default
 %type <list>   when_clause_list
@@ -356,6 +366,7 @@ static TypeName *TableFuncTypeName(List *columns);
 %type <list>   OptCreateAs CreateAsList
 %type <node>   CreateAsElement ctext_expr
 %type <value>  NumericOnly
+%type <list>   NumericOnly_list
 %type <alias>  alias_clause
 %type <sortby> sortby
 %type <ielem>  index_elem
@@ -390,7 +401,7 @@ static TypeName *TableFuncTypeName(List *columns);
 %type <boolean> opt_varying opt_timezone
 
 %type <ival>   Iconst SignedIconst
-%type <str>            Sconst comment_text
+%type <str>            Sconst comment_text notify_payload
 %type <str>            RoleId opt_granted_by opt_boolean ColId_or_Sconst
 %type <list>   var_list
 %type <str>            ColId ColLabel var_name type_function_name param_name
@@ -400,8 +411,7 @@ static TypeName *TableFuncTypeName(List *columns);
 %type <keyword> col_name_keyword reserved_keyword
 
 %type <node>   TableConstraint TableLikeClause
-%type <list>   TableLikeOptionList
-%type <ival>   TableLikeOption
+%type <ival>   TableLikeOptionList TableLikeOption
 %type <list>   ColQualList
 %type <node>   ColConstraint ColConstraintElem ConstraintAttr
 %type <ival>   key_actions key_delete key_match key_update key_action
@@ -413,20 +423,23 @@ static TypeName *TableFuncTypeName(List *columns);
 %type <str>            OptTableSpace OptConsTableSpace OptTableSpaceOwner
 %type <list>   opt_check_option
 
+%type <str>            opt_provider security_label
+
 %type <target> xml_attribute_el
 %type <list>   xml_attribute_list xml_attributes
 %type <node>   xml_root_version opt_xml_root_standalone
+%type <node>   xmlexists_argument
 %type <ival>   document_or_content
 %type <boolean> xml_whitespace_option
 
 %type <node>   common_table_expr
-%type <with>   with_clause
+%type <with>   with_clause opt_with_clause
 %type <list>   cte_list
 
 %type <list>   window_clause window_definition_list opt_partition_clause
 %type <windef> window_definition over_clause window_specification
+                               opt_frame_clause frame_extent frame_bound
 %type <str>            opt_existing_window_name
-%type <ival>   opt_frame_clause frame_extent frame_bound
 
 
 /*
@@ -435,8 +448,8 @@ static TypeName *TableFuncTypeName(List *columns);
  * the set of keywords.  PL/pgsql depends on this so that it can share the
  * same lexer.  If you add/change tokens here, fix PL/pgsql to match!
  *
- * DOT_DOT and COLON_EQUALS are unused in the core SQL grammar, and so will
- * always provoke parse errors.  They are needed by PL/pgsql.
+ * DOT_DOT is unused in the core SQL grammar, and so will always provoke
+ * parse errors.  It is needed by PL/pgsql.
  */
 %token <str>   IDENT FCONST SCONST BCONST XCONST Op
 %token <ival>  ICONST PARAM
@@ -452,14 +465,14 @@ static TypeName *TableFuncTypeName(List *columns);
 /* ordinary key words in alphabetical order */
 %token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER
        AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC
-       ASSERTION ASSIGNMENT ASYMMETRIC AT AUTHORIZATION
+       ASSERTION ASSIGNMENT ASYMMETRIC AT ATTRIBUTE AUTHORIZATION
 
        BACKWARD BEFORE BEGIN_P BETWEEN BIGINT BINARY BIT
        BOOLEAN_P BOTH BY
 
        CACHE CALLED CASCADE CASCADED CASE CAST CATALOG_P CHAIN CHAR_P
        CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
-       CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
+       CLUSTER COALESCE COLLATE COLUMN COMMENT COMMENTS COMMIT
        COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS
        CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CREATEDB
        CREATEROLE CREATEUSER CROSS CSV CURRENT_P
@@ -471,17 +484,17 @@ static TypeName *TableFuncTypeName(List *columns);
        DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP
 
        EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ENUM_P ESCAPE EXCEPT
-       EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
+       EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
 
        FALSE_P FAMILY FETCH FIRST_P FLOAT_P FOLLOWING FOR FORCE FOREIGN FORWARD
-       FREEZE FROM FULL FUNCTION
+       FREEZE FROM FULL FUNCTION FUNCTIONS
 
        GLOBAL GRANT GRANTED GREATEST GROUP_P
 
        HANDLER HAVING HEADER_P HOLD HOUR_P
 
        IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P
-       INCLUDING INCREMENT INDEX INDEXES INHERIT INHERITS INITIALLY
+       INCLUDING INCREMENT INDEX INDEXES INHERIT INHERITS INITIALLY INLINE_P
        INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
        INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
 
@@ -489,36 +502,36 @@ static TypeName *TableFuncTypeName(List *columns);
 
        KEY
 
-       LANCOMPILER LANGUAGE LARGE_P LAST_P LC_COLLATE_P LC_CTYPE_P LEADING
+       LABEL LANGUAGE LARGE_P LAST_P LC_COLLATE_P LC_CTYPE_P LEADING
        LEAST LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP
        LOCATION LOCK_P LOGIN_P
 
        MAPPING MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
 
-       NAME_P NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB
+       NAME_P NAMES NATIONAL NATURAL NCHAR NEXT NO NOCREATEDB
        NOCREATEROLE NOCREATEUSER NOINHERIT NOLOGIN_P NONE NOSUPERUSER
        NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF NULLS_P NUMERIC
 
-       OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OPTIONS OR
+       OBJECT_P OF OFF OFFSET OIDS ON ONLY OPERATOR OPTION OPTIONS OR
        ORDER OUT_P OUTER_P OVER OVERLAPS OVERLAY OWNED OWNER
 
-       PARSER PARTIAL PARTITION PASSWORD PLACING PLANS POSITION
+       PARSER PARTIAL PARTITION PASSING PASSWORD PLACING PLANS POSITION
        PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY
        PRIOR PRIVILEGES PROCEDURAL PROCEDURE
 
        QUOTE
 
-       RANGE READ REAL REASSIGN RECHECK RECURSIVE REFERENCES REINDEX
+       RANGE READ REAL REASSIGN RECHECK RECURSIVE REF REFERENCES REINDEX
        RELATIVE_P RELEASE RENAME REPEATABLE REPLACE REPLICA RESET RESTART
        RESTRICT RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROW ROWS RULE
 
-       SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE
+       SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE SEQUENCES
        SERIALIZABLE SERVER SESSION SESSION_USER SET SETOF SHARE
        SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE_P START STATEMENT
        STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P SUBSTRING SUPERUSER_P
        SYMMETRIC SYSID SYSTEM_P
 
-       TABLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP
+       TABLE TABLES TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP
        TO TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P
        TRUNCATE TRUSTED TYPE_P
 
@@ -530,7 +543,7 @@ static TypeName *TableFuncTypeName(List *columns);
 
        WHEN WHERE WHITESPACE_P WINDOW WITH WITHOUT WORK WRAPPER WRITE
 
-       XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLFOREST XMLPARSE
+       XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLEXISTS XMLFOREST XMLPARSE
        XMLPI XMLROOT XMLSERIALIZE
 
        YEAR_P YES_P
@@ -569,8 +582,18 @@ static TypeName *TableFuncTypeName(List *columns);
  * RANGE, ROWS to support opt_existing_window_name; and for RANGE, ROWS
  * so that they can follow a_expr without creating
  * postfix-operator problems.
+ *
+ * The frame_bound productions UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING
+ * are even messier: since UNBOUNDED is an unreserved keyword (per spec!),
+ * there is no principled way to distinguish these from the productions
+ * a_expr PRECEDING/FOLLOWING.  We hack this up by giving UNBOUNDED slightly
+ * lower precedence than PRECEDING and FOLLOWING.  At present this doesn't
+ * appear to cause UNBOUNDED to be treated differently from other unreserved
+ * keywords anywhere else in the grammar, but it's definitely risky.  We can
+ * blame any funny behavior of UNBOUNDED on the SQL standard, though.
  */
-%nonassoc      IDENT PARTITION RANGE ROWS
+%nonassoc      UNBOUNDED               /* ideally should have same precedence as IDENT */
+%nonassoc      IDENT PARTITION RANGE ROWS PRECEDING FOLLOWING
 %left          Op OPERATOR             /* multi-character ops and user-defined operators */
 %nonassoc      NOTNULL
 %nonassoc      ISNULL
@@ -595,6 +618,7 @@ static TypeName *TableFuncTypeName(List *columns);
 %left          JOIN CROSS LEFT FULL RIGHT INNER_P NATURAL
 /* kluge to keep xml_whitespace_option from causing shift/reduce conflicts */
 %right         PRESERVE STRIP_P
+
 %%
 
 /*
@@ -626,6 +650,7 @@ stmtmulti:  stmtmulti ';' stmt
 stmt :
                        AlterDatabaseStmt
                        | AlterDatabaseSetStmt
+                       | AlterDefaultPrivilegesStmt
                        | AlterDomainStmt
                        | AlterFdwStmt
                        | AlterForeignServerStmt
@@ -635,6 +660,7 @@ stmt :
                        | AlterOwnerStmt
                        | AlterSeqStmt
                        | AlterTableStmt
+                       | AlterCompositeTypeStmt
                        | AlterRoleSetStmt
                        | AlterRoleStmt
                        | AlterTSConfigurationStmt
@@ -676,6 +702,7 @@ stmt :
                        | DefineStmt
                        | DeleteStmt
                        | DiscardStmt
+                       | DoStmt
                        | DropAssertStmt
                        | DropCastStmt
                        | DropFdwStmt
@@ -714,6 +741,7 @@ stmt :
                        | RevokeStmt
                        | RevokeRoleStmt
                        | RuleStmt
+                       | SecLabelStmt
                        | SelectStmt
                        | TransactionStmt
                        | TruncateStmt
@@ -756,11 +784,16 @@ opt_with: WITH                                                                    {}
  * is "WITH ADMIN name".
  */
 OptRoleList:
-                       OptRoleList OptRoleElem                                 { $$ = lappend($1, $2); }
+                       OptRoleList CreateOptRoleElem                   { $$ = lappend($1, $2); }
                        | /* EMPTY */                                                   { $$ = NIL; }
                ;
 
-OptRoleElem:
+AlterOptRoleList:
+                       AlterOptRoleList AlterOptRoleElem               { $$ = lappend($1, $2); }
+                       | /* EMPTY */                                                   { $$ = NIL; }
+               ;
+
+AlterOptRoleElem:
                        PASSWORD Sconst
                                {
                                        $$ = makeDefElem("password",
@@ -842,7 +875,11 @@ OptRoleElem:
                                {
                                        $$ = makeDefElem("rolemembers", (Node *)$2);
                                }
-               /* The following are not supported by ALTER ROLE/USER/GROUP */
+               ;
+
+CreateOptRoleElem:
+                       AlterOptRoleElem                        { $$ = $1; }
+                       /* The following are not supported by ALTER ROLE/USER/GROUP */
                        | SYSID Iconst
                                {
                                        $$ = makeDefElem("sysid", (Node *)makeInteger($2));
@@ -891,7 +928,7 @@ CreateUserStmt:
  *****************************************************************************/
 
 AlterRoleStmt:
-                       ALTER ROLE RoleId opt_with OptRoleList
+                       ALTER ROLE RoleId opt_with AlterOptRoleList
                                 {
                                        AlterRoleStmt *n = makeNode(AlterRoleStmt);
                                        n->role = $3;
@@ -901,12 +938,18 @@ AlterRoleStmt:
                                 }
                ;
 
+opt_in_database:
+                          /* EMPTY */                                  { $$ = NULL; }
+                       | IN_P DATABASE database_name   { $$ = $3; }
+               ;
+
 AlterRoleSetStmt:
-                       ALTER ROLE RoleId SetResetClause
+                       ALTER ROLE RoleId opt_in_database SetResetClause
                                {
                                        AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
                                        n->role = $3;
-                                       n->setstmt = $4;
+                                       n->database = $4;
+                                       n->setstmt = $5;
                                        $$ = (Node *)n;
                                }
                ;
@@ -919,7 +962,7 @@ AlterRoleSetStmt:
  *****************************************************************************/
 
 AlterUserStmt:
-                       ALTER USER RoleId opt_with OptRoleList
+                       ALTER USER RoleId opt_with AlterOptRoleList
                                 {
                                        AlterRoleStmt *n = makeNode(AlterRoleStmt);
                                        n->role = $3;
@@ -935,6 +978,7 @@ AlterUserSetStmt:
                                {
                                        AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
                                        n->role = $3;
+                                       n->database = NULL;
                                        n->setstmt = $4;
                                        $$ = (Node *)n;
                                }
@@ -1568,8 +1612,16 @@ alter_table_cmds:
                ;
 
 alter_table_cmd:
-                       /* ALTER TABLE <name> ADD [COLUMN] <coldef> */
-                       ADD_P opt_column columnDef
+                       /* ALTER TABLE <name> ADD <coldef> */
+                       ADD_P columnDef
+                               {
+                                       AlterTableCmd *n = makeNode(AlterTableCmd);
+                                       n->subtype = AT_AddColumn;
+                                       n->def = $2;
+                                       $$ = (Node *)n;
+                               }
+                       /* ALTER TABLE <name> ADD COLUMN <coldef> */
+                       | ADD_P COLUMN columnDef
                                {
                                        AlterTableCmd *n = makeNode(AlterTableCmd);
                                        n->subtype = AT_AddColumn;
@@ -1610,13 +1662,22 @@ alter_table_cmd:
                                        n->def = (Node *) makeInteger($6);
                                        $$ = (Node *)n;
                                }
-                       /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET STATISTICS DISTINCT <NumericOnly> */
-                       | ALTER opt_column ColId SET STATISTICS DISTINCT NumericOnly
+                       /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET ( column_parameter = value [, ... ] ) */
+                       | ALTER opt_column ColId SET reloptions
+                               {
+                                       AlterTableCmd *n = makeNode(AlterTableCmd);
+                                       n->subtype = AT_SetOptions;
+                                       n->name = $3;
+                                       n->def = (Node *) $5;
+                                       $$ = (Node *)n;
+                               }
+                       /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET ( column_parameter = value [, ... ] ) */
+                       | ALTER opt_column ColId RESET reloptions
                                {
                                        AlterTableCmd *n = makeNode(AlterTableCmd);
-                                       n->subtype = AT_SetDistinct;
+                                       n->subtype = AT_ResetOptions;
                                        n->name = $3;
-                                       n->def = (Node *) $7;
+                                       n->def = (Node *) $5;
                                        $$ = (Node *)n;
                                }
                        /* ALTER TABLE <name> ALTER [COLUMN] <colname> SET STORAGE <storagemode> */
@@ -1891,7 +1952,7 @@ reloption_list:
                ;
 
 /* This should match def_elem and also allow qualified names */
-reloption_elem:        
+reloption_elem:
                        ColLabel '=' def_arg
                                {
                                        $$ = makeDefElem($1, (Node *) $3);
@@ -1912,6 +1973,72 @@ reloption_elem:
                ;
 
 
+/*****************************************************************************
+ *
+ *     ALTER TYPE
+ *
+ * really variants of the ALTER TABLE subcommands with different spellings
+ *****************************************************************************/
+
+AlterCompositeTypeStmt:
+                       ALTER TYPE_P any_name alter_type_cmds
+                               {
+                                       AlterTableStmt *n = makeNode(AlterTableStmt);
+
+                                       /* can't use qualified_name, sigh */
+                                       n->relation = makeRangeVarFromAnyName($3, @3, yyscanner);
+                                       n->cmds = $4;
+                                       n->relkind = OBJECT_TYPE;
+                                       $$ = (Node *)n;
+                               }
+                       ;
+
+alter_type_cmds:
+                       alter_type_cmd                                                  { $$ = list_make1($1); }
+                       | alter_type_cmds ',' alter_type_cmd    { $$ = lappend($1, $3); }
+               ;
+
+alter_type_cmd:
+                       /* ALTER TYPE <name> ADD ATTRIBUTE <coldef> */
+                       ADD_P ATTRIBUTE TableFuncElement
+                               {
+                                       AlterTableCmd *n = makeNode(AlterTableCmd);
+                                       n->subtype = AT_AddColumn;
+                                       n->def = $3;
+                                       $$ = (Node *)n;
+                               }
+                       /* ALTER TYPE <name> DROP ATTRIBUTE IF EXISTS <attname> */
+                       | DROP ATTRIBUTE IF_P EXISTS ColId
+                               {
+                                       AlterTableCmd *n = makeNode(AlterTableCmd);
+                                       n->subtype = AT_DropColumn;
+                                       n->name = $5;
+                                       n->behavior = DROP_RESTRICT; /* currently no effect */
+                                       n->missing_ok = TRUE;
+                                       $$ = (Node *)n;
+                               }
+                       /* ALTER TYPE <name> DROP ATTRIBUTE <attname> */
+                       | DROP ATTRIBUTE ColId opt_drop_behavior
+                               {
+                                       AlterTableCmd *n = makeNode(AlterTableCmd);
+                                       n->subtype = AT_DropColumn;
+                                       n->name = $3;
+                                       n->behavior = DROP_RESTRICT; /* currently no effect */
+                                       n->missing_ok = FALSE;
+                                       $$ = (Node *)n;
+                               }
+                       /* ALTER TYPE <name> ALTER ATTRIBUTE <attname> [SET DATA] TYPE <typename> */
+                       | ALTER ATTRIBUTE ColId opt_set_data TYPE_P Typename
+                               {
+                                       AlterTableCmd *n = makeNode(AlterTableCmd);
+                                       n->subtype = AT_AlterColumnType;
+                                       n->name = $3;
+                                       n->def = (Node *) $6;
+                                       $$ = (Node *)n;
+                               }
+               ;
+
+
 /*****************************************************************************
  *
  *             QUERY :
@@ -1920,7 +2047,7 @@ reloption_elem:
  *****************************************************************************/
 
 ClosePortalStmt:
-                       CLOSE name
+                       CLOSE cursor_name
                                {
                                        ClosePortalStmt *n = makeNode(ClosePortalStmt);
                                        n->portalname = $2;
@@ -1942,7 +2069,7 @@ ClosePortalStmt:
  *                             COPY ( SELECT ... ) TO file [WITH] [(options)]
  *
  *                             In the preferred syntax the options are comma-separated
- *                             and use generic identifiers instead of keywords.  The pre-8.5
+ *                             and use generic identifiers instead of keywords.  The pre-9.0
  *                             syntax had a hard-wired, space-separated set of options.
  *
  *                             Really old syntax, from versions 7.2 and prior:
@@ -2157,23 +2284,55 @@ CreateStmt:     CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
                                        n->options = $9;
                                        n->oncommit = $10;
                                        n->tablespacename = $11;
+                                       n->if_not_exists = false;
                                        $$ = (Node *)n;
                                }
-               | CREATE OptTemp TABLE qualified_name OF qualified_name
-                       '(' OptTableElementList ')' OptWith OnCommitOption OptTableSpace
+               | CREATE OptTemp TABLE IF_P NOT EXISTS qualified_name '('
+                       OptTableElementList ')' OptInherit OptWith OnCommitOption
+                       OptTableSpace
+                               {
+                                       CreateStmt *n = makeNode(CreateStmt);
+                                       $7->istemp = $2;
+                                       n->relation = $7;
+                                       n->tableElts = $9;
+                                       n->inhRelations = $11;
+                                       n->constraints = NIL;
+                                       n->options = $12;
+                                       n->oncommit = $13;
+                                       n->tablespacename = $14;
+                                       n->if_not_exists = true;
+                                       $$ = (Node *)n;
+                               }
+               | CREATE OptTemp TABLE qualified_name OF any_name
+                       OptTypedTableElementList OptWith OnCommitOption OptTableSpace
                                {
-                                       /* SQL99 CREATE TABLE OF <UDT> (cols) seems to be satisfied
-                                        * by our inheritance capabilities. Let's try it...
-                                        */
                                        CreateStmt *n = makeNode(CreateStmt);
                                        $4->istemp = $2;
                                        n->relation = $4;
-                                       n->tableElts = $8;
-                                       n->inhRelations = list_make1($6);
+                                       n->tableElts = $7;
+                                       n->ofTypename = makeTypeNameFromNameList($6);
+                                       n->ofTypename->location = @6;
                                        n->constraints = NIL;
-                                       n->options = $10;
-                                       n->oncommit = $11;
-                                       n->tablespacename = $12;
+                                       n->options = $8;
+                                       n->oncommit = $9;
+                                       n->tablespacename = $10;
+                                       n->if_not_exists = false;
+                                       $$ = (Node *)n;
+                               }
+               | CREATE OptTemp TABLE IF_P NOT EXISTS qualified_name OF any_name
+                       OptTypedTableElementList OptWith OnCommitOption OptTableSpace
+                               {
+                                       CreateStmt *n = makeNode(CreateStmt);
+                                       $7->istemp = $2;
+                                       n->relation = $7;
+                                       n->tableElts = $10;
+                                       n->ofTypename = makeTypeNameFromNameList($9);
+                                       n->ofTypename->location = @9;
+                                       n->constraints = NIL;
+                                       n->options = $11;
+                                       n->oncommit = $12;
+                                       n->tablespacename = $13;
+                                       n->if_not_exists = true;
                                        $$ = (Node *)n;
                                }
                ;
@@ -2199,6 +2358,11 @@ OptTableElementList:
                        | /*EMPTY*/                                                     { $$ = NIL; }
                ;
 
+OptTypedTableElementList:
+                       '(' TypedTableElementList ')'           { $$ = $2; }
+                       | /*EMPTY*/                                                     { $$ = NIL; }
+               ;
+
 TableElementList:
                        TableElement
                                {
@@ -2210,12 +2374,28 @@ TableElementList:
                                }
                ;
 
+TypedTableElementList:
+                       TypedTableElement
+                               {
+                                       $$ = list_make1($1);
+                               }
+                       | TypedTableElementList ',' TypedTableElement
+                               {
+                                       $$ = lappend($1, $3);
+                               }
+               ;
+
 TableElement:
                        columnDef                                                       { $$ = $1; }
                        | TableLikeClause                                       { $$ = $1; }
                        | TableConstraint                                       { $$ = $1; }
                ;
 
+TypedTableElement:
+                       columnOptions                                           { $$ = $1; }
+                       | TableConstraint                                       { $$ = $1; }
+               ;
+
 columnDef:     ColId Typename ColQualList
                                {
                                        ColumnDef *n = makeNode(ColumnDef);
@@ -2227,6 +2407,16 @@ columnDef:       ColId Typename ColQualList
                                }
                ;
 
+columnOptions: ColId WITH OPTIONS ColQualList
+                               {
+                                       ColumnDef *n = makeNode(ColumnDef);
+                                       n->colname = $1;
+                                       n->constraints = $4;
+                                       n->is_local = true;
+                                       $$ = (Node *)n;
+                               }
+               ;
+
 ColQualList:
                        ColQualList ColConstraint                               { $$ = lappend($1, $2); }
                        | /*EMPTY*/                                                             { $$ = NIL; }
@@ -2392,17 +2582,18 @@ TableLikeClause:
                ;
 
 TableLikeOptionList:
-                               TableLikeOptionList TableLikeOption     { $$ = lappend_int($1, $2); }
-                               | /* EMPTY */                                           { $$ = NIL; }
+                               TableLikeOptionList INCLUDING TableLikeOption   { $$ = $1 | $3; }
+                               | TableLikeOptionList EXCLUDING TableLikeOption { $$ = $1 & ~$3; }
+                               | /* EMPTY */                                           { $$ = 0; }
                ;
 
 TableLikeOption:
-                               INCLUDING DEFAULTS                                      { $$ =  CREATE_TABLE_LIKE_INCLUDING_DEFAULTS; }
-                               | EXCLUDING DEFAULTS                            { $$ =  CREATE_TABLE_LIKE_EXCLUDING_DEFAULTS; }
-                               | INCLUDING CONSTRAINTS                         { $$ =  CREATE_TABLE_LIKE_INCLUDING_CONSTRAINTS; }
-                               | EXCLUDING CONSTRAINTS                         { $$ =  CREATE_TABLE_LIKE_EXCLUDING_CONSTRAINTS; }
-                               | INCLUDING INDEXES                                     { $$ =  CREATE_TABLE_LIKE_INCLUDING_INDEXES; }
-                               | EXCLUDING INDEXES                                     { $$ =  CREATE_TABLE_LIKE_EXCLUDING_INDEXES; }
+                               DEFAULTS                        { $$ = CREATE_TABLE_LIKE_DEFAULTS; }
+                               | CONSTRAINTS           { $$ = CREATE_TABLE_LIKE_CONSTRAINTS; }
+                               | INDEXES                       { $$ = CREATE_TABLE_LIKE_INDEXES; }
+                               | STORAGE                       { $$ = CREATE_TABLE_LIKE_STORAGE; }
+                               | COMMENTS                      { $$ = CREATE_TABLE_LIKE_COMMENTS; }
+                               | ALL                           { $$ = CREATE_TABLE_LIKE_ALL; }
                ;
 
 
@@ -2463,6 +2654,22 @@ ConstraintElem:
                                        n->initdeferred = ($8 & 2) != 0;
                                        $$ = (Node *)n;
                                }
+                       | EXCLUDE access_method_clause '(' ExclusionConstraintList ')'
+                               opt_definition OptConsTableSpace ExclusionWhereClause
+                               ConstraintAttributeSpec
+                               {
+                                       Constraint *n = makeNode(Constraint);
+                                       n->contype = CONSTR_EXCLUSION;
+                                       n->location = @1;
+                                       n->access_method        = $2;
+                                       n->exclusions           = $4;
+                                       n->options                      = $6;
+                                       n->indexspace           = $7;
+                                       n->where_clause         = $8;
+                                       n->deferrable           = ($9 & 1) != 0;
+                                       n->initdeferred         = ($9 & 2) != 0;
+                                       $$ = (Node *)n;
+                               }
                        | FOREIGN KEY '(' columnList ')' REFERENCES qualified_name
                                opt_column_list key_match key_actions ConstraintAttributeSpec
                                {
@@ -2520,6 +2727,28 @@ key_match:  MATCH FULL
                        }
                ;
 
+ExclusionConstraintList:
+                       ExclusionConstraintElem                                 { $$ = list_make1($1); }
+                       | ExclusionConstraintList ',' ExclusionConstraintElem
+                                                                                                       { $$ = lappend($1, $3); }
+               ;
+
+ExclusionConstraintElem: index_elem WITH any_operator
+                       {
+                               $$ = list_make2($1, $3);
+                       }
+                       /* allow OPERATOR() decoration for the benefit of ruleutils.c */
+                       | index_elem WITH OPERATOR '(' any_operator ')'
+                       {
+                               $$ = list_make2($1, $5);
+                       }
+               ;
+
+ExclusionWhereClause:
+                       WHERE '(' a_expr ')'                                    { $$ = $3; }
+                       | /*EMPTY*/                                                             { $$ = NULL; }
+               ;
+
 /*
  * We combine the update and delete actions into one value temporarily
  * for simplicity of parsing, and then break them down again in the
@@ -2670,6 +2899,7 @@ CreateSeqStmt:
                                        $4->istemp = $2;
                                        n->sequence = $4;
                                        n->options = $5;
+                                       n->ownerId = InvalidOid;
                                        $$ = (Node *)n;
                                }
                ;
@@ -2756,34 +2986,41 @@ NumericOnly:
                        | SignedIconst                                          { $$ = makeInteger($1); }
                ;
 
+NumericOnly_list:      NumericOnly                                             { $$ = list_make1($1); }
+                               | NumericOnly_list ',' NumericOnly      { $$ = lappend($1, $3); }
+               ;
+
 /*****************************************************************************
  *
  *             QUERIES :
- *                             CREATE PROCEDURAL LANGUAGE ...
- *                             DROP PROCEDURAL LANGUAGE ...
+ *                             CREATE [OR REPLACE] [TRUSTED] [PROCEDURAL] LANGUAGE ...
+ *                             DROP [PROCEDURAL] LANGUAGE ...
  *
  *****************************************************************************/
 
 CreatePLangStmt:
-                       CREATE opt_trusted opt_procedural LANGUAGE ColId_or_Sconst
+                       CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE ColId_or_Sconst
                        {
                                CreatePLangStmt *n = makeNode(CreatePLangStmt);
-                               n->plname = $5;
+                               n->replace = $2;
+                               n->plname = $6;
                                /* parameters are all to be supplied by system */
                                n->plhandler = NIL;
+                               n->plinline = NIL;
                                n->plvalidator = NIL;
                                n->pltrusted = false;
                                $$ = (Node *)n;
                        }
-                       | CREATE opt_trusted opt_procedural LANGUAGE ColId_or_Sconst
-                         HANDLER handler_name opt_validator opt_lancompiler
+                       | CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE ColId_or_Sconst
+                         HANDLER handler_name opt_inline_handler opt_validator
                        {
                                CreatePLangStmt *n = makeNode(CreatePLangStmt);
-                               n->plname = $5;
-                               n->plhandler = $7;
-                               n->plvalidator = $8;
-                               n->pltrusted = $2;
-                               /* LANCOMPILER is now ignored entirely */
+                               n->replace = $2;
+                               n->plname = $6;
+                               n->plhandler = $8;
+                               n->plinline = $9;
+                               n->plvalidator = $10;
+                               n->pltrusted = $3;
                                $$ = (Node *)n;
                        }
                ;
@@ -2802,6 +3039,11 @@ handler_name:
                        | name attrs                            { $$ = lcons(makeString($1), $2); }
                ;
 
+opt_inline_handler:
+                       INLINE_P handler_name                                   { $$ = $2; }
+                       | /*EMPTY*/                                                             { $$ = NIL; }
+               ;
+
 validator_clause:
                        VALIDATOR handler_name                                  { $$ = $2; }
                        | NO VALIDATOR                                                  { $$ = NIL; }
@@ -2812,11 +3054,6 @@ opt_validator:
                        | /*EMPTY*/                                                             { $$ = NIL; }
                ;
 
-opt_lancompiler:
-                       LANCOMPILER Sconst                                              { $$ = $2; }
-                       | /*EMPTY*/                                                             { $$ = NULL; }
-               ;
-
 DropPLangStmt:
                        DROP opt_procedural LANGUAGE ColId_or_Sconst opt_drop_behavior
                                {
@@ -3203,17 +3440,19 @@ AlterUserMappingStmt: ALTER USER MAPPING FOR auth_ident SERVER name alter_generi
 
 CreateTrigStmt:
                        CREATE TRIGGER name TriggerActionTime TriggerEvents ON
-                       qualified_name TriggerForSpec EXECUTE PROCEDURE
-                       func_name '(' TriggerFuncArgs ')'
+                       qualified_name TriggerForSpec TriggerWhen
+                       EXECUTE PROCEDURE func_name '(' TriggerFuncArgs ')'
                                {
                                        CreateTrigStmt *n = makeNode(CreateTrigStmt);
                                        n->trigname = $3;
                                        n->relation = $7;
-                                       n->funcname = $11;
-                                       n->args = $13;
-                                       n->before = $4;
+                                       n->funcname = $12;
+                                       n->args = $14;
                                        n->row = $8;
-                                       n->events = $5;
+                                       n->timing = $4;
+                                       n->events = intVal(linitial($5));
+                                       n->columns = (List *) lsecond($5);
+                                       n->whenClause = $9;
                                        n->isconstraint  = FALSE;
                                        n->deferrable    = FALSE;
                                        n->initdeferred  = FALSE;
@@ -3221,19 +3460,20 @@ CreateTrigStmt:
                                        $$ = (Node *)n;
                                }
                        | CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON
-                       qualified_name OptConstrFromTable
-                       ConstraintAttributeSpec
-                       FOR EACH ROW EXECUTE PROCEDURE
-                       func_name '(' TriggerFuncArgs ')'
+                       qualified_name OptConstrFromTable ConstraintAttributeSpec
+                       FOR EACH ROW TriggerWhen
+                       EXECUTE PROCEDURE func_name '(' TriggerFuncArgs ')'
                                {
                                        CreateTrigStmt *n = makeNode(CreateTrigStmt);
                                        n->trigname = $4;
                                        n->relation = $8;
-                                       n->funcname = $16;
-                                       n->args = $18;
-                                       n->before = FALSE;
+                                       n->funcname = $17;
+                                       n->args = $19;
                                        n->row = TRUE;
-                                       n->events = $6;
+                                       n->timing = TRIGGER_TYPE_AFTER;
+                                       n->events = intVal(linitial($6));
+                                       n->columns = (List *) lsecond($6);
+                                       n->whenClause = $14;
                                        n->isconstraint  = TRUE;
                                        n->deferrable = ($10 & 1) != 0;
                                        n->initdeferred = ($10 & 2) != 0;
@@ -3243,8 +3483,9 @@ CreateTrigStmt:
                ;
 
 TriggerActionTime:
-                       BEFORE                                                                  { $$ = TRUE; }
-                       | AFTER                                                                 { $$ = FALSE; }
+                       BEFORE                                                          { $$ = TRIGGER_TYPE_BEFORE; }
+                       | AFTER                                                         { $$ = TRIGGER_TYPE_AFTER; }
+                       | INSTEAD OF                                            { $$ = TRIGGER_TYPE_INSTEAD; }
                ;
 
 TriggerEvents:
@@ -3252,21 +3493,40 @@ TriggerEvents:
                                { $$ = $1; }
                        | TriggerEvents OR TriggerOneEvent
                                {
-                                       if ($1 & $3)
+                                       int             events1 = intVal(linitial($1));
+                                       int             events2 = intVal(linitial($3));
+                                       List   *columns1 = (List *) lsecond($1);
+                                       List   *columns2 = (List *) lsecond($3);
+
+                                       if (events1 & events2)
                                                parser_yyerror("duplicate trigger events specified");
-                                       $$ = $1 | $3;
+                                       /*
+                                        * concat'ing the columns lists loses information about
+                                        * which columns went with which event, but so long as
+                                        * only UPDATE carries columns and we disallow multiple
+                                        * UPDATE items, it doesn't matter.  Command execution
+                                        * should just ignore the columns for non-UPDATE events.
+                                        */
+                                       $$ = list_make2(makeInteger(events1 | events2),
+                                                                       list_concat(columns1, columns2));
                                }
                ;
 
 TriggerOneEvent:
-                       INSERT                                                          { $$ = TRIGGER_TYPE_INSERT; }
-                       | DELETE_P                                                      { $$ = TRIGGER_TYPE_DELETE; }
-                       | UPDATE                                                        { $$ = TRIGGER_TYPE_UPDATE; }
-                       | TRUNCATE                                                      { $$ = TRIGGER_TYPE_TRUNCATE; }
+                       INSERT
+                               { $$ = list_make2(makeInteger(TRIGGER_TYPE_INSERT), NIL); }
+                       | DELETE_P
+                               { $$ = list_make2(makeInteger(TRIGGER_TYPE_DELETE), NIL); }
+                       | UPDATE
+                               { $$ = list_make2(makeInteger(TRIGGER_TYPE_UPDATE), NIL); }
+                       | UPDATE OF columnList
+                               { $$ = list_make2(makeInteger(TRIGGER_TYPE_UPDATE), $3); }
+                       | TRUNCATE
+                               { $$ = list_make2(makeInteger(TRIGGER_TYPE_TRUNCATE), NIL); }
                ;
 
 TriggerForSpec:
-                       FOR TriggerForOpt TriggerForType
+                       FOR TriggerForOptEach TriggerForType
                                {
                                        $$ = $3;
                                }
@@ -3280,7 +3540,7 @@ TriggerForSpec:
                                }
                ;
 
-TriggerForOpt:
+TriggerForOptEach:
                        EACH                                                                    {}
                        | /*EMPTY*/                                                             {}
                ;
@@ -3290,6 +3550,11 @@ TriggerForType:
                        | STATEMENT                                                             { $$ = FALSE; }
                ;
 
+TriggerWhen:
+                       WHEN '(' a_expr ')'                                             { $$ = $3; }
+                       | /*EMPTY*/                                                             { $$ = NULL; }
+               ;
+
 TriggerFuncArgs:
                        TriggerFuncArg                                                  { $$ = list_make1($1); }
                        | TriggerFuncArgs ',' TriggerFuncArg    { $$ = lappend($1, $3); }
@@ -3485,43 +3750,16 @@ DefineStmt:
                                        n->definition = NIL;
                                        $$ = (Node *)n;
                                }
-                       | CREATE TYPE_P any_name AS '(' TableFuncElementList ')'
+                       | CREATE TYPE_P any_name AS '(' OptTableFuncElementList ')'
                                {
                                        CompositeTypeStmt *n = makeNode(CompositeTypeStmt);
-                                       RangeVar *r = makeNode(RangeVar);
 
                                        /* can't use qualified_name, sigh */
-                                       switch (list_length($3))
-                                       {
-                                               case 1:
-                                                       r->catalogname = NULL;
-                                                       r->schemaname = NULL;
-                                                       r->relname = strVal(linitial($3));
-                                                       break;
-                                               case 2:
-                                                       r->catalogname = NULL;
-                                                       r->schemaname = strVal(linitial($3));
-                                                       r->relname = strVal(lsecond($3));
-                                                       break;
-                                               case 3:
-                                                       r->catalogname = strVal(linitial($3));
-                                                       r->schemaname = strVal(lsecond($3));
-                                                       r->relname = strVal(lthird($3));
-                                                       break;
-                                               default:
-                                                       ereport(ERROR,
-                                                                       (errcode(ERRCODE_SYNTAX_ERROR),
-                                                                        errmsg("improper qualified name (too many dotted names): %s",
-                                                                                       NameListToString($3)),
-                                                                                       parser_errposition(@3)));
-                                                       break;
-                                       }
-                                       r->location = @3;
-                                       n->typevar = r;
+                                       n->typevar = makeRangeVarFromAnyName($3, @3, yyscanner);
                                        n->coldeflist = $6;
                                        $$ = (Node *)n;
                                }
-                       | CREATE TYPE_P any_name AS ENUM_P '(' enum_val_list ')'
+                       | CREATE TYPE_P any_name AS ENUM_P '(' opt_enum_val_list ')'
                                {
                                        CreateEnumStmt *n = makeNode(CreateEnumStmt);
                                        n->typeName = $3;
@@ -3613,6 +3851,11 @@ old_aggr_elem:  IDENT '=' def_arg
                                }
                ;
 
+opt_enum_val_list:
+               enum_val_list                                                   { $$ = $1; }
+               | /*EMPTY*/                                                             { $$ = NIL; }
+               ;
+
 enum_val_list: Sconst
                                { $$ = list_make1(makeString($1)); }
                        | enum_val_list ',' Sconst
@@ -4129,6 +4372,92 @@ comment_text:
                        | NULL_P                                                        { $$ = NULL; }
                ;
 
+
+/*****************************************************************************
+ *
+ *  SECURITY LABEL [FOR <provider>] ON <object> IS <label>
+ *
+ *  As with COMMENT ON, <object> can refer to various types of database
+ *  objects (e.g. TABLE, COLUMN, etc.).
+ *
+ *****************************************************************************/
+
+SecLabelStmt:
+                       SECURITY LABEL opt_provider ON security_label_type any_name
+                       IS security_label
+                               {
+                                       SecLabelStmt *n = makeNode(SecLabelStmt);
+                                       n->provider = $3;
+                                       n->objtype = $5;
+                                       n->objname = $6;
+                                       n->objargs = NIL;
+                                       n->label = $8;
+                                       $$ = (Node *) n;
+                               }
+                       | SECURITY LABEL opt_provider ON AGGREGATE func_name aggr_args
+                         IS security_label
+                               {
+                                       SecLabelStmt *n = makeNode(SecLabelStmt);
+                                       n->provider = $3;
+                                       n->objtype = OBJECT_AGGREGATE;
+                                       n->objname = $6;
+                                       n->objargs = $7;
+                                       n->label = $9;
+                                       $$ = (Node *) n;
+                               }
+                       | SECURITY LABEL opt_provider ON FUNCTION func_name func_args
+                         IS security_label
+                               {
+                                       SecLabelStmt *n = makeNode(SecLabelStmt);
+                                       n->provider = $3;
+                                       n->objtype = OBJECT_FUNCTION;
+                                       n->objname = $6;
+                                       n->objargs = extractArgTypes($7);
+                                       n->label = $9;
+                                       $$ = (Node *) n;
+                               }
+                       | SECURITY LABEL opt_provider ON LARGE_P OBJECT_P NumericOnly
+                         IS security_label
+                               {
+                                       SecLabelStmt *n = makeNode(SecLabelStmt);
+                                       n->provider = $3;
+                                       n->objtype = OBJECT_LARGEOBJECT;
+                                       n->objname = list_make1($7);
+                                       n->objargs = NIL;
+                                       n->label = $9;
+                                       $$ = (Node *) n;
+                               }
+                       | SECURITY LABEL opt_provider ON opt_procedural LANGUAGE any_name
+                         IS security_label
+                               {
+                                       SecLabelStmt *n = makeNode(SecLabelStmt);
+                                       n->provider = $3;
+                                       n->objtype = OBJECT_LANGUAGE;
+                                       n->objname = $7;
+                                       n->objargs = NIL;
+                                       n->label = $9;
+                                       $$ = (Node *) n;
+                               }
+               ;
+
+opt_provider:  FOR ColId_or_Sconst     { $$ = $2; }
+                               | /* empty */           { $$ = NULL; }
+               ;
+
+security_label_type:
+                       COLUMN                                                          { $$ = OBJECT_COLUMN; }
+                       | SCHEMA                                                        { $$ = OBJECT_SCHEMA; }
+                       | SEQUENCE                                                      { $$ = OBJECT_SEQUENCE; }
+                       | TABLE                                                         { $$ = OBJECT_TABLE; }
+                       | DOMAIN_P                                                      { $$ = OBJECT_TYPE; }
+                       | TYPE_P                                                        { $$ = OBJECT_TYPE; }
+                       | VIEW                                                          { $$ = OBJECT_VIEW; }
+               ;
+
+security_label:        Sconst                          { $$ = $1; }
+                               | NULL_P                        { $$ = NULL; }
+               ;
+
 /*****************************************************************************
  *
  *             QUERY:
@@ -4136,142 +4465,144 @@ comment_text:
  *
  *****************************************************************************/
 
-FetchStmt:     FETCH fetch_direction from_in name
+FetchStmt:     FETCH fetch_args
                                {
                                        FetchStmt *n = (FetchStmt *) $2;
-                                       n->portalname = $4;
                                        n->ismove = FALSE;
                                        $$ = (Node *)n;
                                }
-                       | FETCH name
-                               {
-                                       FetchStmt *n = makeNode(FetchStmt);
-                                       n->direction = FETCH_FORWARD;
-                                       n->howMany = 1;
-                                       n->portalname = $2;
-                                       n->ismove = FALSE;
-                                       $$ = (Node *)n;
-                               }
-                       | MOVE fetch_direction from_in name
+                       | MOVE fetch_args
                                {
                                        FetchStmt *n = (FetchStmt *) $2;
-                                       n->portalname = $4;
                                        n->ismove = TRUE;
                                        $$ = (Node *)n;
                                }
-                       | MOVE name
+               ;
+
+fetch_args:    cursor_name
                                {
                                        FetchStmt *n = makeNode(FetchStmt);
+                                       n->portalname = $1;
                                        n->direction = FETCH_FORWARD;
                                        n->howMany = 1;
-                                       n->portalname = $2;
-                                       n->ismove = TRUE;
                                        $$ = (Node *)n;
                                }
-               ;
-
-fetch_direction:
-                       /*EMPTY*/
+                       | from_in cursor_name
                                {
                                        FetchStmt *n = makeNode(FetchStmt);
+                                       n->portalname = $2;
                                        n->direction = FETCH_FORWARD;
                                        n->howMany = 1;
                                        $$ = (Node *)n;
                                }
-                       | NEXT
+                       | NEXT opt_from_in cursor_name
                                {
                                        FetchStmt *n = makeNode(FetchStmt);
+                                       n->portalname = $3;
                                        n->direction = FETCH_FORWARD;
                                        n->howMany = 1;
                                        $$ = (Node *)n;
                                }
-                       | PRIOR
+                       | PRIOR opt_from_in cursor_name
                                {
                                        FetchStmt *n = makeNode(FetchStmt);
+                                       n->portalname = $3;
                                        n->direction = FETCH_BACKWARD;
                                        n->howMany = 1;
                                        $$ = (Node *)n;
                                }
-                       | FIRST_P
+                       | FIRST_P opt_from_in cursor_name
                                {
                                        FetchStmt *n = makeNode(FetchStmt);
+                                       n->portalname = $3;
                                        n->direction = FETCH_ABSOLUTE;
                                        n->howMany = 1;
                                        $$ = (Node *)n;
                                }
-                       | LAST_P
+                       | LAST_P opt_from_in cursor_name
                                {
                                        FetchStmt *n = makeNode(FetchStmt);
+                                       n->portalname = $3;
                                        n->direction = FETCH_ABSOLUTE;
                                        n->howMany = -1;
                                        $$ = (Node *)n;
                                }
-                       | ABSOLUTE_P SignedIconst
+                       | ABSOLUTE_P SignedIconst opt_from_in cursor_name
                                {
                                        FetchStmt *n = makeNode(FetchStmt);
+                                       n->portalname = $4;
                                        n->direction = FETCH_ABSOLUTE;
                                        n->howMany = $2;
                                        $$ = (Node *)n;
                                }
-                       | RELATIVE_P SignedIconst
+                       | RELATIVE_P SignedIconst opt_from_in cursor_name
                                {
                                        FetchStmt *n = makeNode(FetchStmt);
+                                       n->portalname = $4;
                                        n->direction = FETCH_RELATIVE;
                                        n->howMany = $2;
                                        $$ = (Node *)n;
                                }
-                       | SignedIconst
+                       | SignedIconst opt_from_in cursor_name
                                {
                                        FetchStmt *n = makeNode(FetchStmt);
+                                       n->portalname = $3;
                                        n->direction = FETCH_FORWARD;
                                        n->howMany = $1;
                                        $$ = (Node *)n;
                                }
-                       | ALL
+                       | ALL opt_from_in cursor_name
                                {
                                        FetchStmt *n = makeNode(FetchStmt);
+                                       n->portalname = $3;
                                        n->direction = FETCH_FORWARD;
                                        n->howMany = FETCH_ALL;
                                        $$ = (Node *)n;
                                }
-                       | FORWARD
+                       | FORWARD opt_from_in cursor_name
                                {
                                        FetchStmt *n = makeNode(FetchStmt);
+                                       n->portalname = $3;
                                        n->direction = FETCH_FORWARD;
                                        n->howMany = 1;
                                        $$ = (Node *)n;
                                }
-                       | FORWARD SignedIconst
+                       | FORWARD SignedIconst opt_from_in cursor_name
                                {
                                        FetchStmt *n = makeNode(FetchStmt);
+                                       n->portalname = $4;
                                        n->direction = FETCH_FORWARD;
                                        n->howMany = $2;
                                        $$ = (Node *)n;
                                }
-                       | FORWARD ALL
+                       | FORWARD ALL opt_from_in cursor_name
                                {
                                        FetchStmt *n = makeNode(FetchStmt);
+                                       n->portalname = $4;
                                        n->direction = FETCH_FORWARD;
                                        n->howMany = FETCH_ALL;
                                        $$ = (Node *)n;
                                }
-                       | BACKWARD
+                       | BACKWARD opt_from_in cursor_name
                                {
                                        FetchStmt *n = makeNode(FetchStmt);
+                                       n->portalname = $3;
                                        n->direction = FETCH_BACKWARD;
                                        n->howMany = 1;
                                        $$ = (Node *)n;
                                }
-                       | BACKWARD SignedIconst
+                       | BACKWARD SignedIconst opt_from_in cursor_name
                                {
                                        FetchStmt *n = makeNode(FetchStmt);
+                                       n->portalname = $4;
                                        n->direction = FETCH_BACKWARD;
                                        n->howMany = $2;
                                        $$ = (Node *)n;
                                }
-                       | BACKWARD ALL
+                       | BACKWARD ALL opt_from_in cursor_name
                                {
                                        FetchStmt *n = makeNode(FetchStmt);
+                                       n->portalname = $4;
                                        n->direction = FETCH_BACKWARD;
                                        n->howMany = FETCH_ALL;
                                        $$ = (Node *)n;
@@ -4282,6 +4613,10 @@ from_in: FROM                                                                    {}
                        | IN_P                                                                  {}
                ;
 
+opt_from_in:   from_in                                                         {}
+                       | /* EMPTY */                                                   {}
+               ;
+
 
 /*****************************************************************************
  *
@@ -4295,6 +4630,7 @@ GrantStmt:        GRANT privileges ON privilege_target TO grantee_list
                                        GrantStmt *n = makeNode(GrantStmt);
                                        n->is_grant = true;
                                        n->privileges = $2;
+                                       n->targtype = ($4)->targtype;
                                        n->objtype = ($4)->objtype;
                                        n->objects = ($4)->objs;
                                        n->grantees = $6;
@@ -4311,6 +4647,7 @@ RevokeStmt:
                                        n->is_grant = false;
                                        n->grant_option = false;
                                        n->privileges = $2;
+                                       n->targtype = ($4)->targtype;
                                        n->objtype = ($4)->objtype;
                                        n->objects = ($4)->objs;
                                        n->grantees = $6;
@@ -4324,6 +4661,7 @@ RevokeStmt:
                                        n->is_grant = false;
                                        n->grant_option = true;
                                        n->privileges = $5;
+                                       n->targtype = ($7)->targtype;
                                        n->objtype = ($7)->objtype;
                                        n->objects = ($7)->objs;
                                        n->grantees = $9;
@@ -4406,6 +4744,7 @@ privilege_target:
                        qualified_name_list
                                {
                                        PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
+                                       n->targtype = ACL_TARGET_OBJECT;
                                        n->objtype = ACL_OBJECT_RELATION;
                                        n->objs = $1;
                                        $$ = n;
@@ -4413,6 +4752,7 @@ privilege_target:
                        | TABLE qualified_name_list
                                {
                                        PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
+                                       n->targtype = ACL_TARGET_OBJECT;
                                        n->objtype = ACL_OBJECT_RELATION;
                                        n->objs = $2;
                                        $$ = n;
@@ -4420,6 +4760,7 @@ privilege_target:
                        | SEQUENCE qualified_name_list
                                {
                                        PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
+                                       n->targtype = ACL_TARGET_OBJECT;
                                        n->objtype = ACL_OBJECT_SEQUENCE;
                                        n->objs = $2;
                                        $$ = n;
@@ -4427,6 +4768,7 @@ privilege_target:
                        | FOREIGN DATA_P WRAPPER name_list
                                {
                                        PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
+                                       n->targtype = ACL_TARGET_OBJECT;
                                        n->objtype = ACL_OBJECT_FDW;
                                        n->objs = $4;
                                        $$ = n;
@@ -4434,6 +4776,7 @@ privilege_target:
                        | FOREIGN SERVER name_list
                                {
                                        PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
+                                       n->targtype = ACL_TARGET_OBJECT;
                                        n->objtype = ACL_OBJECT_FOREIGN_SERVER;
                                        n->objs = $3;
                                        $$ = n;
@@ -4441,6 +4784,7 @@ privilege_target:
                        | FUNCTION function_with_argtypes_list
                                {
                                        PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
+                                       n->targtype = ACL_TARGET_OBJECT;
                                        n->objtype = ACL_OBJECT_FUNCTION;
                                        n->objs = $2;
                                        $$ = n;
@@ -4448,6 +4792,7 @@ privilege_target:
                        | DATABASE name_list
                                {
                                        PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
+                                       n->targtype = ACL_TARGET_OBJECT;
                                        n->objtype = ACL_OBJECT_DATABASE;
                                        n->objs = $2;
                                        $$ = n;
@@ -4455,13 +4800,23 @@ privilege_target:
                        | LANGUAGE name_list
                                {
                                        PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
+                                       n->targtype = ACL_TARGET_OBJECT;
                                        n->objtype = ACL_OBJECT_LANGUAGE;
                                        n->objs = $2;
                                        $$ = n;
                                }
+                       | LARGE_P OBJECT_P NumericOnly_list
+                               {
+                                       PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
+                                       n->targtype = ACL_TARGET_OBJECT;
+                                       n->objtype = ACL_OBJECT_LARGEOBJECT;
+                                       n->objs = $3;
+                                       $$ = n;
+                               }
                        | SCHEMA name_list
                                {
                                        PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
+                                       n->targtype = ACL_TARGET_OBJECT;
                                        n->objtype = ACL_OBJECT_NAMESPACE;
                                        n->objs = $2;
                                        $$ = n;
@@ -4469,10 +4824,35 @@ privilege_target:
                        | TABLESPACE name_list
                                {
                                        PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
+                                       n->targtype = ACL_TARGET_OBJECT;
                                        n->objtype = ACL_OBJECT_TABLESPACE;
                                        n->objs = $2;
                                        $$ = n;
                                }
+                       | ALL TABLES IN_P SCHEMA name_list
+                               {
+                                       PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
+                                       n->targtype = ACL_TARGET_ALL_IN_SCHEMA;
+                                       n->objtype = ACL_OBJECT_RELATION;
+                                       n->objs = $5;
+                                       $$ = n;
+                               }
+                       | ALL SEQUENCES IN_P SCHEMA name_list
+                               {
+                                       PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
+                                       n->targtype = ACL_TARGET_ALL_IN_SCHEMA;
+                                       n->objtype = ACL_OBJECT_SEQUENCE;
+                                       n->objs = $5;
+                                       $$ = n;
+                               }
+                       | ALL FUNCTIONS IN_P SCHEMA name_list
+                               {
+                                       PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
+                                       n->targtype = ACL_TARGET_ALL_IN_SCHEMA;
+                                       n->objtype = ACL_OBJECT_FUNCTION;
+                                       n->objs = $5;
+                                       $$ = n;
+                               }
                ;
 
 
@@ -4571,8 +4951,98 @@ opt_grant_admin_option: WITH ADMIN OPTION                                { $$ = TRUE; }
                        | /*EMPTY*/                                                                     { $$ = FALSE; }
                ;
 
-opt_granted_by: GRANTED BY RoleId                                              { $$ = $3; }
-                       | /*EMPTY*/                                                                     { $$ = NULL; }
+opt_granted_by: GRANTED BY RoleId                                              { $$ = $3; }
+                       | /*EMPTY*/                                                                     { $$ = NULL; }
+               ;
+
+/*****************************************************************************
+ *
+ * ALTER DEFAULT PRIVILEGES statement
+ *
+ *****************************************************************************/
+
+AlterDefaultPrivilegesStmt:
+                       ALTER DEFAULT PRIVILEGES DefACLOptionList DefACLAction
+                               {
+                                       AlterDefaultPrivilegesStmt *n = makeNode(AlterDefaultPrivilegesStmt);
+                                       n->options = $4;
+                                       n->action = (GrantStmt *) $5;
+                                       $$ = (Node*)n;
+                               }
+               ;
+
+DefACLOptionList:
+                       DefACLOptionList DefACLOption                   { $$ = lappend($1, $2); }
+                       | /* EMPTY */                                                   { $$ = NIL; }
+               ;
+
+DefACLOption:
+                       IN_P SCHEMA name_list
+                               {
+                                       $$ = makeDefElem("schemas", (Node *)$3);
+                               }
+                       | FOR ROLE name_list
+                               {
+                                       $$ = makeDefElem("roles", (Node *)$3);
+                               }
+                       | FOR USER name_list
+                               {
+                                       $$ = makeDefElem("roles", (Node *)$3);
+                               }
+               ;
+
+/*
+ * This should match GRANT/REVOKE, except that individual target objects
+ * are not mentioned and we only allow a subset of object types.
+ */
+DefACLAction:
+                       GRANT privileges ON defacl_privilege_target TO grantee_list
+                       opt_grant_grant_option
+                               {
+                                       GrantStmt *n = makeNode(GrantStmt);
+                                       n->is_grant = true;
+                                       n->privileges = $2;
+                                       n->targtype = ACL_TARGET_DEFAULTS;
+                                       n->objtype = $4;
+                                       n->objects = NIL;
+                                       n->grantees = $6;
+                                       n->grant_option = $7;
+                                       $$ = (Node*)n;
+                               }
+                       | REVOKE privileges ON defacl_privilege_target
+                       FROM grantee_list opt_drop_behavior
+                               {
+                                       GrantStmt *n = makeNode(GrantStmt);
+                                       n->is_grant = false;
+                                       n->grant_option = false;
+                                       n->privileges = $2;
+                                       n->targtype = ACL_TARGET_DEFAULTS;
+                                       n->objtype = $4;
+                                       n->objects = NIL;
+                                       n->grantees = $6;
+                                       n->behavior = $7;
+                                       $$ = (Node *)n;
+                               }
+                       | REVOKE GRANT OPTION FOR privileges ON defacl_privilege_target
+                       FROM grantee_list opt_drop_behavior
+                               {
+                                       GrantStmt *n = makeNode(GrantStmt);
+                                       n->is_grant = false;
+                                       n->grant_option = true;
+                                       n->privileges = $5;
+                                       n->targtype = ACL_TARGET_DEFAULTS;
+                                       n->objtype = $7;
+                                       n->objects = NIL;
+                                       n->grantees = $9;
+                                       n->behavior = $10;
+                                       $$ = (Node *)n;
+                               }
+               ;
+
+defacl_privilege_target:
+                       TABLES                  { $$ = ACL_OBJECT_RELATION; }
+                       | FUNCTIONS             { $$ = ACL_OBJECT_FUNCTION; }
+                       | SEQUENCES             { $$ = ACL_OBJECT_SEQUENCE; }
                ;
 
 
@@ -4580,36 +5050,17 @@ opt_granted_by: GRANTED BY RoleId                                               { $$ = $3; }
  *
  *             QUERY: CREATE INDEX
  *
- * Note: we can't factor CONCURRENTLY into a separate production without
- * making it a reserved word.
- *
  * Note: we cannot put TABLESPACE clause after WHERE clause unless we are
  * willing to make TABLESPACE a fully reserved word.
  *****************************************************************************/
 
-IndexStmt:     CREATE index_opt_unique INDEX index_name
-                       ON qualified_name access_method_clause '(' index_params ')'
-                       opt_reloptions OptTableSpace where_clause
-                               {
-                                       IndexStmt *n = makeNode(IndexStmt);
-                                       n->unique = $2;
-                                       n->concurrent = false;
-                                       n->idxname = $4;
-                                       n->relation = $6;
-                                       n->accessMethod = $7;
-                                       n->indexParams = $9;
-                                       n->options = $11;
-                                       n->tableSpace = $12;
-                                       n->whereClause = $13;
-                                       $$ = (Node *)n;
-                               }
-                       | CREATE index_opt_unique INDEX CONCURRENTLY index_name
+IndexStmt:     CREATE opt_unique INDEX opt_concurrently opt_index_name
                        ON qualified_name access_method_clause '(' index_params ')'
                        opt_reloptions OptTableSpace where_clause
                                {
                                        IndexStmt *n = makeNode(IndexStmt);
                                        n->unique = $2;
-                                       n->concurrent = true;
+                                       n->concurrent = $4;
                                        n->idxname = $5;
                                        n->relation = $7;
                                        n->accessMethod = $8;
@@ -4621,11 +5072,21 @@ IndexStmt:      CREATE index_opt_unique INDEX index_name
                                }
                ;
 
-index_opt_unique:
+opt_unique:
                        UNIQUE                                                                  { $$ = TRUE; }
                        | /*EMPTY*/                                                             { $$ = FALSE; }
                ;
 
+opt_concurrently:
+                       CONCURRENTLY                                                    { $$ = TRUE; }
+                       | /*EMPTY*/                                                             { $$ = FALSE; }
+               ;
+
+opt_index_name:
+                       index_name                                                              { $$ = $1; }
+                       | /*EMPTY*/                                                             { $$ = NULL; }
+               ;
+
 access_method_clause:
                        USING access_method                                             { $$ = $2; }
                        | /*EMPTY*/                                                             { $$ = DEFAULT_INDEX_TYPE; }
@@ -4645,6 +5106,7 @@ index_elem:       ColId opt_class opt_asc_desc opt_nulls_order
                                        $$ = makeNode(IndexElem);
                                        $$->name = $1;
                                        $$->expr = NULL;
+                                       $$->indexcolname = NULL;
                                        $$->opclass = $2;
                                        $$->ordering = $3;
                                        $$->nulls_ordering = $4;
@@ -4654,6 +5116,7 @@ index_elem:       ColId opt_class opt_asc_desc opt_nulls_order
                                        $$ = makeNode(IndexElem);
                                        $$->name = NULL;
                                        $$->expr = $1;
+                                       $$->indexcolname = NULL;
                                        $$->opclass = $2;
                                        $$->ordering = $3;
                                        $$->nulls_ordering = $4;
@@ -4663,6 +5126,7 @@ index_elem:       ColId opt_class opt_asc_desc opt_nulls_order
                                        $$ = makeNode(IndexElem);
                                        $$->name = NULL;
                                        $$->expr = $2;
+                                       $$->indexcolname = NULL;
                                        $$->opclass = $4;
                                        $$->ordering = $5;
                                        $$->nulls_ordering = $6;
@@ -5139,6 +5603,38 @@ any_operator:
                                        { $$ = lcons(makeString($1), $3); }
                ;
 
+/*****************************************************************************
+ *
+ *             DO <anonymous code block> [ LANGUAGE language ]
+ *
+ * We use a DefElem list for future extensibility, and to allow flexibility
+ * in the clause order.
+ *
+ *****************************************************************************/
+
+DoStmt: DO dostmt_opt_list
+                               {
+                                       DoStmt *n = makeNode(DoStmt);
+                                       n->args = $2;
+                                       $$ = (Node *)n;
+                               }
+               ;
+
+dostmt_opt_list:
+                       dostmt_opt_item                                         { $$ = list_make1($1); }
+                       | dostmt_opt_list dostmt_opt_item       { $$ = lappend($1, $2); }
+               ;
+
+dostmt_opt_item:
+                       Sconst
+                               {
+                                       $$ = makeDefElem("as", (Node *)makeString($1));
+                               }
+                       | LANGUAGE ColId_or_Sconst
+                               {
+                                       $$ = makeDefElem("language", (Node *)makeString($2));
+                               }
+               ;
 
 /*****************************************************************************
  *
@@ -5413,6 +5909,24 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
                                        n->newname = $6;
                                        $$ = (Node *)n;
                                }
+                       | ALTER TABLESPACE name SET reloptions
+                               {
+                                       AlterTableSpaceOptionsStmt *n =
+                                               makeNode(AlterTableSpaceOptionsStmt);
+                                       n->tablespacename = $3;
+                                       n->options = $5;
+                                       n->isReset = FALSE;
+                                       $$ = (Node *)n;
+                               }
+                       | ALTER TABLESPACE name RESET reloptions
+                               {
+                                       AlterTableSpaceOptionsStmt *n =
+                                               makeNode(AlterTableSpaceOptionsStmt);
+                                       n->tablespacename = $3;
+                                       n->options = $5;
+                                       n->isReset = TRUE;
+                                       $$ = (Node *)n;
+                               }
                        | ALTER TEXT_P SEARCH PARSER any_name RENAME TO name
                                {
                                        RenameStmt *n = makeNode(RenameStmt);
@@ -5453,6 +5967,15 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
                                        n->newname = $6;
                                        $$ = (Node *)n;
                                }
+                       | ALTER TYPE_P any_name RENAME ATTRIBUTE name TO name
+                               {
+                                       RenameStmt *n = makeNode(RenameStmt);
+                                       n->renameType = OBJECT_ATTRIBUTE;
+                                       n->relation = makeRangeVarFromAnyName($3, @3, yyscanner);
+                                       n->subname = $6;
+                                       n->newname = $8;
+                                       $$ = (Node *)n;
+                               }
                ;
 
 opt_column: COLUMN                                                                     { $$ = COLUMN; }
@@ -5586,6 +6109,14 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
                                        n->newowner = $7;
                                        $$ = (Node *)n;
                                }
+                       | ALTER LARGE_P OBJECT_P NumericOnly OWNER TO RoleId
+                               {
+                                       AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
+                                       n->objectType = OBJECT_LARGEOBJECT;
+                                       n->object = list_make1($4);
+                                       n->newowner = $7;
+                                       $$ = (Node *)n;
+                               }
                        | ALTER OPERATOR any_operator oper_argtypes OWNER TO RoleId
                                {
                                        AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
@@ -5679,20 +6210,18 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
  *****************************************************************************/
 
 RuleStmt:      CREATE opt_or_replace RULE name AS
-                       { pg_yyget_extra(yyscanner)->QueryIsRule = TRUE; }
                        ON event TO qualified_name where_clause
                        DO opt_instead RuleActionList
                                {
                                        RuleStmt *n = makeNode(RuleStmt);
                                        n->replace = $2;
-                                       n->relation = $10;
+                                       n->relation = $9;
                                        n->rulename = $4;
-                                       n->whereClause = $11;
-                                       n->event = $8;
-                                       n->instead = $13;
-                                       n->actions = $14;
+                                       n->whereClause = $10;
+                                       n->event = $7;
+                                       n->instead = $12;
+                                       n->actions = $13;
                                        $$ = (Node *)n;
-                                       pg_yyget_extra(yyscanner)->QueryIsRule = FALSE;
                                }
                ;
 
@@ -5776,14 +6305,20 @@ DropRuleStmt:
  *
  *****************************************************************************/
 
-NotifyStmt: NOTIFY ColId
+NotifyStmt: NOTIFY ColId notify_payload
                                {
                                        NotifyStmt *n = makeNode(NotifyStmt);
                                        n->conditionname = $2;
+                                       n->payload = $3;
                                        $$ = (Node *)n;
                                }
                ;
 
+notify_payload:
+                       ',' Sconst                                                      { $$ = $2; }
+                       | /*EMPTY*/                                                     { $$ = NULL; }
+               ;
+
 ListenStmt: LISTEN ColId
                                {
                                        ListenStmt *n = makeNode(ListenStmt);
@@ -6418,12 +6953,13 @@ cluster_index_specification:
 VacuumStmt: VACUUM opt_full opt_freeze opt_verbose
                                {
                                        VacuumStmt *n = makeNode(VacuumStmt);
-                                       n->vacuum = true;
-                                       n->analyze = false;
-                                       n->full = $2;
+                                       n->options = VACOPT_VACUUM;
+                                       if ($2)
+                                               n->options |= VACOPT_FULL;
+                                       if ($4)
+                                               n->options |= VACOPT_VERBOSE;
                                        n->freeze_min_age = $3 ? 0 : -1;
                                        n->freeze_table_age = $3 ? 0 : -1;
-                                       n->verbose = $4;
                                        n->relation = NULL;
                                        n->va_cols = NIL;
                                        $$ = (Node *)n;
@@ -6431,12 +6967,13 @@ VacuumStmt: VACUUM opt_full opt_freeze opt_verbose
                        | VACUUM opt_full opt_freeze opt_verbose qualified_name
                                {
                                        VacuumStmt *n = makeNode(VacuumStmt);
-                                       n->vacuum = true;
-                                       n->analyze = false;
-                                       n->full = $2;
+                                       n->options = VACOPT_VACUUM;
+                                       if ($2)
+                                               n->options |= VACOPT_FULL;
+                                       if ($4)
+                                               n->options |= VACOPT_VERBOSE;
                                        n->freeze_min_age = $3 ? 0 : -1;
                                        n->freeze_table_age = $3 ? 0 : -1;
-                                       n->verbose = $4;
                                        n->relation = $5;
                                        n->va_cols = NIL;
                                        $$ = (Node *)n;
@@ -6444,25 +6981,64 @@ VacuumStmt: VACUUM opt_full opt_freeze opt_verbose
                        | VACUUM opt_full opt_freeze opt_verbose AnalyzeStmt
                                {
                                        VacuumStmt *n = (VacuumStmt *) $5;
-                                       n->vacuum = true;
-                                       n->full = $2;
+                                       n->options |= VACOPT_VACUUM;
+                                       if ($2)
+                                               n->options |= VACOPT_FULL;
+                                       if ($4)
+                                               n->options |= VACOPT_VERBOSE;
                                        n->freeze_min_age = $3 ? 0 : -1;
                                        n->freeze_table_age = $3 ? 0 : -1;
-                                       n->verbose |= $4;
                                        $$ = (Node *)n;
                                }
+                       | VACUUM '(' vacuum_option_list ')'
+                               {
+                                       VacuumStmt *n = makeNode(VacuumStmt);
+                                       n->options = VACOPT_VACUUM | $3;
+                                       if (n->options & VACOPT_FREEZE)
+                                               n->freeze_min_age = n->freeze_table_age = 0;
+                                       else
+                                               n->freeze_min_age = n->freeze_table_age = -1;
+                                       n->relation = NULL;
+                                       n->va_cols = NIL;
+                                       $$ = (Node *) n;
+                               }
+                       | VACUUM '(' vacuum_option_list ')' qualified_name opt_name_list
+                               {
+                                       VacuumStmt *n = makeNode(VacuumStmt);
+                                       n->options = VACOPT_VACUUM | $3;
+                                       if (n->options & VACOPT_FREEZE)
+                                               n->freeze_min_age = n->freeze_table_age = 0;
+                                       else
+                                               n->freeze_min_age = n->freeze_table_age = -1;
+                                       n->relation = $5;
+                                       n->va_cols = $6;
+                                       if (n->va_cols != NIL)  /* implies analyze */
+                                               n->options |= VACOPT_ANALYZE;
+                                       $$ = (Node *) n;
+                               }
+               ;
+
+vacuum_option_list:
+                       vacuum_option_elem                                                              { $$ = $1; }
+                       | vacuum_option_list ',' vacuum_option_elem             { $$ = $1 | $3; }
+               ;
+
+vacuum_option_elem:
+                       analyze_keyword         { $$ = VACOPT_ANALYZE; }
+                       | VERBOSE                       { $$ = VACOPT_VERBOSE; }
+                       | FREEZE                        { $$ = VACOPT_FREEZE; }
+                       | FULL                          { $$ = VACOPT_FULL; }
                ;
 
 AnalyzeStmt:
                        analyze_keyword opt_verbose
                                {
                                        VacuumStmt *n = makeNode(VacuumStmt);
-                                       n->vacuum = false;
-                                       n->analyze = true;
-                                       n->full = false;
+                                       n->options = VACOPT_ANALYZE;
+                                       if ($2)
+                                               n->options |= VACOPT_VERBOSE;
                                        n->freeze_min_age = -1;
                                        n->freeze_table_age = -1;
-                                       n->verbose = $2;
                                        n->relation = NULL;
                                        n->va_cols = NIL;
                                        $$ = (Node *)n;
@@ -6470,12 +7046,11 @@ AnalyzeStmt:
                        | analyze_keyword opt_verbose qualified_name opt_name_list
                                {
                                        VacuumStmt *n = makeNode(VacuumStmt);
-                                       n->vacuum = false;
-                                       n->analyze = true;
-                                       n->full = false;
+                                       n->options = VACOPT_ANALYZE;
+                                       if ($2)
+                                               n->options |= VACOPT_VERBOSE;
                                        n->freeze_min_age = -1;
                                        n->freeze_table_age = -1;
-                                       n->verbose = $2;
                                        n->relation = $3;
                                        n->va_cols = $4;
                                        $$ = (Node *)n;
@@ -6694,11 +7269,12 @@ DeallocateStmt: DEALLOCATE name
  *****************************************************************************/
 
 InsertStmt:
-                       INSERT INTO qualified_name insert_rest returning_clause
+                       opt_with_clause INSERT INTO qualified_name insert_rest returning_clause
                                {
-                                       $4->relation = $3;
-                                       $4->returningList = $5;
-                                       $$ = (Node *) $4;
+                                       $5->relation = $4;
+                                       $5->returningList = $6;
+                                       $5->withClause = $1;
+                                       $$ = (Node *) $5;
                                }
                ;
 
@@ -6754,14 +7330,15 @@ returning_clause:
  *
  *****************************************************************************/
 
-DeleteStmt: DELETE_P FROM relation_expr_opt_alias
+DeleteStmt: opt_with_clause DELETE_P FROM relation_expr_opt_alias
                        using_clause where_or_current_clause returning_clause
                                {
                                        DeleteStmt *n = makeNode(DeleteStmt);
-                                       n->relation = $3;
-                                       n->usingClause = $4;
-                                       n->whereClause = $5;
-                                       n->returningList = $6;
+                                       n->relation = $4;
+                                       n->usingClause = $5;
+                                       n->whereClause = $6;
+                                       n->returningList = $7;
+                                       n->withClause = $1;
                                        $$ = (Node *)n;
                                }
                ;
@@ -6816,18 +7393,19 @@ opt_nowait:     NOWAIT                                                  { $$ = TRUE; }
  *
  *****************************************************************************/
 
-UpdateStmt: UPDATE relation_expr_opt_alias
+UpdateStmt: opt_with_clause UPDATE relation_expr_opt_alias
                        SET set_clause_list
                        from_clause
                        where_or_current_clause
                        returning_clause
                                {
                                        UpdateStmt *n = makeNode(UpdateStmt);
-                                       n->relation = $2;
-                                       n->targetList = $4;
-                                       n->fromClause = $5;
-                                       n->whereClause = $6;
-                                       n->returningList = $7;
+                                       n->relation = $3;
+                                       n->targetList = $5;
+                                       n->fromClause = $6;
+                                       n->whereClause = $7;
+                                       n->returningList = $8;
+                                       n->withClause = $1;
                                        $$ = (Node *)n;
                                }
                ;
@@ -6901,7 +7479,7 @@ set_target_list:
  *                             CURSOR STATEMENTS
  *
  *****************************************************************************/
-DeclareCursorStmt: DECLARE name cursor_options CURSOR opt_hold FOR SelectStmt
+DeclareCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR SelectStmt
                                {
                                        DeclareCursorStmt *n = makeNode(DeclareCursorStmt);
                                        n->portalname = $2;
@@ -6912,6 +7490,9 @@ DeclareCursorStmt: DECLARE name cursor_options CURSOR opt_hold FOR SelectStmt
                                }
                ;
 
+cursor_name:   name                                            { $$ = $1; }
+               ;
+
 cursor_options: /*EMPTY*/                                      { $$ = 0; }
                        | cursor_options NO SCROLL              { $$ = $1 | CURSOR_OPT_NO_SCROLL; }
                        | cursor_options SCROLL                 { $$ = $1 | CURSOR_OPT_SCROLL; }
@@ -7166,6 +7747,11 @@ common_table_expr:  name opt_name_list AS select_with_parens
                        }
                ;
 
+opt_with_clause:
+               with_clause                                                             { $$ = $1; }
+               | /*EMPTY*/                                                             { $$ = NULL; }
+               ;
+
 into_clause:
                        INTO OptTempTableName
                                {
@@ -7774,18 +8360,15 @@ where_or_current_clause:
                                        n->cursor_param = 0;
                                        $$ = (Node *) n;
                                }
-                       | WHERE CURRENT_P OF PARAM
-                               {
-                                       CurrentOfExpr *n = makeNode(CurrentOfExpr);
-                                       /* cvarno is filled in by parse analysis */
-                                       n->cursor_name = NULL;
-                                       n->cursor_param = $4;
-                                       $$ = (Node *) n;
-                               }
                        | /*EMPTY*/                                                             { $$ = NULL; }
                ;
 
 
+OptTableFuncElementList:
+                       TableFuncElementList                            { $$ = $1; }
+                       | /*EMPTY*/                                                     { $$ = NIL; }
+               ;
+
 TableFuncElementList:
                        TableFuncElement
                                {
@@ -8336,6 +8919,7 @@ a_expr:           c_expr                                                                  { $$ = $1; }
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("timezone");
                                        n->args = list_make2($5, $1);
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -8396,11 +8980,12 @@ a_expr:         c_expr                                                                  { $$ = $1; }
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("like_escape");
                                        n->args = list_make2($3, $5);
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
                                        n->over = NULL;
-                                       n->location = @4;
+                                       n->location = @2;
                                        $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~", $1, (Node *) n, @2);
                                }
                        | a_expr NOT LIKE a_expr
@@ -8410,11 +8995,12 @@ a_expr:         c_expr                                                                  { $$ = $1; }
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("like_escape");
                                        n->args = list_make2($4, $6);
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
                                        n->over = NULL;
-                                       n->location = @5;
+                                       n->location = @2;
                                        $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~", $1, (Node *) n, @2);
                                }
                        | a_expr ILIKE a_expr
@@ -8424,11 +9010,12 @@ a_expr:         c_expr                                                                  { $$ = $1; }
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("like_escape");
                                        n->args = list_make2($3, $5);
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
                                        n->over = NULL;
-                                       n->location = @4;
+                                       n->location = @2;
                                        $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~*", $1, (Node *) n, @2);
                                }
                        | a_expr NOT ILIKE a_expr
@@ -8438,11 +9025,12 @@ a_expr:         c_expr                                                                  { $$ = $1; }
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("like_escape");
                                        n->args = list_make2($4, $6);
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
                                        n->over = NULL;
-                                       n->location = @5;
+                                       n->location = @2;
                                        $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~*", $1, (Node *) n, @2);
                                }
 
@@ -8451,6 +9039,7 @@ a_expr:           c_expr                                                                  { $$ = $1; }
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("similar_escape");
                                        n->args = list_make2($4, makeNullAConst(-1));
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -8463,11 +9052,12 @@ a_expr:         c_expr                                                                  { $$ = $1; }
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("similar_escape");
                                        n->args = list_make2($4, $6);
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
                                        n->over = NULL;
-                                       n->location = @5;
+                                       n->location = @2;
                                        $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~", $1, (Node *) n, @2);
                                }
                        | a_expr NOT SIMILAR TO a_expr                  %prec SIMILAR
@@ -8475,11 +9065,12 @@ a_expr:         c_expr                                                                  { $$ = $1; }
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("similar_escape");
                                        n->args = list_make2($5, makeNullAConst(-1));
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
                                        n->over = NULL;
-                                       n->location = @5;
+                                       n->location = @2;
                                        $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~", $1, (Node *) n, @2);
                                }
                        | a_expr NOT SIMILAR TO a_expr ESCAPE a_expr
@@ -8487,11 +9078,12 @@ a_expr:         c_expr                                                                  { $$ = $1; }
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("similar_escape");
                                        n->args = list_make2($5, $7);
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
                                        n->over = NULL;
-                                       n->location = @6;
+                                       n->location = @2;
                                        $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~", $1, (Node *) n, @2);
                                }
 
@@ -8599,10 +9191,11 @@ a_expr:         c_expr                                                                  { $$ = $1; }
                                        $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", $1, (Node *) $6, @2);
                                }
                        /*
-                        *      Ideally we would not use hard-wired operators below but instead use
-                        *      opclasses.  However, mixed data types and other issues make this
-                        *      difficult:  http://archives.postgresql.org/pgsql-hackers/2008-08/msg01142.php
-                        */                     
+                        *      Ideally we would not use hard-wired operators below but
+                        *      instead use opclasses.  However, mixed data types and other
+                        *      issues make this difficult:
+                        *      http://archives.postgresql.org/pgsql-hackers/2008-08/msg01142.php
+                        */
                        | a_expr BETWEEN opt_asymmetric b_expr AND b_expr               %prec BETWEEN
                                {
                                        $$ = (Node *) makeA_Expr(AEXPR_AND, NIL,
@@ -8904,6 +9497,7 @@ func_expr:        func_name '(' ')' over_clause
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = $1;
                                        n->args = NIL;
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -8911,11 +9505,12 @@ func_expr:      func_name '(' ')' over_clause
                                        n->location = @1;
                                        $$ = (Node *)n;
                                }
-                       | func_name '(' expr_list ')' over_clause
+                       | func_name '(' func_arg_list ')' over_clause
                                {
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = $1;
                                        n->args = $3;
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -8923,11 +9518,12 @@ func_expr:      func_name '(' ')' over_clause
                                        n->location = @1;
                                        $$ = (Node *)n;
                                }
-                       | func_name '(' VARIADIC a_expr ')' over_clause
+                       | func_name '(' VARIADIC func_arg_expr ')' over_clause
                                {
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = $1;
                                        n->args = list_make1($4);
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = TRUE;
@@ -8935,11 +9531,12 @@ func_expr:      func_name '(' ')' over_clause
                                        n->location = @1;
                                        $$ = (Node *)n;
                                }
-                       | func_name '(' expr_list ',' VARIADIC a_expr ')' over_clause
+                       | func_name '(' func_arg_list ',' VARIADIC func_arg_expr ')' over_clause
                                {
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = $1;
                                        n->args = lappend($3, $6);
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = TRUE;
@@ -8947,11 +9544,25 @@ func_expr:      func_name '(' ')' over_clause
                                        n->location = @1;
                                        $$ = (Node *)n;
                                }
-                       | func_name '(' ALL expr_list ')' over_clause
+                       | func_name '(' func_arg_list sort_clause ')' over_clause
+                               {
+                                       FuncCall *n = makeNode(FuncCall);
+                                       n->funcname = $1;
+                                       n->args = $3;
+                                       n->agg_order = $4;
+                                       n->agg_star = FALSE;
+                                       n->agg_distinct = FALSE;
+                                       n->func_variadic = FALSE;
+                                       n->over = $6;
+                                       n->location = @1;
+                                       $$ = (Node *)n;
+                               }
+                       | func_name '(' ALL func_arg_list opt_sort_clause ')' over_clause
                                {
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = $1;
                                        n->args = $4;
+                                       n->agg_order = $5;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        /* Ideally we'd mark the FuncCall node to indicate
@@ -8959,19 +9570,20 @@ func_expr:      func_name '(' ')' over_clause
                                         * for that in FuncCall at the moment.
                                         */
                                        n->func_variadic = FALSE;
-                                       n->over = $6;
+                                       n->over = $7;
                                        n->location = @1;
                                        $$ = (Node *)n;
                                }
-                       | func_name '(' DISTINCT expr_list ')' over_clause
+                       | func_name '(' DISTINCT func_arg_list opt_sort_clause ')' over_clause
                                {
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = $1;
                                        n->args = $4;
+                                       n->agg_order = $5;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = TRUE;
                                        n->func_variadic = FALSE;
-                                       n->over = $6;
+                                       n->over = $7;
                                        n->location = @1;
                                        $$ = (Node *)n;
                                }
@@ -8990,6 +9602,7 @@ func_expr:        func_name '(' ')' over_clause
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = $1;
                                        n->args = NIL;
+                                       n->agg_order = NIL;
                                        n->agg_star = TRUE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -9050,6 +9663,7 @@ func_expr:        func_name '(' ')' over_clause
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("now");
                                        n->args = NIL;
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -9121,6 +9735,7 @@ func_expr:        func_name '(' ')' over_clause
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("current_user");
                                        n->args = NIL;
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -9133,6 +9748,7 @@ func_expr:        func_name '(' ')' over_clause
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("current_user");
                                        n->args = NIL;
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -9145,6 +9761,7 @@ func_expr:        func_name '(' ')' over_clause
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("session_user");
                                        n->args = NIL;
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -9157,6 +9774,7 @@ func_expr:        func_name '(' ')' over_clause
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("current_user");
                                        n->args = NIL;
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -9169,6 +9787,7 @@ func_expr:        func_name '(' ')' over_clause
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("current_database");
                                        n->args = NIL;
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -9181,6 +9800,7 @@ func_expr:        func_name '(' ')' over_clause
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("current_schema");
                                        n->args = NIL;
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -9195,6 +9815,7 @@ func_expr:        func_name '(' ')' over_clause
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("date_part");
                                        n->args = $3;
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -9205,13 +9826,14 @@ func_expr:      func_name '(' ')' over_clause
                        | OVERLAY '(' overlay_list ')'
                                {
                                        /* overlay(A PLACING B FROM C FOR D) is converted to
-                                        * substring(A, 1, C-1) || B || substring(A, C+1, C+D)
+                                        * overlay(A, B, C, D)
                                         * overlay(A PLACING B FROM C) is converted to
-                                        * substring(A, 1, C-1) || B || substring(A, C+1, C+char_length(B))
+                                        * overlay(A, B, C)
                                         */
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("overlay");
                                        n->args = $3;
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -9225,6 +9847,7 @@ func_expr:        func_name '(' ')' over_clause
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("position");
                                        n->args = $3;
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -9240,6 +9863,7 @@ func_expr:        func_name '(' ')' over_clause
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("substring");
                                        n->args = $3;
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -9261,6 +9885,7 @@ func_expr:        func_name '(' ')' over_clause
                                         */
                                        n->funcname = SystemFuncName(((Value *)llast($5->names))->val.str);
                                        n->args = list_make1($3);
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -9276,6 +9901,7 @@ func_expr:        func_name '(' ')' over_clause
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("btrim");
                                        n->args = $4;
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -9288,6 +9914,7 @@ func_expr:        func_name '(' ')' over_clause
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("ltrim");
                                        n->args = $4;
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -9300,6 +9927,7 @@ func_expr:        func_name '(' ')' over_clause
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("rtrim");
                                        n->args = $4;
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -9312,6 +9940,7 @@ func_expr:        func_name '(' ')' over_clause
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = SystemFuncName("btrim");
                                        n->args = $3;
+                                       n->agg_order = NIL;
                                        n->agg_star = FALSE;
                                        n->agg_distinct = FALSE;
                                        n->func_variadic = FALSE;
@@ -9366,6 +9995,21 @@ func_expr:       func_name '(' ')' over_clause
                                {
                                        $$ = makeXmlExpr(IS_XMLELEMENT, $4, $6, $8, @1);
                                }
+                       | XMLEXISTS '(' c_expr xmlexists_argument ')'
+                               {
+                                       /* xmlexists(A PASSING [BY REF] B [BY REF]) is
+                                        * converted to xmlexists(A, B)*/
+                                       FuncCall *n = makeNode(FuncCall);
+                                       n->funcname = SystemFuncName("xmlexists");
+                                       n->args = list_make2($3, $4);
+                                       n->agg_order = NIL;
+                                       n->agg_star = FALSE;
+                                       n->agg_distinct = FALSE;
+                                       n->func_variadic = FALSE;
+                                       n->over = NULL;
+                                       n->location = @1;
+                                       $$ = (Node *)n;
+                               }
                        | XMLFOREST '(' xml_attribute_list ')'
                                {
                                        $$ = makeXmlExpr(IS_XMLFOREST, NULL, $3, NIL, @1);
@@ -9456,6 +10100,27 @@ xml_whitespace_option: PRESERVE WHITESPACE_P            { $$ = TRUE; }
                        | /*EMPTY*/                                                             { $$ = FALSE; }
                ;
 
+/* We allow several variants for SQL and other compatibility. */
+xmlexists_argument:
+                       PASSING c_expr
+                               {
+                                       $$ = $2;
+                               }
+                       | PASSING c_expr BY REF
+                               {
+                                       $$ = $2;
+                               }
+                       | PASSING BY REF c_expr
+                               {
+                                       $$ = $4;
+                               }
+                       | PASSING BY REF c_expr BY REF
+                               {
+                                       $$ = $4;
+                               }
+               ;
+
+
 /*
  * Window Definitions
  */
@@ -9489,6 +10154,8 @@ over_clause: OVER window_specification
                                        n->partitionClause = NIL;
                                        n->orderClause = NIL;
                                        n->frameOptions = FRAMEOPTION_DEFAULTS;
+                                       n->startOffset = NULL;
+                                       n->endOffset = NULL;
                                        n->location = @2;
                                        $$ = n;
                                }
@@ -9504,7 +10171,10 @@ window_specification: '(' opt_existing_window_name opt_partition_clause
                                        n->refname = $2;
                                        n->partitionClause = $3;
                                        n->orderClause = $4;
-                                       n->frameOptions = $5;
+                                       /* copy relevant fields of opt_frame_clause */
+                                       n->frameOptions = $5->frameOptions;
+                                       n->startOffset = $5->startOffset;
+                                       n->endOffset = $5->endOffset;
                                        n->location = @1;
                                        $$ = n;
                                }
@@ -9529,58 +10199,100 @@ opt_partition_clause: PARTITION BY expr_list          { $$ = $3; }
                ;
 
 /*
+ * For frame clauses, we return a WindowDef, but only some fields are used:
+ * frameOptions, startOffset, and endOffset.
+ *
  * This is only a subset of the full SQL:2008 frame_clause grammar.
- * We don't support <expression> PRECEDING, <expression> FOLLOWING,
- * nor <window frame exclusion> yet.
+ * We don't support <window frame exclusion> yet.
  */
 opt_frame_clause:
                        RANGE frame_extent
                                {
-                                       $$ = FRAMEOPTION_NONDEFAULT | FRAMEOPTION_RANGE | $2;
+                                       WindowDef *n = $2;
+                                       n->frameOptions |= FRAMEOPTION_NONDEFAULT | FRAMEOPTION_RANGE;
+                                       if (n->frameOptions & (FRAMEOPTION_START_VALUE_PRECEDING |
+                                                                                  FRAMEOPTION_END_VALUE_PRECEDING))
+                                               ereport(ERROR,
+                                                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                                                                errmsg("RANGE PRECEDING is only supported with UNBOUNDED"),
+                                                                parser_errposition(@1)));
+                                       if (n->frameOptions & (FRAMEOPTION_START_VALUE_FOLLOWING |
+                                                                                  FRAMEOPTION_END_VALUE_FOLLOWING))
+                                               ereport(ERROR,
+                                                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                                                                errmsg("RANGE FOLLOWING is only supported with UNBOUNDED"),
+                                                                parser_errposition(@1)));
+                                       $$ = n;
                                }
                        | ROWS frame_extent
                                {
-                                       $$ = FRAMEOPTION_NONDEFAULT | FRAMEOPTION_ROWS | $2;
+                                       WindowDef *n = $2;
+                                       n->frameOptions |= FRAMEOPTION_NONDEFAULT | FRAMEOPTION_ROWS;
+                                       $$ = n;
                                }
                        | /*EMPTY*/
-                               { $$ = FRAMEOPTION_DEFAULTS; }
+                               {
+                                       WindowDef *n = makeNode(WindowDef);
+                                       n->frameOptions = FRAMEOPTION_DEFAULTS;
+                                       n->startOffset = NULL;
+                                       n->endOffset = NULL;
+                                       $$ = n;
+                               }
                ;
 
 frame_extent: frame_bound
                                {
+                                       WindowDef *n = $1;
                                        /* reject invalid cases */
-                                       if ($1 & FRAMEOPTION_START_UNBOUNDED_FOLLOWING)
+                                       if (n->frameOptions & FRAMEOPTION_START_UNBOUNDED_FOLLOWING)
                                                ereport(ERROR,
                                                                (errcode(ERRCODE_WINDOWING_ERROR),
                                                                 errmsg("frame start cannot be UNBOUNDED FOLLOWING"),
                                                                 parser_errposition(@1)));
-                                       if ($1 & FRAMEOPTION_START_CURRENT_ROW)
+                                       if (n->frameOptions & FRAMEOPTION_START_VALUE_FOLLOWING)
                                                ereport(ERROR,
-                                                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                                                errmsg("frame start at CURRENT ROW is not implemented"),
+                                                               (errcode(ERRCODE_WINDOWING_ERROR),
+                                                                errmsg("frame starting from following row cannot end with current row"),
                                                                 parser_errposition(@1)));
-                                       $$ = $1 | FRAMEOPTION_END_CURRENT_ROW;
+                                       n->frameOptions |= FRAMEOPTION_END_CURRENT_ROW;
+                                       $$ = n;
                                }
                        | BETWEEN frame_bound AND frame_bound
                                {
+                                       WindowDef *n1 = $2;
+                                       WindowDef *n2 = $4;
+                                       /* form merged options */
+                                       int             frameOptions = n1->frameOptions;
+                                       /* shift converts START_ options to END_ options */
+                                       frameOptions |= n2->frameOptions << 1;
+                                       frameOptions |= FRAMEOPTION_BETWEEN;
                                        /* reject invalid cases */
-                                       if ($2 & FRAMEOPTION_START_UNBOUNDED_FOLLOWING)
+                                       if (frameOptions & FRAMEOPTION_START_UNBOUNDED_FOLLOWING)
                                                ereport(ERROR,
                                                                (errcode(ERRCODE_WINDOWING_ERROR),
                                                                 errmsg("frame start cannot be UNBOUNDED FOLLOWING"),
                                                                 parser_errposition(@2)));
-                                       if ($2 & FRAMEOPTION_START_CURRENT_ROW)
-                                               ereport(ERROR,
-                                                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                                                errmsg("frame start at CURRENT ROW is not implemented"),
-                                                                parser_errposition(@2)));
-                                       if ($4 & FRAMEOPTION_START_UNBOUNDED_PRECEDING)
+                                       if (frameOptions & FRAMEOPTION_END_UNBOUNDED_PRECEDING)
                                                ereport(ERROR,
                                                                (errcode(ERRCODE_WINDOWING_ERROR),
                                                                 errmsg("frame end cannot be UNBOUNDED PRECEDING"),
                                                                 parser_errposition(@4)));
-                                       /* shift converts START_ options to END_ options */
-                                       $$ = FRAMEOPTION_BETWEEN | $2 | ($4 << 1);
+                                       if ((frameOptions & FRAMEOPTION_START_CURRENT_ROW) &&
+                                               (frameOptions & FRAMEOPTION_END_VALUE_PRECEDING))
+                                               ereport(ERROR,
+                                                               (errcode(ERRCODE_WINDOWING_ERROR),
+                                                                errmsg("frame starting from current row cannot have preceding rows"),
+                                                                parser_errposition(@4)));
+                                       if ((frameOptions & FRAMEOPTION_START_VALUE_FOLLOWING) &&
+                                               (frameOptions & (FRAMEOPTION_END_VALUE_PRECEDING |
+                                                                                FRAMEOPTION_END_CURRENT_ROW)))
+                                               ereport(ERROR,
+                                                               (errcode(ERRCODE_WINDOWING_ERROR),
+                                                                errmsg("frame starting from following row cannot have preceding rows"),
+                                                                parser_errposition(@4)));
+                                       n1->frameOptions = frameOptions;
+                                       n1->endOffset = n2->startOffset;
+                                       $$ = n1;
                                }
                ;
 
@@ -9592,15 +10304,43 @@ frame_extent: frame_bound
 frame_bound:
                        UNBOUNDED PRECEDING
                                {
-                                       $$ = FRAMEOPTION_START_UNBOUNDED_PRECEDING;
+                                       WindowDef *n = makeNode(WindowDef);
+                                       n->frameOptions = FRAMEOPTION_START_UNBOUNDED_PRECEDING;
+                                       n->startOffset = NULL;
+                                       n->endOffset = NULL;
+                                       $$ = n;
                                }
                        | UNBOUNDED FOLLOWING
                                {
-                                       $$ = FRAMEOPTION_START_UNBOUNDED_FOLLOWING;
+                                       WindowDef *n = makeNode(WindowDef);
+                                       n->frameOptions = FRAMEOPTION_START_UNBOUNDED_FOLLOWING;
+                                       n->startOffset = NULL;
+                                       n->endOffset = NULL;
+                                       $$ = n;
                                }
                        | CURRENT_P ROW
                                {
-                                       $$ = FRAMEOPTION_START_CURRENT_ROW;
+                                       WindowDef *n = makeNode(WindowDef);
+                                       n->frameOptions = FRAMEOPTION_START_CURRENT_ROW;
+                                       n->startOffset = NULL;
+                                       n->endOffset = NULL;
+                                       $$ = n;
+                               }
+                       | a_expr PRECEDING
+                               {
+                                       WindowDef *n = makeNode(WindowDef);
+                                       n->frameOptions = FRAMEOPTION_START_VALUE_PRECEDING;
+                                       n->startOffset = $1;
+                                       n->endOffset = NULL;
+                                       $$ = n;
+                               }
+                       | a_expr FOLLOWING
+                               {
+                                       WindowDef *n = makeNode(WindowDef);
+                                       n->frameOptions = FRAMEOPTION_START_VALUE_FOLLOWING;
+                                       n->startOffset = $1;
+                                       n->endOffset = NULL;
+                                       $$ = n;
                                }
                ;
 
@@ -9686,6 +10426,32 @@ expr_list:      a_expr
                                }
                ;
 
+/* function arguments can have names */
+func_arg_list:  func_arg_expr
+                               {
+                                       $$ = list_make1($1);
+                               }
+                       | func_arg_list ',' func_arg_expr
+                               {
+                                       $$ = lappend($1, $3);
+                               }
+               ;
+
+func_arg_expr:  a_expr
+                               {
+                                       $$ = $1;
+                               }
+                       | param_name COLON_EQUALS a_expr
+                               {
+                                       NamedArgExpr *na = makeNode(NamedArgExpr);
+                                       na->name = $1;
+                                       na->arg = (Expr *) $3;
+                                       na->argnumber = -1;             /* until determined */
+                                       na->location = @1;
+                                       $$ = (Node *) na;
+                               }
+               ;
+
 type_list:     Typename                                                                { $$ = list_make1($1); }
                        | type_list ',' Typename                                { $$ = lappend($1, $3); }
                ;
@@ -9735,6 +10501,7 @@ extract_arg:
  * SQL99 defines the OVERLAY() function:
  * o overlay(text placing text from int for int)
  * o overlay(text placing text from int)
+ * and similarly for binary strings
  */
 overlay_list:
                        a_expr overlay_placing substr_from substr_for
@@ -9875,16 +10642,11 @@ case_arg:      a_expr                                                                  { $$ = $1; }
                        | /*EMPTY*/                                                             { $$ = NULL; }
                ;
 
-/*
- * columnref starts with relation_name not ColId, so that OLD and NEW
- * references can be accepted. Note that when there are more than two
- * dotted names, the first name is not actually a relation name...
- */
-columnref:     relation_name
+columnref:     ColId
                                {
                                        $$ = makeColumnRef($1, NIL, @1, yyscanner);
                                }
-                       | relation_name indirection
+                       | ColId indirection
                                {
                                        $$ = makeColumnRef($1, $2, @1, yyscanner);
                                }
@@ -10024,11 +10786,6 @@ target_el:     a_expr AS ColLabel
  *
  *****************************************************************************/
 
-relation_name:
-                       SpecialRuleRelation                                             { $$ = $1; }
-                       | ColId                                                                 { $$ = $1; }
-               ;
-
 qualified_name_list:
                        qualified_name                                                  { $$ = list_make1($1); }
                        | qualified_name_list ',' qualified_name { $$ = lappend($1, $3); }
@@ -10042,7 +10799,7 @@ qualified_name_list:
  * which may contain subscripts, and reject that case in the C code.
  */
 qualified_name:
-                       relation_name
+                       ColId
                                {
                                        $$ = makeNode(RangeVar);
                                        $$->catalogname = NULL;
@@ -10050,7 +10807,7 @@ qualified_name:
                                        $$->relname = $1;
                                        $$->location = @1;
                                }
-                       | relation_name indirection
+                       | ColId indirection
                                {
                                        check_qualified_name($2, yyscanner);
                                        $$ = makeNode(RangeVar);
@@ -10109,7 +10866,7 @@ file_name:      Sconst                                                                  { $$ = $1; };
  */
 func_name:     type_function_name
                                        { $$ = list_make1(makeString($1)); }
-                       | relation_name indirection
+                       | ColId indirection
                                        {
                                                $$ = check_func_name(lcons(makeString($1), $2),
                                                                                         yyscanner);
@@ -10152,10 +10909,27 @@ AexprConst: Iconst
                                        t->location = @1;
                                        $$ = makeStringConstCast($2, @2, t);
                                }
-                       | func_name '(' expr_list ')' Sconst
+                       | func_name '(' func_arg_list ')' Sconst
                                {
                                        /* generic syntax with a type modifier */
                                        TypeName *t = makeTypeNameFromNameList($1);
+                                       ListCell *lc;
+
+                                       /*
+                                        * We must use func_arg_list in the production to avoid
+                                        * reduce/reduce conflicts, but we don't actually wish
+                                        * to allow NamedArgExpr in this context.
+                                        */
+                                       foreach(lc, $3)
+                                       {
+                                               NamedArgExpr *arg = (NamedArgExpr *) lfirst(lc);
+
+                                               if (IsA(arg, NamedArgExpr))
+                                                       ereport(ERROR,
+                                                                   (errcode(ERRCODE_SYNTAX_ERROR),
+                                                                    errmsg("type modifier cannot have parameter name"),
+                                                                    parser_errposition(arg->location)));
+                                       }
                                        t->typmods = $3;
                                        t->location = @1;
                                        $$ = makeStringConstCast($5, @5, t);
@@ -10276,6 +11050,7 @@ unreserved_keyword:
                        | ASSERTION
                        | ASSIGNMENT
                        | AT
+                       | ATTRIBUTE
                        | BACKWARD
                        | BEFORE
                        | BEGIN_P
@@ -10292,9 +11067,9 @@ unreserved_keyword:
                        | CLOSE
                        | CLUSTER
                        | COMMENT
+                       | COMMENTS
                        | COMMIT
                        | COMMITTED
-                       | CONCURRENTLY
                        | CONFIGURATION
                        | CONNECTION
                        | CONSTRAINTS
@@ -10334,6 +11109,7 @@ unreserved_keyword:
                        | ENCRYPTED
                        | ENUM_P
                        | ESCAPE
+                       | EXCLUDE
                        | EXCLUDING
                        | EXCLUSIVE
                        | EXECUTE
@@ -10345,6 +11121,7 @@ unreserved_keyword:
                        | FORCE
                        | FORWARD
                        | FUNCTION
+                       | FUNCTIONS
                        | GLOBAL
                        | GRANTED
                        | HANDLER
@@ -10362,6 +11139,7 @@ unreserved_keyword:
                        | INDEXES
                        | INHERIT
                        | INHERITS
+                       | INLINE_P
                        | INPUT_P
                        | INSENSITIVE
                        | INSERT
@@ -10369,7 +11147,7 @@ unreserved_keyword:
                        | INVOKER
                        | ISOLATION
                        | KEY
-                       | LANCOMPILER
+                       | LABEL
                        | LANGUAGE
                        | LARGE_P
                        | LAST_P
@@ -10415,6 +11193,7 @@ unreserved_keyword:
                        | PARSER
                        | PARTIAL
                        | PARTITION
+                       | PASSING
                        | PASSWORD
                        | PLANS
                        | PRECEDING
@@ -10431,6 +11210,7 @@ unreserved_keyword:
                        | REASSIGN
                        | RECHECK
                        | RECURSIVE
+                       | REF
                        | REINDEX
                        | RELATIVE_P
                        | RELEASE
@@ -10454,6 +11234,7 @@ unreserved_keyword:
                        | SECOND_P
                        | SECURITY
                        | SEQUENCE
+                       | SEQUENCES
                        | SERIALIZABLE
                        | SERVER
                        | SESSION
@@ -10474,6 +11255,7 @@ unreserved_keyword:
                        | SUPERUSER_P
                        | SYSID
                        | SYSTEM_P
+                       | TABLES
                        | TABLESPACE
                        | TEMP
                        | TEMPLATE
@@ -10521,7 +11303,8 @@ unreserved_keyword:
  * looks too much like a function call for an LR(1) parser.
  */
 col_name_keyword:
-                         BIGINT
+                         BETWEEN
+                       | BIGINT
                        | BIT
                        | BOOLEAN_P
                        | CHAR_P
@@ -10561,6 +11344,7 @@ col_name_keyword:
                        | XMLATTRIBUTES
                        | XMLCONCAT
                        | XMLELEMENT
+                       | XMLEXISTS
                        | XMLFOREST
                        | XMLPARSE
                        | XMLPI
@@ -10580,8 +11364,8 @@ col_name_keyword:
  */
 type_func_name_keyword:
                          AUTHORIZATION
-                       | BETWEEN
                        | BINARY
+                       | CONCURRENTLY
                        | CROSS
                        | CURRENT_SCHEMA
                        | FREEZE
@@ -10657,12 +11441,10 @@ reserved_keyword:
                        | LIMIT
                        | LOCALTIME
                        | LOCALTIMESTAMP
-                       | NEW
                        | NOT
                        | NULL_P
                        | OFF
                        | OFFSET
-                       | OLD
                        | ON
                        | ONLY
                        | OR
@@ -10691,30 +11473,6 @@ reserved_keyword:
                        | WITH
                ;
 
-
-SpecialRuleRelation:
-                       OLD
-                               {
-                                       if (pg_yyget_extra(yyscanner)->QueryIsRule)
-                                               $$ = "*OLD*";
-                                       else
-                                               ereport(ERROR,
-                                                               (errcode(ERRCODE_SYNTAX_ERROR),
-                                                                errmsg("OLD used in query that is not in a rule"),
-                                                                parser_errposition(@1)));
-                               }
-                       | NEW
-                               {
-                                       if (pg_yyget_extra(yyscanner)->QueryIsRule)
-                                               $$ = "*NEW*";
-                                       else
-                                               ereport(ERROR,
-                                                               (errcode(ERRCODE_SYNTAX_ERROR),
-                                                                errmsg("NEW used in query that is not in a rule"),
-                                                                parser_errposition(@1)));
-                               }
-               ;
-
 %%
 
 /*
@@ -10723,14 +11481,14 @@ SpecialRuleRelation:
  * available from the scanner.
  */
 static void
-base_yyerror(YYLTYPE *yylloc, base_yyscan_t yyscanner, const char *msg)
+base_yyerror(YYLTYPE *yylloc, core_yyscan_t yyscanner, const char *msg)
 {
        parser_yyerror(msg);
 }
 
 static Node *
 makeColumnRef(char *colname, List *indirection,
-                         int location, base_yyscan_t yyscanner)
+                         int location, core_yyscan_t yyscanner)
 {
        /*
         * Generate a ColumnRef node, with an A_Indirection node added if there
@@ -10900,7 +11658,7 @@ makeBoolAConst(bool state, int location)
  * Create and populate a FuncCall node to support the OVERLAPS operator.
  */
 static FuncCall *
-makeOverlaps(List *largs, List *rargs, int location, base_yyscan_t yyscanner)
+makeOverlaps(List *largs, List *rargs, int location, core_yyscan_t yyscanner)
 {
        FuncCall *n = makeNode(FuncCall);
 
@@ -10920,6 +11678,7 @@ makeOverlaps(List *largs, List *rargs, int location, base_yyscan_t yyscanner)
                                 errmsg("wrong number of parameters on right side of OVERLAPS expression"),
                                 parser_errposition(location)));
        n->args = list_concat(largs, rargs);
+       n->agg_order = NIL;
        n->agg_star = FALSE;
        n->agg_distinct = FALSE;
        n->func_variadic = FALSE;
@@ -10934,7 +11693,7 @@ makeOverlaps(List *largs, List *rargs, int location, base_yyscan_t yyscanner)
  * subscripts and '*', which we then must reject here.
  */
 static void
-check_qualified_name(List *names, base_yyscan_t yyscanner)
+check_qualified_name(List *names, core_yyscan_t yyscanner)
 {
        ListCell   *i;
 
@@ -10951,7 +11710,7 @@ check_qualified_name(List *names, base_yyscan_t yyscanner)
  * and '*', which we then must reject here.
  */
 static List *
-check_func_name(List *names, base_yyscan_t yyscanner)
+check_func_name(List *names, core_yyscan_t yyscanner)
 {
        ListCell   *i;
 
@@ -10969,7 +11728,7 @@ check_func_name(List *names, base_yyscan_t yyscanner)
  * in the grammar, so do it here.
  */
 static List *
-check_indirection(List *indirection, base_yyscan_t yyscanner)
+check_indirection(List *indirection, core_yyscan_t yyscanner)
 {
        ListCell *l;
 
@@ -11028,7 +11787,7 @@ insertSelectOptions(SelectStmt *stmt,
                                        List *sortClause, List *lockingClause,
                                        Node *limitOffset, Node *limitCount,
                                        WithClause *withClause,
-                                       base_yyscan_t yyscanner)
+                                       core_yyscan_t yyscanner)
 {
        Assert(IsA(stmt, SelectStmt));
 
@@ -11206,7 +11965,6 @@ void
 parser_init(base_yy_extra_type *yyext)
 {
        yyext->parsetree = NIL;         /* in case grammar forgets to set it */
-       yyext->QueryIsRule = FALSE;
 }
 
 /*
@@ -11255,12 +12013,50 @@ TableFuncTypeName(List *columns)
 }
 
 /*
- * Must undefine base_yylex before including scan.c, since we want it
- * to create the function base_yylex not filtered_base_yylex.
+ * Convert a list of (dotted) names to a RangeVar (like
+ * makeRangeVarFromNameList, but with position support).  The
+ * "AnyName" refers to the any_name production in the grammar.
  */
-#undef base_yylex
+static RangeVar *
+makeRangeVarFromAnyName(List *names, int position, core_yyscan_t yyscanner)
+{
+       RangeVar *r = makeNode(RangeVar);
+
+       switch (list_length(names))
+       {
+               case 1:
+                       r->catalogname = NULL;
+                       r->schemaname = NULL;
+                       r->relname = strVal(linitial(names));
+                       break;
+               case 2:
+                       r->catalogname = NULL;
+                       r->schemaname = strVal(linitial(names));
+                       r->relname = strVal(lsecond(names));
+                       break;
+               case 3:
+                       r->catalogname = strVal(linitial(names));;
+                       r->schemaname = strVal(lsecond(names));
+                       r->relname = strVal(lthird(names));
+                       break;
+               default:
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_SYNTAX_ERROR),
+                                        errmsg("improper qualified name (too many dotted names): %s",
+                                                       NameListToString(names)),
+                                        parser_errposition(position)));
+                       break;
+       }
+
+       r->location = position;
 
-/* Undefine some other stuff that would conflict in scan.c, too */
+       return r;
+}
+
+/*
+ * Must undefine this stuff before including scan.c, since it has different
+ * definitions for these macros.
+ */
 #undef yyerror
 #undef yylval
 #undef yylloc