]> 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 4325e4d0eda5467a3178567f18701b4668fe7c1a..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.690 2009/11/09 18:38:48 tgl Exp $
+ *       src/backend/parser/gram.y
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -131,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);
 
 %}
 
@@ -184,7 +185,7 @@ static TypeName *TableFuncTypeName(List *columns);
                AlterDatabaseStmt AlterDatabaseSetStmt AlterDomainStmt AlterFdwStmt
                AlterForeignServerStmt AlterGroupStmt
                AlterObjectSchemaStmt AlterOwnerStmt AlterSeqStmt AlterTableStmt
-               AlterUserStmt AlterUserMappingStmt AlterUserSetStmt
+               AlterCompositeTypeStmt AlterUserStmt AlterUserMappingStmt AlterUserSetStmt
                AlterRoleStmt AlterRoleSetStmt
                AlterDefaultPrivilegesStmt DefACLAction
                AnalyzeStmt ClosePortalStmt ClusterStmt CommentStmt
@@ -204,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
@@ -218,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
 
@@ -229,6 +230,7 @@ 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
@@ -244,14 +246,16 @@ static TypeName *TableFuncTypeName(List *columns);
 %type <str>            OptSchemaName
 %type <list>   OptSchemaEltList
 
-%type <boolean> TriggerActionTime TriggerForSpec opt_trusted opt_restart_seqs
-
+%type <boolean> TriggerForSpec TriggerForType
+%type <ival>   TriggerActionTime
 %type <list>   TriggerEvents TriggerOneEvent
 %type <value>  TriggerFuncArg
+%type <node>   TriggerWhen
 
 %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_inline_handler opt_validator validator_clause
@@ -274,6 +278,7 @@ static TypeName *TableFuncTypeName(List *columns);
 
 %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
@@ -291,10 +296,10 @@ 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 dostmt_opt_list
 
@@ -306,7 +311,7 @@ static TypeName *TableFuncTypeName(List *columns);
 %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
@@ -323,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
@@ -344,12 +349,14 @@ 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
@@ -359,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
@@ -393,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
@@ -415,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
 
 
 /*
@@ -437,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
@@ -454,7 +465,7 @@ 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
@@ -473,7 +484,7 @@ 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 FUNCTIONS
@@ -491,7 +502,7 @@ static TypeName *TableFuncTypeName(List *columns);
 
        KEY
 
-       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
 
@@ -504,13 +515,13 @@ static TypeName *TableFuncTypeName(List *columns);
        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
 
@@ -532,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
@@ -571,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
@@ -639,6 +660,7 @@ stmt :
                        | AlterOwnerStmt
                        | AlterSeqStmt
                        | AlterTableStmt
+                       | AlterCompositeTypeStmt
                        | AlterRoleSetStmt
                        | AlterRoleStmt
                        | AlterTSConfigurationStmt
@@ -719,6 +741,7 @@ stmt :
                        | RevokeStmt
                        | RevokeRoleStmt
                        | RuleStmt
+                       | SecLabelStmt
                        | SelectStmt
                        | TransactionStmt
                        | TruncateStmt
@@ -1589,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;
@@ -1631,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> */
@@ -1933,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 :
@@ -1941,7 +2047,7 @@ reloption_elem:
  *****************************************************************************/
 
 ClosePortalStmt:
-                       CLOSE name
+                       CLOSE cursor_name
                                {
                                        ClosePortalStmt *n = makeNode(ClosePortalStmt);
                                        n->portalname = $2;
@@ -1963,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:
@@ -2178,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;
                                }
                ;
@@ -2220,6 +2358,11 @@ OptTableElementList:
                        | /*EMPTY*/                                                     { $$ = NIL; }
                ;
 
+OptTypedTableElementList:
+                       '(' TypedTableElementList ')'           { $$ = $2; }
+                       | /*EMPTY*/                                                     { $$ = NIL; }
+               ;
+
 TableElementList:
                        TableElement
                                {
@@ -2231,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);
@@ -2248,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; }
@@ -2485,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
                                {
@@ -2542,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
@@ -2692,6 +2899,7 @@ CreateSeqStmt:
                                        $4->istemp = $2;
                                        n->sequence = $4;
                                        n->options = $5;
+                                       n->ownerId = InvalidOid;
                                        $$ = (Node *)n;
                                }
                ;
@@ -2778,19 +2986,24 @@ 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;
@@ -2798,15 +3011,16 @@ CreatePLangStmt:
                                n->pltrusted = false;
                                $$ = (Node *)n;
                        }
