]> granicus.if.org Git - postgresql/blobdiff - src/include/nodes/primnodes.h
Support domains over composite types.
[postgresql] / src / include / nodes / primnodes.h
index 6d9f3d95eeea7d4aad65e5ba8ba5d5a19686b9e4..c2929ac387fec7ef2a8365a6f2b9a3646543bddd 100644 (file)
@@ -7,7 +7,7 @@
  *       and join trees.
  *
  *
- * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * src/include/nodes/primnodes.h
@@ -18,6 +18,7 @@
 #define PRIMNODES_H
 
 #include "access/attnum.h"
+#include "nodes/bitmapset.h"
 #include "nodes/pg_list.h"
 
 
@@ -42,13 +43,6 @@ typedef struct Alias
        List       *colnames;           /* optional list of column aliases */
 } Alias;
 
-typedef enum InhOption
-{
-       INH_NO,                                         /* Do NOT scan child tables */
-       INH_YES,                                        /* DO scan child tables */
-       INH_DEFAULT                                     /* Use current SQL_inheritance option */
-} InhOption;
-
 /* What to do at commit time for temporary relations */
 typedef enum OnCommitAction
 {
@@ -62,7 +56,7 @@ typedef enum OnCommitAction
  * RangeVar - range variable, used in FROM clauses
  *
  * Also used to represent table names in utility statements; there, the alias
- * field is not used, and inhOpt shows whether to apply the operation
+ * field is not used, and inh tells whether to apply the operation
  * recursively to child tables.  In some contexts it is also useful to carry
  * a TEMP table indication here.
  */
@@ -72,13 +66,34 @@ typedef struct RangeVar
        char       *catalogname;        /* the catalog (database) name, or NULL */
        char       *schemaname;         /* the schema name, or NULL */
        char       *relname;            /* the relation/sequence name */
-       InhOption       inhOpt;                 /* expand rel by inheritance? recursively act
+       bool            inh;                    /* expand rel by inheritance? recursively act
                                                                 * on children? */
        char            relpersistence; /* see RELPERSISTENCE_* in pg_class.h */
        Alias      *alias;                      /* table alias & optional column aliases */
        int                     location;               /* token location, or -1 if unknown */
 } RangeVar;
 
+/*
+ * TableFunc - node for a table function, such as XMLTABLE.
+ */
+typedef struct TableFunc
+{
+       NodeTag         type;
+       List       *ns_uris;            /* list of namespace uri */
+       List       *ns_names;           /* list of namespace names */
+       Node       *docexpr;            /* input document expression */
+       Node       *rowexpr;            /* row filter expression */
+       List       *colnames;           /* column names (list of String) */
+       List       *coltypes;           /* OID list of column type OIDs */
+       List       *coltypmods;         /* integer list of column typmods */
+       List       *colcollations;      /* OID list of column collation OIDs */
+       List       *colexprs;           /* list of column filter expressions */
+       List       *coldefexprs;        /* list of column default expressions */
+       Bitmapset  *notnulls;           /* nullability flag for each output column */
+       int                     ordinalitycol;  /* counts from 0; -1 if none specified */
+       int                     location;               /* token location, or -1 if unknown */
+} TableFunc;
+
 /*
  * IntoClause - target information for SELECT INTO, CREATE TABLE AS, and
  * CREATE MATERIALIZED VIEW
@@ -127,13 +142,17 @@ typedef struct Expr
  * upper-level plan nodes are reassigned to point to the outputs of their
  * subplans; for example, in a join node varno becomes INNER_VAR or OUTER_VAR
  * and varattno becomes the index of the proper element of that subplan's
- * target list.  But varnoold/varoattno continue to hold the original values.
- * The code doesn't really need varnoold/varoattno, but they are very useful
- * for debugging and interpreting completed plans, so we keep them around.
+ * target list.  Similarly, INDEX_VAR is used to identify Vars that reference
+ * an index column rather than a heap column.  (In ForeignScan and CustomScan
+ * plan nodes, INDEX_VAR is abused to signify references to columns of a
+ * custom scan tuple type.)  In all these cases, varnoold/varoattno hold the
+ * original values.  The code doesn't really need varnoold/varoattno, but they
+ * are very useful for debugging and interpreting completed plans, so we keep
+ * them around.
  */
