summaryrefslogtreecommitdiff
path: root/src/backend/nodes
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/nodes')
-rw-r--r--src/backend/nodes/bitmapset.c32
-rw-r--r--src/backend/nodes/copyfuncs.c529
-rw-r--r--src/backend/nodes/equalfuncs.c358
-rw-r--r--src/backend/nodes/extensible.c2
-rw-r--r--src/backend/nodes/list.c2
-rw-r--r--src/backend/nodes/makefuncs.c19
-rw-r--r--src/backend/nodes/nodeFuncs.c145
-rw-r--r--src/backend/nodes/nodes.c2
-rw-r--r--src/backend/nodes/outfuncs.c630
-rw-r--r--src/backend/nodes/params.c2
-rw-r--r--src/backend/nodes/print.c10
-rw-r--r--src/backend/nodes/read.c2
-rw-r--r--src/backend/nodes/readfuncs.c190
-rw-r--r--src/backend/nodes/tidbitmap.c738
-rw-r--r--src/backend/nodes/value.c2
15 files changed, 2311 insertions, 352 deletions
diff --git a/src/backend/nodes/bitmapset.c b/src/backend/nodes/bitmapset.c
index 0626a49238..3348a22742 100644
--- a/src/backend/nodes/bitmapset.c
+++ b/src/backend/nodes/bitmapset.c
@@ -11,7 +11,7 @@
* bms_is_empty() in preference to testing for NULL.)
*
*
- * Copyright (c) 2003-2016, PostgreSQL Global Development Group
+ * Copyright (c) 2003-2017, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/backend/nodes/bitmapset.c
@@ -21,6 +21,7 @@
#include "postgres.h"
#include "access/hash.h"
+#include "nodes/pg_list.h"
#define WORDNUM(x) ((x) / BITS_PER_BITMAPWORD)
@@ -458,6 +459,35 @@ bms_overlap(const Bitmapset *a, const Bitmapset *b)
}
/*
+ * bms_overlap_list - does a set overlap an integer list?
+ */
+bool
+bms_overlap_list(const Bitmapset *a, const List *b)
+{
+ ListCell *lc;
+ int wordnum,
+ bitnum;
+
+ if (a == NULL || b == NIL)
+ return false;
+
+ foreach(lc, b)
+ {
+ int x = lfirst_int(lc);
+
+ if (x < 0)
+ elog(ERROR, "negative bitmapset member not allowed");
+ wordnum = WORDNUM(x);
+ bitnum = BITNUM(x);
+ if (wordnum < a->nwords)
+ if ((a->words[wordnum] & ((bitmapword) 1 << bitnum)) != 0)
+ return true;
+ }
+
+ return false;
+}
+
+/*
* bms_nonempty_difference - do sets have a nonempty difference?
*/
bool
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 0cdd6559d0..fc21909ea3 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -12,7 +12,7 @@
*
*
* Portions Copyright (c) 2012-2014, TransLattice, Inc.
- * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 2010-2012 Postgres-XC Development Group
*
@@ -52,7 +52,7 @@
/* Copy a field that is a pointer to some kind of Node or Node tree */
#define COPY_NODE_FIELD(fldname) \
- (newnode->fldname = copyObject(from->fldname))
+ (newnode->fldname = copyObjectImpl(from->fldname))
/* Copy a field that is a pointer to a Bitmapset */
#define COPY_BITMAPSET_FIELD(fldname) \
@@ -99,7 +99,8 @@ _copyPlannedStmt(const PlannedStmt *from)
COPY_NODE_FIELD(planTree);
COPY_NODE_FIELD(rtable);
COPY_NODE_FIELD(resultRelations);
- COPY_NODE_FIELD(utilityStmt);
+ COPY_NODE_FIELD(nonleafResultRelations);
+ COPY_NODE_FIELD(rootResultRelations);
COPY_NODE_FIELD(subplans);
COPY_BITMAPSET_FIELD(rewindPlanIDs);
COPY_NODE_FIELD(rowMarks);
@@ -116,6 +117,9 @@ _copyPlannedStmt(const PlannedStmt *from)
COPY_NODE_FIELD(distributionNodes);
COPY_NODE_FIELD(distributionRestrict);
#endif
+ COPY_NODE_FIELD(utilityStmt);
+ COPY_LOCATION_FIELD(stmt_location);
+ COPY_LOCATION_FIELD(stmt_len);
return newnode;
}
@@ -134,6 +138,7 @@ CopyPlanFields(const Plan *from, Plan *newnode)
COPY_SCALAR_FIELD(plan_rows);
COPY_SCALAR_FIELD(plan_width);
COPY_SCALAR_FIELD(parallel_aware);
+ COPY_SCALAR_FIELD(parallel_safe);
COPY_SCALAR_FIELD(plan_node_id);
COPY_NODE_FIELD(targetlist);
COPY_NODE_FIELD(qual);
@@ -183,6 +188,22 @@ _copyResult(const Result *from)
}
/*
+ * _copyProjectSet
+ */
+static ProjectSet *
+_copyProjectSet(const ProjectSet *from)
+{
+ ProjectSet *newnode = makeNode(ProjectSet);
+
+ /*
+ * copy node superclass fields
+ */
+ CopyPlanFields((const Plan *) from, (Plan *) newnode);
+
+ return newnode;
+}
+
+/*
* _copyModifyTable
*/
static ModifyTable *
@@ -201,8 +222,10 @@ _copyModifyTable(const ModifyTable *from)
COPY_SCALAR_FIELD(operation);
COPY_SCALAR_FIELD(canSetTag);
COPY_SCALAR_FIELD(nominalRelation);
+ COPY_NODE_FIELD(partitioned_rels);
COPY_NODE_FIELD(resultRelations);
COPY_SCALAR_FIELD(resultRelIndex);
+ COPY_SCALAR_FIELD(rootResultRelIndex);
COPY_NODE_FIELD(plans);
COPY_NODE_FIELD(withCheckOptionLists);
COPY_NODE_FIELD(returningLists);
@@ -236,6 +259,7 @@ _copyAppend(const Append *from)
/*
* copy remainder of node
*/
+ COPY_NODE_FIELD(partitioned_rels);
COPY_NODE_FIELD(appendplans);
return newnode;
@@ -257,6 +281,7 @@ _copyMergeAppend(const MergeAppend *from)
/*
* copy remainder of node
*/
+ COPY_NODE_FIELD(partitioned_rels);
COPY_NODE_FIELD(mergeplans);
COPY_SCALAR_FIELD(numCols);
COPY_POINTER_FIELD(sortColIdx, from->numCols * sizeof(AttrNumber));
@@ -332,6 +357,7 @@ _copyBitmapOr(const BitmapOr *from)
/*
* copy remainder of node
*/
+ COPY_SCALAR_FIELD(isshared);
COPY_NODE_FIELD(bitmapplans);
return newnode;
@@ -360,6 +386,31 @@ _copyGather(const Gather *from)
return newnode;
}
+/*
+ * _copyGatherMerge
+ */
+static GatherMerge *
+_copyGatherMerge(const GatherMerge *from)
+{
+ GatherMerge *newnode = makeNode(GatherMerge);
+
+ /*
+ * copy node superclass fields
+ */
+ CopyPlanFields((const Plan *) from, (Plan *) newnode);
+
+ /*
+ * copy remainder of node
+ */
+ COPY_SCALAR_FIELD(num_workers);
+ COPY_SCALAR_FIELD(numCols);
+ COPY_POINTER_FIELD(sortColIdx, from->numCols * sizeof(AttrNumber));
+ COPY_POINTER_FIELD(sortOperators, from->numCols * sizeof(Oid));
+ COPY_POINTER_FIELD(collations, from->numCols * sizeof(Oid));
+ COPY_POINTER_FIELD(nullsFirst, from->numCols * sizeof(bool));
+
+ return newnode;
+}
/*
* CopyScanFields
@@ -497,6 +548,7 @@ _copyBitmapIndexScan(const BitmapIndexScan *from)
* copy remainder of node
*/
COPY_SCALAR_FIELD(indexid);
+ COPY_SCALAR_FIELD(isshared);
COPY_NODE_FIELD(indexqual);
COPY_NODE_FIELD(indexqualorig);
@@ -589,6 +641,27 @@ _copyFunctionScan(const FunctionScan *from)
}
/*
+ * _copyTableFuncScan
+ */
+static TableFuncScan *
+_copyTableFuncScan(const TableFuncScan *from)
+{
+ TableFuncScan *newnode = makeNode(TableFuncScan);
+
+ /*
+ * copy node superclass fields
+ */
+ CopyScanFields((const Scan *) from, (Scan *) newnode);
+
+ /*
+ * copy remainder of node
+ */
+ COPY_NODE_FIELD(tablefunc);
+
+ return newnode;
+}
+
+/*
* _copyValuesScan
*/
static ValuesScan *
@@ -632,6 +705,27 @@ _copyCteScan(const CteScan *from)
}
/*
+ * _copyNamedTuplestoreScan
+ */
+static NamedTuplestoreScan *
+_copyNamedTuplestoreScan(const NamedTuplestoreScan *from)
+{
+ NamedTuplestoreScan *newnode = makeNode(NamedTuplestoreScan);
+
+ /*
+ * copy node superclass fields
+ */
+ CopyScanFields((const Scan *) from, (Scan *) newnode);
+
+ /*
+ * copy remainder of node
+ */
+ COPY_STRING_FIELD(enrname);
+
+ return newnode;
+}
+
+/*
* _copyWorkTableScan
*/
static WorkTableScan *
@@ -725,6 +819,7 @@ CopyJoinFields(const Join *from, Join *newnode)
CopyPlanFields((const Plan *) from, (Plan *) newnode);
COPY_SCALAR_FIELD(jointype);
+ COPY_SCALAR_FIELD(inner_unique);
COPY_NODE_FIELD(joinqual);
}
@@ -785,6 +880,7 @@ _copyMergeJoin(const MergeJoin *from)
/*
* copy remainder of node
*/
+ COPY_SCALAR_FIELD(skip_mark_restore);
COPY_NODE_FIELD(mergeclauses);
numCols = list_length(from->mergeclauses);
if (numCols > 0)
@@ -896,6 +992,7 @@ _copyAgg(const Agg *from)
COPY_POINTER_FIELD(grpOperators, from->numCols * sizeof(Oid));
}
COPY_SCALAR_FIELD(numGroups);
+ COPY_BITMAPSET_FIELD(aggParams);
COPY_NODE_FIELD(groupingSets);
COPY_NODE_FIELD(chain);
@@ -974,8 +1071,6 @@ _copyHash(const Hash *from)
COPY_SCALAR_FIELD(skewTable);
COPY_SCALAR_FIELD(skewColumn);
COPY_SCALAR_FIELD(skewInherit);
- COPY_SCALAR_FIELD(skewColType);
- COPY_SCALAR_FIELD(skewColTypmod);
return newnode;
}
@@ -1283,7 +1378,7 @@ _copyRangeVar(const RangeVar *from)
COPY_STRING_FIELD(catalogname);
COPY_STRING_FIELD(schemaname);
COPY_STRING_FIELD(relname);
- COPY_SCALAR_FIELD(inhOpt);
+ COPY_SCALAR_FIELD(inh);
COPY_SCALAR_FIELD(relpersistence);
COPY_NODE_FIELD(alias);
COPY_LOCATION_FIELD(location);
@@ -1292,6 +1387,31 @@ _copyRangeVar(const RangeVar *from)
}
/*
+ * _copyTableFunc
+ */
+static TableFunc *
+_copyTableFunc(const TableFunc *from)
+{
+ TableFunc *newnode = makeNode(TableFunc);
+
+ COPY_NODE_FIELD(ns_names);
+ COPY_NODE_FIELD(ns_uris);
+ COPY_NODE_FIELD(docexpr);
+ COPY_NODE_FIELD(rowexpr);
+ COPY_NODE_FIELD(colnames);
+ COPY_NODE_FIELD(coltypes);
+ COPY_NODE_FIELD(coltypmods);
+ COPY_NODE_FIELD(colcollations);
+ COPY_NODE_FIELD(colexprs);
+ COPY_NODE_FIELD(coldefexprs);
+ COPY_BITMAPSET_FIELD(notnulls);
+ COPY_SCALAR_FIELD(ordinalitycol);
+ COPY_LOCATION_FIELD(location);
+
+ return newnode;
+}
+
+/*
* _copyIntoClause
*/
static IntoClause *
@@ -1652,6 +1772,7 @@ _copySubPlan(const SubPlan *from)
COPY_SCALAR_FIELD(firstColCollation);
COPY_SCALAR_FIELD(useHashTable);
COPY_SCALAR_FIELD(unknownEqFalse);
+ COPY_SCALAR_FIELD(parallel_safe);
COPY_NODE_FIELD(setParam);
COPY_NODE_FIELD(parParam);
COPY_NODE_FIELD(args);
@@ -1929,6 +2050,22 @@ _copyMinMaxExpr(const MinMaxExpr *from)
}
/*
+ * _copySQLValueFunction
+ */
+static SQLValueFunction *
+_copySQLValueFunction(const SQLValueFunction *from)
+{
+ SQLValueFunction *newnode = makeNode(SQLValueFunction);
+
+ COPY_SCALAR_FIELD(op);
+ COPY_SCALAR_FIELD(type);
+ COPY_SCALAR_FIELD(typmod);
+ COPY_LOCATION_FIELD(location);
+
+ return newnode;
+}
+
+/*
* _copyXmlExpr
*/
static XmlExpr *
@@ -2045,6 +2182,20 @@ _copyCurrentOfExpr(const CurrentOfExpr *from)
return newnode;
}
+ /*
+ * _copyNextValueExpr
+ */
+static NextValueExpr *
+_copyNextValueExpr(const NextValueExpr *from)
+{
+ NextValueExpr *newnode = makeNode(NextValueExpr);
+
+ COPY_SCALAR_FIELD(seqid);
+ COPY_SCALAR_FIELD(typeId);
+
+ return newnode;
+}
+
/*
* _copyInferenceElem
*/
@@ -2184,6 +2335,8 @@ _copyRestrictInfo(const RestrictInfo *from)
COPY_SCALAR_FIELD(outerjoin_delayed);
COPY_SCALAR_FIELD(can_join);
COPY_SCALAR_FIELD(pseudoconstant);
+ COPY_SCALAR_FIELD(leakproof);
+ COPY_SCALAR_FIELD(security_level);
COPY_BITMAPSET_FIELD(clause_relids);
COPY_BITMAPSET_FIELD(required_relids);
COPY_BITMAPSET_FIELD(outer_relids);
@@ -2270,6 +2423,20 @@ _copyAppendRelInfo(const AppendRelInfo *from)
}
/*
+ * _copyPartitionedChildRelInfo
+ */
+static PartitionedChildRelInfo *
+_copyPartitionedChildRelInfo(const PartitionedChildRelInfo *from)
+{
+ PartitionedChildRelInfo *newnode = makeNode(PartitionedChildRelInfo);
+
+ COPY_SCALAR_FIELD(parent_relid);
+ COPY_NODE_FIELD(child_rels);
+
+ return newnode;
+}
+
+/*
* _copyPlaceHolderInfo
*/
static PlaceHolderInfo *
@@ -2308,14 +2475,15 @@ _copyRangeTblEntry(const RangeTblEntry *from)
COPY_NODE_FIELD(joinaliasvars);
COPY_NODE_FIELD(functions);
COPY_SCALAR_FIELD(funcordinality);
+ COPY_NODE_FIELD(tablefunc);
COPY_NODE_FIELD(values_lists);
- COPY_NODE_FIELD(values_collations);
COPY_STRING_FIELD(ctename);
COPY_SCALAR_FIELD(ctelevelsup);
COPY_SCALAR_FIELD(self_reference);
- COPY_NODE_FIELD(ctecoltypes);
- COPY_NODE_FIELD(ctecoltypmods);
- COPY_NODE_FIELD(ctecolcollations);
+ COPY_STRING_FIELD(enrname);
+ COPY_NODE_FIELD(coltypes);
+ COPY_NODE_FIELD(coltypmods);
+ COPY_NODE_FIELD(colcollations);
COPY_NODE_FIELD(alias);
COPY_NODE_FIELD(eref);
COPY_SCALAR_FIELD(lateral);
@@ -2730,6 +2898,38 @@ _copyRangeTableSample(const RangeTableSample *from)
return newnode;
}
+static RangeTableFunc *
+_copyRangeTableFunc(const RangeTableFunc *from)
+{
+ RangeTableFunc *newnode = makeNode(RangeTableFunc);
+
+ COPY_SCALAR_FIELD(lateral);
+ COPY_NODE_FIELD(docexpr);
+ COPY_NODE_FIELD(rowexpr);
+ COPY_NODE_FIELD(namespaces);
+ COPY_NODE_FIELD(columns);
+ COPY_NODE_FIELD(alias);
+ COPY_LOCATION_FIELD(location);
+
+ return newnode;
+}
+
+static RangeTableFuncCol *
+_copyRangeTableFuncCol(const RangeTableFuncCol *from)
+{
+ RangeTableFuncCol *newnode = makeNode(RangeTableFuncCol);
+
+ COPY_STRING_FIELD(colname);
+ COPY_NODE_FIELD(typeName);
+ COPY_SCALAR_FIELD(for_ordinality);
+ COPY_SCALAR_FIELD(is_not_null);
+ COPY_NODE_FIELD(colexpr);
+ COPY_NODE_FIELD(coldefexpr);
+ COPY_LOCATION_FIELD(location);
+
+ return newnode;
+}
+
static TypeCast *
_copyTypeCast(const TypeCast *from)
{
@@ -2781,9 +2981,11 @@ _copyColumnDef(const ColumnDef *from)
COPY_SCALAR_FIELD(is_local);
COPY_SCALAR_FIELD(is_not_null);
COPY_SCALAR_FIELD(is_from_type);
+ COPY_SCALAR_FIELD(is_from_parent);
COPY_SCALAR_FIELD(storage);
COPY_NODE_FIELD(raw_default);
COPY_NODE_FIELD(cooked_default);
+ COPY_SCALAR_FIELD(identity);
COPY_NODE_FIELD(collClause);
COPY_SCALAR_FIELD(collOid);
COPY_NODE_FIELD(constraints);
@@ -2806,6 +3008,7 @@ _copyConstraint(const Constraint *from)
COPY_SCALAR_FIELD(is_no_inherit);
COPY_NODE_FIELD(raw_expr);
COPY_STRING_FIELD(cooked_expr);
+ COPY_SCALAR_FIELD(generated_when);
COPY_NODE_FIELD(keys);
COPY_NODE_FIELD(exclusions);
COPY_NODE_FIELD(options);
@@ -2836,6 +3039,7 @@ _copyDefElem(const DefElem *from)
COPY_STRING_FIELD(defname);
COPY_NODE_FIELD(arg);
COPY_SCALAR_FIELD(defaction);
+ COPY_LOCATION_FIELD(location);
return newnode;
}
@@ -2877,6 +3081,18 @@ _copyRoleSpec(const RoleSpec *from)
return newnode;
}
+static TriggerTransition *
+_copyTriggerTransition(const TriggerTransition *from)
+{
+ TriggerTransition *newnode = makeNode(TriggerTransition);
+
+ COPY_STRING_FIELD(name);
+ COPY_SCALAR_FIELD(isNew);
+ COPY_SCALAR_FIELD(isTable);
+
+ return newnode;
+}
+
static Query *
_copyQuery(const Query *from)
{
@@ -2890,6 +3106,7 @@ _copyQuery(const Query *from)
COPY_SCALAR_FIELD(resultRelation);
COPY_SCALAR_FIELD(hasAggs);
COPY_SCALAR_FIELD(hasWindowFuncs);
+ COPY_SCALAR_FIELD(hasTargetSRFs);
COPY_SCALAR_FIELD(hasSubLinks);
COPY_SCALAR_FIELD(hasDistinctOn);
COPY_SCALAR_FIELD(hasRecursive);
@@ -2900,6 +3117,7 @@ _copyQuery(const Query *from)
COPY_NODE_FIELD(rtable);
COPY_NODE_FIELD(jointree);
COPY_NODE_FIELD(targetList);
+ COPY_SCALAR_FIELD(override);
COPY_NODE_FIELD(onConflict);
COPY_NODE_FIELD(returningList);
COPY_NODE_FIELD(groupClause);
@@ -2914,6 +3132,20 @@ _copyQuery(const Query *from)
COPY_NODE_FIELD(setOperations);
COPY_NODE_FIELD(constraintDeps);
COPY_NODE_FIELD(withCheckOptions);
+ COPY_LOCATION_FIELD(stmt_location);
+ COPY_LOCATION_FIELD(stmt_len);
+
+ return newnode;
+}
+
+static RawStmt *
+_copyRawStmt(const RawStmt *from)
+{
+ RawStmt *newnode = makeNode(RawStmt);
+
+ COPY_NODE_FIELD(stmt);
+ COPY_LOCATION_FIELD(stmt_location);
+ COPY_LOCATION_FIELD(stmt_len);
return newnode;
}
@@ -2929,6 +3161,7 @@ _copyInsertStmt(const InsertStmt *from)
COPY_NODE_FIELD(onConflictClause);
COPY_NODE_FIELD(returningList);
COPY_NODE_FIELD(withClause);
+ COPY_SCALAR_FIELD(override);
return newnode;
}
@@ -3034,6 +3267,16 @@ _copyAlterTableCmd(const AlterTableCmd *from)
return newnode;
}
+static AlterCollationStmt *
+_copyAlterCollationStmt(const AlterCollationStmt *from)
+{
+ AlterCollationStmt *newnode = makeNode(AlterCollationStmt);
+
+ COPY_NODE_FIELD(collname);
+
+ return newnode;
+}
+
static AlterDomainStmt *
_copyAlterDomainStmt(const AlterDomainStmt *from)
{
@@ -3066,13 +3309,14 @@ _copyGrantStmt(const GrantStmt *from)
return newnode;
}
-static FuncWithArgs *
-_copyFuncWithArgs(const FuncWithArgs *from)
+static ObjectWithArgs *
+_copyObjectWithArgs(const ObjectWithArgs *from)
{
- FuncWithArgs *newnode = makeNode(FuncWithArgs);
+ ObjectWithArgs *newnode = makeNode(ObjectWithArgs);
- COPY_NODE_FIELD(funcname);
- COPY_NODE_FIELD(funcargs);
+ COPY_NODE_FIELD(objname);
+ COPY_NODE_FIELD(objargs);
+ COPY_SCALAR_FIELD(args_unspecified);
return newnode;
}
@@ -3200,6 +3444,8 @@ CopyCreateStmtFields(const CreateStmt *from, CreateStmt *newnode)
COPY_NODE_FIELD(relation);
COPY_NODE_FIELD(tableElts);
COPY_NODE_FIELD(inhRelations);
+ COPY_NODE_FIELD(partspec);
+ COPY_NODE_FIELD(partbound);
COPY_NODE_FIELD(ofTypename);
COPY_NODE_FIELD(constraints);
COPY_NODE_FIELD(options);
@@ -3245,6 +3491,7 @@ _copyDefineStmt(const DefineStmt *from)
COPY_NODE_FIELD(defnames);
COPY_NODE_FIELD(args);
COPY_NODE_FIELD(definition);
+ COPY_SCALAR_FIELD(if_not_exists);
return newnode;
}
@@ -3255,7 +3502,6 @@ _copyDropStmt(const DropStmt *from)
DropStmt *newnode = makeNode(DropStmt);
COPY_NODE_FIELD(objects);
- COPY_NODE_FIELD(arguments);
COPY_SCALAR_FIELD(removeType);
COPY_SCALAR_FIELD(behavior);
COPY_SCALAR_FIELD(missing_ok);
@@ -3282,8 +3528,7 @@ _copyCommentStmt(const CommentStmt *from)
CommentStmt *newnode = makeNode(CommentStmt);
COPY_SCALAR_FIELD(objtype);
- COPY_NODE_FIELD(objname);
- COPY_NODE_FIELD(objargs);
+ COPY_NODE_FIELD(object);
COPY_STRING_FIELD(comment);
return newnode;
@@ -3295,8 +3540,7 @@ _copySecLabelStmt(const SecLabelStmt *from)
SecLabelStmt *newnode = makeNode(SecLabelStmt);
COPY_SCALAR_FIELD(objtype);
- COPY_NODE_FIELD(objname);
- COPY_NODE_FIELD(objargs);
+ COPY_NODE_FIELD(object);
COPY_STRING_FIELD(provider);
COPY_STRING_FIELD(label);
@@ -3344,6 +3588,20 @@ _copyIndexStmt(const IndexStmt *from)
return newnode;
}
+static CreateStatsStmt *
+_copyCreateStatsStmt(const CreateStatsStmt *from)
+{
+ CreateStatsStmt *newnode = makeNode(CreateStatsStmt);
+
+ COPY_NODE_FIELD(defnames);
+ COPY_NODE_FIELD(stat_types);
+ COPY_NODE_FIELD(exprs);
+ COPY_NODE_FIELD(relations);
+ COPY_SCALAR_FIELD(if_not_exists);
+
+ return newnode;
+}
+
static CreateFunctionStmt *
_copyCreateFunctionStmt(const CreateFunctionStmt *from)
{
@@ -3402,7 +3660,6 @@ _copyRenameStmt(const RenameStmt *from)
COPY_SCALAR_FIELD(relationType);
COPY_NODE_FIELD(relation);
COPY_NODE_FIELD(object);
- COPY_NODE_FIELD(objarg);
COPY_STRING_FIELD(subname);
COPY_STRING_FIELD(newname);
COPY_SCALAR_FIELD(behavior);
@@ -3418,8 +3675,7 @@ _copyAlterObjectDependsStmt(const AlterObjectDependsStmt *from)
COPY_SCALAR_FIELD(objectType);
COPY_NODE_FIELD(relation);
- COPY_NODE_FIELD(objname);
- COPY_NODE_FIELD(objargs);
+ COPY_NODE_FIELD(object);
COPY_NODE_FIELD(extname);
return newnode;
@@ -3433,7 +3689,6 @@ _copyAlterObjectSchemaStmt(const AlterObjectSchemaStmt *from)
COPY_SCALAR_FIELD(objectType);
COPY_NODE_FIELD(relation);
COPY_NODE_FIELD(object);
- COPY_NODE_FIELD(objarg);
COPY_STRING_FIELD(newschema);
COPY_SCALAR_FIELD(missing_ok);
@@ -3448,7 +3703,6 @@ _copyAlterOwnerStmt(const AlterOwnerStmt *from)
COPY_SCALAR_FIELD(objectType);
COPY_NODE_FIELD(relation);
COPY_NODE_FIELD(object);
- COPY_NODE_FIELD(objarg);
COPY_NODE_FIELD(newowner);
return newnode;
@@ -3460,7 +3714,6 @@ _copyAlterOperatorStmt(const AlterOperatorStmt *from)
AlterOperatorStmt *newnode = makeNode(AlterOperatorStmt);
COPY_NODE_FIELD(opername);
- COPY_NODE_FIELD(operargs);
COPY_NODE_FIELD(options);
return newnode;
@@ -3564,10 +3817,11 @@ _copyAlterEnumStmt(const AlterEnumStmt *from)
AlterEnumStmt *newnode = makeNode(AlterEnumStmt);
COPY_NODE_FIELD(typeName);
+ COPY_STRING_FIELD(oldVal);
COPY_STRING_FIELD(newVal);
COPY_STRING_FIELD(newValNeighbor);
COPY_SCALAR_FIELD(newValIsAfter);
- COPY_SCALAR_FIELD(skipIfExists);
+ COPY_SCALAR_FIELD(skipIfNewValExists);
return newnode;
}
@@ -3632,7 +3886,6 @@ _copyCreateOpClassItem(const CreateOpClassItem *from)
COPY_SCALAR_FIELD(itemtype);
COPY_NODE_FIELD(name);
- COPY_NODE_FIELD(args);
COPY_SCALAR_FIELD(number);
COPY_NODE_FIELD(order_family);
COPY_NODE_FIELD(class_args);
@@ -3790,6 +4043,7 @@ _copyCreateSeqStmt(const CreateSeqStmt *from)
COPY_NODE_FIELD(sequence);
COPY_NODE_FIELD(options);
COPY_SCALAR_FIELD(ownerId);
+ COPY_SCALAR_FIELD(for_identity);
COPY_SCALAR_FIELD(if_not_exists);
return newnode;
@@ -3802,6 +4056,7 @@ _copyAlterSeqStmt(const AlterSeqStmt *from)
COPY_NODE_FIELD(sequence);
COPY_NODE_FIELD(options);
+ COPY_SCALAR_FIELD(for_identity);
COPY_SCALAR_FIELD(missing_ok);
return newnode;
@@ -3921,8 +4176,7 @@ _copyAlterExtensionContentsStmt(const AlterExtensionContentsStmt *from)
COPY_STRING_FIELD(extname);
COPY_SCALAR_FIELD(action);
COPY_SCALAR_FIELD(objtype);
- COPY_NODE_FIELD(objname);
- COPY_NODE_FIELD(objargs);
+ COPY_NODE_FIELD(object);
return newnode;
}
@@ -3961,6 +4215,7 @@ _copyCreateForeignServerStmt(const CreateForeignServerStmt *from)
COPY_STRING_FIELD(version);
COPY_STRING_FIELD(fdwname);
COPY_NODE_FIELD(options);
+ COPY_SCALAR_FIELD(if_not_exists);
return newnode;
}
@@ -3986,6 +4241,7 @@ _copyCreateUserMappingStmt(const CreateUserMappingStmt *from)
COPY_NODE_FIELD(user);
COPY_STRING_FIELD(servername);
COPY_NODE_FIELD(options);
+ COPY_SCALAR_FIELD(if_not_exists);
return newnode;
}
@@ -4083,6 +4339,7 @@ _copyCreateTrigStmt(const CreateTrigStmt *from)
COPY_NODE_FIELD(columns);
COPY_NODE_FIELD(whenClause);
COPY_SCALAR_FIELD(isconstraint);
+ COPY_NODE_FIELD(transitionRels);
COPY_SCALAR_FIELD(deferrable);
COPY_SCALAR_FIELD(initdeferred);
COPY_NODE_FIELD(constrrel);
@@ -4343,6 +4600,7 @@ _copyCreatePolicyStmt(const CreatePolicyStmt *from)
COPY_STRING_FIELD(policy_name);
COPY_NODE_FIELD(table);
COPY_STRING_FIELD(cmd_name);
+ COPY_SCALAR_FIELD(permissive);
COPY_NODE_FIELD(roles);
COPY_NODE_FIELD(qual);
COPY_NODE_FIELD(with_check);
@@ -4364,6 +4622,135 @@ _copyAlterPolicyStmt(const AlterPolicyStmt *from)
return newnode;
}
+static PartitionElem *
+_copyPartitionElem(const PartitionElem *from)
+{
+ PartitionElem *newnode = makeNode(PartitionElem);
+
+ COPY_STRING_FIELD(name);
+ COPY_NODE_FIELD(expr);
+ COPY_NODE_FIELD(collation);
+ COPY_NODE_FIELD(opclass);
+ COPY_LOCATION_FIELD(location);
+
+ return newnode;
+}
+
+static PartitionSpec *
+_copyPartitionSpec(const PartitionSpec *from)
+{
+ PartitionSpec *newnode = makeNode(PartitionSpec);
+
+ COPY_STRING_FIELD(strategy);
+ COPY_NODE_FIELD(partParams);
+ COPY_LOCATION_FIELD(location);
+
+ return newnode;
+}
+
+static PartitionBoundSpec *
+_copyPartitionBoundSpec(const PartitionBoundSpec *from)
+{
+ PartitionBoundSpec *newnode = makeNode(PartitionBoundSpec);
+
+ COPY_SCALAR_FIELD(strategy);
+ COPY_NODE_FIELD(listdatums);
+ COPY_NODE_FIELD(lowerdatums);
+ COPY_NODE_FIELD(upperdatums);
+ COPY_LOCATION_FIELD(location);
+
+ return newnode;
+}
+
+static PartitionRangeDatum *
+_copyPartitionRangeDatum(const PartitionRangeDatum *from)
+{
+ PartitionRangeDatum *newnode = makeNode(PartitionRangeDatum);
+
+ COPY_SCALAR_FIELD(infinite);
+ COPY_NODE_FIELD(value);
+ COPY_LOCATION_FIELD(location);
+
+ return newnode;
+}
+
+static PartitionCmd *
+_copyPartitionCmd(const PartitionCmd *from)
+{
+ PartitionCmd *newnode = makeNode(PartitionCmd);
+
+ COPY_NODE_FIELD(name);
+ COPY_NODE_FIELD(bound);
+
+ return newnode;
+}
+
+static CreatePublicationStmt *
+_copyCreatePublicationStmt(const CreatePublicationStmt *from)
+{
+ CreatePublicationStmt *newnode = makeNode(CreatePublicationStmt);
+
+ COPY_STRING_FIELD(pubname);
+ COPY_NODE_FIELD(options);
+ COPY_NODE_FIELD(tables);
+ COPY_SCALAR_FIELD(for_all_tables);
+
+ return newnode;
+}
+
+static AlterPublicationStmt *
+_copyAlterPublicationStmt(const AlterPublicationStmt *from)
+{
+ AlterPublicationStmt *newnode = makeNode(AlterPublicationStmt);
+
+ COPY_STRING_FIELD(pubname);
+ COPY_NODE_FIELD(options);
+ COPY_NODE_FIELD(tables);
+ COPY_SCALAR_FIELD(for_all_tables);
+ COPY_SCALAR_FIELD(tableAction);
+
+ return newnode;
+}
+
+static CreateSubscriptionStmt *
+_copyCreateSubscriptionStmt(const CreateSubscriptionStmt *from)
+{
+ CreateSubscriptionStmt *newnode = makeNode(CreateSubscriptionStmt);
+
+ COPY_STRING_FIELD(subname);
+ COPY_STRING_FIELD(conninfo);
+ COPY_NODE_FIELD(publication);
+ COPY_NODE_FIELD(options);
+
+ return newnode;
+}
+
+static AlterSubscriptionStmt *
+_copyAlterSubscriptionStmt(const AlterSubscriptionStmt *from)
+{
+ AlterSubscriptionStmt *newnode = makeNode(AlterSubscriptionStmt);
+
+ COPY_SCALAR_FIELD(kind);
+ COPY_STRING_FIELD(subname);
+ COPY_STRING_FIELD(conninfo);
+ COPY_NODE_FIELD(publication);
+ COPY_NODE_FIELD(options);
+
+ return newnode;
+}
+
+static DropSubscriptionStmt *
+_copyDropSubscriptionStmt(const DropSubscriptionStmt *from)
+{
+ DropSubscriptionStmt *newnode = makeNode(DropSubscriptionStmt);
+
+ COPY_STRING_FIELD(subname);
+ COPY_SCALAR_FIELD(missing_ok);
+ COPY_SCALAR_FIELD(behavior);
+
+ return newnode;
+}
+
/* ****************************************************************
* pg_list.h copy functions
* ****************************************************************
@@ -4376,7 +4763,7 @@ _copyAlterPolicyStmt(const AlterPolicyStmt *from)
*/
#define COPY_NODE_CELL(new, old) \
(new) = (ListCell *) palloc(sizeof(ListCell)); \
- lfirst(new) = copyObject(lfirst(old));
+ lfirst(new) = copyObjectImpl(lfirst(old));
static List *
_copyList(const List *from)
@@ -4581,13 +4968,13 @@ _copyCleanConnStmt(const CleanConnStmt *from)
#endif
/*
- * copyObject
+ * copyObjectImpl -- implementation of copyObject(); see nodes/nodes.h
*
* Create a copy of a Node tree or list. This is a "deep" copy: all
* substructure is copied too, recursively.
*/
void *
-copyObject(const void *from)
+copyObjectImpl(const void *from)
{
void *retval;
@@ -4611,6 +4998,9 @@ copyObject(const void *from)
case T_Result:
retval = _copyResult(from);
break;
+ case T_ProjectSet:
+ retval = _copyProjectSet(from);
+ break;
case T_ModifyTable:
retval = _copyModifyTable(from);
break;
@@ -4635,6 +5025,9 @@ copyObject(const void *from)
case T_Gather:
retval = _copyGather(from);
break;
+ case T_GatherMerge:
+ retval = _copyGatherMerge(from);
+ break;
case T_SeqScan:
retval = _copySeqScan(from);
break;
@@ -4662,12 +5055,18 @@ copyObject(const void *from)
case T_FunctionScan:
retval = _copyFunctionScan(from);
break;
+ case T_TableFuncScan:
+ retval = _copyTableFuncScan(from);
+ break;
case T_ValuesScan:
retval = _copyValuesScan(from);
break;
case T_CteScan:
retval = _copyCteScan(from);
break;
+ case T_NamedTuplestoreScan:
+ retval = _copyNamedTuplestoreScan(from);
+ break;
case T_WorkTableScan:
retval = _copyWorkTableScan(from);
break;
@@ -4762,6 +5161,9 @@ copyObject(const void *from)
case T_RangeVar:
retval = _copyRangeVar(from);
break;
+ case T_TableFunc:
+ retval = _copyTableFunc(from);
+ break;
case T_IntoClause:
retval = _copyIntoClause(from);
break;
@@ -4861,6 +5263,9 @@ copyObject(const void *from)
case T_MinMaxExpr:
retval = _copyMinMaxExpr(from);
break;
+ case T_SQLValueFunction:
+ retval = _copySQLValueFunction(from);
+ break;
case T_XmlExpr:
retval = _copyXmlExpr(from);
break;
@@ -4882,6 +5287,9 @@ copyObject(const void *from)
case T_CurrentOfExpr:
retval = _copyCurrentOfExpr(from);
break;
+ case T_NextValueExpr:
+ retval = _copyNextValueExpr(from);
+ break;
case T_InferenceElem:
retval = _copyInferenceElem(from);
break;
@@ -4919,6 +5327,9 @@ copyObject(const void *from)
case T_AppendRelInfo:
retval = _copyAppendRelInfo(from);
break;
+ case T_PartitionedChildRelInfo:
+ retval = _copyPartitionedChildRelInfo(from);
+ break;
case T_PlaceHolderInfo:
retval = _copyPlaceHolderInfo(from);
break;
@@ -4963,6 +5374,9 @@ copyObject(const void *from)
case T_Query:
retval = _copyQuery(from);
break;
+ case T_RawStmt:
+ retval = _copyRawStmt(from);
+ break;
case T_InsertStmt:
retval = _copyInsertStmt(from);
break;
@@ -4984,6 +5398,9 @@ copyObject(const void *from)
case T_AlterTableCmd:
retval = _copyAlterTableCmd(from);
break;
+ case T_AlterCollationStmt:
+ retval = _copyAlterCollationStmt(from);
+ break;
case T_AlterDomainStmt:
retval = _copyAlterDomainStmt(from);
break;
@@ -5035,6 +5452,9 @@ copyObject(const void *from)
case T_IndexStmt:
retval = _copyIndexStmt(from);
break;
+ case T_CreateStatsStmt:
+ retval = _copyCreateStatsStmt(from);
+ break;
case T_CreateFunctionStmt:
retval = _copyCreateFunctionStmt(from);
break;
@@ -5307,6 +5727,21 @@ copyObject(const void *from)
case T_AlterPolicyStmt:
retval = _copyAlterPolicyStmt(from);
break;
+ case T_CreatePublicationStmt:
+ retval = _copyCreatePublicationStmt(from);
+ break;
+ case T_AlterPublicationStmt:
+ retval = _copyAlterPublicationStmt(from);
+ break;
+ case T_CreateSubscriptionStmt:
+ retval = _copyCreateSubscriptionStmt(from);
+ break;
+ case T_AlterSubscriptionStmt:
+ retval = _copyAlterSubscriptionStmt(from);
+ break;
+ case T_DropSubscriptionStmt:
+ retval = _copyDropSubscriptionStmt(from);
+ break;
case T_A_Expr:
retval = _copyAExpr(from);
break;
@@ -5361,6 +5796,12 @@ copyObject(const void *from)
case T_RangeTableSample:
retval = _copyRangeTableSample(from);
break;
+ case T_RangeTableFunc:
+ retval = _copyRangeTableFunc(from);
+ break;
+ case T_RangeTableFuncCol:
+ retval = _copyRangeTableFuncCol(from);
+ break;
case T_TypeName:
retval = _copyTypeName(from);
break;
@@ -5415,8 +5856,8 @@ copyObject(const void *from)
case T_CommonTableExpr:
retval = _copyCommonTableExpr(from);
break;
- case T_FuncWithArgs:
- retval = _copyFuncWithArgs(from);
+ case T_ObjectWithArgs:
+ retval = _copyObjectWithArgs(from);
break;
case T_AccessPriv:
retval = _copyAccessPriv(from);
@@ -5436,6 +5877,24 @@ copyObject(const void *from)
case T_RoleSpec:
retval = _copyRoleSpec(from);
break;
+ case T_TriggerTransition:
+ retval = _copyTriggerTransition(from);
+ break;
+ case T_PartitionElem:
+ retval = _copyPartitionElem(from);
+ break;
+ case T_PartitionSpec:
+ retval = _copyPartitionSpec(from);
+ break;
+ case T_PartitionBoundSpec:
+ retval = _copyPartitionBoundSpec(from);
+ break;
+ case T_PartitionRangeDatum:
+ retval = _copyPartitionRangeDatum(from);
+ break;
+ case T_PartitionCmd:
+ retval = _copyPartitionCmd(from);
+ break;
/*
* MISCELLANEOUS NODES
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index e6f44f1cf8..c644aba4c1 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -19,7 +19,7 @@
*
*
* Portions Copyright (c) 2012-2014, TransLattice, Inc.
- * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 2010-2012 Postgres-XC Development Group
*
@@ -110,7 +110,7 @@ _equalRangeVar(const RangeVar *a, const RangeVar *b)
COMPARE_STRING_FIELD(catalogname);
COMPARE_STRING_FIELD(schemaname);
COMPARE_STRING_FIELD(relname);
- COMPARE_SCALAR_FIELD(inhOpt);
+ COMPARE_SCALAR_FIELD(inh);
COMPARE_SCALAR_FIELD(relpersistence);
COMPARE_NODE_FIELD(alias);
COMPARE_LOCATION_FIELD(location);
@@ -119,6 +119,26 @@ _equalRangeVar(const RangeVar *a, const RangeVar *b)
}
static bool
+_equalTableFunc(const TableFunc *a, const TableFunc *b)
+{
+ COMPARE_NODE_FIELD(ns_names);
+ COMPARE_NODE_FIELD(ns_uris);
+ COMPARE_NODE_FIELD(docexpr);
+ COMPARE_NODE_FIELD(rowexpr);
+ COMPARE_NODE_FIELD(colnames);
+ COMPARE_NODE_FIELD(coltypes);
+ COMPARE_NODE_FIELD(coltypes);
+ COMPARE_NODE_FIELD(colcollations);
+ COMPARE_NODE_FIELD(colexprs);
+ COMPARE_NODE_FIELD(coldefexprs);
+ COMPARE_BITMAPSET_FIELD(notnulls);
+ COMPARE_SCALAR_FIELD(ordinalitycol);
+ COMPARE_LOCATION_FIELD(location);
+
+ return true;
+}
+
+static bool
_equalIntoClause(const IntoClause *a, const IntoClause *b)
{
COMPARE_NODE_FIELD(rel);
@@ -447,6 +467,7 @@ _equalSubPlan(const SubPlan *a, const SubPlan *b)
COMPARE_SCALAR_FIELD(firstColCollation);
COMPARE_SCALAR_FIELD(useHashTable);
COMPARE_SCALAR_FIELD(unknownEqFalse);
+ COMPARE_SCALAR_FIELD(parallel_safe);
COMPARE_NODE_FIELD(setParam);
COMPARE_NODE_FIELD(parParam);
COMPARE_NODE_FIELD(args);
@@ -644,6 +665,17 @@ _equalMinMaxExpr(const MinMaxExpr *a, const MinMaxExpr *b)
}
static bool
+_equalSQLValueFunction(const SQLValueFunction *a, const SQLValueFunction *b)
+{
+ COMPARE_SCALAR_FIELD(op);
+ COMPARE_SCALAR_FIELD(type);
+ COMPARE_SCALAR_FIELD(typmod);
+ COMPARE_LOCATION_FIELD(location);
+
+ return true;
+}
+
+static bool
_equalXmlExpr(const XmlExpr *a, const XmlExpr *b)
{
COMPARE_SCALAR_FIELD(op);
@@ -726,6 +758,15 @@ _equalCurrentOfExpr(const CurrentOfExpr *a, const CurrentOfExpr *b)
}
static bool
+_equalNextValueExpr(const NextValueExpr *a, const NextValueExpr *b)
+{
+ COMPARE_SCALAR_FIELD(seqid);
+ COMPARE_SCALAR_FIELD(typeId);
+
+ return true;
+}
+
+static bool
_equalInferenceElem(const InferenceElem *a, const InferenceElem *b)
{
COMPARE_NODE_FIELD(expr);
@@ -818,6 +859,7 @@ _equalRestrictInfo(const RestrictInfo *a, const RestrictInfo *b)
COMPARE_NODE_FIELD(clause);
COMPARE_SCALAR_FIELD(is_pushed_down);
COMPARE_SCALAR_FIELD(outerjoin_delayed);
+ COMPARE_SCALAR_FIELD(security_level);
COMPARE_BITMAPSET_FIELD(required_relids);
COMPARE_BITMAPSET_FIELD(outer_relids);
COMPARE_BITMAPSET_FIELD(nullable_relids);
@@ -887,6 +929,15 @@ _equalAppendRelInfo(const AppendRelInfo *a, const AppendRelInfo *b)
}
static bool
+_equalPartitionedChildRelInfo(const PartitionedChildRelInfo *a, const PartitionedChildRelInfo *b)
+{
+ COMPARE_SCALAR_FIELD(parent_relid);
+ COMPARE_NODE_FIELD(child_rels);
+
+ return true;
+}
+
+static bool
_equalPlaceHolderInfo(const PlaceHolderInfo *a, const PlaceHolderInfo *b)
{
COMPARE_SCALAR_FIELD(phid);
@@ -934,6 +985,7 @@ _equalQuery(const Query *a, const Query *b)
COMPARE_SCALAR_FIELD(resultRelation);
COMPARE_SCALAR_FIELD(hasAggs);
COMPARE_SCALAR_FIELD(hasWindowFuncs);
+ COMPARE_SCALAR_FIELD(hasTargetSRFs);
COMPARE_SCALAR_FIELD(hasSubLinks);
COMPARE_SCALAR_FIELD(hasDistinctOn);
COMPARE_SCALAR_FIELD(hasRecursive);
@@ -944,6 +996,7 @@ _equalQuery(const Query *a, const Query *b)
COMPARE_NODE_FIELD(rtable);
COMPARE_NODE_FIELD(jointree);
COMPARE_NODE_FIELD(targetList);
+ COMPARE_SCALAR_FIELD(override);
COMPARE_NODE_FIELD(onConflict);
COMPARE_NODE_FIELD(returningList);
COMPARE_NODE_FIELD(groupClause);
@@ -958,6 +1011,18 @@ _equalQuery(const Query *a, const Query *b)
COMPARE_NODE_FIELD(setOperations);
COMPARE_NODE_FIELD(constraintDeps);
COMPARE_NODE_FIELD(withCheckOptions);
+ COMPARE_LOCATION_FIELD(stmt_location);
+ COMPARE_LOCATION_FIELD(stmt_len);
+
+ return true;
+}
+
+static bool
+_equalRawStmt(const RawStmt *a, const RawStmt *b)
+{
+ COMPARE_NODE_FIELD(stmt);
+ COMPARE_LOCATION_FIELD(stmt_location);
+ COMPARE_LOCATION_FIELD(stmt_len);
return true;
}
@@ -971,6 +1036,7 @@ _equalInsertStmt(const InsertStmt *a, const InsertStmt *b)
COMPARE_NODE_FIELD(onConflictClause);
COMPARE_NODE_FIELD(returningList);
COMPARE_NODE_FIELD(withClause);
+ COMPARE_SCALAR_FIELD(override);
return true;
}
@@ -1065,6 +1131,14 @@ _equalAlterTableCmd(const AlterTableCmd *a, const AlterTableCmd *b)
}
static bool
+_equalAlterCollationStmt(const AlterCollationStmt *a, const AlterCollationStmt *b)
+{
+ COMPARE_NODE_FIELD(collname);
+
+ return true;
+}
+
+static bool
_equalAlterDomainStmt(const AlterDomainStmt *a, const AlterDomainStmt *b)
{
COMPARE_SCALAR_FIELD(subtype);
@@ -1093,10 +1167,11 @@ _equalGrantStmt(const GrantStmt *a, const GrantStmt *b)
}
static bool
-_equalFuncWithArgs(const FuncWithArgs *a, const FuncWithArgs *b)
+_equalObjectWithArgs(const ObjectWithArgs *a, const ObjectWithArgs *b)
{
- COMPARE_NODE_FIELD(funcname);
- COMPARE_NODE_FIELD(funcargs);
+ COMPARE_NODE_FIELD(objname);
+ COMPARE_NODE_FIELD(objargs);
+ COMPARE_SCALAR_FIELD(args_unspecified);
return true;
}
@@ -1180,6 +1255,8 @@ _equalCreateStmt(const CreateStmt *a, const CreateStmt *b)
COMPARE_NODE_FIELD(relation);
COMPARE_NODE_FIELD(tableElts);
COMPARE_NODE_FIELD(inhRelations);
+ COMPARE_NODE_FIELD(partspec);
+ COMPARE_NODE_FIELD(partbound);
COMPARE_NODE_FIELD(ofTypename);
COMPARE_NODE_FIELD(constraints);
COMPARE_NODE_FIELD(options);
@@ -1213,6 +1290,7 @@ _equalDefineStmt(const DefineStmt *a, const DefineStmt *b)
COMPARE_NODE_FIELD(defnames);
COMPARE_NODE_FIELD(args);
COMPARE_NODE_FIELD(definition);
+ COMPARE_SCALAR_FIELD(if_not_exists);
return true;
}
@@ -1221,7 +1299,6 @@ static bool
_equalDropStmt(const DropStmt *a, const DropStmt *b)
{
COMPARE_NODE_FIELD(objects);
- COMPARE_NODE_FIELD(arguments);
COMPARE_SCALAR_FIELD(removeType);
COMPARE_SCALAR_FIELD(behavior);
COMPARE_SCALAR_FIELD(missing_ok);
@@ -1244,8 +1321,7 @@ static bool
_equalCommentStmt(const CommentStmt *a, const CommentStmt *b)
{
COMPARE_SCALAR_FIELD(objtype);
- COMPARE_NODE_FIELD(objname);
- COMPARE_NODE_FIELD(objargs);
+ COMPARE_NODE_FIELD(object);
COMPARE_STRING_FIELD(comment);
return true;
@@ -1255,8 +1331,7 @@ static bool
_equalSecLabelStmt(const SecLabelStmt *a, const SecLabelStmt *b)
{
COMPARE_SCALAR_FIELD(objtype);
- COMPARE_NODE_FIELD(objname);
- COMPARE_NODE_FIELD(objargs);
+ COMPARE_NODE_FIELD(object);
COMPARE_STRING_FIELD(provider);
COMPARE_STRING_FIELD(label);
@@ -1301,6 +1376,18 @@ _equalIndexStmt(const IndexStmt *a, const IndexStmt *b)
}
static bool
+_equalCreateStatsStmt(const CreateStatsStmt *a, const CreateStatsStmt *b)
+{
+ COMPARE_NODE_FIELD(defnames);
+ COMPARE_NODE_FIELD(stat_types);
+ COMPARE_NODE_FIELD(exprs);
+ COMPARE_NODE_FIELD(relations);
+ COMPARE_SCALAR_FIELD(if_not_exists);
+
+ return true;
+}
+
+static bool
_equalCreateFunctionStmt(const CreateFunctionStmt *a, const CreateFunctionStmt *b)
{
COMPARE_SCALAR_FIELD(replace);
@@ -1348,7 +1435,6 @@ _equalRenameStmt(const RenameStmt *a, const RenameStmt *b)
COMPARE_SCALAR_FIELD(relationType);
COMPARE_NODE_FIELD(relation);
COMPARE_NODE_FIELD(object);
- COMPARE_NODE_FIELD(objarg);
COMPARE_STRING_FIELD(subname);
COMPARE_STRING_FIELD(newname);
COMPARE_SCALAR_FIELD(behavior);
@@ -1362,8 +1448,7 @@ _equalAlterObjectDependsStmt(const AlterObjectDependsStmt *a, const AlterObjectD
{
COMPARE_SCALAR_FIELD(objectType);
COMPARE_NODE_FIELD(relation);
- COMPARE_NODE_FIELD(objname);
- COMPARE_NODE_FIELD(objargs);
+ COMPARE_NODE_FIELD(object);
COMPARE_NODE_FIELD(extname);
return true;
@@ -1375,7 +1460,6 @@ _equalAlterObjectSchemaStmt(const AlterObjectSchemaStmt *a, const AlterObjectSch
COMPARE_SCALAR_FIELD(objectType);
COMPARE_NODE_FIELD(relation);
COMPARE_NODE_FIELD(object);
- COMPARE_NODE_FIELD(objarg);
COMPARE_STRING_FIELD(newschema);
COMPARE_SCALAR_FIELD(missing_ok);
@@ -1388,7 +1472,6 @@ _equalAlterOwnerStmt(const AlterOwnerStmt *a, const AlterOwnerStmt *b)
COMPARE_SCALAR_FIELD(objectType);
COMPARE_NODE_FIELD(relation);
COMPARE_NODE_FIELD(object);
- COMPARE_NODE_FIELD(objarg);
COMPARE_NODE_FIELD(newowner);
return true;
@@ -1398,7 +1481,6 @@ static bool
_equalAlterOperatorStmt(const AlterOperatorStmt *a, const AlterOperatorStmt *b)
{
COMPARE_NODE_FIELD(opername);
- COMPARE_NODE_FIELD(operargs);
COMPARE_NODE_FIELD(options);
return true;
@@ -1484,10 +1566,11 @@ static bool
_equalAlterEnumStmt(const AlterEnumStmt *a, const AlterEnumStmt *b)
{
COMPARE_NODE_FIELD(typeName);
+ COMPARE_STRING_FIELD(oldVal);
COMPARE_STRING_FIELD(newVal);
COMPARE_STRING_FIELD(newValNeighbor);
COMPARE_SCALAR_FIELD(newValIsAfter);
- COMPARE_SCALAR_FIELD(skipIfExists);
+ COMPARE_SCALAR_FIELD(skipIfNewValExists);
return true;
}
@@ -1542,7 +1625,6 @@ _equalCreateOpClassItem(const CreateOpClassItem *a, const CreateOpClassItem *b)
{
COMPARE_SCALAR_FIELD(itemtype);
COMPARE_NODE_FIELD(name);
- COMPARE_NODE_FIELD(args);
COMPARE_SCALAR_FIELD(number);
COMPARE_NODE_FIELD(order_family);
COMPARE_NODE_FIELD(class_args);
@@ -1675,6 +1757,7 @@ _equalCreateSeqStmt(const CreateSeqStmt *a, const CreateSeqStmt *b)
COMPARE_NODE_FIELD(sequence);
COMPARE_NODE_FIELD(options);
COMPARE_SCALAR_FIELD(ownerId);
+ COMPARE_SCALAR_FIELD(for_identity);
COMPARE_SCALAR_FIELD(if_not_exists);
return true;
@@ -1685,6 +1768,7 @@ _equalAlterSeqStmt(const AlterSeqStmt *a, const AlterSeqStmt *b)
{
COMPARE_NODE_FIELD(sequence);
COMPARE_NODE_FIELD(options);
+ COMPARE_SCALAR_FIELD(for_identity);
COMPARE_SCALAR_FIELD(missing_ok);
return true;
@@ -1786,8 +1870,7 @@ _equalAlterExtensionContentsStmt(const AlterExtensionContentsStmt *a, const Alte
COMPARE_STRING_FIELD(extname);
COMPARE_SCALAR_FIELD(action);
COMPARE_SCALAR_FIELD(objtype);
- COMPARE_NODE_FIELD(objname);
- COMPARE_NODE_FIELD(objargs);
+ COMPARE_NODE_FIELD(object);
return true;
}
@@ -1820,6 +1903,7 @@ _equalCreateForeignServerStmt(const CreateForeignServerStmt *a, const CreateFore
COMPARE_STRING_FIELD(version);
COMPARE_STRING_FIELD(fdwname);
COMPARE_NODE_FIELD(options);
+ COMPARE_SCALAR_FIELD(if_not_exists);
return true;
}
@@ -1841,6 +1925,7 @@ _equalCreateUserMappingStmt(const CreateUserMappingStmt *a, const CreateUserMapp
COMPARE_NODE_FIELD(user);
COMPARE_STRING_FIELD(servername);
COMPARE_NODE_FIELD(options);
+ COMPARE_SCALAR_FIELD(if_not_exists);
return true;
}
@@ -1925,6 +2010,7 @@ _equalCreateTrigStmt(const CreateTrigStmt *a, const CreateTrigStmt *b)
COMPARE_NODE_FIELD(columns);
COMPARE_NODE_FIELD(whenClause);
COMPARE_SCALAR_FIELD(isconstraint);
+ COMPARE_NODE_FIELD(transitionRels);
COMPARE_SCALAR_FIELD(deferrable);
COMPARE_SCALAR_FIELD(initdeferred);
COMPARE_NODE_FIELD(constrrel);
@@ -2139,11 +2225,73 @@ _equalAlterTSConfigurationStmt(const AlterTSConfigurationStmt *a,
}
static bool
+_equalCreatePublicationStmt(const CreatePublicationStmt *a,
+ const CreatePublicationStmt *b)
+{
+ COMPARE_STRING_FIELD(pubname);
+ COMPARE_NODE_FIELD(options);
+ COMPARE_NODE_FIELD(tables);
+ COMPARE_SCALAR_FIELD(for_all_tables);
+
+ return true;
+}
+
+static bool
+_equalAlterPublicationStmt(const AlterPublicationStmt *a,
+ const AlterPublicationStmt *b)
+{
+ COMPARE_STRING_FIELD(pubname);
+ COMPARE_NODE_FIELD(options);
+ COMPARE_NODE_FIELD(tables);
+ COMPARE_SCALAR_FIELD(for_all_tables);
+ COMPARE_SCALAR_FIELD(tableAction);
+
+ return true;
+}
+
+static bool
+_equalCreateSubscriptionStmt(const CreateSubscriptionStmt *a,
+ const CreateSubscriptionStmt *b)
+{
+ COMPARE_STRING_FIELD(subname);
+ COMPARE_STRING_FIELD(conninfo);
+ COMPARE_NODE_FIELD(publication);
+ COMPARE_NODE_FIELD(options);
+
+ return true;
+}
+
+static bool
+_equalAlterSubscriptionStmt(const AlterSubscriptionStmt *a,
+ const AlterSubscriptionStmt *b)
+{
+ COMPARE_SCALAR_FIELD(kind);
+ COMPARE_STRING_FIELD(subname);
+ COMPARE_STRING_FIELD(conninfo);
+ COMPARE_NODE_FIELD(publication);
+ COMPARE_NODE_FIELD(options);
+
+ return true;
+}
+
+static bool
+_equalDropSubscriptionStmt(const DropSubscriptionStmt *a,
+ const DropSubscriptionStmt *b)
+{
+ COMPARE_STRING_FIELD(subname);
+ COMPARE_SCALAR_FIELD(missing_ok);
+ COMPARE_SCALAR_FIELD(behavior);
+
+ return true;
+}
+
+static bool
_equalCreatePolicyStmt(const CreatePolicyStmt *a, const CreatePolicyStmt *b)
{
COMPARE_STRING_FIELD(policy_name);
COMPARE_NODE_FIELD(table);
COMPARE_STRING_FIELD(cmd_name);
+ COMPARE_SCALAR_FIELD(permissive);
COMPARE_NODE_FIELD(roles);
COMPARE_NODE_FIELD(qual);
COMPARE_NODE_FIELD(with_check);
@@ -2373,6 +2521,36 @@ _equalRangeTableSample(const RangeTableSample *a, const RangeTableSample *b)
}
static bool
+_equalRangeTableFunc(const RangeTableFunc *a, const RangeTableFunc *b)
+{
+ COMPARE_SCALAR_FIELD(lateral);
+ COMPARE_NODE_FIELD(docexpr);
+ COMPARE_NODE_FIELD(rowexpr);
+ COMPARE_NODE_FIELD(namespaces);
+ COMPARE_NODE_FIELD(columns);
+ COMPARE_NODE_FIELD(alias);
+ COMPARE_LOCATION_FIELD(location);
+
+ return true;
+}
+
+static bool
+_equalRangeTableFuncCol(const RangeTableFuncCol *a, const RangeTableFuncCol *b)
+{
+ COMPARE_STRING_FIELD(colname);
+ COMPARE_NODE_FIELD(typeName);
+ COMPARE_SCALAR_FIELD(for_ordinality);
+ COMPARE_NODE_FIELD(typeName);
+ COMPARE_SCALAR_FIELD(is_not_null);
+ COMPARE_NODE_FIELD(colexpr);
+ COMPARE_NODE_FIELD(coldefexpr);
+ COMPARE_LOCATION_FIELD(location);
+
+ return true;
+}
+
+
+static bool
_equalIndexElem(const IndexElem *a, const IndexElem *b)
{
COMPARE_STRING_FIELD(name);
@@ -2395,9 +2573,11 @@ _equalColumnDef(const ColumnDef *a, const ColumnDef *b)
COMPARE_SCALAR_FIELD(is_local);
COMPARE_SCALAR_FIELD(is_not_null);
COMPARE_SCALAR_FIELD(is_from_type);
+ COMPARE_SCALAR_FIELD(is_from_parent);
COMPARE_SCALAR_FIELD(storage);
COMPARE_NODE_FIELD(raw_default);
COMPARE_NODE_FIELD(cooked_default);
+ COMPARE_SCALAR_FIELD(identity);
COMPARE_NODE_FIELD(collClause);
COMPARE_SCALAR_FIELD(collOid);
COMPARE_NODE_FIELD(constraints);
@@ -2418,6 +2598,7 @@ _equalConstraint(const Constraint *a, const Constraint *b)
COMPARE_SCALAR_FIELD(is_no_inherit);
COMPARE_NODE_FIELD(raw_expr);
COMPARE_STRING_FIELD(cooked_expr);
+ COMPARE_SCALAR_FIELD(generated_when);
COMPARE_NODE_FIELD(keys);
COMPARE_NODE_FIELD(exclusions);
COMPARE_NODE_FIELD(options);
@@ -2446,6 +2627,7 @@ _equalDefElem(const DefElem *a, const DefElem *b)
COMPARE_STRING_FIELD(defname);
COMPARE_NODE_FIELD(arg);
COMPARE_SCALAR_FIELD(defaction);
+ COMPARE_LOCATION_FIELD(location);
return true;
}
@@ -2456,6 +2638,7 @@ _equalLockingClause(const LockingClause *a, const LockingClause *b)
COMPARE_NODE_FIELD(lockedRels);
COMPARE_SCALAR_FIELD(strength);
COMPARE_SCALAR_FIELD(waitPolicy);
+ COMPARE_LOCATION_FIELD(location);
return true;
}
@@ -2472,15 +2655,15 @@ _equalRangeTblEntry(const RangeTblEntry *a, const RangeTblEntry *b)
COMPARE_SCALAR_FIELD(jointype);
COMPARE_NODE_FIELD(joinaliasvars);
COMPARE_NODE_FIELD(functions);
+ COMPARE_NODE_FIELD(tablefunc);
COMPARE_SCALAR_FIELD(funcordinality);
COMPARE_NODE_FIELD(values_lists);
- COMPARE_NODE_FIELD(values_collations);
COMPARE_STRING_FIELD(ctename);
COMPARE_SCALAR_FIELD(ctelevelsup);
COMPARE_SCALAR_FIELD(self_reference);
- COMPARE_NODE_FIELD(ctecoltypes);
- COMPARE_NODE_FIELD(ctecoltypmods);
- COMPARE_NODE_FIELD(ctecolcollations);
+ COMPARE_NODE_FIELD(coltypes);
+ COMPARE_NODE_FIELD(coltypmods);
+ COMPARE_NODE_FIELD(colcollations);
COMPARE_NODE_FIELD(alias);
COMPARE_NODE_FIELD(eref);
COMPARE_SCALAR_FIELD(lateral);
@@ -2682,6 +2865,69 @@ _equalRoleSpec(const RoleSpec *a, const RoleSpec *b)
return true;
}
+static bool
+_equalTriggerTransition(const TriggerTransition *a, const TriggerTransition *b)
+{
+ COMPARE_STRING_FIELD(name);
+ COMPARE_SCALAR_FIELD(isNew);
+ COMPARE_SCALAR_FIELD(isTable);
+
+ return true;
+}
+
+static bool
+_equalPartitionElem(const PartitionElem *a, const PartitionElem *b)
+{
+ COMPARE_STRING_FIELD(name);
+ COMPARE_NODE_FIELD(expr);
+ COMPARE_NODE_FIELD(collation);
+ COMPARE_NODE_FIELD(opclass);
+ COMPARE_LOCATION_FIELD(location);
+
+ return true;
+}
+
+static bool
+_equalPartitionSpec(const PartitionSpec *a, const PartitionSpec *b)
+{
+ COMPARE_STRING_FIELD(strategy);
+ COMPARE_NODE_FIELD(partParams);
+ COMPARE_LOCATION_FIELD(location);
+
+ return true;
+}
+
+static bool
+_equalPartitionBoundSpec(const PartitionBoundSpec *a, const PartitionBoundSpec *b)
+{
+ COMPARE_SCALAR_FIELD(strategy);
+ COMPARE_NODE_FIELD(listdatums);
+ COMPARE_NODE_FIELD(lowerdatums);
+ COMPARE_NODE_FIELD(upperdatums);
+ COMPARE_LOCATION_FIELD(location);
+
+ return true;
+}
+
+static bool
+_equalPartitionRangeDatum(const PartitionRangeDatum *a, const PartitionRangeDatum *b)
+{
+ COMPARE_SCALAR_FIELD(infinite);
+ COMPARE_NODE_FIELD(value);
+ COMPARE_LOCATION_FIELD(location);
+
+ return true;
+}
+
+static bool
+_equalPartitionCmd(const PartitionCmd *a, const PartitionCmd *b)
+{
+ COMPARE_NODE_FIELD(name);
+ COMPARE_NODE_FIELD(bound);
+
+ return true;
+}
+
/*
* Stuff from pg_list.h
*/
@@ -2891,6 +3137,9 @@ equal(const void *a, const void *b)
case T_RangeVar:
retval = _equalRangeVar(a, b);
break;
+ case T_TableFunc:
+ retval = _equalTableFunc(a, b);
+ break;
case T_IntoClause:
retval = _equalIntoClause(a, b);
break;
@@ -2990,6 +3239,9 @@ equal(const void *a, const void *b)
case T_MinMaxExpr:
retval = _equalMinMaxExpr(a, b);
break;
+ case T_SQLValueFunction:
+ retval = _equalSQLValueFunction(a, b);
+ break;
case T_XmlExpr:
retval = _equalXmlExpr(a, b);
break;
@@ -3011,6 +3263,9 @@ equal(const void *a, const void *b)
case T_CurrentOfExpr:
retval = _equalCurrentOfExpr(a, b);
break;
+ case T_NextValueExpr:
+ retval = _equalNextValueExpr(a, b);
+ break;
case T_InferenceElem:
retval = _equalInferenceElem(a, b);
break;
@@ -3048,6 +3303,9 @@ equal(const void *a, const void *b)
case T_AppendRelInfo:
retval = _equalAppendRelInfo(a, b);
break;
+ case T_PartitionedChildRelInfo:
+ retval = _equalPartitionedChildRelInfo(a, b);
+ break;
case T_PlaceHolderInfo:
retval = _equalPlaceHolderInfo(a, b);
break;
@@ -3079,6 +3337,9 @@ equal(const void *a, const void *b)
case T_Query:
retval = _equalQuery(a, b);
break;
+ case T_RawStmt:
+ retval = _equalRawStmt(a, b);
+ break;
case T_InsertStmt:
retval = _equalInsertStmt(a, b);
break;
@@ -3100,6 +3361,9 @@ equal(const void *a, const void *b)
case T_AlterTableCmd:
retval = _equalAlterTableCmd(a, b);
break;
+ case T_AlterCollationStmt:
+ retval = _equalAlterCollationStmt(a, b);
+ break;
case T_AlterDomainStmt:
retval = _equalAlterDomainStmt(a, b);
break;
@@ -3151,6 +3415,9 @@ equal(const void *a, const void *b)
case T_IndexStmt:
retval = _equalIndexStmt(a, b);
break;
+ case T_CreateStatsStmt:
+ retval = _equalCreateStatsStmt(a, b);
+ break;
case T_CreateFunctionStmt:
retval = _equalCreateFunctionStmt(a, b);
break;
@@ -3423,6 +3690,21 @@ equal(const void *a, const void *b)
case T_AlterPolicyStmt:
retval = _equalAlterPolicyStmt(a, b);
break;
+ case T_CreatePublicationStmt:
+ retval = _equalCreatePublicationStmt(a, b);
+ break;
+ case T_AlterPublicationStmt:
+ retval = _equalAlterPublicationStmt(a, b);
+ break;
+ case T_CreateSubscriptionStmt:
+ retval = _equalCreateSubscriptionStmt(a, b);
+ break;
+ case T_AlterSubscriptionStmt:
+ retval = _equalAlterSubscriptionStmt(a, b);
+ break;
+ case T_DropSubscriptionStmt:
+ retval = _equalDropSubscriptionStmt(a, b);
+ break;
case T_A_Expr:
retval = _equalAExpr(a, b);
break;
@@ -3477,6 +3759,12 @@ equal(const void *a, const void *b)
case T_RangeTableSample:
retval = _equalRangeTableSample(a, b);
break;
+ case T_RangeTableFunc:
+ retval = _equalRangeTableFunc(a, b);
+ break;
+ case T_RangeTableFuncCol:
+ retval = _equalRangeTableFuncCol(a, b);
+ break;
case T_TypeName:
retval = _equalTypeName(a, b);
break;
@@ -3531,8 +3819,8 @@ equal(const void *a, const void *b)
case T_CommonTableExpr:
retval = _equalCommonTableExpr(a, b);
break;
- case T_FuncWithArgs:
- retval = _equalFuncWithArgs(a, b);
+ case T_ObjectWithArgs:
+ retval = _equalObjectWithArgs(a, b);
break;
case T_AccessPriv:
retval = _equalAccessPriv(a, b);
@@ -3548,6 +3836,24 @@ equal(const void *a, const void *b)
case T_RoleSpec:
retval = _equalRoleSpec(a, b);
break;
+ case T_TriggerTransition:
+ retval = _equalTriggerTransition(a, b);
+ break;
+ case T_PartitionElem:
+ retval = _equalPartitionElem(a, b);
+ break;
+ case T_PartitionSpec:
+ retval = _equalPartitionSpec(a, b);
+ break;
+ case T_PartitionBoundSpec:
+ retval = _equalPartitionBoundSpec(a, b);
+ break;
+ case T_PartitionRangeDatum:
+ retval = _equalPartitionRangeDatum(a, b);
+ break;
+ case T_PartitionCmd:
+ retval = _equalPartitionCmd(a, b);
+ break;
default:
elog(ERROR, "unrecognized node type: %d",
diff --git a/src/backend/nodes/extensible.c b/src/backend/nodes/extensible.c
index a4f1c99016..01cd3c84fb 100644
--- a/src/backend/nodes/extensible.c
+++ b/src/backend/nodes/extensible.c
@@ -10,7 +10,7 @@
* and GetExtensibleNodeMethods to get information about a previously
* registered type of extensible node.
*
- * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
diff --git a/src/backend/nodes/list.c b/src/backend/nodes/list.c
index 085b68cd1f..f09aa248d8 100644
--- a/src/backend/nodes/list.c
+++ b/src/backend/nodes/list.c
@@ -4,7 +4,7 @@
* implementation for PostgreSQL generic linked list package
*
*
- * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index b564d403a5..f138afd706 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -4,7 +4,7 @@
* creator functions for primitive nodes. The functions here are for
* the most frequently created nodes.
*
- * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
@@ -216,10 +216,10 @@ makeWholeRowVar(RangeTblEntry *rte,
default:
/*
- * RTE is a join, subselect, or VALUES. We represent this as a
- * whole-row Var of RECORD type. (Note that in most cases the Var
- * will be expanded to a RowExpr during planning, but that is not
- * our concern here.)
+ * RTE is a join, subselect, tablefunc, or VALUES. We represent
+ * this as a whole-row Var of RECORD type. (Note that in most
+ * cases the Var will be expanded to a RowExpr during planning,
+ * but that is not our concern here.)
*/
result = makeVar(varno,
InvalidAttrNumber,
@@ -429,7 +429,7 @@ makeRangeVar(char *schemaname, char *relname, int location)
r->catalogname = NULL;
r->schemaname = schemaname;
r->relname = relname;
- r->inhOpt = INH_DEFAULT;
+ r->inh = true;
r->relpersistence = RELPERSISTENCE_PERMANENT;
r->alias = NULL;
r->location = location;
@@ -500,6 +500,7 @@ makeColumnDef(const char *colname, Oid typeOid, int32 typmod, Oid collOid)
n->is_local = true;
n->is_not_null = false;
n->is_from_type = false;
+ n->is_from_parent = false;
n->storage = 0;
n->raw_default = NULL;
n->cooked_default = NULL;
@@ -546,7 +547,7 @@ makeFuncExpr(Oid funcid, Oid rettype, List *args,
* and no special action.
*/
DefElem *
-makeDefElem(char *name, Node *arg)
+makeDefElem(char *name, Node *arg, int location)
{
DefElem *res = makeNode(DefElem);
@@ -554,6 +555,7 @@ makeDefElem(char *name, Node *arg)
res->defname = name;
res->arg = arg;
res->defaction = DEFELEM_UNSPEC;
+ res->location = location;
return res;
}
@@ -564,7 +566,7 @@ makeDefElem(char *name, Node *arg)
*/
DefElem *
makeDefElemExtended(char *nameSpace, char *name, Node *arg,
- DefElemAction defaction)
+ DefElemAction defaction, int location)
{
DefElem *res = makeNode(DefElem);
@@ -572,6 +574,7 @@ makeDefElemExtended(char *nameSpace, char *name, Node *arg,
res->defname = name;
res->arg = arg;
res->defaction = defaction;
+ res->location = location;
return res;
}
diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c
index d05332c10a..eb3e1ce1c1 100644
--- a/src/backend/nodes/nodeFuncs.c
+++ b/src/backend/nodes/nodeFuncs.c
@@ -3,7 +3,7 @@
* nodeFuncs.c
* Various general-purpose manipulations of Node trees
*
- * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
@@ -111,8 +111,7 @@ exprType(const Node *expr)
if (!qtree || !IsA(qtree, Query))
elog(ERROR, "cannot get type for untransformed sublink");
- tent = (TargetEntry *) linitial(qtree->targetList);
- Assert(IsA(tent, TargetEntry));
+ tent = linitial_node(TargetEntry, qtree->targetList);
Assert(!tent->resjunk);
type = exprType((Node *) tent->expr);
if (sublink->subLinkType == ARRAY_SUBLINK)
@@ -218,6 +217,9 @@ exprType(const Node *expr)
case T_MinMaxExpr:
type = ((const MinMaxExpr *) expr)->minmaxtype;
break;
+ case T_SQLValueFunction:
+ type = ((const SQLValueFunction *) expr)->type;
+ break;
case T_XmlExpr:
if (((const XmlExpr *) expr)->op == IS_DOCUMENT)
type = BOOLOID;
@@ -244,6 +246,9 @@ exprType(const Node *expr)
case T_CurrentOfExpr:
type = BOOLOID;
break;
+ case T_NextValueExpr:
+ type = ((const NextValueExpr *) expr)->typeId;
+ break;
case T_InferenceElem:
{
const InferenceElem *n = (const InferenceElem *) expr;
@@ -319,8 +324,7 @@ exprTypmod(const Node *expr)
if (!qtree || !IsA(qtree, Query))
elog(ERROR, "cannot get type for untransformed sublink");
- tent = (TargetEntry *) linitial(qtree->targetList);
- Assert(IsA(tent, TargetEntry));
+ tent = linitial_node(TargetEntry, qtree->targetList);
Assert(!tent->resjunk);
return exprTypmod((Node *) tent->expr);
/* note we don't need to care if it's an array */
@@ -378,9 +382,8 @@ exprTypmod(const Node *expr)
return -1; /* no point in trying harder */
foreach(arg, cexpr->args)
{
- CaseWhen *w = (CaseWhen *) lfirst(arg);
+ CaseWhen *w = lfirst_node(CaseWhen, arg);
- Assert(IsA(w, CaseWhen));
if (exprType((Node *) w->result) != casetype)
return -1;
if (exprTypmod((Node *) w->result) != typmod)
@@ -479,6 +482,8 @@ exprTypmod(const Node *expr)
return typmod;
}
break;
+ case T_SQLValueFunction:
+ return ((const SQLValueFunction *) expr)->typmod;
case T_CoerceToDomain:
return ((const CoerceToDomain *) expr)->resulttypmod;
case T_CoerceToDomainValue:
@@ -718,6 +723,8 @@ expression_returns_set_walker(Node *node, void *context)
return false;
if (IsA(node, MinMaxExpr))
return false;
+ if (IsA(node, SQLValueFunction))
+ return false;
if (IsA(node, XmlExpr))
return false;
@@ -802,8 +809,7 @@ exprCollation(const Node *expr)
if (!qtree || !IsA(qtree, Query))
elog(ERROR, "cannot get collation for untransformed sublink");
- tent = (TargetEntry *) linitial(qtree->targetList);
- Assert(IsA(tent, TargetEntry));
+ tent = linitial_node(TargetEntry, qtree->targetList);
Assert(!tent->resjunk);
coll = exprCollation((Node *) tent->expr);
/* collation doesn't change if it's converted to array */
@@ -883,6 +889,9 @@ exprCollation(const Node *expr)
case T_MinMaxExpr:
coll = ((const MinMaxExpr *) expr)->minmaxcollid;
break;
+ case T_SQLValueFunction:
+ coll = InvalidOid; /* all cases return non-collatable types */
+ break;
case T_XmlExpr:
/*
@@ -913,6 +922,9 @@ exprCollation(const Node *expr)
case T_CurrentOfExpr:
coll = InvalidOid; /* result is always boolean */
break;
+ case T_NextValueExpr:
+ coll = InvalidOid; /* result is always an integer type */
+ break;
case T_InferenceElem:
coll = exprCollation((Node *) ((const InferenceElem *) expr)->expr);
break;
@@ -1042,8 +1054,7 @@ exprSetCollation(Node *expr, Oid collation)
if (!qtree || !IsA(qtree, Query))
elog(ERROR, "cannot set collation for untransformed sublink");
- tent = (TargetEntry *) linitial(qtree->targetList);
- Assert(IsA(tent, TargetEntry));
+ tent = linitial_node(TargetEntry, qtree->targetList);
Assert(!tent->resjunk);
Assert(collation == exprCollation((Node *) tent->expr));
}
@@ -1091,6 +1102,9 @@ exprSetCollation(Node *expr, Oid collation)
case T_MinMaxExpr:
((MinMaxExpr *) expr)->minmaxcollid = collation;
break;
+ case T_SQLValueFunction:
+ Assert(!OidIsValid(collation)); /* no collatable results */
+ break;
case T_XmlExpr:
Assert((((XmlExpr *) expr)->op == IS_XMLSERIALIZE) ?
(collation == DEFAULT_COLLATION_OID) :
@@ -1114,6 +1128,10 @@ exprSetCollation(Node *expr, Oid collation)
case T_CurrentOfExpr:
Assert(!OidIsValid(collation)); /* result is always boolean */
break;
+ case T_NextValueExpr:
+ Assert(!OidIsValid(collation)); /* result is always an integer
+ * type */
+ break;
default:
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
break;
@@ -1204,6 +1222,9 @@ exprLocation(const Node *expr)
case T_RangeVar:
loc = ((const RangeVar *) expr)->location;
break;
+ case T_TableFunc:
+ loc = ((const TableFunc *) expr)->location;
+ break;
case T_Var:
loc = ((const Var *) expr)->location;
break;
@@ -1364,6 +1385,10 @@ exprLocation(const Node *expr)
/* GREATEST/LEAST keyword should always be the first thing */
loc = ((const MinMaxExpr *) expr)->location;
break;
+ case T_SQLValueFunction:
+ /* function keyword should always be the first thing */
+ loc = ((const SQLValueFunction *) expr)->location;
+ break;
case T_XmlExpr:
{
const XmlExpr *xexpr = (const XmlExpr *) expr;
@@ -1535,6 +1560,18 @@ exprLocation(const Node *expr)
/* just use nested expr's location */
loc = exprLocation((Node *) ((const InferenceElem *) expr)->expr);
break;
+ case T_PartitionElem:
+ loc = ((const PartitionElem *) expr)->location;
+ break;
+ case T_PartitionSpec:
+ loc = ((const PartitionSpec *) expr)->location;
+ break;
+ case T_PartitionBoundSpec:
+ loc = ((const PartitionBoundSpec *) expr)->location;
+ break;
+ case T_PartitionRangeDatum:
+ loc = ((const PartitionRangeDatum *) expr)->location;
+ break;
default:
/* for any other node type it's just unknown... */
loc = -1;
@@ -1633,9 +1670,10 @@ set_sa_opfuncid(ScalarArrayOpExpr *opexpr)
* for themselves, in case additional checks should be made, or because they
* have special rules about which parts of the tree need to be visited.
*
- * Note: we ignore MinMaxExpr, XmlExpr, and CoerceToDomain nodes, because they
- * do not contain SQL function OIDs. However, they can invoke SQL-visible
- * functions, so callers should take thought about how to treat them.
+ * Note: we ignore MinMaxExpr, SQLValueFunction, XmlExpr, and CoerceToDomain
+ * nodes, because they do not contain SQL function OIDs. However, they can
+ * invoke SQL-visible functions, so callers should take thought about how to
+ * treat them.
*/
bool
check_functions_in_node(Node *node, check_function_callback checker,
@@ -1859,6 +1897,8 @@ expression_tree_walker(Node *node,
case T_CaseTestExpr:
case T_SetToDefault:
case T_CurrentOfExpr:
+ case T_NextValueExpr:
+ case T_SQLValueFunction:
case T_RangeTblRef:
case T_SortGroupClause:
/* primitive node types with no expression subnodes */
@@ -2025,9 +2065,8 @@ expression_tree_walker(Node *node,
/* we assume walker doesn't care about CaseWhens, either */
foreach(temp, caseexpr->args)
{
- CaseWhen *when = (CaseWhen *) lfirst(temp);
+ CaseWhen *when = lfirst_node(CaseWhen, temp);
- Assert(IsA(when, CaseWhen));
if (walker(when->expr, context))
return true;
if (walker(when->result, context))
@@ -2192,6 +2231,22 @@ expression_tree_walker(Node *node,
return true;
}
break;
+ case T_TableFunc:
+ {
+ TableFunc *tf = (TableFunc *) node;
+
+ if (walker(tf->ns_uris, context))
+ return true;
+ if (walker(tf->docexpr, context))
+ return true;
+ if (walker(tf->rowexpr, context))
+ return true;
+ if (walker(tf->colexprs, context))
+ return true;
+ if (walker(tf->coldefexprs, context))
+ return true;
+ }
+ break;
default:
elog(ERROR, "unrecognized node type: %d",
(int) nodeTag(node));
@@ -2283,6 +2338,7 @@ range_table_walker(List *rtable,
return true;
break;
case RTE_CTE:
+ case RTE_NAMEDTUPLESTORE:
/* nothing to do */
break;
case RTE_SUBQUERY:
@@ -2299,6 +2355,10 @@ range_table_walker(List *rtable,
if (walker(rte->functions, context))
return true;
break;
+ case RTE_TABLEFUNC:
+ if (walker(rte->tablefunc, context))
+ return true;
+ break;
case RTE_VALUES:
if (walker(rte->values_lists, context))
return true;
@@ -2438,6 +2498,8 @@ expression_tree_mutator(Node *node,
case T_CaseTestExpr:
case T_SetToDefault:
case T_CurrentOfExpr:
+ case T_NextValueExpr:
+ case T_SQLValueFunction:
case T_RangeTblRef:
case T_SortGroupClause:
return (Node *) copyObject(node);
@@ -2992,6 +3054,20 @@ expression_tree_mutator(Node *node,
return (Node *) newnode;
}
break;
+ case T_TableFunc:
+ {
+ TableFunc *tf = (TableFunc *) node;
+ TableFunc *newnode;
+
+ FLATCOPY(newnode, tf, TableFunc);
+ MUTATE(newnode->ns_uris, tf->ns_uris, List *);
+ MUTATE(newnode->docexpr, tf->docexpr, Node *);
+ MUTATE(newnode->rowexpr, tf->rowexpr, Node *);
+ MUTATE(newnode->colexprs, tf->colexprs, List *);
+ MUTATE(newnode->coldefexprs, tf->coldefexprs, List *);
+ return (Node *) newnode;
+ }
+ break;
default:
elog(ERROR, "unrecognized node type: %d",
(int) nodeTag(node));
@@ -3086,6 +3162,7 @@ range_table_mutator(List *rtable,
#ifdef PGXC
case RTE_REMOTE_DUMMY:
#endif /* PGXC */
+ case RTE_NAMEDTUPLESTORE:
/* nothing to do */
break;
case RTE_SUBQUERY:
@@ -3112,6 +3189,9 @@ range_table_mutator(List *rtable,
case RTE_FUNCTION:
MUTATE(newrte->functions, rte->functions, List *);
break;
+ case RTE_TABLEFUNC:
+ MUTATE(newrte->tablefunc, rte->tablefunc, TableFunc *);
+ break;
case RTE_VALUES:
MUTATE(newrte->values_lists, rte->values_lists, List *);
break;
@@ -3205,6 +3285,7 @@ raw_expression_tree_walker(Node *node,
{
case T_SetToDefault:
case T_CurrentOfExpr:
+ case T_SQLValueFunction:
case T_Integer:
case T_Float:
case T_String:
@@ -3242,9 +3323,8 @@ raw_expression_tree_walker(Node *node,
/* we assume walker doesn't care about CaseWhens, either */
foreach(temp, caseexpr->args)
{
- CaseWhen *when = (CaseWhen *) lfirst(temp);
+ CaseWhen *when = lfirst_node(CaseWhen, temp);
- Assert(IsA(when, CaseWhen));
if (walker(when->expr, context))
return true;
if (walker(when->result, context))
@@ -3536,6 +3616,32 @@ raw_expression_tree_walker(Node *node,
return true;
}
break;
+ case T_RangeTableFunc:
+ {
+ RangeTableFunc *rtf = (RangeTableFunc *) node;
+
+ if (walker(rtf->docexpr, context))
+ return true;
+ if (walker(rtf->rowexpr, context))
+ return true;
+ if (walker(rtf->namespaces, context))
+ return true;
+ if (walker(rtf->columns, context))
+ return true;
+ if (walker(rtf->alias, context))
+ return true;
+ }
+ break;
+ case T_RangeTableFuncCol:
+ {
+ RangeTableFuncCol *rtfc = (RangeTableFuncCol *) node;
+
+ if (walker(rtfc->colexpr, context))
+ return true;
+ if (walker(rtfc->coldefexpr, context))
+ return true;
+ }
+ break;
case T_TypeName:
{
TypeName *tn = (TypeName *) node;
@@ -3716,9 +3822,8 @@ planstate_walk_subplans(List *plans,
foreach(lc, plans)
{
- SubPlanState *sps = (SubPlanState *) lfirst(lc);
+ SubPlanState *sps = lfirst_node(SubPlanState, lc);
- Assert(IsA(sps, SubPlanState));
if (walker(sps->planstate, context))
return true;
}
diff --git a/src/backend/nodes/nodes.c b/src/backend/nodes/nodes.c
index aea3880858..d3345aae6d 100644
--- a/src/backend/nodes/nodes.c
+++ b/src/backend/nodes/nodes.c
@@ -4,7 +4,7 @@
* support code for nodes (now that we have removed the home-brew
* inheritance system, our support code for nodes is much simpler)
*
- * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 522387a3f8..d5165ddd4e 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -4,7 +4,7 @@
* Output functions for Postgres tree nodes.
*
* Portions Copyright (c) 2012-2014, TransLattice, Inc.
- * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
@@ -118,7 +118,7 @@ set_portable_output(bool value)
/* Write a character-string (possibly NULL) field */
#define WRITE_STRING_FIELD(fldname) \
(appendStringInfo(str, " :" CppAsString(fldname) " "), \
- _outToken(str, node->fldname))
+ outToken(str, node->fldname))
/* Write a parse location field (actually same as INT case) */
#define WRITE_LOCATION_FIELD(fldname) \
@@ -134,7 +134,7 @@ set_portable_output(bool value)
/* Write a bitmapset field */
#define WRITE_BITMAPSET_FIELD(fldname) \
(appendStringInfo(str, " :" CppAsString(fldname) " "), \
- _outBitmapset(str, node->fldname))
+ outBitmapset(str, node->fldname))
#ifdef XCP
#define NSP_NAME(oid) \
@@ -146,9 +146,9 @@ set_portable_output(bool value)
*/
#define WRITE_RELID_INTERNAL(relid) \
- (_outToken(str, OidIsValid((relid)) ? NSP_NAME(get_rel_namespace((relid))) : NULL), \
+ (outToken(str, OidIsValid((relid)) ? NSP_NAME(get_rel_namespace((relid))) : NULL), \
appendStringInfoChar(str, ' '), \
- _outToken(str, OidIsValid((relid)) ? get_rel_name((relid)) : NULL))
+ outToken(str, OidIsValid((relid)) ? get_rel_name((relid)) : NULL))
/* write an OID which is a relation OID */
#define WRITE_RELID_FIELD(fldname) \
@@ -179,9 +179,9 @@ set_portable_output(bool value)
/* write an OID which is a data type OID */
#define WRITE_TYPID_FIELD(fldname) \
(appendStringInfo(str, " :" CppAsString(fldname) " "), \
- _outToken(str, OidIsValid(node->fldname) ? NSP_NAME(get_typ_namespace(node->fldname)) : NULL), \
+ outToken(str, OidIsValid(node->fldname) ? NSP_NAME(get_typ_namespace(node->fldname)) : NULL), \
appendStringInfoChar(str, ' '), \
- _outToken(str, OidIsValid(node->fldname) ? get_typ_name(node->fldname) : NULL))
+ outToken(str, OidIsValid(node->fldname) ? get_typ_name(node->fldname) : NULL))
/* write an OID which is a function OID */
#define WRITE_FUNCID_FIELD(fldname) \
@@ -191,18 +191,18 @@ set_portable_output(bool value)
{ \
Oid *argtypes; \
int i, nargs; \
- _outToken(str, NSP_NAME(get_func_namespace(node->fldname))); \
+ outToken(str, NSP_NAME(get_func_namespace(node->fldname))); \
appendStringInfoChar(str, ' '); \
- _outToken(str, get_func_name(node->fldname)); \
+ outToken(str, get_func_name(node->fldname)); \
appendStringInfoChar(str, ' '); \
get_func_signature(node->fldname, &argtypes, &nargs); \
appendStringInfo(str, "%d", nargs); \
for (i = 0; i < nargs; i++) \
{ \
appendStringInfoChar(str, ' '); \
- _outToken(str, NSP_NAME(get_typ_namespace(argtypes[i]))); \
+ outToken(str, NSP_NAME(get_typ_namespace(argtypes[i]))); \
appendStringInfoChar(str, ' '); \
- _outToken(str, get_typ_name(argtypes[i])); \
+ outToken(str, get_typ_name(argtypes[i])); \
} \
} \
else \
@@ -216,20 +216,20 @@ set_portable_output(bool value)
if (OidIsValid(node->fldname)) \
{ \
Oid oprleft, oprright; \
- _outToken(str, NSP_NAME(get_opnamespace(node->fldname))); \
+ outToken(str, NSP_NAME(get_opnamespace(node->fldname))); \
appendStringInfoChar(str, ' '); \
- _outToken(str, get_opname(node->fldname)); \
+ outToken(str, get_opname(node->fldname)); \
appendStringInfoChar(str, ' '); \
op_input_types(node->fldname, &oprleft, &oprright); \
- _outToken(str, OidIsValid(oprleft) ? \
+ outToken(str, OidIsValid(oprleft) ? \
NSP_NAME(get_typ_namespace(oprleft)) : NULL); \
appendStringInfoChar(str, ' '); \
- _outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL); \
+ outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL); \
appendStringInfoChar(str, ' '); \
- _outToken(str, OidIsValid(oprright) ? \
+ outToken(str, OidIsValid(oprright) ? \
NSP_NAME(get_typ_namespace(oprright)) : NULL); \
appendStringInfoChar(str, ' '); \
- _outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL); \
+ outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL); \
appendStringInfoChar(str, ' '); \
} \
else \
@@ -242,9 +242,9 @@ set_portable_output(bool value)
appendStringInfo(str, " :" CppAsString(fldname) " "); \
if (OidIsValid(node->fldname)) \
{ \
- _outToken(str, NSP_NAME(get_collation_namespace(node->fldname))); \
+ outToken(str, NSP_NAME(get_collation_namespace(node->fldname))); \
appendStringInfoChar(str, ' '); \
- _outToken(str, get_collation_name(node->fldname)); \
+ outToken(str, get_collation_name(node->fldname)); \
appendStringInfo(str, " %d", get_collation_encoding(node->fldname)); \
} \
else \
@@ -258,14 +258,14 @@ set_portable_output(bool value)
/*
- * _outToken
+ * outToken
* Convert an ordinary string (eg, an identifier) into a form that
* will be decoded back to a plain token by read.c's functions.
*
* If a null or empty string is given, it is encoded as "<>".
*/
-static void
-_outToken(StringInfo str, const char *s)
+void
+outToken(StringInfo str, const char *s)
{
if (s == NULL || *s == '\0')
{
@@ -296,13 +296,6 @@ _outToken(StringInfo str, const char *s)
}
}
-/* for use by extensions which define extensible nodes */
-void
-outToken(StringInfo str, const char *s)
-{
- _outToken(str, s);
-}
-
static void
_outList(StringInfo str, const List *node)
{
@@ -341,13 +334,13 @@ _outList(StringInfo str, const List *node)
}
/*
- * _outBitmapset -
+ * outBitmapset -
* converts a bitmap set of integers
*
* Note: the output format is "(b int int ...)", similar to an integer List.
*/
-static void
-_outBitmapset(StringInfo str, const Bitmapset *bms)
+void
+outBitmapset(StringInfo str, const Bitmapset *bms)
{
int x;
@@ -359,13 +352,6 @@ _outBitmapset(StringInfo str, const Bitmapset *bms)
appendStringInfoChar(str, ')');
}
-/* for use by extensions which define extensible nodes */
-void
-outBitmapset(StringInfo str, const Bitmapset *bms)
-{
- _outBitmapset(str, bms);
-}
-
/*
* Print the value of a Datum given its type.
*/
@@ -437,7 +423,7 @@ _printDatum(StringInfo str, Datum value, Oid typid)
DateStyle = USE_ISO_DATES;
textvalue = DatumGetCString(FunctionCall1(&finfo, tmpval));
- _outToken(str, textvalue);
+ outToken(str, textvalue);
DateStyle = saveDateStyle;
}
@@ -464,13 +450,17 @@ _outPlannedStmt(StringInfo str, const PlannedStmt *node)
WRITE_NODE_FIELD(planTree);
WRITE_NODE_FIELD(rtable);
WRITE_NODE_FIELD(resultRelations);
- WRITE_NODE_FIELD(utilityStmt);
+ WRITE_NODE_FIELD(nonleafResultRelations);
+ WRITE_NODE_FIELD(rootResultRelations);
WRITE_NODE_FIELD(subplans);
WRITE_BITMAPSET_FIELD(rewindPlanIDs);
WRITE_NODE_FIELD(rowMarks);
WRITE_NODE_FIELD(relationOids);
WRITE_NODE_FIELD(invalItems);
WRITE_INT_FIELD(nParamExec);
+ WRITE_NODE_FIELD(utilityStmt);
+ WRITE_LOCATION_FIELD(stmt_location);
+ WRITE_LOCATION_FIELD(stmt_len);
}
/*
@@ -484,6 +474,7 @@ _outPlanInfo(StringInfo str, const Plan *node)
WRITE_FLOAT_FIELD(plan_rows, "%.0f");
WRITE_INT_FIELD(plan_width);
WRITE_BOOL_FIELD(parallel_aware);
+ WRITE_BOOL_FIELD(parallel_safe);
WRITE_INT_FIELD(plan_node_id);
WRITE_NODE_FIELD(targetlist);
WRITE_NODE_FIELD(qual);
@@ -514,6 +505,7 @@ _outJoinPlanInfo(StringInfo str, const Join *node)
_outPlanInfo(str, (const Plan *) node);
WRITE_ENUM_FIELD(jointype, JoinType);
+ WRITE_BOOL_FIELD(inner_unique);
WRITE_NODE_FIELD(joinqual);
}
@@ -537,6 +529,14 @@ _outResult(StringInfo str, const Result *node)
}
static void
+_outProjectSet(StringInfo str, const ProjectSet *node)
+{
+ WRITE_NODE_TYPE("PROJECTSET");
+
+ _outPlanInfo(str, (const Plan *) node);
+}
+
+static void
_outModifyTable(StringInfo str, const ModifyTable *node)
{
WRITE_NODE_TYPE("MODIFYTABLE");
@@ -546,8 +546,10 @@ _outModifyTable(StringInfo str, const ModifyTable *node)
WRITE_ENUM_FIELD(operation, CmdType);
WRITE_BOOL_FIELD(canSetTag);
WRITE_UINT_FIELD(nominalRelation);
+ WRITE_NODE_FIELD(partitioned_rels);
WRITE_NODE_FIELD(resultRelations);
WRITE_INT_FIELD(resultRelIndex);
+ WRITE_INT_FIELD(rootResultRelIndex);
WRITE_NODE_FIELD(plans);
WRITE_NODE_FIELD(withCheckOptionLists);
WRITE_NODE_FIELD(returningLists);
@@ -579,6 +581,7 @@ _outAppend(StringInfo str, const Append *node)
_outPlanInfo(str, (const Plan *) node);
+ WRITE_NODE_FIELD(partitioned_rels);
WRITE_NODE_FIELD(appendplans);
}
@@ -591,6 +594,7 @@ _outMergeAppend(StringInfo str, const MergeAppend *node)
_outPlanInfo(str, (const Plan *) node);
+ WRITE_NODE_FIELD(partitioned_rels);
WRITE_NODE_FIELD(mergeplans);
WRITE_INT_FIELD(numCols);
@@ -609,20 +613,20 @@ _outMergeAppend(StringInfo str, const MergeAppend *node)
/* Sort operator is always valid */
Assert(OidIsValid(oper));
appendStringInfoChar(str, ' ');
- _outToken(str, NSP_NAME(get_opnamespace(oper)));
+ outToken(str, NSP_NAME(get_opnamespace(oper)));
appendStringInfoChar(str, ' ');
- _outToken(str, get_opname(oper));
+ outToken(str, get_opname(oper));
appendStringInfoChar(str, ' ');
op_input_types(oper, &oprleft, &oprright);
- _outToken(str, OidIsValid(oprleft) ?
+ outToken(str, OidIsValid(oprleft) ?
NSP_NAME(get_typ_namespace(oprleft)) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL);
+ outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprright) ?
+ outToken(str, OidIsValid(oprright) ?
NSP_NAME(get_typ_namespace(oprright)) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL);
+ outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL);
}
else
#endif
@@ -637,9 +641,9 @@ _outMergeAppend(StringInfo str, const MergeAppend *node)
if (OidIsValid(coll))
{
appendStringInfoChar(str, ' ');
- _outToken(str, NSP_NAME(get_collation_namespace(coll)));
+ outToken(str, NSP_NAME(get_collation_namespace(coll)));
appendStringInfoChar(str, ' ');
- _outToken(str, get_collation_name(coll));
+ outToken(str, get_collation_name(coll));
appendStringInfo(str, " %d", get_collation_encoding(coll));
}
else
@@ -680,20 +684,20 @@ _outRecursiveUnion(StringInfo str, const RecursiveUnion *node)
/* Unique operator is always valid */
Assert(OidIsValid(oper));
appendStringInfoChar(str, ' ');
- _outToken(str, NSP_NAME(get_opnamespace(oper)));
+ outToken(str, NSP_NAME(get_opnamespace(oper)));
appendStringInfoChar(str, ' ');
- _outToken(str, get_opname(oper));
+ outToken(str, get_opname(oper));
appendStringInfoChar(str, ' ');
op_input_types(oper, &oprleft, &oprright);
- _outToken(str, OidIsValid(oprleft) ?
+ outToken(str, OidIsValid(oprleft) ?
NSP_NAME(get_typ_namespace(oprleft)) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL);
+ outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprright) ?
+ outToken(str, OidIsValid(oprright) ?
NSP_NAME(get_typ_namespace(oprright)) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL);
+ outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL);
appendStringInfoChar(str, ' ');
}
else
@@ -720,6 +724,7 @@ _outBitmapOr(StringInfo str, const BitmapOr *node)
_outPlanInfo(str, (const Plan *) node);
+ WRITE_BOOL_FIELD(isshared);
WRITE_NODE_FIELD(bitmapplans);
}
@@ -736,6 +741,35 @@ _outGather(StringInfo str, const Gather *node)
}
static void
+_outGatherMerge(StringInfo str, const GatherMerge *node)
+{
+ int i;
+
+ WRITE_NODE_TYPE("GATHERMERGE");
+
+ _outPlanInfo(str, (const Plan *) node);
+
+ WRITE_INT_FIELD(num_workers);
+ WRITE_INT_FIELD(numCols);
+
+ appendStringInfoString(str, " :sortColIdx");
+ for (i = 0; i < node->numCols; i++)
+ appendStringInfo(str, " %d", node->sortColIdx[i]);
+
+ appendStringInfoString(str, " :sortOperators");
+ for (i = 0; i < node->numCols; i++)
+ appendStringInfo(str, " %u", node->sortOperators[i]);
+
+ appendStringInfoString(str, " :collations");
+ for (i = 0; i < node->numCols; i++)
+ appendStringInfo(str, " %u", node->collations[i]);
+
+ appendStringInfoString(str, " :nullsFirst");
+ for (i = 0; i < node->numCols; i++)
+ appendStringInfo(str, " %s", booltostr(node->nullsFirst[i]));
+}
+
+static void
_outScan(StringInfo str, const Scan *node)
{
WRITE_NODE_TYPE("SCAN");
@@ -857,6 +891,7 @@ _outBitmapIndexScan(StringInfo str, const BitmapIndexScan *node)
else
#endif
WRITE_OID_FIELD(indexid);
+ WRITE_BOOL_FIELD(isshared);
WRITE_NODE_FIELD(indexqual);
WRITE_NODE_FIELD(indexqualorig);
}
@@ -903,6 +938,16 @@ _outFunctionScan(StringInfo str, const FunctionScan *node)
}
static void
+_outTableFuncScan(StringInfo str, const TableFuncScan *node)
+{
+ WRITE_NODE_TYPE("TABLEFUNCSCAN");
+
+ _outScanInfo(str, (const Scan *) node);
+
+ WRITE_NODE_FIELD(tablefunc);
+}
+
+static void
_outValuesScan(StringInfo str, const ValuesScan *node)
{
WRITE_NODE_TYPE("VALUESSCAN");
@@ -924,6 +969,16 @@ _outCteScan(StringInfo str, const CteScan *node)
}
static void
+_outNamedTuplestoreScan(StringInfo str, const NamedTuplestoreScan *node)
+{
+ WRITE_NODE_TYPE("NAMEDTUPLESTORESCAN");
+
+ _outScanInfo(str, (const Scan *) node);
+
+ WRITE_STRING_FIELD(enrname);
+}
+
+static void
_outWorkTableScan(StringInfo str, const WorkTableScan *node)
{
WRITE_NODE_TYPE("WORKTABLESCAN");
@@ -965,7 +1020,7 @@ _outCustomScan(StringInfo str, const CustomScan *node)
WRITE_BITMAPSET_FIELD(custom_relids);
/* CustomName is a key to lookup CustomScanMethods */
appendStringInfoString(str, " :methods ");
- _outToken(str, node->methods->CustomName);
+ outToken(str, node->methods->CustomName);
}
static void
@@ -996,6 +1051,7 @@ _outMergeJoin(StringInfo str, const MergeJoin *node)
_outJoinPlanInfo(str, (const Join *) node);
+ WRITE_BOOL_FIELD(skip_mark_restore);
WRITE_NODE_FIELD(mergeclauses);
numCols = list_length(node->mergeclauses);
@@ -1013,9 +1069,9 @@ _outMergeJoin(StringInfo str, const MergeJoin *node)
if (OidIsValid(coll))
{
appendStringInfoChar(str, ' ');
- _outToken(str, NSP_NAME(get_collation_namespace(coll)));
+ outToken(str, NSP_NAME(get_collation_namespace(coll)));
appendStringInfoChar(str, ' ');
- _outToken(str, get_collation_name(coll));
+ outToken(str, get_collation_name(coll));
appendStringInfo(str, " %d", get_collation_encoding(coll));
}
else
@@ -1071,20 +1127,20 @@ _outAgg(StringInfo str, const Agg *node)
/* Group operator is always valid */
Assert(OidIsValid(oper));
appendStringInfoChar(str, ' ');
- _outToken(str, NSP_NAME(get_opnamespace(oper)));
+ outToken(str, NSP_NAME(get_opnamespace(oper)));
appendStringInfoChar(str, ' ');
- _outToken(str, get_opname(oper));
+ outToken(str, get_opname(oper));
appendStringInfoChar(str, ' ');
op_input_types(oper, &oprleft, &oprright);
- _outToken(str, OidIsValid(oprleft) ?
+ outToken(str, OidIsValid(oprleft) ?
NSP_NAME(get_typ_namespace(oprleft)) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL);
+ outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprright) ?
+ outToken(str, OidIsValid(oprright) ?
NSP_NAME(get_typ_namespace(oprright)) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL);
+ outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL);
appendStringInfoChar(str, ' ');
}
else
@@ -1092,6 +1148,7 @@ _outAgg(StringInfo str, const Agg *node)
appendStringInfo(str, " %u", node->grpOperators[i]);
WRITE_LONG_FIELD(numGroups);
+ WRITE_BITMAPSET_FIELD(aggParams);
WRITE_NODE_FIELD(groupingSets);
WRITE_NODE_FIELD(chain);
}
@@ -1122,20 +1179,20 @@ _outWindowAgg(StringInfo str, const WindowAgg *node)
/* The operator is always valid */
Assert(OidIsValid(oper));
appendStringInfoChar(str, ' ');
- _outToken(str, NSP_NAME(get_opnamespace(oper)));
+ outToken(str, NSP_NAME(get_opnamespace(oper)));
appendStringInfoChar(str, ' ');
- _outToken(str, get_opname(oper));
+ outToken(str, get_opname(oper));
appendStringInfoChar(str, ' ');
op_input_types(oper, &oprleft, &oprright);
- _outToken(str, OidIsValid(oprleft) ?
+ outToken(str, OidIsValid(oprleft) ?
NSP_NAME(get_typ_namespace(oprleft)) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL);
+ outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprright) ?
+ outToken(str, OidIsValid(oprright) ?
NSP_NAME(get_typ_namespace(oprright)) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL);
+ outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL);
appendStringInfoChar(str, ' ');
}
else
@@ -1158,20 +1215,20 @@ _outWindowAgg(StringInfo str, const WindowAgg *node)
/* Group operator is always valid */
Assert(OidIsValid(oper));
appendStringInfoChar(str, ' ');
- _outToken(str, NSP_NAME(get_opnamespace(oper)));
+ outToken(str, NSP_NAME(get_opnamespace(oper)));
appendStringInfoChar(str, ' ');
- _outToken(str, get_opname(oper));
+ outToken(str, get_opname(oper));
appendStringInfoChar(str, ' ');
op_input_types(oper, &oprleft, &oprright);
- _outToken(str, OidIsValid(oprleft) ?
+ outToken(str, OidIsValid(oprleft) ?
NSP_NAME(get_typ_namespace(oprleft)) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL);
+ outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprright) ?
+ outToken(str, OidIsValid(oprright) ?
NSP_NAME(get_typ_namespace(oprright)) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL);
+ outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL);
appendStringInfoChar(str, ' ');
}
else
@@ -1208,20 +1265,20 @@ _outGroup(StringInfo str, const Group *node)
/* Group operator is always valid */
Assert(OidIsValid(oper));
appendStringInfoChar(str, ' ');
- _outToken(str, NSP_NAME(get_opnamespace(oper)));
+ outToken(str, NSP_NAME(get_opnamespace(oper)));
appendStringInfoChar(str, ' ');
- _outToken(str, get_opname(oper));
+ outToken(str, get_opname(oper));
appendStringInfoChar(str, ' ');
op_input_types(oper, &oprleft, &oprright);
- _outToken(str, OidIsValid(oprleft) ?
+ outToken(str, OidIsValid(oprleft) ?
NSP_NAME(get_typ_namespace(oprleft)) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL);
+ outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprright) ?
+ outToken(str, OidIsValid(oprright) ?
NSP_NAME(get_typ_namespace(oprright)) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL);
+ outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL);
appendStringInfoChar(str, ' ');
}
else
@@ -1262,20 +1319,20 @@ _outSort(StringInfo str, const Sort *node)
/* Sort operator is always valid */
Assert(OidIsValid(oper));
appendStringInfoChar(str, ' ');
- _outToken(str, NSP_NAME(get_opnamespace(oper)));
+ outToken(str, NSP_NAME(get_opnamespace(oper)));
appendStringInfoChar(str, ' ');
- _outToken(str, get_opname(oper));
+ outToken(str, get_opname(oper));
appendStringInfoChar(str, ' ');
op_input_types(oper, &oprleft, &oprright);
- _outToken(str, OidIsValid(oprleft) ?
+ outToken(str, OidIsValid(oprleft) ?
NSP_NAME(get_typ_namespace(oprleft)) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL);
+ outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprright) ?
+ outToken(str, OidIsValid(oprright) ?
NSP_NAME(get_typ_namespace(oprright)) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL);
+ outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL);
}
else
#endif
@@ -1290,9 +1347,9 @@ _outSort(StringInfo str, const Sort *node)
if (OidIsValid(coll))
{
appendStringInfoChar(str, ' ');
- _outToken(str, NSP_NAME(get_collation_namespace(coll)));
+ outToken(str, NSP_NAME(get_collation_namespace(coll)));
appendStringInfoChar(str, ' ');
- _outToken(str, get_collation_name(coll));
+ outToken(str, get_collation_name(coll));
appendStringInfo(str, " %d", get_collation_encoding(coll));
}
else
@@ -1332,20 +1389,20 @@ _outUnique(StringInfo str, const Unique *node)
/* Unique operator is always valid */
Assert(OidIsValid(oper));
appendStringInfoChar(str, ' ');
- _outToken(str, NSP_NAME(get_opnamespace(oper)));
+ outToken(str, NSP_NAME(get_opnamespace(oper)));
appendStringInfoChar(str, ' ');
- _outToken(str, get_opname(oper));
+ outToken(str, get_opname(oper));
appendStringInfoChar(str, ' ');
op_input_types(oper, &oprleft, &oprright);
- _outToken(str, OidIsValid(oprleft) ?
+ outToken(str, OidIsValid(oprleft) ?
NSP_NAME(get_typ_namespace(oprleft)) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL);
+ outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprright) ?
+ outToken(str, OidIsValid(oprright) ?
NSP_NAME(get_typ_namespace(oprright)) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL);
+ outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL);
appendStringInfoChar(str, ' ');
}
else
@@ -1368,13 +1425,6 @@ _outHash(StringInfo str, const Hash *node)
WRITE_OID_FIELD(skewTable);
WRITE_INT_FIELD(skewColumn);
WRITE_BOOL_FIELD(skewInherit);
-#ifdef XCP
- if (portable_output)
- WRITE_TYPID_FIELD(skewColType);
- else
-#endif
- WRITE_OID_FIELD(skewColType);
- WRITE_INT_FIELD(skewColTypmod);
}
static void
@@ -1404,20 +1454,20 @@ _outSetOp(StringInfo str, const SetOp *node)
/* Unique operator is always valid */
Assert(OidIsValid(oper));
appendStringInfoChar(str, ' ');
- _outToken(str, NSP_NAME(get_opnamespace(oper)));
+ outToken(str, NSP_NAME(get_opnamespace(oper)));
appendStringInfoChar(str, ' ');
- _outToken(str, get_opname(oper));
+ outToken(str, get_opname(oper));
appendStringInfoChar(str, ' ');
op_input_types(oper, &oprleft, &oprright);
- _outToken(str, OidIsValid(oprleft) ?
+ outToken(str, OidIsValid(oprleft) ?
NSP_NAME(get_typ_namespace(oprleft)) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL);
+ outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprright) ?
+ outToken(str, OidIsValid(oprright) ?
NSP_NAME(get_typ_namespace(oprright)) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL);
+ outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL);
}
else
#endif
@@ -1503,9 +1553,9 @@ _outRemoteStmt(StringInfo str, const RemoteStmt *node)
Oid ptype = rparam->paramtype;
Assert(OidIsValid(ptype));
appendStringInfoChar(str, ' ');
- _outToken(str, NSP_NAME(get_typ_namespace(ptype)));
+ outToken(str, NSP_NAME(get_typ_namespace(ptype)));
appendStringInfoChar(str, ' ');
- _outToken(str, get_typ_name(ptype));
+ outToken(str, get_typ_name(ptype));
}
else
appendStringInfo(str, " %u", rparam->paramtype);
@@ -1539,20 +1589,20 @@ _outSimpleSort(StringInfo str, const SimpleSort *node)
/* Sort operator is always valid */
Assert(OidIsValid(oper));
appendStringInfoChar(str, ' ');
- _outToken(str, NSP_NAME(get_opnamespace(oper)));
+ outToken(str, NSP_NAME(get_opnamespace(oper)));
appendStringInfoChar(str, ' ');
- _outToken(str, get_opname(oper));
+ outToken(str, get_opname(oper));
appendStringInfoChar(str, ' ');
op_input_types(oper, &oprleft, &oprright);
- _outToken(str, OidIsValid(oprleft) ?
+ outToken(str, OidIsValid(oprleft) ?
NSP_NAME(get_typ_namespace(oprleft)) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL);
+ outToken(str, OidIsValid(oprleft) ? get_typ_name(oprleft) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprright) ?
+ outToken(str, OidIsValid(oprright) ?
NSP_NAME(get_typ_namespace(oprright)) : NULL);
appendStringInfoChar(str, ' ');
- _outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL);
+ outToken(str, OidIsValid(oprright) ? get_typ_name(oprright) : NULL);
}
else
appendStringInfo(str, " %u", node->sortOperators[i]);
@@ -1565,9 +1615,9 @@ _outSimpleSort(StringInfo str, const SimpleSort *node)
if (OidIsValid(coll))
{
appendStringInfoChar(str, ' ');
- _outToken(str, NSP_NAME(get_collation_namespace(coll)));
+ outToken(str, NSP_NAME(get_collation_namespace(coll)));
appendStringInfoChar(str, ' ');
- _outToken(str, get_collation_name(coll));
+ outToken(str, get_collation_name(coll));
appendStringInfo(str, " %d", get_collation_encoding(coll));
}
else
@@ -1641,13 +1691,33 @@ _outRangeVar(StringInfo str, const RangeVar *node)
*/
WRITE_STRING_FIELD(schemaname);
WRITE_STRING_FIELD(relname);
- WRITE_ENUM_FIELD(inhOpt, InhOption);
+ WRITE_BOOL_FIELD(inh);
WRITE_CHAR_FIELD(relpersistence);
WRITE_NODE_FIELD(alias);
WRITE_LOCATION_FIELD(location);
}
static void
+_outTableFunc(StringInfo str, const TableFunc *node)
+{
+ WRITE_NODE_TYPE("TABLEFUNC");
+
+ WRITE_NODE_FIELD(ns_names);
+ WRITE_NODE_FIELD(ns_uris);
+ WRITE_NODE_FIELD(docexpr);
+ WRITE_NODE_FIELD(rowexpr);
+ WRITE_NODE_FIELD(colnames);
+ WRITE_NODE_FIELD(coltypes);
+ WRITE_NODE_FIELD(coltypmods);
+ WRITE_NODE_FIELD(colcollations);
+ WRITE_NODE_FIELD(colexprs);
+ WRITE_NODE_FIELD(coldefexprs);
+ WRITE_BITMAPSET_FIELD(notnulls);
+ WRITE_INT_FIELD(ordinalitycol);
+ WRITE_LOCATION_FIELD(location);
+}
+
+static void
_outIntoClause(StringInfo str, const IntoClause *node)
{
WRITE_NODE_TYPE("INTOCLAUSE");
@@ -2089,7 +2159,7 @@ _outBoolExpr(StringInfo str, const BoolExpr *node)
break;
}
appendStringInfoString(str, " :boolop ");
- _outToken(str, opstr);
+ outToken(str, opstr);
WRITE_NODE_FIELD(args);
WRITE_LOCATION_FIELD(location);
@@ -2133,6 +2203,7 @@ _outSubPlan(StringInfo str, const SubPlan *node)
WRITE_OID_FIELD(firstColCollation);
WRITE_BOOL_FIELD(useHashTable);
WRITE_BOOL_FIELD(unknownEqFalse);
+ WRITE_BOOL_FIELD(parallel_safe);
WRITE_NODE_FIELD(setParam);
WRITE_NODE_FIELD(parParam);
WRITE_NODE_FIELD(args);
@@ -2448,6 +2519,17 @@ _outMinMaxExpr(StringInfo str, const MinMaxExpr *node)
}
static void
+_outSQLValueFunction(StringInfo str, const SQLValueFunction *node)
+{
+ WRITE_NODE_TYPE("SQLVALUEFUNCTION");
+
+ WRITE_ENUM_FIELD(op, SQLValueFunctionOp);
+ WRITE_OID_FIELD(type);
+ WRITE_INT_FIELD(typmod);
+ WRITE_LOCATION_FIELD(location);
+}
+
+static void
_outXmlExpr(StringInfo str, const XmlExpr *node)
{
WRITE_NODE_TYPE("XMLEXPR");
@@ -2661,14 +2743,14 @@ _outPathInfo(StringInfo str, const Path *node)
{
WRITE_ENUM_FIELD(pathtype, NodeTag);
appendStringInfoString(str, " :parent_relids ");
- _outBitmapset(str, node->parent->relids);
+ outBitmapset(str, node->parent->relids);
if (node->pathtarget != node->parent->reltarget)
WRITE_NODE_FIELD(pathtarget);
appendStringInfoString(str, " :required_outer ");
if (node->param_info)
- _outBitmapset(str, node->param_info->ppi_req_outer);
+ outBitmapset(str, node->param_info->ppi_req_outer);
else
- _outBitmapset(str, NULL);
+ outBitmapset(str, NULL);
WRITE_BOOL_FIELD(parallel_aware);
WRITE_BOOL_FIELD(parallel_safe);
WRITE_INT_FIELD(parallel_workers);
@@ -2687,6 +2769,7 @@ _outJoinPathInfo(StringInfo str, const JoinPath *node)
_outPathInfo(str, (const Path *) node);
WRITE_ENUM_FIELD(jointype, JoinType);
+ WRITE_BOOL_FIELD(inner_unique);
WRITE_NODE_FIELD(outerjoinpath);
WRITE_NODE_FIELD(innerjoinpath);
WRITE_NODE_FIELD(joinrestrictinfo);
@@ -2793,7 +2876,7 @@ _outCustomPath(StringInfo str, const CustomPath *node)
WRITE_NODE_FIELD(custom_paths);
WRITE_NODE_FIELD(custom_private);
appendStringInfoString(str, " :methods ");
- _outToken(str, node->methods->CustomName);
+ outToken(str, node->methods->CustomName);
}
static void
@@ -2803,6 +2886,7 @@ _outAppendPath(StringInfo str, const AppendPath *node)
_outPathInfo(str, (const Path *) node);
+ WRITE_NODE_FIELD(partitioned_rels);
WRITE_NODE_FIELD(subpaths);
}
@@ -2813,6 +2897,7 @@ _outMergeAppendPath(StringInfo str, const MergeAppendPath *node)
_outPathInfo(str, (const Path *) node);
+ WRITE_NODE_FIELD(partitioned_rels);
WRITE_NODE_FIELD(subpaths);
WRITE_FLOAT_FIELD(limit_tuples, "%.0f");
}
@@ -2859,6 +2944,7 @@ _outGatherPath(StringInfo str, const GatherPath *node)
WRITE_NODE_FIELD(subpath);
WRITE_BOOL_FIELD(single_copy);
+ WRITE_INT_FIELD(num_workers);
}
static void
@@ -2873,6 +2959,16 @@ _outProjectionPath(StringInfo str, const ProjectionPath *node)
}
static void
+_outProjectSetPath(StringInfo str, const ProjectSetPath *node)
+{
+ WRITE_NODE_TYPE("PROJECTSETPATH");
+
+ _outPathInfo(str, (const Path *) node);
+
+ WRITE_NODE_FIELD(subpath);
+}
+
+static void
_outSortPath(StringInfo str, const SortPath *node)
{
WRITE_NODE_TYPE("SORTPATH");
@@ -2921,6 +3017,28 @@ _outAggPath(StringInfo str, const AggPath *node)
}
static void
+_outRollupData(StringInfo str, const RollupData *node)
+{
+ WRITE_NODE_TYPE("ROLLUP");
+
+ WRITE_NODE_FIELD(groupClause);
+ WRITE_NODE_FIELD(gsets);
+ WRITE_NODE_FIELD(gsets_data);
+ WRITE_FLOAT_FIELD(numGroups, "%.0f");
+ WRITE_BOOL_FIELD(hashable);
+ WRITE_BOOL_FIELD(is_hashed);
+}
+
+static void
+_outGroupingSetData(StringInfo str, const GroupingSetData *node)
+{
+ WRITE_NODE_TYPE("GSDATA");
+
+ WRITE_NODE_FIELD(set);
+ WRITE_FLOAT_FIELD(numGroups, "%.0f");
+}
+
+static void
_outGroupingSetsPath(StringInfo str, const GroupingSetsPath *node)
{
WRITE_NODE_TYPE("GROUPINGSETSPATH");
@@ -2928,8 +3046,8 @@ _outGroupingSetsPath(StringInfo str, const GroupingSetsPath *node)
_outPathInfo(str, (const Path *) node);
WRITE_NODE_FIELD(subpath);
- WRITE_NODE_FIELD(rollup_groupclauses);
- WRITE_NODE_FIELD(rollup_lists);
+ WRITE_ENUM_FIELD(aggstrategy, AggStrategy);
+ WRITE_NODE_FIELD(rollups);
WRITE_NODE_FIELD(qual);
}
@@ -3008,6 +3126,7 @@ _outModifyTablePath(StringInfo str, const ModifyTablePath *node)
WRITE_ENUM_FIELD(operation, CmdType);
WRITE_BOOL_FIELD(canSetTag);
WRITE_UINT_FIELD(nominalRelation);
+ WRITE_NODE_FIELD(partitioned_rels);
WRITE_NODE_FIELD(resultRelations);
WRITE_NODE_FIELD(subpaths);
WRITE_NODE_FIELD(subroots);
@@ -3031,6 +3150,17 @@ _outLimitPath(StringInfo str, const LimitPath *node)
}
static void
+_outGatherMergePath(StringInfo str, const GatherMergePath *node)
+{
+ WRITE_NODE_TYPE("GATHERMERGEPATH");
+
+ _outPathInfo(str, (const Path *) node);
+
+ WRITE_NODE_FIELD(subpath);
+ WRITE_INT_FIELD(num_workers);
+}
+
+static void
_outNestPath(StringInfo str, const NestPath *node)
{
WRITE_NODE_TYPE("NESTPATH");
@@ -3048,6 +3178,7 @@ _outMergePath(StringInfo str, const MergePath *node)
WRITE_NODE_FIELD(path_mergeclauses);
WRITE_NODE_FIELD(outersortkeys);
WRITE_NODE_FIELD(innersortkeys);
+ WRITE_BOOL_FIELD(skip_mark_restore);
WRITE_BOOL_FIELD(materialize_inner);
}
@@ -3073,6 +3204,8 @@ _outPlannerGlobal(StringInfo str, const PlannerGlobal *node)
WRITE_NODE_FIELD(finalrtable);
WRITE_NODE_FIELD(finalrowmarks);
WRITE_NODE_FIELD(resultRelations);
+ WRITE_NODE_FIELD(nonleafResultRelations);
+ WRITE_NODE_FIELD(rootResultRelations);
WRITE_NODE_FIELD(relationOids);
WRITE_NODE_FIELD(invalItems);
WRITE_INT_FIELD(nParamExec);
@@ -3083,6 +3216,7 @@ _outPlannerGlobal(StringInfo str, const PlannerGlobal *node)
WRITE_BOOL_FIELD(dependsOnRole);
WRITE_BOOL_FIELD(parallelModeOK);
WRITE_BOOL_FIELD(parallelModeNeeded);
+ WRITE_CHAR_FIELD(maxParallelHazard);
}
static void
@@ -3110,6 +3244,7 @@ _outPlannerInfo(StringInfo str, const PlannerInfo *node)
WRITE_NODE_FIELD(full_join_clauses);
WRITE_NODE_FIELD(join_info_list);
WRITE_NODE_FIELD(append_rel_list);
+ WRITE_NODE_FIELD(pcinfo_list);
WRITE_NODE_FIELD(rowMarks);
WRITE_NODE_FIELD(placeholder_list);
WRITE_NODE_FIELD(fkey_list);
@@ -3123,6 +3258,7 @@ _outPlannerInfo(StringInfo str, const PlannerInfo *node)
WRITE_FLOAT_FIELD(total_table_pages, "%.0f");
WRITE_FLOAT_FIELD(tuple_fraction, "%.4f");
WRITE_FLOAT_FIELD(limit_tuples, "%.0f");
+ WRITE_UINT_FIELD(qual_security_level);
WRITE_BOOL_FIELD(hasInheritedTarget);
WRITE_BOOL_FIELD(hasJoinRTEs);
WRITE_BOOL_FIELD(hasLateralRTEs);
@@ -3165,6 +3301,7 @@ _outRelOptInfo(StringInfo str, const RelOptInfo *node)
WRITE_NODE_FIELD(lateral_vars);
WRITE_BITMAPSET_FIELD(lateral_referencers);
WRITE_NODE_FIELD(indexlist);
+ WRITE_NODE_FIELD(statlist);
WRITE_UINT_FIELD(pages);
WRITE_FLOAT_FIELD(tuples, "%.0f");
WRITE_FLOAT_FIELD(allvisfrac, "%.6f");
@@ -3175,9 +3312,12 @@ _outRelOptInfo(StringInfo str, const RelOptInfo *node)
WRITE_OID_FIELD(userid);
WRITE_BOOL_FIELD(useridiscurrent);
/* we don't try to print fdwroutine or fdw_private */
+ /* can't print unique_for_rels/non_unique_for_rels; BMSes aren't Nodes */
WRITE_NODE_FIELD(baserestrictinfo);
+ WRITE_UINT_FIELD(baserestrict_min_security);
WRITE_NODE_FIELD(joininfo);
WRITE_BOOL_FIELD(has_eclass_joins);
+ WRITE_BITMAPSET_FIELD(top_parent_relids);
}
static void
@@ -3237,6 +3377,18 @@ _outForeignKeyOptInfo(StringInfo str, const ForeignKeyOptInfo *node)
}
static void
+_outStatisticExtInfo(StringInfo str, const StatisticExtInfo *node)
+{
+ WRITE_NODE_TYPE("STATISTICEXTINFO");
+
+ /* NB: this isn't a complete set of fields */
+ WRITE_OID_FIELD(statOid);
+ /* don't write rel, leads to infinite recursion in plan tree dump */
+ WRITE_CHAR_FIELD(kind);
+ WRITE_BITMAPSET_FIELD(keys);
+}
+
+static void
_outEquivalenceClass(StringInfo str, const EquivalenceClass *node)
{
/*
@@ -3264,6 +3416,8 @@ _outEquivalenceClass(StringInfo str, const EquivalenceClass *node)
WRITE_BOOL_FIELD(ec_below_outer_join);
WRITE_BOOL_FIELD(ec_broken);
WRITE_UINT_FIELD(ec_sortref);
+ WRITE_UINT_FIELD(ec_min_security);
+ WRITE_UINT_FIELD(ec_max_security);
}
static void
@@ -3330,6 +3484,8 @@ _outRestrictInfo(StringInfo str, const RestrictInfo *node)
WRITE_BOOL_FIELD(outerjoin_delayed);
WRITE_BOOL_FIELD(can_join);
WRITE_BOOL_FIELD(pseudoconstant);
+ WRITE_BOOL_FIELD(leakproof);
+ WRITE_UINT_FIELD(security_level);
WRITE_BITMAPSET_FIELD(clause_relids);
WRITE_BITMAPSET_FIELD(required_relids);
WRITE_BITMAPSET_FIELD(outer_relids);
@@ -3397,6 +3553,15 @@ _outAppendRelInfo(StringInfo str, const AppendRelInfo *node)
}
static void
+_outPartitionedChildRelInfo(StringInfo str, const PartitionedChildRelInfo *node)
+{
+ WRITE_NODE_TYPE("PARTITIONEDCHILDRELINFO");
+
+ WRITE_UINT_FIELD(parent_relid);
+ WRITE_NODE_FIELD(child_rels);
+}
+
+static void
_outPlaceHolderInfo(StringInfo str, const PlaceHolderInfo *node)
{
WRITE_NODE_TYPE("PLACEHOLDERINFO");
@@ -3468,6 +3633,8 @@ _outCreateStmtInfo(StringInfo str, const CreateStmt *node)
WRITE_NODE_FIELD(relation);
WRITE_NODE_FIELD(tableElts);
WRITE_NODE_FIELD(inhRelations);
+ WRITE_NODE_FIELD(partspec);
+ WRITE_NODE_FIELD(partbound);
WRITE_NODE_FIELD(ofTypename);
WRITE_NODE_FIELD(constraints);
WRITE_NODE_FIELD(options);
@@ -3535,6 +3702,18 @@ _outIndexStmt(StringInfo str, const IndexStmt *node)
}
static void
+_outCreateStatsStmt(StringInfo str, const CreateStatsStmt *node)
+{
+ WRITE_NODE_TYPE("CREATESTATSSTMT");
+
+ WRITE_NODE_FIELD(defnames);
+ WRITE_NODE_FIELD(stat_types);
+ WRITE_NODE_FIELD(exprs);
+ WRITE_NODE_FIELD(relations);
+ WRITE_BOOL_FIELD(if_not_exists);
+}
+
+static void
_outNotifyStmt(StringInfo str, const NotifyStmt *node)
{
WRITE_NODE_TYPE("NOTIFY");
@@ -3604,6 +3783,7 @@ _outDefElem(StringInfo str, const DefElem *node)
WRITE_STRING_FIELD(defname);
WRITE_NODE_FIELD(arg);
WRITE_ENUM_FIELD(defaction, DefElemAction);
+ WRITE_LOCATION_FIELD(location);
}
static void
@@ -3637,6 +3817,16 @@ _outXmlSerialize(StringInfo str, const XmlSerialize *node)
}
static void
+_outTriggerTransition(StringInfo str, const TriggerTransition *node)
+{
+ WRITE_NODE_TYPE("TRIGGERTRANSITION");
+
+ WRITE_STRING_FIELD(name);
+ WRITE_BOOL_FIELD(isNew);
+ WRITE_BOOL_FIELD(isTable);
+}
+
+static void
_outColumnDef(StringInfo str, const ColumnDef *node)
{
WRITE_NODE_TYPE("COLUMNDEF");
@@ -3647,9 +3837,11 @@ _outColumnDef(StringInfo str, const ColumnDef *node)
WRITE_BOOL_FIELD(is_local);
WRITE_BOOL_FIELD(is_not_null);
WRITE_BOOL_FIELD(is_from_type);
+ WRITE_BOOL_FIELD(is_from_parent);
WRITE_CHAR_FIELD(storage);
WRITE_NODE_FIELD(raw_default);
WRITE_NODE_FIELD(cooked_default);
+ WRITE_CHAR_FIELD(identity);
WRITE_NODE_FIELD(collClause);
WRITE_OID_FIELD(collOid);
WRITE_NODE_FIELD(constraints);
@@ -3744,6 +3936,7 @@ _outQuery(StringInfo str, const Query *node)
WRITE_INT_FIELD(resultRelation);
WRITE_BOOL_FIELD(hasAggs);
WRITE_BOOL_FIELD(hasWindowFuncs);
+ WRITE_BOOL_FIELD(hasTargetSRFs);
WRITE_BOOL_FIELD(hasSubLinks);
WRITE_BOOL_FIELD(hasDistinctOn);
WRITE_BOOL_FIELD(hasRecursive);
@@ -3754,6 +3947,7 @@ _outQuery(StringInfo str, const Query *node)
WRITE_NODE_FIELD(rtable);
WRITE_NODE_FIELD(jointree);
WRITE_NODE_FIELD(targetList);
+ WRITE_ENUM_FIELD(override, OverridingKind);
WRITE_NODE_FIELD(onConflict);
WRITE_NODE_FIELD(returningList);
WRITE_NODE_FIELD(groupClause);
@@ -3767,6 +3961,9 @@ _outQuery(StringInfo str, const Query *node)
WRITE_NODE_FIELD(rowMarks);
WRITE_NODE_FIELD(setOperations);
WRITE_NODE_FIELD(constraintDeps);
+ /* withCheckOptions intentionally omitted, see comment in parsenodes.h */
+ WRITE_LOCATION_FIELD(stmt_location);
+ WRITE_LOCATION_FIELD(stmt_len);
}
static void
@@ -3916,17 +4113,29 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node)
WRITE_NODE_FIELD(functions);
WRITE_BOOL_FIELD(funcordinality);
break;
+ case RTE_TABLEFUNC:
+ WRITE_NODE_FIELD(tablefunc);
+ break;
case RTE_VALUES:
WRITE_NODE_FIELD(values_lists);
- WRITE_NODE_FIELD(values_collations);
+ WRITE_NODE_FIELD(coltypes);
+ WRITE_NODE_FIELD(coltypmods);
+ WRITE_NODE_FIELD(colcollations);
break;
case RTE_CTE:
WRITE_STRING_FIELD(ctename);
WRITE_UINT_FIELD(ctelevelsup);
WRITE_BOOL_FIELD(self_reference);
- WRITE_NODE_FIELD(ctecoltypes);
- WRITE_NODE_FIELD(ctecoltypmods);
- WRITE_NODE_FIELD(ctecolcollations);
+ WRITE_NODE_FIELD(coltypes);
+ WRITE_NODE_FIELD(coltypmods);
+ WRITE_NODE_FIELD(colcollations);
+ break;
+ case RTE_NAMEDTUPLESTORE:
+ WRITE_STRING_FIELD(enrname);
+ WRITE_OID_FIELD(relid);
+ WRITE_NODE_FIELD(coltypes);
+ WRITE_NODE_FIELD(coltypmods);
+ WRITE_NODE_FIELD(colcollations);
break;
#ifdef PGXC
case RTE_REMOTE_DUMMY:
@@ -4091,12 +4300,12 @@ _outValue(StringInfo str, const Value *value)
case T_String:
/*
- * We use _outToken to provide escaping of the string's content,
+ * We use outToken to provide escaping of the string's content,
* but we don't want it to do anything with an empty string.
*/
appendStringInfoChar(str, '"');
if (value->val.str[0] != '\0')
- _outToken(str, value->val.str);
+ outToken(str, value->val.str);
appendStringInfoChar(str, '"');
break;
case T_BitString:
@@ -4259,6 +4468,34 @@ _outRangeTableSample(StringInfo str, const RangeTableSample *node)
}
static void
+_outRangeTableFunc(StringInfo str, const RangeTableFunc *node)
+{
+ WRITE_NODE_TYPE("RANGETABLEFUNC");
+
+ WRITE_BOOL_FIELD(lateral);
+ WRITE_NODE_FIELD(docexpr);
+ WRITE_NODE_FIELD(rowexpr);
+ WRITE_NODE_FIELD(namespaces);
+ WRITE_NODE_FIELD(columns);
+ WRITE_NODE_FIELD(alias);
+ WRITE_LOCATION_FIELD(location);
+}
+
+static void
+_outRangeTableFuncCol(StringInfo str, const RangeTableFuncCol *node)
+{
+ WRITE_NODE_TYPE("RANGETABLEFUNCCOL");
+
+ WRITE_STRING_FIELD(colname);
+ WRITE_NODE_FIELD(typeName);
+ WRITE_BOOL_FIELD(for_ordinality);
+ WRITE_BOOL_FIELD(is_not_null);
+ WRITE_NODE_FIELD(colexpr);
+ WRITE_NODE_FIELD(coldefexpr);
+ WRITE_LOCATION_FIELD(location);
+}
+
+static void
_outConstraint(StringInfo str, const Constraint *node)
{
WRITE_NODE_TYPE("CONSTRAINT");
@@ -4285,6 +4522,13 @@ _outConstraint(StringInfo str, const Constraint *node)
WRITE_STRING_FIELD(cooked_expr);
break;
+ case CONSTR_IDENTITY:
+ appendStringInfoString(str, "IDENTITY");
+ WRITE_NODE_FIELD(raw_expr);
+ WRITE_STRING_FIELD(cooked_expr);
+ WRITE_CHAR_FIELD(generated_when);
+ break;
+
case CONSTR_CHECK:
appendStringInfoString(str, "CHECK");
WRITE_BOOL_FIELD(is_no_inherit);
@@ -4378,6 +4622,49 @@ _outForeignKeyCacheInfo(StringInfo str, const ForeignKeyCacheInfo *node)
appendStringInfo(str, " %u", node->conpfeqop[i]);
}
+static void
+_outPartitionElem(StringInfo str, const PartitionElem *node)
+{
+ WRITE_NODE_TYPE("PARTITIONELEM");
+
+ WRITE_STRING_FIELD(name);
+ WRITE_NODE_FIELD(expr);
+ WRITE_NODE_FIELD(collation);
+ WRITE_NODE_FIELD(opclass);
+ WRITE_LOCATION_FIELD(location);
+}
+
+static void
+_outPartitionSpec(StringInfo str, const PartitionSpec *node)
+{
+ WRITE_NODE_TYPE("PARTITIONBY");
+
+ WRITE_STRING_FIELD(strategy);
+ WRITE_NODE_FIELD(partParams);
+ WRITE_LOCATION_FIELD(location);
+}
+
+static void
+_outPartitionBoundSpec(StringInfo str, const PartitionBoundSpec *node)
+{
+ WRITE_NODE_TYPE("PARTITIONBOUND");
+
+ WRITE_CHAR_FIELD(strategy);
+ WRITE_NODE_FIELD(listdatums);
+ WRITE_NODE_FIELD(lowerdatums);
+ WRITE_NODE_FIELD(upperdatums);
+ /* XXX somebody forgot location field; too late to change for v10 */
+}
+
+static void
+_outPartitionRangeDatum(StringInfo str, const PartitionRangeDatum *node)
+{
+ WRITE_NODE_TYPE("PARTRANGEDATUM");
+
+ WRITE_BOOL_FIELD(infinite);
+ WRITE_NODE_FIELD(value);
+ /* XXX somebody forgot location field; too late to change for v10 */
+}
/*
* outNode -
@@ -4412,6 +4699,9 @@ outNode(StringInfo str, const void *obj)
case T_Result:
_outResult(str, obj);
break;
+ case T_ProjectSet:
+ _outProjectSet(str, obj);
+ break;
case T_ModifyTable:
_outModifyTable(str, obj);
break;
@@ -4433,6 +4723,9 @@ outNode(StringInfo str, const void *obj)
case T_Gather:
_outGather(str, obj);
break;
+ case T_GatherMerge:
+ _outGatherMerge(str, obj);
+ break;
case T_Scan:
_outScan(str, obj);
break;
@@ -4468,12 +4761,18 @@ outNode(StringInfo str, const void *obj)
case T_FunctionScan:
_outFunctionScan(str, obj);
break;
+ case T_TableFuncScan:
+ _outTableFuncScan(str, obj);
+ break;
case T_ValuesScan:
_outValuesScan(str, obj);
break;
case T_CteScan:
_outCteScan(str, obj);
break;
+ case T_NamedTuplestoreScan:
+ _outNamedTuplestoreScan(str, obj);
+ break;
case T_WorkTableScan:
_outWorkTableScan(str, obj);
break;
@@ -4551,6 +4850,9 @@ outNode(StringInfo str, const void *obj)
case T_RangeVar:
_outRangeVar(str, obj);
break;
+ case T_TableFunc:
+ _outTableFunc(str, obj);
+ break;
case T_IntoClause:
_outIntoClause(str, obj);
break;
@@ -4650,6 +4952,9 @@ outNode(StringInfo str, const void *obj)
case T_MinMaxExpr:
_outMinMaxExpr(str, obj);
break;
+ case T_SQLValueFunction:
+ _outSQLValueFunction(str, obj);
+ break;
case T_XmlExpr:
_outXmlExpr(str, obj);
break;
@@ -4737,6 +5042,9 @@ outNode(StringInfo str, const void *obj)
case T_ProjectionPath:
_outProjectionPath(str, obj);
break;
+ case T_ProjectSetPath:
+ _outProjectSetPath(str, obj);
+ break;
case T_SortPath:
_outSortPath(str, obj);
break;
@@ -4773,6 +5081,9 @@ outNode(StringInfo str, const void *obj)
case T_LimitPath:
_outLimitPath(str, obj);
break;
+ case T_GatherMergePath:
+ _outGatherMergePath(str, obj);
+ break;
case T_NestPath:
_outNestPath(str, obj);
break;
@@ -4824,6 +5135,9 @@ outNode(StringInfo str, const void *obj)
case T_AppendRelInfo:
_outAppendRelInfo(str, obj);
break;
+ case T_PartitionedChildRelInfo:
+ _outPartitionedChildRelInfo(str, obj);
+ break;
case T_PlaceHolderInfo:
_outPlaceHolderInfo(str, obj);
break;
@@ -4833,11 +5147,18 @@ outNode(StringInfo str, const void *obj)
case T_PlannerParamItem:
_outPlannerParamItem(str, obj);
break;
-
+ case T_RollupData:
+ _outRollupData(str, obj);
+ break;
+ case T_GroupingSetData:
+ _outGroupingSetData(str, obj);
+ break;
+ case T_StatisticExtInfo:
+ _outStatisticExtInfo(str, obj);
+ break;
case T_ExtensibleNode:
_outExtensibleNode(str, obj);
break;
-
case T_CreateStmt:
_outCreateStmt(str, obj);
break;
@@ -4850,6 +5171,9 @@ outNode(StringInfo str, const void *obj)
case T_IndexStmt:
_outIndexStmt(str, obj);
break;
+ case T_CreateStatsStmt:
+ _outCreateStatsStmt(str, obj);
+ break;
case T_NotifyStmt:
_outNotifyStmt(str, obj);
break;
@@ -4955,6 +5279,12 @@ outNode(StringInfo str, const void *obj)
case T_RangeTableSample:
_outRangeTableSample(str, obj);
break;
+ case T_RangeTableFunc:
+ _outRangeTableFunc(str, obj);
+ break;
+ case T_RangeTableFuncCol:
+ _outRangeTableFuncCol(str, obj);
+ break;
case T_Constraint:
_outConstraint(str, obj);
break;
@@ -4981,6 +5311,21 @@ outNode(StringInfo str, const void *obj)
_outExecNodes(str, obj);
break;
#endif
+ case T_TriggerTransition:
+ _outTriggerTransition(str, obj);
+ break;
+ case T_PartitionElem:
+ _outPartitionElem(str, obj);
+ break;
+ case T_PartitionSpec:
+ _outPartitionSpec(str, obj);
+ break;
+ case T_PartitionBoundSpec:
+ _outPartitionBoundSpec(str, obj);
+ break;
+ case T_PartitionRangeDatum:
+ _outPartitionRangeDatum(str, obj);
+ break;
default:
@@ -5010,3 +5355,18 @@ nodeToString(const void *obj)
outNode(&str, obj);
return str.data;
}
+
+/*
+ * bmsToString -
+ * returns the ascii representation of the Bitmapset as a palloc'd string
+ */
+char *
+bmsToString(const Bitmapset *bms)
+{
+ StringInfoData str;
+
+ /* see stringinfo.h for an explanation of this maneuver */
+ initStringInfo(&str);
+ outBitmapset(&str, bms);
+ return str.data;
+}
diff --git a/src/backend/nodes/params.c b/src/backend/nodes/params.c
index f2e26b80c4..0fb08b94db 100644
--- a/src/backend/nodes/params.c
+++ b/src/backend/nodes/params.c
@@ -4,7 +4,7 @@
* Support for finding the values associated with Param nodes.
*
*
- * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
diff --git a/src/backend/nodes/print.c b/src/backend/nodes/print.c
index a5b4d24262..0cf7f40c8c 100644
--- a/src/backend/nodes/print.c
+++ b/src/backend/nodes/print.c
@@ -3,7 +3,7 @@
* print.c
* various print routines (used mostly for debugging)
*
- * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
@@ -282,6 +282,10 @@ print_rt(const List *rtable)
printf("%d\t%s\t[rangefunction]",
i, rte->eref->aliasname);
break;
+ case RTE_TABLEFUNC:
+ printf("%d\t%s\t[table function]",
+ i, rte->eref->aliasname);
+ break;
case RTE_VALUES:
printf("%d\t%s\t[values list]",
i, rte->eref->aliasname);
@@ -290,6 +294,10 @@ print_rt(const List *rtable)
printf("%d\t%s\t[cte]",
i, rte->eref->aliasname);
break;
+ case RTE_NAMEDTUPLESTORE:
+ printf("%d\t%s\t[tuplestore]",
+ i, rte->eref->aliasname);
+ break;
default:
printf("%d\t%s\t[unknown rtekind]",
i, rte->eref->aliasname);
diff --git a/src/backend/nodes/read.c b/src/backend/nodes/read.c
index c1ab494d77..b56f28e15f 100644
--- a/src/backend/nodes/read.c
+++ b/src/backend/nodes/read.c
@@ -4,7 +4,7 @@
* routines to convert a string (legal ascii representation of node) back
* to nodes
*
- * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 933825cd74..23091c2bcc 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -4,7 +4,7 @@
* Reader functions for Postgres tree nodes.
*
* Portions Copyright (c) 2012-2014, TransLattice, Inc.
- * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 2010-2012 Postgres-XC Development Group
*
@@ -451,8 +451,6 @@ set_portable_input(bool value)
*/
#define atoui(x) ((unsigned int) strtoul((x), NULL, 10))
-#define atooid(x) ((Oid) strtoul((x), NULL, 10))
-
#define strtobool(x) ((*(x) == 't') ? true : false)
#define nullable_string(token,length) \
@@ -528,6 +526,7 @@ _readQuery(void)
READ_INT_FIELD(resultRelation);
READ_BOOL_FIELD(hasAggs);
READ_BOOL_FIELD(hasWindowFuncs);
+ READ_BOOL_FIELD(hasTargetSRFs);
READ_BOOL_FIELD(hasSubLinks);
READ_BOOL_FIELD(hasDistinctOn);
READ_BOOL_FIELD(hasRecursive);
@@ -538,6 +537,7 @@ _readQuery(void)
READ_NODE_FIELD(rtable);
READ_NODE_FIELD(jointree);
READ_NODE_FIELD(targetList);
+ READ_ENUM_FIELD(override, OverridingKind);
READ_NODE_FIELD(onConflict);
READ_NODE_FIELD(returningList);
READ_NODE_FIELD(groupClause);
@@ -551,6 +551,9 @@ _readQuery(void)
READ_NODE_FIELD(rowMarks);
READ_NODE_FIELD(setOperations);
READ_NODE_FIELD(constraintDeps);
+ /* withCheckOptions intentionally omitted, see comment in parsenodes.h */
+ READ_LOCATION_FIELD(stmt_location);
+ READ_LOCATION_FIELD(stmt_len);
READ_DONE();
}
@@ -748,7 +751,7 @@ _readRangeVar(void)
READ_STRING_FIELD(schemaname);
READ_STRING_FIELD(relname);
- READ_ENUM_FIELD(inhOpt, InhOption);
+ READ_BOOL_FIELD(inh);
READ_CHAR_FIELD(relpersistence);
READ_NODE_FIELD(alias);
READ_LOCATION_FIELD(location);
@@ -756,6 +759,31 @@ _readRangeVar(void)
READ_DONE();
}
+/*
+ * _readTableFunc
+ */
+static TableFunc *
+_readTableFunc(void)
+{
+ READ_LOCALS(TableFunc);
+
+ READ_NODE_FIELD(ns_names);
+ READ_NODE_FIELD(ns_uris);
+ READ_NODE_FIELD(docexpr);
+ READ_NODE_FIELD(rowexpr);
+ READ_NODE_FIELD(colnames);
+ READ_NODE_FIELD(coltypes);
+ READ_NODE_FIELD(coltypmods);
+ READ_NODE_FIELD(colcollations);
+ READ_NODE_FIELD(colexprs);
+ READ_NODE_FIELD(coldefexprs);
+ READ_BITMAPSET_FIELD(notnulls);
+ READ_INT_FIELD(ordinalitycol);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
static IntoClause *
_readIntoClause(void)
{
@@ -1679,6 +1707,22 @@ _readMinMaxExpr(void)
}
/*
+ * _readSQLValueFunction
+ */
+static SQLValueFunction *
+_readSQLValueFunction(void)
+{
+ READ_LOCALS(SQLValueFunction);
+
+ READ_ENUM_FIELD(op, SQLValueFunctionOp);
+ READ_OID_FIELD(type);
+ READ_INT_FIELD(typmod);
+ READ_LOCATION_FIELD(location);
+
+ READ_DONE();
+}
+
+/*
* _readXmlExpr
*/
static XmlExpr *
@@ -1983,17 +2027,29 @@ _readRangeTblEntry(void)
READ_NODE_FIELD(functions);
READ_BOOL_FIELD(funcordinality);
break;
+ case RTE_TABLEFUNC:
+ READ_NODE_FIELD(tablefunc);
+ break;
case RTE_VALUES:
READ_NODE_FIELD(values_lists);
- READ_NODE_FIELD(values_collations);
+ READ_NODE_FIELD(coltypes);
+ READ_NODE_FIELD(coltypmods);
+ READ_NODE_FIELD(colcollations);
break;
case RTE_CTE:
READ_STRING_FIELD(ctename);
READ_UINT_FIELD(ctelevelsup);
READ_BOOL_FIELD(self_reference);
- READ_NODE_FIELD(ctecoltypes);
- READ_NODE_FIELD(ctecoltypmods);
- READ_NODE_FIELD(ctecolcollations);
+ READ_NODE_FIELD(coltypes);
+ READ_NODE_FIELD(coltypmods);
+ READ_NODE_FIELD(colcollations);
+ break;
+ case RTE_NAMEDTUPLESTORE:
+ READ_STRING_FIELD(enrname);
+ READ_OID_FIELD(relid);
+ READ_NODE_FIELD(coltypes);
+ READ_NODE_FIELD(coltypmods);
+ READ_NODE_FIELD(colcollations);
break;
#ifdef PGXC
case RTE_REMOTE_DUMMY:
@@ -2105,6 +2161,7 @@ _readDefElem(void)
READ_STRING_FIELD(defname);
READ_NODE_FIELD(arg);
READ_ENUM_FIELD(defaction, DefElemAction);
+ READ_LOCATION_FIELD(location);
READ_DONE();
}
@@ -2141,13 +2198,17 @@ _readPlannedStmt(void)
READ_NODE_FIELD(planTree);
READ_NODE_FIELD(rtable);
READ_NODE_FIELD(resultRelations);
- READ_NODE_FIELD(utilityStmt);
+ READ_NODE_FIELD(nonleafResultRelations);
+ READ_NODE_FIELD(rootResultRelations);
READ_NODE_FIELD(subplans);
READ_BITMAPSET_FIELD(rewindPlanIDs);
READ_NODE_FIELD(rowMarks);
READ_NODE_FIELD(relationOids);
READ_NODE_FIELD(invalItems);
READ_INT_FIELD(nParamExec);
+ READ_NODE_FIELD(utilityStmt);
+ READ_LOCATION_FIELD(stmt_location);
+ READ_LOCATION_FIELD(stmt_len);
READ_DONE();
}
@@ -2168,6 +2229,19 @@ _readResult(void)
}
/*
+ * _readProjectSet
+ */
+static ProjectSet *
+_readProjectSet(void)
+{
+ READ_LOCALS_NO_FIELDS(ProjectSet);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_DONE();
+}
+
+/*
* _readModifyTable
*/
static ModifyTable *
@@ -2180,8 +2254,10 @@ _readModifyTable(void)
READ_ENUM_FIELD(operation, CmdType);
READ_BOOL_FIELD(canSetTag);
READ_UINT_FIELD(nominalRelation);
+ READ_NODE_FIELD(partitioned_rels);
READ_NODE_FIELD(resultRelations);
READ_INT_FIELD(resultRelIndex);
+ READ_INT_FIELD(rootResultRelIndex);
READ_NODE_FIELD(plans);
READ_NODE_FIELD(withCheckOptionLists);
READ_NODE_FIELD(returningLists);
@@ -2212,6 +2288,7 @@ _readAppend(void)
ReadCommonPlan(&local_node->plan);
+ READ_NODE_FIELD(partitioned_rels);
READ_NODE_FIELD(appendplans);
READ_DONE();
@@ -2228,6 +2305,7 @@ _readMergeAppend(void)
ReadCommonPlan(&local_node->plan);
+ READ_NODE_FIELD(partitioned_rels);
READ_NODE_FIELD(mergeplans);
READ_INT_FIELD(numCols);
READ_ATTRNUMBER_ARRAY(sortColIdx, local_node->numCols);
@@ -2354,6 +2432,7 @@ _readBitmapOr(void)
ReadCommonPlan(&local_node->plan);
+ READ_BOOL_FIELD(isshared);
READ_NODE_FIELD(bitmapplans);
READ_DONE();
@@ -2474,6 +2553,7 @@ _readBitmapIndexScan(void)
READ_RELID_FIELD(indexid);
else
READ_OID_FIELD(indexid);
+ READ_BOOL_FIELD(isshared);
READ_NODE_FIELD(indexqual);
READ_NODE_FIELD(indexqualorig);
@@ -2557,6 +2637,21 @@ _readValuesScan(void)
}
/*
+ * _readTableFuncScan
+ */
+static TableFuncScan *
+_readTableFuncScan(void)
+{
+ READ_LOCALS(TableFuncScan);
+
+ ReadCommonScan(&local_node->scan);
+
+ READ_NODE_FIELD(tablefunc);
+
+ READ_DONE();
+}
+
+/*
* _readCteScan
*/
static CteScan *
@@ -2650,6 +2745,7 @@ ReadCommonJoin(Join *local_node)
ReadCommonPlan(&local_node->plan);
READ_ENUM_FIELD(jointype, JoinType);
+ READ_BOOL_FIELD(inner_unique);
READ_NODE_FIELD(joinqual);
}
@@ -2694,6 +2790,7 @@ _readMergeJoin(void)
ReadCommonJoin(&local_node->join);
+ READ_BOOL_FIELD(skip_mark_restore);
READ_NODE_FIELD(mergeclauses);
numCols = list_length(local_node->mergeclauses);
@@ -3001,6 +3098,7 @@ _readAgg(void)
#endif
READ_LONG_FIELD(numGroups);
+ READ_BITMAPSET_FIELD(aggParams);
READ_NODE_FIELD(groupingSets);
READ_NODE_FIELD(chain);
@@ -3218,6 +3316,26 @@ _readGather(void)
}
/*
+ * _readGatherMerge
+ */
+static GatherMerge *
+_readGatherMerge(void)
+{
+ READ_LOCALS(GatherMerge);
+
+ ReadCommonPlan(&local_node->plan);
+
+ READ_INT_FIELD(num_workers);
+ READ_INT_FIELD(numCols);
+ READ_ATTRNUMBER_ARRAY(sortColIdx, local_node->numCols);
+ READ_OID_ARRAY(sortOperators, local_node->numCols);
+ READ_OID_ARRAY(collations, local_node->numCols);
+ READ_BOOL_ARRAY(nullsFirst, local_node->numCols);
+
+ READ_DONE();
+}
+
+/*
* _readHash
*/
static Hash *
@@ -3233,11 +3351,6 @@ _readHash(void)
READ_OID_FIELD(skewTable);
READ_INT_FIELD(skewColumn);
READ_BOOL_FIELD(skewInherit);
- if (portable_input)
- READ_TYPID_FIELD(skewColType);
- else
- READ_OID_FIELD(skewColType);
- READ_INT_FIELD(skewColTypmod);
READ_DONE();
}
@@ -3434,6 +3547,7 @@ _readSubPlan(void)
READ_OID_FIELD(firstColCollation);
READ_BOOL_FIELD(useHashTable);
READ_BOOL_FIELD(unknownEqFalse);
+ READ_BOOL_FIELD(parallel_safe);
READ_NODE_FIELD(setParam);
READ_NODE_FIELD(parParam);
READ_NODE_FIELD(args);
@@ -3685,6 +3799,40 @@ _readSimpleSort(void)
/*
+ * _readPartitionBoundSpec
+ */
+static PartitionBoundSpec *
+_readPartitionBoundSpec(void)
+{
+ READ_LOCALS(PartitionBoundSpec);
+
+ READ_CHAR_FIELD(strategy);
+ READ_NODE_FIELD(listdatums);
+ READ_NODE_FIELD(lowerdatums);
+ READ_NODE_FIELD(upperdatums);
+ /* XXX somebody forgot location field; too late to change for v10 */
+ local_node->location = -1;
+
+ READ_DONE();
+}
+
+/*
+ * _readPartitionRangeDatum
+ */
+static PartitionRangeDatum *
+_readPartitionRangeDatum(void)
+{
+ READ_LOCALS(PartitionRangeDatum);
+
+ READ_BOOL_FIELD(infinite);
+ READ_NODE_FIELD(value);
+ /* XXX somebody forgot location field; too late to change for v10 */
+ local_node->location = -1;
+
+ READ_DONE();
+}
+
+/*
* parseNodeString
*
* Given a character string representing a node tree, parseNodeString creates
@@ -3726,6 +3874,8 @@ parseNodeString(void)
return_value = _readRangeVar();
else if (MATCH("INTOCLAUSE", 10))
return_value = _readIntoClause();
+ else if (MATCH("TABLEFUNC", 9))
+ return_value = _readTableFunc();
else if (MATCH("VAR", 3))
return_value = _readVar();
else if (MATCH("CONST", 5))
@@ -3786,6 +3936,8 @@ parseNodeString(void)
return_value = _readCoalesceExpr();
else if (MATCH("MINMAX", 6))
return_value = _readMinMaxExpr();
+ else if (MATCH("SQLVALUEFUNCTION", 16))
+ return_value = _readSQLValueFunction();
else if (MATCH("XMLEXPR", 7))
return_value = _readXmlExpr();
else if (MATCH("NULLTEST", 8))
@@ -3830,6 +3982,8 @@ parseNodeString(void)
return_value = _readPlan();
else if (MATCH("RESULT", 6))
return_value = _readResult();
+ else if (MATCH("PROJECTSET", 10))
+ return_value = _readProjectSet();
else if (MATCH("MODIFYTABLE", 11))
return_value = _readModifyTable();
else if (MATCH("APPEND", 6))
@@ -3864,6 +4018,8 @@ parseNodeString(void)
return_value = _readFunctionScan();
else if (MATCH("VALUESSCAN", 10))
return_value = _readValuesScan();
+ else if (MATCH("TABLEFUNCSCAN", 13))
+ return_value = _readTableFuncScan();
else if (MATCH("CTESCAN", 7))
return_value = _readCteScan();
else if (MATCH("WORKTABLESCAN", 13))
@@ -3894,6 +4050,8 @@ parseNodeString(void)
return_value = _readUnique();
else if (MATCH("GATHER", 6))
return_value = _readGather();
+ else if (MATCH("GATHERMERGE", 11))
+ return_value = _readGatherMerge();
else if (MATCH("HASH", 4))
return_value = _readHash();
else if (MATCH("SETOP", 5))
@@ -3920,6 +4078,10 @@ parseNodeString(void)
return_value = _readRemoteStmt();
else if (MATCH("SIMPLESORT", 10))
return_value = _readSimpleSort();
+ else if (MATCH("PARTITIONBOUND", 14))
+ return_value = _readPartitionBoundSpec();
+ else if (MATCH("PARTRANGEDATUM", 14))
+ return_value = _readPartitionRangeDatum();
else
{
elog(ERROR, "badly formatted node string \"%.32s\"...", token);
diff --git a/src/backend/nodes/tidbitmap.c b/src/backend/nodes/tidbitmap.c
index dfeb7d5c63..bbd39a2ed9 100644
--- a/src/backend/nodes/tidbitmap.c
+++ b/src/backend/nodes/tidbitmap.c
@@ -29,7 +29,7 @@
* and a non-lossy page.
*
*
- * Copyright (c) 2003-2016, PostgreSQL Global Development Group
+ * Copyright (c) 2003-2017, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/backend/nodes/tidbitmap.c
@@ -43,7 +43,8 @@
#include "access/htup_details.h"
#include "nodes/bitmapset.h"
#include "nodes/tidbitmap.h"
-#include "utils/hsearch.h"
+#include "storage/lwlock.h"
+#include "utils/dsa.h"
/*
* The maximum number of tuples per page is not large (typically 256 with
@@ -61,12 +62,12 @@
* for that page in the page table.
*
* We actually store both exact pages and lossy chunks in the same hash
- * table, using identical data structures. (This is because dynahash.c's
- * memory management doesn't allow space to be transferred easily from one
- * hashtable to another.) Therefore it's best if PAGES_PER_CHUNK is the
- * same as MAX_TUPLES_PER_PAGE, or at least not too different. But we
- * also want PAGES_PER_CHUNK to be a power of 2 to avoid expensive integer
- * remainder operations. So, define it like this:
+ * table, using identical data structures. (This is because the memory
+ * management for hashtables doesn't easily/efficiently allow space to be
+ * transferred easily from one hashtable to another.) Therefore it's best
+ * if PAGES_PER_CHUNK is the same as MAX_TUPLES_PER_PAGE, or at least not
+ * too different. But we also want PAGES_PER_CHUNK to be a power of 2 to
+ * avoid expensive integer remainder operations. So, define it like this:
*/
#define PAGES_PER_CHUNK (BLCKSZ / 32)
@@ -97,21 +98,31 @@
typedef struct PagetableEntry
{
BlockNumber blockno; /* page number (hashtable key) */
+ char status; /* hash entry status */
bool ischunk; /* T = lossy storage, F = exact */
bool recheck; /* should the tuples be rechecked? */
bitmapword words[Max(WORDS_PER_PAGE, WORDS_PER_CHUNK)];
} PagetableEntry;
/*
- * dynahash.c is optimized for relatively large, long-lived hash tables.
- * This is not ideal for TIDBitMap, particularly when we are using a bitmap
- * scan on the inside of a nestloop join: a bitmap may well live only long
- * enough to accumulate one entry in such cases. We therefore avoid creating
- * an actual hashtable until we need two pagetable entries. When just one
- * pagetable entry is needed, we store it in a fixed field of TIDBitMap.
- * (NOTE: we don't get rid of the hashtable if the bitmap later shrinks down
- * to zero or one page again. So, status can be TBM_HASH even when nentries
- * is zero or one.)
+ * Holds array of pagetable entries.
+ */
+typedef struct PTEntryArray
+{
+ pg_atomic_uint32 refcount; /* no. of iterator attached */
+ PagetableEntry ptentry[FLEXIBLE_ARRAY_MEMBER];
+} PTEntryArray;
+
+/*
+ * We want to avoid the overhead of creating the hashtable, which is
+ * comparatively large, when not necessary. Particularly when we are using a
+ * bitmap scan on the inside of a nestloop join: a bitmap may well live only
+ * long enough to accumulate one entry in such cases. We therefore avoid
+ * creating an actual hashtable until we need two pagetable entries. When
+ * just one pagetable entry is needed, we store it in a fixed field of
+ * TIDBitMap. (NOTE: we don't get rid of the hashtable if the bitmap later
+ * shrinks down to zero or one page again. So, status can be TBM_HASH even
+ * when nentries is zero or one.)
*/
typedef enum
{
@@ -121,6 +132,16 @@ typedef enum
} TBMStatus;
/*
+ * Current iterating state of the TBM.
+ */
+typedef enum
+{
+ TBM_NOT_ITERATING, /* not yet converted to page and chunk array */
+ TBM_ITERATING_PRIVATE, /* converted to local page and chunk array */
+ TBM_ITERATING_SHARED /* converted to shared page and chunk array */
+} TBMIteratingState;
+
+/*
* Here is the representation for a whole TIDBitMap:
*/
struct TIDBitmap
@@ -128,16 +149,22 @@ struct TIDBitmap
NodeTag type; /* to make it a valid Node */
MemoryContext mcxt; /* memory context containing me */
TBMStatus status; /* see codes above */
- HTAB *pagetable; /* hash table of PagetableEntry's */
+ struct pagetable_hash *pagetable; /* hash table of PagetableEntry's */
int nentries; /* number of entries in pagetable */
int maxentries; /* limit on same to meet maxbytes */
int npages; /* number of exact entries in pagetable */
int nchunks; /* number of lossy entries in pagetable */
- bool iterating; /* tbm_begin_iterate called? */
+ TBMIteratingState iterating; /* tbm_begin_iterate called? */
+ uint32 lossify_start; /* offset to start lossifying hashtable at */
PagetableEntry entry1; /* used when status == TBM_ONE_PAGE */
/* these are valid when iterating is true: */
PagetableEntry **spages; /* sorted exact-page list, or NULL */
PagetableEntry **schunks; /* sorted lossy-chunk list, or NULL */
+ dsa_pointer dsapagetable; /* dsa_pointer to the element array */
+ dsa_pointer dsapagetableold; /* dsa_pointer to the old element array */
+ dsa_pointer ptpages; /* dsa_pointer to the page array */
+ dsa_pointer ptchunks; /* dsa_pointer to the chunk array */
+ dsa_area *dsa; /* reference to per-query dsa area */
};
/*
@@ -155,6 +182,46 @@ struct TBMIterator
TBMIterateResult output; /* MUST BE LAST (because variable-size) */
};
+/*
+ * Holds the shared members of the iterator so that multiple processes
+ * can jointly iterate.
+ */
+typedef struct TBMSharedIteratorState
+{
+ int nentries; /* number of entries in pagetable */
+ int maxentries; /* limit on same to meet maxbytes */
+ int npages; /* number of exact entries in pagetable */
+ int nchunks; /* number of lossy entries in pagetable */
+ dsa_pointer pagetable; /* dsa pointers to head of pagetable data */
+ dsa_pointer spages; /* dsa pointer to page array */
+ dsa_pointer schunks; /* dsa pointer to chunk array */
+ LWLock lock; /* lock to protect below members */
+ int spageptr; /* next spages index */
+ int schunkptr; /* next schunks index */
+ int schunkbit; /* next bit to check in current schunk */
+} TBMSharedIteratorState;
+
+/*
+ * pagetable iteration array.
+ */
+typedef struct PTIterationArray
+{
+ pg_atomic_uint32 refcount; /* no. of iterator attached */
+ int index[FLEXIBLE_ARRAY_MEMBER]; /* index array */
+} PTIterationArray;
+
+/*
+ * same as TBMIterator, but it is used for joint iteration, therefore this
+ * also holds a reference to the shared state.
+ */
+struct TBMSharedIterator
+{
+ TBMSharedIteratorState *state; /* shared state */
+ PTEntryArray *ptbase; /* pagetable element array */
+ PTIterationArray *ptpages; /* sorted exact page index list */
+ PTIterationArray *ptchunks; /* sorted lossy page index list */
+ TBMIterateResult output; /* MUST BE LAST (because variable-size) */
+};
/* Local function prototypes */
static void tbm_union_page(TIDBitmap *a, const PagetableEntry *bpage);
@@ -167,6 +234,38 @@ static bool tbm_page_is_lossy(const TIDBitmap *tbm, BlockNumber pageno);
static void tbm_mark_page_lossy(TIDBitmap *tbm, BlockNumber pageno);
static void tbm_lossify(TIDBitmap *tbm);
static int tbm_comparator(const void *left, const void *right);
+static int tbm_shared_comparator(const void *left, const void *right,
+ void *arg);
+
+/*
+ * Simple inline murmur hash implementation for the exact width required, for
+ * performance.
+ */
+static inline uint32
+hash_blockno(BlockNumber b)
+{
+ uint32 h = b;
+
+ h ^= h >> 16;
+ h *= 0x85ebca6b;
+ h ^= h >> 13;
+ h *= 0xc2b2ae35;
+ h ^= h >> 16;
+ return h;
+}
+
+/* define hashtable mapping block numbers to PagetableEntry's */
+#define SH_USE_NONDEFAULT_ALLOCATOR
+#define SH_PREFIX pagetable
+#define SH_ELEMENT_TYPE PagetableEntry
+#define SH_KEY_TYPE BlockNumber
+#define SH_KEY blockno
+#define SH_HASH_KEY(tb, key) hash_blockno(key)
+#define SH_EQUAL(tb, a, b) a == b
+#define SH_SCOPE static inline
+#define SH_DEFINE
+#define SH_DECLARE
+#include "lib/simplehash.h"
/*
@@ -174,10 +273,12 @@ static int tbm_comparator(const void *left, const void *right);
*
* The bitmap will live in the memory context that is CurrentMemoryContext
* at the time of this call. It will be limited to (approximately) maxbytes
- * total memory consumption.
+ * total memory consumption. If the DSA passed to this function is not NULL
+ * then the memory for storing elements of the underlying page table will
+ * be allocated from the DSA.
*/
TIDBitmap *
-tbm_create(long maxbytes)
+tbm_create(long maxbytes, dsa_area *dsa)
{
TIDBitmap *tbm;
long nbuckets;
@@ -190,17 +291,21 @@ tbm_create(long maxbytes)
/*
* Estimate number of hashtable entries we can have within maxbytes. This
- * estimates the hash overhead at MAXALIGN(sizeof(HASHELEMENT)) plus a
- * pointer per hash entry, which is crude but good enough for our purpose.
- * Also count an extra Pointer per entry for the arrays created during
- * iteration readout.
+ * estimates the hash cost as sizeof(PagetableEntry), which is good enough
+ * for our purpose. Also count an extra Pointer per entry for the arrays
+ * created during iteration readout.
*/
nbuckets = maxbytes /
- (MAXALIGN(sizeof(HASHELEMENT)) + MAXALIGN(sizeof(PagetableEntry))
- + sizeof(Pointer) + sizeof(Pointer));
+ (sizeof(PagetableEntry) + sizeof(Pointer) + sizeof(Pointer));
nbuckets = Min(nbuckets, INT_MAX - 1); /* safety limit */
nbuckets = Max(nbuckets, 16); /* sanity limit */
tbm->maxentries = (int) nbuckets;
+ tbm->lossify_start = 0;
+ tbm->dsa = dsa;
+ tbm->dsapagetable = InvalidDsaPointer;
+ tbm->dsapagetableold = InvalidDsaPointer;
+ tbm->ptpages = InvalidDsaPointer;
+ tbm->ptchunks = InvalidDsaPointer;
return tbm;
}
@@ -212,32 +317,25 @@ tbm_create(long maxbytes)
static void
tbm_create_pagetable(TIDBitmap *tbm)
{
- HASHCTL hash_ctl;
-
Assert(tbm->status != TBM_HASH);
Assert(tbm->pagetable == NULL);
- /* Create the hashtable proper */
- MemSet(&hash_ctl, 0, sizeof(hash_ctl));
- hash_ctl.keysize = sizeof(BlockNumber);
- hash_ctl.entrysize = sizeof(PagetableEntry);
- hash_ctl.hcxt = tbm->mcxt;
- tbm->pagetable = hash_create("TIDBitmap",
- 128, /* start small and extend */
- &hash_ctl,
- HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
+ tbm->pagetable = pagetable_create(tbm->mcxt, 128, tbm);
/* If entry1 is valid, push it into the hashtable */
if (tbm->status == TBM_ONE_PAGE)
{
PagetableEntry *page;
bool found;
+ char oldstatus;
- page = (PagetableEntry *) hash_search(tbm->pagetable,
- (void *) &tbm->entry1.blockno,
- HASH_ENTER, &found);
+ page = pagetable_insert(tbm->pagetable,
+ tbm->entry1.blockno,
+ &found);
Assert(!found);
+ oldstatus = page->status;
memcpy(page, &tbm->entry1, sizeof(PagetableEntry));
+ page->status = oldstatus;
}
tbm->status = TBM_HASH;
@@ -250,7 +348,7 @@ void
tbm_free(TIDBitmap *tbm)
{
if (tbm->pagetable)
- hash_destroy(tbm->pagetable);
+ pagetable_destroy(tbm->pagetable);
if (tbm->spages)
pfree(tbm->spages);
if (tbm->schunks)
@@ -259,6 +357,43 @@ tbm_free(TIDBitmap *tbm)
}
/*
+ * tbm_free_shared_area - free shared state
+ *
+ * Free shared iterator state, Also free shared pagetable and iterator arrays
+ * memory if they are not referred by any of the shared iterator i.e recount
+ * is becomes 0.
+ */
+void
+tbm_free_shared_area(dsa_area *dsa, dsa_pointer dp)
+{
+ TBMSharedIteratorState *istate = dsa_get_address(dsa, dp);
+ PTEntryArray *ptbase;
+ PTIterationArray *ptpages;
+ PTIterationArray *ptchunks;
+
+ if (DsaPointerIsValid(istate->pagetable))
+ {
+ ptbase = dsa_get_address(dsa, istate->pagetable);
+ if (pg_atomic_sub_fetch_u32(&ptbase->refcount, 1) == 0)
+ dsa_free(dsa, istate->pagetable);
+ }
+ if (DsaPointerIsValid(istate->spages))
+ {
+ ptpages = dsa_get_address(dsa, istate->spages);
+ if (pg_atomic_sub_fetch_u32(&ptpages->refcount, 1) == 0)
+ dsa_free(dsa, istate->spages);
+ }
+ if (DsaPointerIsValid(istate->schunks))
+ {
+ ptchunks = dsa_get_address(dsa, istate->schunks);
+ if (pg_atomic_sub_fetch_u32(&ptchunks->refcount, 1) == 0)
+ dsa_free(dsa, istate->schunks);
+ }
+
+ dsa_free(dsa, dp);
+}
+
+/*
* tbm_add_tuples - add some tuple IDs to a TIDBitmap
*
* If recheck is true, then the recheck flag will be set in the
@@ -272,7 +407,7 @@ tbm_add_tuples(TIDBitmap *tbm, const ItemPointer tids, int ntids,
PagetableEntry *page = NULL; /* only valid when currblk is valid */
int i;
- Assert(!tbm->iterating);
+ Assert(tbm->iterating == TBM_NOT_ITERATING);
for (i = 0; i < ntids; i++)
{
BlockNumber blk = ItemPointerGetBlockNumber(tids + i);
@@ -357,12 +492,12 @@ tbm_union(TIDBitmap *a, const TIDBitmap *b)
tbm_union_page(a, &b->entry1);
else
{
- HASH_SEQ_STATUS status;
+ pagetable_iterator i;
PagetableEntry *bpage;
Assert(b->status == TBM_HASH);
- hash_seq_init(&status, b->pagetable);
- while ((bpage = (PagetableEntry *) hash_seq_search(&status)) != NULL)
+ pagetable_start_iterate(b->pagetable, &i);
+ while ((bpage = pagetable_iterate(b->pagetable, &i)) != NULL)
tbm_union_page(a, bpage);
}
}
@@ -449,12 +584,12 @@ tbm_intersect(TIDBitmap *a, const TIDBitmap *b)
}
else
{
- HASH_SEQ_STATUS status;
+ pagetable_iterator i;
PagetableEntry *apage;
Assert(a->status == TBM_HASH);
- hash_seq_init(&status, a->pagetable);
- while ((apage = (PagetableEntry *) hash_seq_search(&status)) != NULL)
+ pagetable_start_iterate(a->pagetable, &i);
+ while ((apage = pagetable_iterate(a->pagetable, &i)) != NULL)
{
if (tbm_intersect_page(a, apage, b))
{
@@ -464,9 +599,7 @@ tbm_intersect(TIDBitmap *a, const TIDBitmap *b)
else
a->npages--;
a->nentries--;
- if (hash_search(a->pagetable,
- (void *) &apage->blockno,
- HASH_REMOVE, NULL) == NULL)
+ if (!pagetable_delete(a->pagetable, apage->blockno))
elog(ERROR, "hash table corrupted");
}
}
@@ -583,6 +716,8 @@ tbm_begin_iterate(TIDBitmap *tbm)
{
TBMIterator *iterator;
+ Assert(tbm->iterating != TBM_ITERATING_SHARED);
+
/*
* Create the TBMIterator struct, with enough trailing space to serve the
* needs of the TBMIterateResult sub-struct.
@@ -604,9 +739,9 @@ tbm_begin_iterate(TIDBitmap *tbm)
* attached to the bitmap not the iterator, so they can be used by more
* than one iterator.
*/
- if (tbm->status == TBM_HASH && !tbm->iterating)
+ if (tbm->status == TBM_HASH && tbm->iterating == TBM_NOT_ITERATING)
{
- HASH_SEQ_STATUS status;
+ pagetable_iterator i;
PagetableEntry *page;
int npages;
int nchunks;
@@ -620,9 +755,9 @@ tbm_begin_iterate(TIDBitmap *tbm)
MemoryContextAlloc(tbm->mcxt,
tbm->nchunks * sizeof(PagetableEntry *));
- hash_seq_init(&status, tbm->pagetable);
npages = nchunks = 0;
- while ((page = (PagetableEntry *) hash_seq_search(&status)) != NULL)
+ pagetable_start_iterate(tbm->pagetable, &i);
+ while ((page = pagetable_iterate(tbm->pagetable, &i)) != NULL)
{
if (page->ischunk)
tbm->schunks[nchunks++] = page;
@@ -639,12 +774,214 @@ tbm_begin_iterate(TIDBitmap *tbm)
tbm_comparator);
}
- tbm->iterating = true;
+ tbm->iterating = TBM_ITERATING_PRIVATE;
return iterator;
}
/*
+ * tbm_prepare_shared_iterate - prepare shared iteration state for a TIDBitmap.
+ *
+ * The necessary shared state will be allocated from the DSA passed to
+ * tbm_create, so that multiple processes can attach to it and iterate jointly.
+ *
+ * This will convert the pagetable hash into page and chunk array of the index
+ * into pagetable array.
+ */
+dsa_pointer
+tbm_prepare_shared_iterate(TIDBitmap *tbm)
+{
+ dsa_pointer dp;
+ TBMSharedIteratorState *istate;
+ PTEntryArray *ptbase = NULL;
+ PTIterationArray *ptpages = NULL;
+ PTIterationArray *ptchunks = NULL;
+
+ Assert(tbm->dsa != NULL);
+ Assert(tbm->iterating != TBM_ITERATING_PRIVATE);
+
+ /*
+ * Allocate TBMSharedIteratorState from DSA to hold the shared members and
+ * lock, this will also be used by multiple worker for shared iterate.
+ */
+ dp = dsa_allocate0(tbm->dsa, sizeof(TBMSharedIteratorState));
+ istate = dsa_get_address(tbm->dsa, dp);
+
+ /*
+ * If we're not already iterating, create and fill the sorted page lists.
+ * (If we are, the sorted page lists are already stored in the TIDBitmap,
+ * and we can just reuse them.)
+ */
+ if (tbm->iterating == TBM_NOT_ITERATING)
+ {
+ pagetable_iterator i;
+ PagetableEntry *page;
+ int idx;
+ int npages;
+ int nchunks;
+
+ /*
+ * Allocate the page and chunk array memory from the DSA to share
+ * across multiple processes.
+ */
+ if (tbm->npages)
+ {
+ tbm->ptpages = dsa_allocate(tbm->dsa, sizeof(PTIterationArray) +
+ tbm->npages * sizeof(int));
+ ptpages = dsa_get_address(tbm->dsa, tbm->ptpages);
+ pg_atomic_init_u32(&ptpages->refcount, 0);
+ }
+ if (tbm->nchunks)
+ {
+ tbm->ptchunks = dsa_allocate(tbm->dsa, sizeof(PTIterationArray) +
+ tbm->nchunks * sizeof(int));
+ ptchunks = dsa_get_address(tbm->dsa, tbm->ptchunks);
+ pg_atomic_init_u32(&ptchunks->refcount, 0);
+ }
+
+ /*
+ * If TBM status is TBM_HASH then iterate over the pagetable and
+ * convert it to page and chunk arrays. But if it's in the
+ * TBM_ONE_PAGE mode then directly allocate the space for one entry
+ * from the DSA.
+ */
+ npages = nchunks = 0;
+ if (tbm->status == TBM_HASH)
+ {
+ ptbase = dsa_get_address(tbm->dsa, tbm->dsapagetable);
+
+ pagetable_start_iterate(tbm->pagetable, &i);
+ while ((page = pagetable_iterate(tbm->pagetable, &i)) != NULL)
+ {
+ idx = page - ptbase->ptentry;
+ if (page->ischunk)
+ ptchunks->index[nchunks++] = idx;
+ else
+ ptpages->index[npages++] = idx;
+ }
+
+ Assert(npages == tbm->npages);
+ Assert(nchunks == tbm->nchunks);
+ }
+ else if (tbm->status == TBM_ONE_PAGE)
+ {
+ /*
+ * In one page mode allocate the space for one pagetable entry,
+ * initialize it, and directly store its index (i.e. 0) in the
+ * page array.
+ */
+ tbm->dsapagetable = dsa_allocate(tbm->dsa, sizeof(PTEntryArray) +
+ sizeof(PagetableEntry));
+ ptbase = dsa_get_address(tbm->dsa, tbm->dsapagetable);
+ memcpy(ptbase->ptentry, &tbm->entry1, sizeof(PagetableEntry));
+ ptpages->index[0] = 0;
+ }
+
+ if (ptbase != NULL)
+ pg_atomic_init_u32(&ptbase->refcount, 0);
+ if (npages > 1)
+ qsort_arg((void *) (ptpages->index), npages, sizeof(int),
+ tbm_shared_comparator, (void *) ptbase->ptentry);
+ if (nchunks > 1)
+ qsort_arg((void *) (ptchunks->index), nchunks, sizeof(int),
+ tbm_shared_comparator, (void *) ptbase->ptentry);
+ }
+
+ /*
+ * Store the TBM members in the shared state so that we can share them
+ * across multiple processes.
+ */
+ istate->nentries = tbm->nentries;
+ istate->maxentries = tbm->maxentries;
+ istate->npages = tbm->npages;
+ istate->nchunks = tbm->nchunks;
+ istate->pagetable = tbm->dsapagetable;
+ istate->spages = tbm->ptpages;
+ istate->schunks = tbm->ptchunks;
+
+ ptbase = dsa_get_address(tbm->dsa, tbm->dsapagetable);
+ ptpages = dsa_get_address(tbm->dsa, tbm->ptpages);
+ ptchunks = dsa_get_address(tbm->dsa, tbm->ptchunks);
+
+ /*
+ * For every shared iterator, referring to pagetable and iterator array,
+ * increase the refcount by 1 so that while freeing the shared iterator we
+ * don't free pagetable and iterator array until its refcount becomes 0.
+ */
+ if (ptbase != NULL)
+ pg_atomic_add_fetch_u32(&ptbase->refcount, 1);
+ if (ptpages != NULL)
+ pg_atomic_add_fetch_u32(&ptpages->refcount, 1);
+ if (ptchunks != NULL)
+ pg_atomic_add_fetch_u32(&ptchunks->refcount, 1);
+
+ /* Initialize the iterator lock */
+ LWLockInitialize(&istate->lock, LWTRANCHE_TBM);
+
+ /* Initialize the shared iterator state */
+ istate->schunkbit = 0;
+ istate->schunkptr = 0;
+ istate->spageptr = 0;
+
+ tbm->iterating = TBM_ITERATING_SHARED;
+
+ return dp;
+}
+
+/*
+ * tbm_extract_page_tuple - extract the tuple offsets from a page
+ *
+ * The extracted offsets are stored into TBMIterateResult.
+ */
+static inline int
+tbm_extract_page_tuple(PagetableEntry *page, TBMIterateResult *output)
+{
+ int wordnum;
+ int ntuples = 0;
+
+ for (wordnum = 0; wordnum < WORDS_PER_PAGE; wordnum++)
+ {
+ bitmapword w = page->words[wordnum];
+
+ if (w != 0)
+ {
+ int off = wordnum * BITS_PER_BITMAPWORD + 1;
+
+ while (w != 0)
+ {
+ if (w & 1)
+ output->offsets[ntuples++] = (OffsetNumber) off;
+ off++;
+ w >>= 1;
+ }
+ }
+ }
+
+ return ntuples;
+}
+
+/*
+ * tbm_advance_schunkbit - Advance the chunkbit
+ */
+static inline void
+tbm_advance_schunkbit(PagetableEntry *chunk, int *schunkbitp)
+{
+ int schunkbit = *schunkbitp;
+
+ while (schunkbit < PAGES_PER_CHUNK)
+ {
+ int wordnum = WORDNUM(schunkbit);
+ int bitnum = BITNUM(schunkbit);
+
+ if ((chunk->words[wordnum] & ((bitmapword) 1 << bitnum)) != 0)
+ break;
+ schunkbit++;
+ }
+
+ *schunkbitp = schunkbit;
+}
+
+/*
* tbm_iterate - scan through next page of a TIDBitmap
*
* Returns a TBMIterateResult representing one page, or NULL if there are
@@ -662,7 +999,7 @@ tbm_iterate(TBMIterator *iterator)
TIDBitmap *tbm = iterator->tbm;
TBMIterateResult *output = &(iterator->output);
- Assert(tbm->iterating);
+ Assert(tbm->iterating == TBM_ITERATING_PRIVATE);
/*
* If lossy chunk pages remain, make sure we've advanced schunkptr/
@@ -673,15 +1010,7 @@ tbm_iterate(TBMIterator *iterator)
PagetableEntry *chunk = tbm->schunks[iterator->schunkptr];
int schunkbit = iterator->schunkbit;
- while (schunkbit < PAGES_PER_CHUNK)
- {
- int wordnum = WORDNUM(schunkbit);
- int bitnum = BITNUM(schunkbit);
-
- if ((chunk->words[wordnum] & ((bitmapword) 1 << bitnum)) != 0)
- break;
- schunkbit++;
- }
+ tbm_advance_schunkbit(chunk, &schunkbit);
if (schunkbit < PAGES_PER_CHUNK)
{
iterator->schunkbit = schunkbit;
@@ -718,7 +1047,6 @@ tbm_iterate(TBMIterator *iterator)
{
PagetableEntry *page;
int ntuples;
- int wordnum;
/* In ONE_PAGE state, we don't allocate an spages[] array */
if (tbm->status == TBM_ONE_PAGE)
@@ -727,31 +1055,108 @@ tbm_iterate(TBMIterator *iterator)
page = tbm->spages[iterator->spageptr];
/* scan bitmap to extract individual offset numbers */
- ntuples = 0;
- for (wordnum = 0; wordnum < WORDS_PER_PAGE; wordnum++)
+ ntuples = tbm_extract_page_tuple(page, output);
+ output->blockno = page->blockno;
+ output->ntuples = ntuples;
+ output->recheck = page->recheck;
+ iterator->spageptr++;
+ return output;
+ }
+
+ /* Nothing more in the bitmap */
+ return NULL;
+}
+
+/*
+ * tbm_shared_iterate - scan through next page of a TIDBitmap
+ *
+ * As above, but this will iterate using an iterator which is shared
+ * across multiple processes. We need to acquire the iterator LWLock,
+ * before accessing the shared members.
+ */
+TBMIterateResult *
+tbm_shared_iterate(TBMSharedIterator *iterator)
+{
+ TBMIterateResult *output = &iterator->output;
+ TBMSharedIteratorState *istate = iterator->state;
+ PagetableEntry *ptbase = NULL;
+ int *idxpages = NULL;
+ int *idxchunks = NULL;
+
+ if (iterator->ptbase != NULL)
+ ptbase = iterator->ptbase->ptentry;
+ if (iterator->ptpages != NULL)
+ idxpages = iterator->ptpages->index;
+ if (iterator->ptchunks != NULL)
+ idxchunks = iterator->ptchunks->index;
+
+ /* Acquire the LWLock before accessing the shared members */
+ LWLockAcquire(&istate->lock, LW_EXCLUSIVE);
+
+ /*
+ * If lossy chunk pages remain, make sure we've advanced schunkptr/
+ * schunkbit to the next set bit.
+ */
+ while (istate->schunkptr < istate->nchunks)
+ {
+ PagetableEntry *chunk = &ptbase[idxchunks[istate->schunkptr]];
+ int schunkbit = istate->schunkbit;
+
+ tbm_advance_schunkbit(chunk, &schunkbit);
+ if (schunkbit < PAGES_PER_CHUNK)
{
- bitmapword w = page->words[wordnum];
+ istate->schunkbit = schunkbit;
+ break;
+ }
+ /* advance to next chunk */
+ istate->schunkptr++;
+ istate->schunkbit = 0;
+ }
- if (w != 0)
- {
- int off = wordnum * BITS_PER_BITMAPWORD + 1;
+ /*
+ * If both chunk and per-page data remain, must output the numerically
+ * earlier page.
+ */
+ if (istate->schunkptr < istate->nchunks)
+ {
+ PagetableEntry *chunk = &ptbase[idxchunks[istate->schunkptr]];
+ BlockNumber chunk_blockno;
- while (w != 0)
- {
- if (w & 1)
- output->offsets[ntuples++] = (OffsetNumber) off;
- off++;
- w >>= 1;
- }
- }
+ chunk_blockno = chunk->blockno + istate->schunkbit;
+
+ if (istate->spageptr >= istate->npages ||
+ chunk_blockno < ptbase[idxpages[istate->spageptr]].blockno)
+ {
+ /* Return a lossy page indicator from the chunk */
+ output->blockno = chunk_blockno;
+ output->ntuples = -1;
+ output->recheck = true;
+ istate->schunkbit++;
+
+ LWLockRelease(&istate->lock);
+ return output;
}
+ }
+
+ if (istate->spageptr < istate->npages)
+ {
+ PagetableEntry *page = &ptbase[idxpages[istate->spageptr]];
+ int ntuples;
+
+ /* scan bitmap to extract individual offset numbers */
+ ntuples = tbm_extract_page_tuple(page, output);
output->blockno = page->blockno;
output->ntuples = ntuples;
output->recheck = page->recheck;
- iterator->spageptr++;
+ istate->spageptr++;
+
+ LWLockRelease(&istate->lock);
+
return output;
}
+ LWLockRelease(&istate->lock);
+
/* Nothing more in the bitmap */
return NULL;
}
@@ -770,6 +1175,18 @@ tbm_end_iterate(TBMIterator *iterator)
}
/*
+ * tbm_end_shared_iterate - finish a shared iteration over a TIDBitmap
+ *
+ * This doesn't free any of the shared state associated with the iterator,
+ * just our backend-private state.
+ */
+void
+tbm_end_shared_iterate(TBMSharedIterator *iterator)
+{
+ pfree(iterator);
+}
+
+/*
* tbm_find_pageentry - find a PagetableEntry for the pageno
*
* Returns NULL if there is no non-lossy entry for the pageno.
@@ -791,9 +1208,7 @@ tbm_find_pageentry(const TIDBitmap *tbm, BlockNumber pageno)
return page;
}
- page = (PagetableEntry *) hash_search(tbm->pagetable,
- (void *) &pageno,
- HASH_FIND, NULL);
+ page = pagetable_lookup(tbm->pagetable, pageno);
if (page == NULL)
return NULL;
if (page->ischunk)
@@ -834,15 +1249,16 @@ tbm_get_pageentry(TIDBitmap *tbm, BlockNumber pageno)
}
/* Look up or create an entry */
- page = (PagetableEntry *) hash_search(tbm->pagetable,
- (void *) &pageno,
- HASH_ENTER, &found);
+ page = pagetable_insert(tbm->pagetable, pageno, &found);
}
/* Initialize it if not present before */
if (!found)
{
+ char oldstatus = page->status;
+
MemSet(page, 0, sizeof(PagetableEntry));
+ page->status = oldstatus;
page->blockno = pageno;
/* must count it too */
tbm->nentries++;
@@ -869,9 +1285,9 @@ tbm_page_is_lossy(const TIDBitmap *tbm, BlockNumber pageno)
bitno = pageno % PAGES_PER_CHUNK;
chunk_pageno = pageno - bitno;
- page = (PagetableEntry *) hash_search(tbm->pagetable,
- (void *) &chunk_pageno,
- HASH_FIND, NULL);
+
+ page = pagetable_lookup(tbm->pagetable, chunk_pageno);
+
if (page != NULL && page->ischunk)
{
int wordnum = WORDNUM(bitno);
@@ -912,9 +1328,7 @@ tbm_mark_page_lossy(TIDBitmap *tbm, BlockNumber pageno)
*/
if (bitno != 0)
{
- if (hash_search(tbm->pagetable,
- (void *) &pageno,
- HASH_REMOVE, NULL) != NULL)
+ if (pagetable_delete(tbm->pagetable, pageno))
{
/* It was present, so adjust counts */
tbm->nentries--;
@@ -923,14 +1337,15 @@ tbm_mark_page_lossy(TIDBitmap *tbm, BlockNumber pageno)
}
/* Look up or create entry for chunk-header page */
- page = (PagetableEntry *) hash_search(tbm->pagetable,
- (void *) &chunk_pageno,
- HASH_ENTER, &found);
+ page = pagetable_insert(tbm->pagetable, chunk_pageno, &found);
/* Initialize it if not present before */
if (!found)
{
+ char oldstatus = page->status;
+
MemSet(page, 0, sizeof(PagetableEntry));
+ page->status = oldstatus;
page->blockno = chunk_pageno;
page->ischunk = true;
/* must count it too */
@@ -939,8 +1354,11 @@ tbm_mark_page_lossy(TIDBitmap *tbm, BlockNumber pageno)
}
else if (!page->ischunk)
{
+ char oldstatus = page->status;
+
/* chunk header page was formerly non-lossy, make it lossy */
MemSet(page, 0, sizeof(PagetableEntry));
+ page->status = oldstatus;
page->blockno = chunk_pageno;
page->ischunk = true;
/* we assume it had some tuple bit(s) set, so mark it lossy */
@@ -962,7 +1380,7 @@ tbm_mark_page_lossy(TIDBitmap *tbm, BlockNumber pageno)
static void
tbm_lossify(TIDBitmap *tbm)
{
- HASH_SEQ_STATUS status;
+ pagetable_iterator i;
PagetableEntry *page;
/*
@@ -974,11 +1392,11 @@ tbm_lossify(TIDBitmap *tbm)
* push nentries down to significantly less than maxentries, or else we'll
* just end up doing this again very soon. We shoot for maxentries/2.
*/
- Assert(!tbm->iterating);
+ Assert(tbm->iterating == TBM_NOT_ITERATING);
Assert(tbm->status == TBM_HASH);
- hash_seq_init(&status, tbm->pagetable);
- while ((page = (PagetableEntry *) hash_seq_search(&status)) != NULL)
+ pagetable_start_iterate_at(tbm->pagetable, &i, tbm->lossify_start);
+ while ((page = pagetable_iterate(tbm->pagetable, &i)) != NULL)
{
if (page->ischunk)
continue; /* already a chunk header */
@@ -995,15 +1413,19 @@ tbm_lossify(TIDBitmap *tbm)
if (tbm->nentries <= tbm->maxentries / 2)
{
- /* we have done enough */
- hash_seq_term(&status);
+ /*
+ * We have made enough room. Remember where to start lossifying
+ * next round, so we evenly iterate over the hashtable.
+ */
+ tbm->lossify_start = i.cur;
break;
}
/*
* Note: tbm_mark_page_lossy may have inserted a lossy chunk into the
- * hashtable. We can continue the same seq_search scan since we do
- * not care whether we visit lossy chunks or not.
+ * hashtable and may have deleted the non-lossy chunk. We can
+ * continue the same hash table scan, since failure to visit one
+ * element or visiting the newly inserted element, isn't fatal.
*/
}
@@ -1036,3 +1458,107 @@ tbm_comparator(const void *left, const void *right)
return 1;
return 0;
}
+
+/*
+ * As above, but this will get index into PagetableEntry array. Therefore,
+ * it needs to get actual PagetableEntry using the index before comparing the
+ * blockno.
+ */
+static int
+tbm_shared_comparator(const void *left, const void *right, void *arg)
+{
+ PagetableEntry *base = (PagetableEntry *) arg;
+ PagetableEntry *lpage = &base[*(int *) left];
+ PagetableEntry *rpage = &base[*(int *) right];
+
+ if (lpage->blockno < rpage->blockno)
+ return -1;
+ else if (lpage->blockno > rpage->blockno)
+ return 1;
+ return 0;
+}
+
+/*
+ * tbm_attach_shared_iterate
+ *
+ * Allocate a backend-private iterator and attach the shared iterator state
+ * to it so that multiple processed can iterate jointly.
+ *
+ * We also converts the DSA pointers to local pointers and store them into
+ * our private iterator.
+ */
+TBMSharedIterator *
+tbm_attach_shared_iterate(dsa_area *dsa, dsa_pointer dp)
+{
+ TBMSharedIterator *iterator;
+ TBMSharedIteratorState *istate;
+
+ /*
+ * Create the TBMSharedIterator struct, with enough trailing space to
+ * serve the needs of the TBMIterateResult sub-struct.
+ */
+ iterator = (TBMSharedIterator *) palloc0(sizeof(TBMSharedIterator) +
+ MAX_TUPLES_PER_PAGE * sizeof(OffsetNumber));
+
+ istate = (TBMSharedIteratorState *) dsa_get_address(dsa, dp);
+
+ iterator->state = istate;
+
+ iterator->ptbase = dsa_get_address(dsa, istate->pagetable);
+
+ if (istate->npages)
+ iterator->ptpages = dsa_get_address(dsa, istate->spages);
+ if (istate->nchunks)
+ iterator->ptchunks = dsa_get_address(dsa, istate->schunks);
+
+ return iterator;
+}
+
+/*
+ * pagetable_allocate
+ *
+ * Callback function for allocating the memory for hashtable elements.
+ * Allocate memory for hashtable elements, using DSA if available.
+ */
+static inline void *
+pagetable_allocate(pagetable_hash *pagetable, Size size)
+{
+ TIDBitmap *tbm = (TIDBitmap *) pagetable->private_data;
+ PTEntryArray *ptbase;
+
+ if (tbm->dsa == NULL)
+ return MemoryContextAllocExtended(pagetable->ctx, size,
+ MCXT_ALLOC_HUGE | MCXT_ALLOC_ZERO);
+
+ /*
+ * Save the dsapagetable reference in dsapagetableold before allocating
+ * new memory so that pagetable_free can free the old entry.
+ */
+ tbm->dsapagetableold = tbm->dsapagetable;
+ tbm->dsapagetable = dsa_allocate_extended(tbm->dsa,
+ sizeof(PTEntryArray) + size,
+ DSA_ALLOC_HUGE | DSA_ALLOC_ZERO);
+ ptbase = dsa_get_address(tbm->dsa, tbm->dsapagetable);
+
+ return ptbase->ptentry;
+}
+
+/*
+ * pagetable_free
+ *
+ * Callback function for freeing hash table elements.
+ */
+static inline void
+pagetable_free(pagetable_hash *pagetable, void *pointer)
+{
+ TIDBitmap *tbm = (TIDBitmap *) pagetable->private_data;
+
+ /* pfree the input pointer if DSA is not available */
+ if (tbm->dsa == NULL)
+ pfree(pointer);
+ else if (DsaPointerIsValid(tbm->dsapagetableold))
+ {
+ dsa_free(tbm->dsa, tbm->dsapagetableold);
+ tbm->dsapagetableold = InvalidDsaPointer;
+ }
+}
diff --git a/src/backend/nodes/value.c b/src/backend/nodes/value.c
index a5ed5bc7c2..5d2f96c103 100644
--- a/src/backend/nodes/value.c
+++ b/src/backend/nodes/value.c
@@ -4,7 +4,7 @@
* implementation of Value nodes
*
*
- * Copyright (c) 2003-2016, PostgreSQL Global Development Group
+ * Copyright (c) 2003-2017, PostgreSQL Global Development Group
*
*
* IDENTIFICATION