-                       | CREATE opt_trusted opt_procedural LANGUAGE ColId_or_Sconst
+                       | 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->plinline = $8;
-                               n->plvalidator = $9;
-                               n->pltrusted = $2;
+                               n->replace = $2;
+                               n->plname = $6;
+                               n->plhandler = $8;
+                               n->plinline = $9;
+                               n->plvalidator = $10;
+                               n->pltrusted = $3;
                                $$ = (Node *)n;
                        }
                ;
@@ -3226,18 +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->timing = $4;
                                        n->events = intVal(linitial($5));
                                        n->columns = (List *) lsecond($5);
+                                       n->whenClause = $9;
                                        n->isconstraint  = FALSE;
                                        n->deferrable    = FALSE;
                                        n->initdeferred  = FALSE;
@@ -3245,20 +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->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;
@@ -3268,8 +3483,9 @@ CreateTrigStmt:
                ;
 
 TriggerActionTime:
-                       BEFORE                                                                  { $$ = TRUE; }
-                       | AFTER                                                                 { $$ = FALSE; }
+                       BEFORE                                                          { $$ = TRIGGER_TYPE_BEFORE; }
+                       | AFTER                                                         { $$ = TRIGGER_TYPE_AFTER; }
+                       | INSTEAD OF                                            { $$ = TRIGGER_TYPE_INSTEAD; }
                ;
 
 TriggerEvents:
@@ -3310,7 +3526,7 @@ TriggerOneEvent:
                ;
 
 TriggerForSpec:
-                       FOR TriggerForOpt TriggerForType
+                       FOR TriggerForOptEach TriggerForType
                                {
                                        $$ = $3;
                                }
@@ -3324,7 +3540,7 @@ TriggerForSpec:
                                }
                ;
 
-TriggerForOpt:
+TriggerForOptEach:
                        EACH                                                                    {}
                        | /*EMPTY*/                                                             {}
                ;
@@ -3334,6 +3550,11 @@ TriggerForType:
                        | STATEMENT                                                             { $$ = FALSE; }
                ;
 
+TriggerWhen:
+                       WHEN '(' a_expr ')'                                             { $$ = $3; }
+                       | /*EMPTY*/                                                             { $$ = NULL; }
+               ;
+
 TriggerFuncArgs:
                        TriggerFuncArg                                                  { $$ = list_make1($1); }
                        | TriggerFuncArgs ',' TriggerFuncArg    { $$ = lappend($1, $3); }
@@ -3529,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;
@@ -3657,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
@@ -4173,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:
@@ -4180,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;
@@ -4326,6 +4613,10 @@ from_in: FROM                                                                    {}
                        | IN_P                                                                  {}
                ;
 
+opt_from_in:   from_in                                                         {}
+                       | /* EMPTY */                                                   {}
+               ;
+
 
 /*****************************************************************************
  *
@@ -4514,6 +4805,14 @@ privilege_target:
                                        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));
@@ -4751,36 +5050,17 @@ defacl_privilege_target:
  *
  *             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;
@@ -4792,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; }
@@ -4816,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;
@@ -4825,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;
@@ -4834,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;
@@ -5616,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);
@@ -5656,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; }
@@ -5789,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);
@@ -5977,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);
@@ -6619,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;
@@ -6632,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;
@@ -6645,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;
@@ -6671,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;
@@ -6895,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;
                                }
                ;
 
@@ -6955,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;
                                }
                ;
@@ -7017,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;
                                }
                ;
@@ -7102,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;
@@ -7113,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; }
@@ -7367,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
                                {
@@ -7979,6 +8364,11 @@ where_or_current_clause:
                ;
 
 
+OptTableFuncElementList:
+                       TableFuncElementList                            { $$ = $1; }
+                       | /*EMPTY*/                                                     { $$ = NIL; }
+               ;
+
 TableFuncElementList:
                        TableFuncElement
                                {
@@ -8529,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;
@@ -8589,6 +8980,7 @@ 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;
@@ -8603,6 +8995,7 @@ 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;
@@ -8617,6 +9010,7 @@ 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;
@@ -8631,6 +9025,7 @@ 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;
@@ -8644,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;
@@ -8656,6 +9052,7 @@ 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;
@@ -8668,6 +9065,7 @@ 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;
@@ -8680,6 +9078,7 @@ 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;
@@ -9098,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;
@@ -9110,6 +9510,7 @@ func_expr:        func_name '(' ')' 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;
@@ -9122,6 +9523,7 @@ func_expr:        func_name '(' ')' 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;
@@ -9134,6 +9536,7 @@ func_expr:        func_name '(' ')' 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;
@@ -9141,11 +9544,25 @@ func_expr:      func_name '(' ')' over_clause
                                        n->location = @1;
                                        $$ = (Node *)n;
                                }