-#define    INNER_VAR           65000           /* reference to inner subplan */
-#define    OUTER_VAR           65001           /* reference to outer subplan */
-#define    INDEX_VAR           65002           /* reference to index column */
+#define    INNER_VAR           65000   /* reference to inner subplan */
+#define    OUTER_VAR           65001   /* reference to outer subplan */
+#define    INDEX_VAR           65002   /* reference to index column */
 
 #define IS_SPECIAL_VARNO(varno)                ((varno) >= INNER_VAR)
 
@@ -147,7 +166,7 @@ typedef struct Var
        Index           varno;                  /* index of this var's relation in the range
                                                                 * table, or INNER_VAR/OUTER_VAR/INDEX_VAR */
        AttrNumber      varattno;               /* attribute number of this var, or zero for
-                                                                * all */
+                                                                * all attrs ("whole-row Var") */
        Oid                     vartype;                /* pg_type OID for the type of this var */
        int32           vartypmod;              /* pg_attribute typmod value */
        Oid                     varcollid;              /* OID of collation, or InvalidOid if none */
@@ -161,6 +180,11 @@ typedef struct Var
 
 /*
  * Const
+ *
+ * Note: for varlena data types, we make a rule that a Const node's value
+ * must be in non-extended form (4-byte header, no compression or external
+ * references).  This ensures that the Const node is self-contained and makes
+ * it more likely that equal() will see logically identical values as equal.
  */
 typedef struct Const
 {
@@ -179,9 +203,10 @@ typedef struct Const
        int                     location;               /* token location, or -1 if unknown */
 } Const;
 
