* 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
#define PRIMNODES_H
#include "access/attnum.h"
+#include "nodes/bitmapset.h"
#include "nodes/pg_list.h"
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
{
* 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.
*/
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
* 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)
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 */
/*
* 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
{
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.
* 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
{
* 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
{
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) */
* 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
*/
* 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
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
/* 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
* 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
* 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.
* ----------------
*/
{
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;
* 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).
* ----------------
*/
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
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
*
* 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
{
* 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".
* ----------------
*/
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;
/*
Expr xpr;
Expr *arg; /* input expression */
BoolTestType booltesttype; /* test type */
+ int location; /* token location, or -1 if unknown */
} BooleanTest;
/*
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)
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
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 */