]> 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 2541d0212877c476c160ac9715dd1573147ce5a5..609c4727017429e09f3679ad0bc60c4a84185a69 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.707 2010/02/08 04:33:54 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
 
@@ -245,8 +246,8 @@ 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
@@ -295,7 +296,7 @@ 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
                                opt_enum_val_list enum_val_list table_func_column_list
@@ -310,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
@@ -334,7 +335,7 @@ static TypeName *TableFuncTypeName(List *columns);
 %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_args limit_clause select_limit_value
                                offset_clause select_offset_value
@@ -365,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
@@ -399,8 +401,7 @@ static TypeName *TableFuncTypeName(List *columns);
 %type <boolean> opt_varying opt_timezone
 
 %type <ival>   Iconst SignedIconst
-%type <list>   Iconst_list
-%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
@@ -422,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
 
 
 /*
@@ -444,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
@@ -461,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
@@ -498,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
 
@@ -511,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
 
@@ -539,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
@@ -578,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
@@ -646,6 +660,7 @@ stmt :
                        | AlterOwnerStmt
                        | AlterSeqStmt
                        | AlterTableStmt
+                       | AlterCompositeTypeStmt
                        | AlterRoleSetStmt
                        | AlterRoleStmt
                        | AlterTSConfigurationStmt
@@ -726,6 +741,7 @@ stmt :
                        | RevokeStmt
                        | RevokeRoleStmt
                        | RuleStmt
+                       | SecLabelStmt
                        | SelectStmt
                        | TransactionStmt
                        | TruncateStmt
@@ -1957,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 :
@@ -1987,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:
@@ -2202,6 +2284,23 @@ 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 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
@@ -2217,6 +2316,23 @@ CreateStmt:      CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
                                        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;
                                }
                ;
@@ -2783,6 +2899,7 @@ CreateSeqStmt:
                                        $4->istemp = $2;
                                        n->sequence = $4;
                                        n->options = $5;
+                                       n->ownerId = InvalidOid;
                                        $$ = (Node *)n;
                                }
                ;
@@ -2869,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;
@@ -2889,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;
                        }
                ;
@@ -3325,8 +3448,8 @@ CreateTrigStmt:
                                        n->relation = $7;
                                        n->funcname = $12;
                                        n->args = $14;
-                                       n->before = $4;
                                        n->row = $8;
+                                       n->timing = $4;
                                        n->events = intVal(linitial($5));
                                        n->columns = (List *) lsecond($5);
                                        n->whenClause = $9;
@@ -3346,8 +3469,8 @@ CreateTrigStmt:
                                        n->relation = $8;
                                        n->funcname = $17;
                                        n->args = $19;
-                                       n->before = FALSE;
                                        n->row = TRUE;
+                                       n->timing = TRIGGER_TYPE_AFTER;
                                        n->events = intVal(linitial($6));
                                        n->columns = (List *) lsecond($6);
                                        n->whenClause = $14;
@@ -3360,8 +3483,9 @@ CreateTrigStmt:
                ;
 
 TriggerActionTime:
-                       BEFORE                                                                  { $$ = TRUE; }
-                       | AFTER                                                                 { $$ = FALSE; }
+                       BEFORE                                                          { $$ = TRIGGER_TYPE_BEFORE; }
+                       | AFTER                                                         { $$ = TRIGGER_TYPE_AFTER; }
+                       | INSTEAD OF                                            { $$ = TRIGGER_TYPE_INSTEAD; }
                ;
 
 TriggerEvents:
@@ -3402,7 +3526,7 @@ TriggerOneEvent:
                ;
 
 TriggerForSpec:
-                       FOR TriggerForOpt TriggerForType
+                       FOR TriggerForOptEach TriggerForType
                                {
                                        $$ = $3;
                                }
@@ -3416,7 +3540,7 @@ TriggerForSpec:
                                }
                ;
 
-TriggerForOpt:
+TriggerForOptEach:
                        EACH                                                                    {}
                        | /*EMPTY*/                                                             {}
                ;