-/* ----------------
+/*
  * Param
- *             paramkind - specifies the kind of parameter. The possible values
+ *
+ *             paramkind specifies the kind of parameter. The possible values
  *             for this field are:
  *
  *             PARAM_EXTERN:  The parameter value is supplied from outside the plan.
@@ -204,12 +229,6 @@ typedef struct Const
  *                             of the `paramid' field contain the SubLink's subLinkId, and
  *                             the low-order 16 bits contain the column number.  (This type
  *                             of Param is also converted to PARAM_EXEC during planning.)
- *
- * Note: currently, paramtypmod is always -1 for PARAM_EXTERN params, since
- * the APIs that supply values for such parameters don't carry any typmod
- * info.  It is valid in other types of Params, if they represent expressions
- * with determinable typmod.
- * ----------------
  */
 typedef enum ParamKind
 {
@@ -251,6 +270,23 @@ typedef struct Param
  * DISTINCT is not supported in this case, so aggdistinct will be NIL.
  * The direct arguments appear in aggdirectargs (as a list of plain
  * expressions, not TargetEntry nodes).
+ *
+ * aggtranstype is the data type of the state transition values for this
+ * aggregate (resolved to an actual type, if agg's transtype is polymorphic).
+ * This is determined during planning and is InvalidOid before that.
+ *
+ * aggargtypes is an OID list of the data types of the direct and regular
+ * arguments.  Normally it's redundant with the aggdirectargs and args lists,
+ * but in a combining aggregate, it's not because the args list has been
+ * replaced with a single argument representing the partial-aggregate
+ * transition values.
+ *
+ * aggsplit indicates the expected partial-aggregation mode for the Aggref's
+ * parent plan node.  It's always set to AGGSPLIT_SIMPLE in the parser, but
+ * the planner might change it to something else.  We use this mainly as
+ * a crosscheck that the Aggrefs match the plan; but note that when aggsplit
+ * indicates a non-final mode, aggtype reflects the transition data type
+ * not the SQL-level output type of the aggregate.
  */
 typedef struct Aggref
 {
@@ -259,6 +295,8 @@ typedef struct Aggref
        Oid                     aggtype;                /* type Oid of result of the aggregate */
        Oid                     aggcollid;              /* OID of collation of result */
        Oid                     inputcollid;    /* OID of collation that function should use */
+       Oid                     aggtranstype;   /* type Oid of aggregate's transition value */
+       List       *aggargtypes;        /* type Oids of direct and aggregated args */
        List       *aggdirectargs;      /* direct arguments, if an ordered-set agg */
        List       *args;                       /* aggregated arguments and sort expressions */
        List       *aggorder;           /* ORDER BY (list of SortGroupClause) */
@@ -269,9 +307,45 @@ typedef struct Aggref
                                                                 * combined into an array last argument */
        char            aggkind;                /* aggregate kind (see pg_aggregate.h) */
        Index           agglevelsup;    /* > 0 if agg belongs to outer query */
+       AggSplit        aggsplit;               /* expected agg-splitting mode of parent Agg */
        int                     location;               /* token location, or -1 if unknown */
 } Aggref;
 
+/*
+ * GroupingFunc
+ *
+ * A GroupingFunc is a GROUPING(...) expression, which behaves in many ways
+ * like an aggregate function (e.g. it "belongs" to a specific query level,
+ * which might not be the one immediately containing it), but also differs in
+ * an important respect: it never evaluates its arguments, they merely
+ * designate expressions from the GROUP BY clause of the query level to which
+ * it belongs.
+ *
+ * The spec defines the evaluation of GROUPING() purely by syntactic
+ * replacement, but we make it a real expression for optimization purposes so
+ * that one Agg node can handle multiple grouping sets at once.  Evaluating the
+ * result only needs the column positions to check against the grouping set
+ * being projected.  However, for EXPLAIN to produce meaningful output, we have
+ * to keep the original expressions around, since expression deparse does not
+ * give us any feasible way to get at the GROUP BY clause.
+ *
+ * Also, we treat two GroupingFunc nodes as equal if they have equal arguments
+ * lists and agglevelsup, without comparing the refs and cols annotations.
+ *
+ * In raw parse output we have only the args list; parse analysis fills in the
+ * refs list, and the planner fills in the cols list.
+ */
+typedef struct GroupingFunc
+{
+       Expr            xpr;
+       List       *args;                       /* arguments, not evaluated but kept for
+                                                                * benefit of EXPLAIN etc. */
+       List       *refs;                       /* ressortgrouprefs of arguments */
+       List       *cols;                       /* actual column positions set by planner */
+       Index           agglevelsup;    /* same as Aggref.agglevelsup */
+       int                     location;               /* token location */
+} GroupingFunc;
+
 /*
  * WindowFunc
  */
@@ -307,9 +381,16 @@ typedef struct WindowFunc
  * reflowerindexpr must be the same length as refupperindexpr when it
  * is not NIL.
  *
+ * In the slice case, individual expressions in the subscript lists can be
+ * NULL, meaning "substitute the array's current lower or upper bound".
+ *
  * Note: the result datatype is the element type when fetching a single
  * element; but it is the array type when doing subarray fetch or either
  * type of store.
+ *
+ * Note: for the cases where an array is returned, if refexpr yields a R/W
+ * expanded array, then the implementation is allowed to modify that object
+ * in-place and return the same object.)
  * ----------------
  */
 typedef struct ArrayRef
@@ -319,10 +400,11 @@ typedef struct ArrayRef
        Oid                     refelemtype;    /* type of the array elements */
        int32           reftypmod;              /* typmod of the array (and elements too) */
        Oid                     refcollid;              /* OID of collation, or InvalidOid if none */
-       List       *refupperindexpr;/* expressions that evaluate to upper array
-                                                                * indexes */
-       List       *reflowerindexpr;/* expressions that evaluate to lower array
-                                                                * indexes */
+       List       *refupperindexpr;    /* expressions that evaluate to upper
+                                                                        * array indexes */
+       List       *reflowerindexpr;    /* expressions that evaluate to lower
+                                                                        * array indexes, or NIL for single array
+                                                                        * element */
        Expr       *refexpr;            /* the expression that evaluates to an array
                                                                 * value */
        Expr       *refassgnexpr;       /* expression for the source value, or NULL if
@@ -610,14 +692,16 @@ typedef struct SubPlan
        /* Extra data useful for determining subplan's output type: */
        Oid                     firstColType;   /* Type of first column of subplan result */
        int32           firstColTypmod; /* Typmod of first column of subplan result */
-       Oid                     firstColCollation;              /* Collation of first column of
-                                                                                * subplan result */
+       Oid                     firstColCollation;      /* Collation of first column of subplan
+                                                                        * result */
        /* Information about execution strategy: */
        bool            useHashTable;   /* TRUE to store subselect output in a hash
                                                                 * table (implies we are doing "IN") */
        bool            unknownEqFalse; /* TRUE if it's okay to return FALSE when the
                                                                 * spec result is UNKNOWN; this allows much
                                                                 * simpler handling of null values */
+       bool            parallel_safe;  /* is the subplan parallel-safe? */
+       /* Note: parallel_safe does not consider contents of testexpr or args */
        /* Information for passing params into and out of the subselect: */
        /* setParam and parParam are lists of integers (param IDs) */
        List       *setParam;           /* initplan subqueries have to set these
@@ -671,6 +755,9 @@ typedef struct FieldSelect
  * the assign case of ArrayRef, this is used to implement UPDATE of a
  * portion of a column.
  *
+ * resulttype is always a named composite type (not a domain).  To update
+ * a composite domain value, apply CoerceToDomain to the FieldStore.
+ *
  * A single FieldStore can actually represent updates of several different
  * fields.  The parser only generates FieldStores with single-element lists,
  * but the planner will collapse multiple updates of the same base column
@@ -736,11 +823,12 @@ typedef struct CoerceViaIO
  * ArrayCoerceExpr
  *
  * ArrayCoerceExpr represents a type coercion from one array type to another,
- * which is implemented by applying the indicated element-type coercion
- * function to each element of the source array.  If elemfuncid is InvalidOid
- * then the element types are binary-compatible, but the coercion still
- * requires some effort (we have to fix the element type ID stored in the
- * array header).
+ * which is implemented by applying the per-element coercion expression
+ * "elemexpr" to each element of the source array.  Within elemexpr, the
+ * source element is represented by a CaseTestExpr node.  Note that even if
+ * elemexpr is a no-op (that is, just CaseTestExpr + RelabelType), the
+ * coercion still requires some effort: we have to fix the element type OID
+ * stored in the array header.
  * ----------------
  */
 
@@ -748,11 +836,10 @@ typedef struct ArrayCoerceExpr
 {
        Expr            xpr;
        Expr       *arg;                        /* input expression (yields an array) */
-       Oid                     elemfuncid;             /* OID of element coercion function, or 0 */
+       Expr       *elemexpr;           /* expression representing per-element work */
        Oid                     resulttype;             /* output type of coercion (an array type) */
        int32           resulttypmod;   /* output typmod (also element typmod) */
        Oid                     resultcollid;   /* OID of collation, or InvalidOid if none */
-       bool            isExplicit;             /* conversion semantics flag to pass to func */
        CoercionForm coerceformat;      /* how to display this node */
        int                     location;               /* token location, or -1 if unknown */
 } ArrayCoerceExpr;
@@ -765,7 +852,8 @@ typedef struct ArrayCoerceExpr
  * needed for the destination type plus possibly others; the columns need not
  * be in the same positions, but are matched up by name.  This is primarily
  * used to convert a whole-row value of an inheritance child table into a
- * valid whole-row value of its parent table's rowtype.
+ * valid whole-row value of its parent table's rowtype.  Both resulttype
+ * and the exposed type of "arg" must be named composite types (not domains).
  * ----------------
  */
 
@@ -903,6 +991,9 @@ typedef struct RowExpr
        Oid                     row_typeid;             /* RECORDOID or a composite type's ID */
 
        /*
+        * row_typeid cannot be a domain over composite, only plain composite.  To
+        * create a composite domain value, apply CoerceToDomain to the RowExpr.
+        *
         * Note: we deliberately do NOT store a typmod.  Although a typmod will be
         * associated with specific RECORD types at runtime, it will differ for
         * different backends, and so cannot safely be stored in stored
@@ -984,6 +1075,45 @@ typedef struct MinMaxExpr
        int                     location;               /* token location, or -1 if unknown */
 } MinMaxExpr;
 