-                       | func_name '(' ALL func_arg_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
@@ -9153,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 func_arg_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;
                                }
@@ -9184,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;
@@ -9244,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;
@@ -9315,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;
@@ -9327,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;
@@ -9339,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;
@@ -9351,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;
@@ -9363,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;
@@ -9375,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;
@@ -9389,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;
@@ -9399,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;
@@ -9419,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;
@@ -9434,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;
@@ -9455,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;
@@ -9470,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;
@@ -9482,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;
@@ -9494,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;
@@ -9506,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;
@@ -9560,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);
@@ -9650,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
  */
@@ -9683,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;
                                }
@@ -9698,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;
                                }
@@ -9723,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;
                                }
                ;
 
@@ -9786,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;
                                }
                ;
 
@@ -9895,13 +10441,13 @@ func_arg_expr:  a_expr
                                {
                                        $$ = $1;
                                }
-                       | a_expr AS param_name
+                       | param_name COLON_EQUALS a_expr
                                {
                                        NamedArgExpr *na = makeNode(NamedArgExpr);
-                                       na->arg = (Expr *) $1;
-                                       na->name = $3;
+                                       na->name = $1;
+                                       na->arg = (Expr *) $3;
                                        na->argnumber = -1;             /* until determined */
-                                       na->location = @3;
+                                       na->location = @1;
                                        $$ = (Node *) na;
                                }
                ;
@@ -9955,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
@@ -10380,7 +10927,7 @@ AexprConst: Iconst
                                                if (IsA(arg, NamedArgExpr))
                                                        ereport(ERROR,
                                                                    (errcode(ERRCODE_SYNTAX_ERROR),
-                                                                    errmsg("type modifier cannot have AS name"),
+                                                                    errmsg("type modifier cannot have parameter name"),
                                                                     parser_errposition(arg->location)));
                                        }
                                        t->typmods = $3;
@@ -10503,6 +11050,7 @@ unreserved_keyword:
                        | ASSERTION
                        | ASSIGNMENT
                        | AT
+                       | ATTRIBUTE
                        | BACKWARD
                        | BEFORE
                        | BEGIN_P
@@ -10522,7 +11070,6 @@ unreserved_keyword:
                        | COMMENTS
                        | COMMIT
                        | COMMITTED
-                       | CONCURRENTLY
                        | CONFIGURATION
                        | CONNECTION
                        | CONSTRAINTS
@@ -10562,6 +11109,7 @@ unreserved_keyword:
                        | ENCRYPTED
                        | ENUM_P
                        | ESCAPE
+                       | EXCLUDE
                        | EXCLUDING
                        | EXCLUSIVE
                        | EXECUTE
@@ -10599,6 +11147,7 @@ unreserved_keyword:
                        | INVOKER
                        | ISOLATION
                        | KEY
+                       | LABEL
                        | LANGUAGE
                        | LARGE_P
                        | LAST_P
@@ -10644,6 +11193,7 @@ unreserved_keyword:
                        | PARSER
                        | PARTIAL
                        | PARTITION
+                       | PASSING
                        | PASSWORD
                        | PLANS
                        | PRECEDING
@@ -10660,6 +11210,7 @@ unreserved_keyword:
                        | REASSIGN
                        | RECHECK
                        | RECURSIVE
+                       | REF
                        | REINDEX
                        | RELATIVE_P
                        | RELEASE
@@ -10752,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
@@ -10792,6 +11344,7 @@ col_name_keyword:
                        | XMLATTRIBUTES
                        | XMLCONCAT
                        | XMLELEMENT
+                       | XMLEXISTS
                        | XMLFOREST
                        | XMLPARSE
                        | XMLPI
@@ -10811,8 +11364,8 @@ col_name_keyword:
  */
 type_func_name_keyword:
                          AUTHORIZATION
-                       | BETWEEN
                        | BINARY
+                       | CONCURRENTLY
                        | CROSS
                        | CURRENT_SCHEMA
                        | FREEZE
@@ -11125,6 +11678,7 @@ makeOverlaps(List *largs, List *rargs, int location, core_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;
@@ -11458,6 +12012,47 @@ TableFuncTypeName(List *columns)
        return result;
 }
 
+/*
+ * 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.
+ */
+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;
+
+       return r;
+}
+
 /*
  * Must undefine this stuff before including scan.c, since it has different
  * definitions for these macros.