@@ -3626,39 +3750,12 @@ 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;
                                }
@@ -4275,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:
@@ -4622,7 +4805,7 @@ privilege_target:
                                        n->objs = $2;
                                        $$ = n;
                                }
-                       | LARGE_P OBJECT_P Iconst_list
+                       | LARGE_P OBJECT_P NumericOnly_list
                                {
                                        PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget));
                                        n->targtype = ACL_TARGET_OBJECT;
@@ -5784,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; }
@@ -5917,11 +6109,11 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
                                        n->newowner = $7;
                                        $$ = (Node *)n;
                                }
-                       | ALTER LARGE_P OBJECT_P Iconst OWNER TO RoleId
+                       | ALTER LARGE_P OBJECT_P NumericOnly OWNER TO RoleId
                                {
                                        AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
                                        n->objectType = OBJECT_LARGEOBJECT;
-                                       n->object = list_make1(makeInteger($4));
+                                       n->object = list_make1($4);
                                        n->newowner = $7;
                                        $$ = (Node *)n;
                                }
@@ -6113,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);
@@ -7071,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;
                                }
                ;
 
@@ -7131,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;
                                }
                ;
@@ -7193,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;
                                }
                ;
@@ -7546,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
                                {
@@ -8158,6 +8364,11 @@ where_or_current_clause:
                ;
 
 
+OptTableFuncElementList:
+                       TableFuncElementList                            { $$ = $1; }
+                       | /*EMPTY*/                                                     { $$ = NIL; }
+               ;
+
 TableFuncElementList:
                        TableFuncElement
                                {
@@ -9784,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);
@@ -9874,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
  */
@@ -9907,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;
                                }
@@ -9922,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;
                                }
@@ -9947,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;
                                }
                ;
 
@@ -10010,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;
                                }
                ;
 
@@ -10119,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;
                                }
                ;
@@ -10605,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;
@@ -10662,10 +10984,6 @@ SignedIconst: Iconst                                                           { $$ = $1; }
                        | '-' Iconst                                                    { $$ = - $2; }
                ;
 
-Iconst_list:   Iconst                                          { $$ = list_make1(makeInteger($1)); }
-                               | Iconst_list ',' Iconst        { $$ = lappend($1, makeInteger($3)); }
-               ;
-
 /*
  * Name classification hierarchy.
  *
@@ -10732,6 +11050,7 @@ unreserved_keyword:
                        | ASSERTION
                        | ASSIGNMENT
                        | AT
+                       | ATTRIBUTE
                        | BACKWARD
                        | BEFORE
                        | BEGIN_P
@@ -10828,6 +11147,7 @@ unreserved_keyword:
                        | INVOKER
                        | ISOLATION
                        | KEY
+                       | LABEL
                        | LANGUAGE
                        | LARGE_P
                        | LAST_P
@@ -10873,6 +11193,7 @@ unreserved_keyword:
                        | PARSER
                        | PARTIAL
                        | PARTITION
+                       | PASSING
                        | PASSWORD
                        | PLANS
                        | PRECEDING
@@ -10889,6 +11210,7 @@ unreserved_keyword:
                        | REASSIGN
                        | RECHECK
                        | RECURSIVE
+                       | REF
                        | REINDEX
                        | RELATIVE_P
                        | RELEASE
@@ -10981,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
@@ -11021,6 +11344,7 @@ col_name_keyword:
                        | XMLATTRIBUTES
                        | XMLCONCAT
                        | XMLELEMENT
+                       | XMLEXISTS
                        | XMLFOREST
                        | XMLPARSE
                        | XMLPI
@@ -11040,7 +11364,6 @@ col_name_keyword:
  */
 type_func_name_keyword:
                          AUTHORIZATION
-                       | BETWEEN
                        | BINARY
                        | CONCURRENTLY
                        | CROSS
@@ -11689,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.