+/*
+ * SQLValueFunction - parameterless functions with special grammar productions
+ *
+ * The SQL standard categorizes some of these as <datetime value function>
+ * and others as <general value specification>.  We call 'em SQLValueFunctions
+ * for lack of a better term.  We store type and typmod of the result so that
+ * some code doesn't need to know each function individually, and because
+ * we would need to store typmod anyway for some of the datetime functions.
+ * Note that currently, all variants return non-collating datatypes, so we do
+ * not need a collation field; also, all these functions are stable.
+ */
+typedef enum SQLValueFunctionOp
+{
+       SVFOP_CURRENT_DATE,
+       SVFOP_CURRENT_TIME,
+       SVFOP_CURRENT_TIME_N,
+       SVFOP_CURRENT_TIMESTAMP,
+       SVFOP_CURRENT_TIMESTAMP_N,
+       SVFOP_LOCALTIME,
+       SVFOP_LOCALTIME_N,
+       SVFOP_LOCALTIMESTAMP,
+       SVFOP_LOCALTIMESTAMP_N,
+       SVFOP_CURRENT_ROLE,
+       SVFOP_CURRENT_USER,
+       SVFOP_USER,
+       SVFOP_SESSION_USER,
+       SVFOP_CURRENT_CATALOG,
+       SVFOP_CURRENT_SCHEMA
+} SQLValueFunctionOp;
+
+typedef struct SQLValueFunction
+{
+       Expr            xpr;
+       SQLValueFunctionOp op;          /* which function this is */
+       Oid                     type;                   /* result type/typmod */
+       int32           typmod;
+       int                     location;               /* token location, or -1 if unknown */
+} SQLValueFunction;
+
 /*
  * XmlExpr - various SQL/XML functions requiring special grammar productions
  *
@@ -994,7 +1124,6 @@ typedef struct MinMaxExpr
  * Note: result type/typmod/collation are not stored, but can be deduced
  * from the XmlExprOp.  The type/typmod fields are just used for display
  * purposes, and are NOT necessarily the true result type of the node.
- * (We also use type == InvalidOid to mark a not-yet-parse-analyzed XmlExpr.)
  */
 typedef enum XmlExprOp
 {
@@ -1034,8 +1163,16 @@ typedef struct XmlExpr
  * NullTest represents the operation of testing a value for NULLness.
  * The appropriate test is performed and returned as a boolean Datum.
  *
- * NOTE: the semantics of this for rowtype inputs are noticeably different
- * from the scalar case.  We provide an "argisrow" flag to reflect that.
+ * When argisrow is false, this simply represents a test for the null value.
+ *
+ * When argisrow is true, the input expression must yield a rowtype, and
+ * the node implements "row IS [NOT] NULL" per the SQL standard.  This
+ * includes checking individual fields for NULLness when the row datum
+ * itself isn't NULL.
+ *
+ * NOTE: the combination of a rowtype input and argisrow==false does NOT
+ * correspond to the SQL notation "row IS [NOT] NULL"; instead, this case
+ * represents the SQL notation "row IS [NOT] DISTINCT FROM NULL".
  * ----------------
  */
 
@@ -1049,7 +1186,8 @@ typedef struct NullTest
        Expr            xpr;
        Expr       *arg;                        /* input expression */
        NullTestType nulltesttype;      /* IS NULL, IS NOT NULL */
-       bool            argisrow;               /* T if input is of a composite type */
+       bool            argisrow;               /* T to perform field-by-field null checks */
+       int                     location;               /* token location, or -1 if unknown */
 } NullTest;
 
 /*
@@ -1071,6 +1209,7 @@ typedef struct BooleanTest
        Expr            xpr;
        Expr       *arg;                        /* input expression */
        BoolTestType booltesttype;      /* test type */
+       int                     location;               /* token location, or -1 if unknown */
 } BooleanTest;
 
 /*
@@ -1147,6 +1286,35 @@ typedef struct CurrentOfExpr
        int                     cursor_param;   /* refcursor parameter number, or 0 */
 } CurrentOfExpr;
 
+/*
+ * NextValueExpr - get next value from sequence
+ *
+ * This has the same effect as calling the nextval() function, but it does not
+ * check permissions on the sequence.  This is used for identity columns,
+ * where the sequence is an implicit dependency without its own permissions.
+ */
+typedef struct NextValueExpr
+{
+       Expr            xpr;
+       Oid                     seqid;
+       Oid                     typeId;
+} NextValueExpr;
+
+/*
+ * InferenceElem - an element of a unique index inference specification
+ *
+ * This mostly matches the structure of IndexElems, but having a dedicated
+ * primnode allows for a clean separation between the use of index parameters
+ * by utility commands, and this node.
+ */
+typedef struct InferenceElem
+{
+       Expr            xpr;
+       Node       *expr;                       /* expression to infer from, or NULL */
+       Oid                     infercollid;    /* OID of collation, or InvalidOid */
+       Oid                     inferopclass;   /* OID of att opclass, or InvalidOid */
+} InferenceElem;
+
 /*--------------------
  * TargetEntry -
  *        a target entry (used in query target lists)
@@ -1207,8 +1375,8 @@ typedef struct TargetEntry
        Expr       *expr;                       /* expression to evaluate */
        AttrNumber      resno;                  /* attribute number (see notes above) */
        char       *resname;            /* name of the column (could be NULL) */
-       Index           ressortgroupref;/* nonzero if referenced by a sort/group
-                                                                * clause */
+       Index           ressortgroupref;        /* nonzero if referenced by a sort/group
+                                                                        * clause */
        Oid                     resorigtbl;             /* OID of column's source table */
        AttrNumber      resorigcol;             /* column's number in source table */
        bool            resjunk;                /* set to true to eliminate the attribute from
@@ -1311,4 +1479,31 @@ typedef struct FromExpr
        Node       *quals;                      /* qualifiers on join, if any */
 } FromExpr;
 
-#endif   /* PRIMNODES_H */
+/*----------
+ * OnConflictExpr - represents an ON CONFLICT DO ... expression
+ *
+ * The optimizer requires a list of inference elements, and optionally a WHERE
+ * clause to infer a unique index.  The unique index (or, occasionally,
+ * indexes) inferred are used to arbitrate whether or not the alternative ON
+ * CONFLICT path is taken.
+ *----------
+ */
+typedef struct OnConflictExpr
+{
+       NodeTag         type;
+       OnConflictAction action;        /* DO NOTHING or UPDATE? */
+
+       /* Arbiter */
+       List       *arbiterElems;       /* unique index arbiter list (of
+                                                                * InferenceElem's) */
+       Node       *arbiterWhere;       /* unique index arbiter WHERE clause */
+       Oid                     constraint;             /* pg_constraint OID for arbiter */
+
+       /* ON CONFLICT UPDATE */
+       List       *onConflictSet;      /* List of ON CONFLICT SET TargetEntrys */
+       Node       *onConflictWhere;    /* qualifiers to restrict UPDATE to */
+       int                     exclRelIndex;   /* RT index of 'excluded' relation */
+       List       *exclRelTlist;       /* tlist of the EXCLUDED pseudo relation */
+} OnConflictExpr;
+
+#endif                                                 /* PRIMNODES_H */