}
+#ifdef XCP
/*
- * parseNodeString
- *
- * Given a character string representing a node tree, parseNodeString creates
- * the internal node structure.
- *
- * The string to be read must already have been loaded into pg_strtok().
+ * _readPlan
*/
-Node *
-parseNodeString(void)
+static Plan *
+_readPlan(void)
{
- void *return_value;
+ READ_PLAN_FIELDS(Plan);
- READ_TEMP_LOCALS();
+ READ_DONE();
+}
- token = pg_strtok(&length);
-#define MATCH(tokname, namelen) \
- (length == namelen && memcmp(token, tokname, namelen) == 0)
+/*
+ * _readResult
+ */
+static Result *
+_readResult(void)
+{
+ READ_PLAN_FIELDS(Result);
- if (MATCH("QUERY", 5))
- return_value = _readQuery();
- else if (MATCH("WITHCHECKOPTION", 15))
- return_value = _readWithCheckOption();
- else if (MATCH("SORTGROUPCLAUSE", 15))
- return_value = _readSortGroupClause();
- else if (MATCH("GROUPINGSET", 11))
- return_value = _readGroupingSet();
- else if (MATCH("WINDOWCLAUSE", 12))
- return_value = _readWindowClause();
- else if (MATCH("ROWMARKCLAUSE", 13))
- return_value = _readRowMarkClause();
- else if (MATCH("COMMONTABLEEXPR", 15))
- return_value = _readCommonTableExpr();
- else if (MATCH("SETOPERATIONSTMT", 16))
- return_value = _readSetOperationStmt();
- else if (MATCH("ALIAS", 5))
- return_value = _readAlias();
- else if (MATCH("RANGEVAR", 8))
- return_value = _readRangeVar();
- else if (MATCH("INTOCLAUSE", 10))
- return_value = _readIntoClause();
- else if (MATCH("VAR", 3))
- return_value = _readVar();
- else if (MATCH("CONST", 5))
- return_value = _readConst();
- else if (MATCH("PARAM", 5))
- return_value = _readParam();
- else if (MATCH("AGGREF", 6))
- return_value = _readAggref();
- else if (MATCH("GROUPINGFUNC", 12))
- return_value = _readGroupingFunc();
- else if (MATCH("WINDOWFUNC", 10))
- return_value = _readWindowFunc();
- else if (MATCH("ARRAYREF", 8))
- return_value = _readArrayRef();
- else if (MATCH("FUNCEXPR", 8))
- return_value = _readFuncExpr();
- else if (MATCH("NAMEDARGEXPR", 12))
- return_value = _readNamedArgExpr();
- else if (MATCH("OPEXPR", 6))
- return_value = _readOpExpr();
- else if (MATCH("DISTINCTEXPR", 12))
- return_value = _readDistinctExpr();
- else if (MATCH("NULLIFEXPR", 10))
- return_value = _readNullIfExpr();
- else if (MATCH("SCALARARRAYOPEXPR", 17))
- return_value = _readScalarArrayOpExpr();
- else if (MATCH("BOOLEXPR", 8))
- return_value = _readBoolExpr();
- else if (MATCH("SUBLINK", 7))
- return_value = _readSubLink();
- else if (MATCH("FIELDSELECT", 11))
- return_value = _readFieldSelect();
- else if (MATCH("FIELDSTORE", 10))
- return_value = _readFieldStore();
- else if (MATCH("RELABELTYPE", 11))
- return_value = _readRelabelType();
- else if (MATCH("COERCEVIAIO", 11))
- return_value = _readCoerceViaIO();
- else if (MATCH("ARRAYCOERCEEXPR", 15))
- return_value = _readArrayCoerceExpr();
- else if (MATCH("CONVERTROWTYPEEXPR", 18))
- return_value = _readConvertRowtypeExpr();
- else if (MATCH("COLLATE", 7))
- return_value = _readCollateExpr();
- else if (MATCH("CASE", 4))
- return_value = _readCaseExpr();
- else if (MATCH("WHEN", 4))
- return_value = _readCaseWhen();
- else if (MATCH("CASETESTEXPR", 12))
- return_value = _readCaseTestExpr();
- else if (MATCH("ARRAY", 5))
- return_value = _readArrayExpr();
- else if (MATCH("ROW", 3))
- return_value = _readRowExpr();
- else if (MATCH("ROWCOMPARE", 10))
- return_value = _readRowCompareExpr();
- else if (MATCH("COALESCE", 8))
- return_value = _readCoalesceExpr();
- else if (MATCH("MINMAX", 6))
- return_value = _readMinMaxExpr();
- else if (MATCH("XMLEXPR", 7))
- return_value = _readXmlExpr();
- else if (MATCH("NULLTEST", 8))
- return_value = _readNullTest();
- else if (MATCH("BOOLEANTEST", 11))
- return_value = _readBooleanTest();
- else if (MATCH("COERCETODOMAIN", 14))
- return_value = _readCoerceToDomain();
- else if (MATCH("COERCETODOMAINVALUE", 19))
- return_value = _readCoerceToDomainValue();
- else if (MATCH("SETTODEFAULT", 12))
- return_value = _readSetToDefault();
- else if (MATCH("CURRENTOFEXPR", 13))
- return_value = _readCurrentOfExpr();
- else if (MATCH("INFERENCEELEM", 13))
+ READ_NODE_FIELD(resconstantqual);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readModifyTable
+ */
+static ModifyTable *
+_readModifyTable(void)
+{
+ READ_PLAN_FIELDS(ModifyTable);
+
+ READ_ENUM_FIELD(operation, CmdType);
+ READ_BOOL_FIELD(canSetTag);
+ READ_UINT_FIELD(nominalRelation);
+ READ_NODE_FIELD(resultRelations);
+ READ_INT_FIELD(resultRelIndex);
+ READ_NODE_FIELD(plans);
+ READ_NODE_FIELD(withCheckOptionLists);
+ READ_NODE_FIELD(returningLists);
+ READ_NODE_FIELD(fdwPrivLists);
+ READ_NODE_FIELD(rowMarks);
+ READ_INT_FIELD(epqParam);
+ READ_ENUM_FIELD(onConflictAction, OnConflictAction);
+#ifdef XCP
+ if (portable_input)
+ READ_RELID_LIST_FIELD(arbiterIndexes);
+ else
+#endif
+ READ_NODE_FIELD(arbiterIndexes);
+ READ_NODE_FIELD(onConflictSet);
+ READ_NODE_FIELD(onConflictWhere);
+ READ_INT_FIELD(exclRelRTI);
+ READ_NODE_FIELD(exclRelTlist);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readAppend
+ */
+static Append *
+_readAppend(void)
+{
+ READ_PLAN_FIELDS(Append);
+
+ READ_NODE_FIELD(appendplans);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readMergeAppend
+ */
+static MergeAppend *
+_readMergeAppend(void)
+{
+ int i;
+ READ_PLAN_FIELDS(MergeAppend);
+
+ READ_NODE_FIELD(mergeplans);
+ READ_INT_FIELD(numCols);
+
+ token = pg_strtok(&length); /* skip :sortColIdx */
+ local_node->sortColIdx = (AttrNumber *) palloc(local_node->numCols * sizeof(AttrNumber));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ local_node->sortColIdx[i] = atoi(token);
+ }
+
+ token = pg_strtok(&length); /* skip :sortOperators */
+ local_node->sortOperators = (Oid *) palloc(local_node->numCols * sizeof(Oid));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ if (portable_input)
+ {
+ char *nspname; /* namespace name */
+ char *oprname; /* operator name */
+ char *leftnspname; /* left type namespace */
+ char *leftname; /* left type name */
+ Oid oprleft; /* left type */
+ char *rightnspname; /* right type namespace */
+ char *rightname; /* right type name */
+ Oid oprright; /* right type */
+ /* token is already set to nspname */
+ nspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* get operator name */
+ oprname = nullable_string(token, length);
+ token = pg_strtok(&length); /* left type namespace */
+ leftnspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* left type name */
+ leftname = nullable_string(token, length);
+ token = pg_strtok(&length); /* right type namespace */
+ rightnspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* right type name */
+ rightname = nullable_string(token, length);
+ if (leftname)
+ oprleft = get_typname_typid(leftname,
+ NSP_OID(leftnspname));
+ else
+ oprleft = InvalidOid;
+ if (rightname)
+ oprright = get_typname_typid(rightname,
+ NSP_OID(rightnspname));
+ else
+ oprright = InvalidOid;
+ local_node->sortOperators[i] = get_operid(oprname,
+ oprleft,
+ oprright,
+ NSP_OID(nspname));
+ }
+ else
+ local_node->sortOperators[i] = atooid(token);
+ }
+
+ token = pg_strtok(&length); /* skip :collations */
+ local_node->collations = (Oid *) palloc(local_node->numCols * sizeof(Oid));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ if (portable_input)
+ {
+ char *nspname; /* namespace name */
+ char *collname; /* collation name */
+ int collencoding; /* collation encoding */
+ /* the token is already read */
+ nspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* get collname */
+ collname = nullable_string(token, length);
+ token = pg_strtok(&length); /* get nargs */
+ collencoding = atoi(token);
+ if (collname)
+ local_node->collations[i] = get_collid(collname,
+ collencoding,
+ NSP_OID(nspname));
+ else
+ local_node->collations[i] = InvalidOid;
+ }
+ else
+ local_node->collations[i] = atooid(token);
+ }
+
+ token = pg_strtok(&length); /* skip :nullsFirst */
+ local_node->nullsFirst = (bool *) palloc(local_node->numCols * sizeof(bool));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ local_node->nullsFirst[i] = strtobool(token);
+ }
+
+ READ_DONE();
+}
+
+
+/*
+ * _readRecursiveUnion
+ */
+static RecursiveUnion *
+_readRecursiveUnion(void)
+{
+ int i;
+ READ_PLAN_FIELDS(RecursiveUnion);
+
+ READ_INT_FIELD(wtParam);
+ READ_INT_FIELD(numCols);
+
+ token = pg_strtok(&length); /* skip :dupColIdx */
+ local_node->dupColIdx = (AttrNumber *) palloc(local_node->numCols * sizeof(AttrNumber));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ local_node->dupColIdx[i] = atoi(token);
+ }
+
+ token = pg_strtok(&length); /* skip :dupOperators */
+ local_node->dupOperators = (Oid *) palloc(local_node->numCols * sizeof(Oid));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ local_node->dupOperators[i] = atooid(token);
+ }
+
+ READ_LONG_FIELD(numGroups);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readBitmapAnd
+ */
+static BitmapAnd *
+_readBitmapAnd(void)
+{
+ READ_PLAN_FIELDS(BitmapAnd);
+
+ READ_NODE_FIELD(bitmapplans);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readBitmapOr
+ */
+static BitmapOr *
+_readBitmapOr(void)
+{
+ READ_PLAN_FIELDS(BitmapOr);
+
+ READ_NODE_FIELD(bitmapplans);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readScan
+ */
+static Scan *
+_readScan(void)
+{
+ READ_SCAN_FIELDS(Scan);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readSeqScan
+ */
+static SeqScan *
+_readSeqScan(void)
+{
+ READ_SCAN_FIELDS(SeqScan);
+
+ READ_DONE();
+}
+
+/*
+ * _readSampleScan
+ */
+static SampleScan *
+_readSampleScan(void)
+{
+ READ_SCAN_FIELDS(SampleScan);
+ READ_NODE_FIELD(tablesample);
+
+ READ_DONE();
+}
+
+/*
+ * _readIndexScan
+ */
+static IndexScan *
+_readIndexScan(void)
+{
+ READ_SCAN_FIELDS(IndexScan);
+
+ if (portable_input)
+ READ_RELID_FIELD(indexid);
+ else
+ READ_OID_FIELD(indexid);
+ READ_NODE_FIELD(indexqual);
+ READ_NODE_FIELD(indexqualorig);
+ READ_NODE_FIELD(indexorderby);
+ READ_NODE_FIELD(indexorderbyorig);
+ READ_NODE_FIELD(indexorderbyops);
+ READ_ENUM_FIELD(indexorderdir, ScanDirection);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readIndexOnlyScan
+ */
+static IndexOnlyScan *
+_readIndexOnlyScan(void)
+{
+ READ_SCAN_FIELDS(IndexOnlyScan);
+
+ if (portable_input)
+ READ_RELID_FIELD(indexid);
+ else
+ READ_OID_FIELD(indexid);
+ READ_NODE_FIELD(indexqual);
+ READ_NODE_FIELD(indexorderby);
+ READ_NODE_FIELD(indextlist);
+ READ_ENUM_FIELD(indexorderdir, ScanDirection);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readBitmapIndexScan
+ */
+static BitmapIndexScan *
+_readBitmapIndexScan(void)
+{
+ READ_SCAN_FIELDS(BitmapIndexScan);
+
+ if (portable_input)
+ READ_RELID_FIELD(indexid);
+ else
+ READ_OID_FIELD(indexid);
+ READ_NODE_FIELD(indexqual);
+ READ_NODE_FIELD(indexqualorig);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readBitmapHeapScan
+ */
+static BitmapHeapScan *
+_readBitmapHeapScan(void)
+{
+ READ_SCAN_FIELDS(BitmapHeapScan);
+
+ READ_NODE_FIELD(bitmapqualorig);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readTidScan
+ */
+static TidScan *
+_readTidScan(void)
+{
+ READ_SCAN_FIELDS(TidScan);
+
+ READ_NODE_FIELD(tidquals);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readSubqueryScan
+ */
+static SubqueryScan *
+_readSubqueryScan(void)
+{
+ READ_SCAN_FIELDS(SubqueryScan);
+
+ READ_NODE_FIELD(subplan);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readFunctionScan
+ */
+static FunctionScan *
+_readFunctionScan(void)
+{
+ READ_SCAN_FIELDS(FunctionScan);
+
+ READ_NODE_FIELD(functions);
+ READ_BOOL_FIELD(funcordinality);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readValuesScan
+ */
+static ValuesScan *
+_readValuesScan(void)
+{
+ READ_SCAN_FIELDS(ValuesScan);
+
+ READ_NODE_FIELD(values_lists);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readCteScan
+ */
+static CteScan *
+_readCteScan(void)
+{
+ READ_SCAN_FIELDS(CteScan);
+
+ READ_INT_FIELD(ctePlanId);
+ READ_INT_FIELD(cteParam);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readWorkTableScan
+ */
+static WorkTableScan *
+_readWorkTableScan(void)
+{
+ READ_SCAN_FIELDS(WorkTableScan);
+
+ READ_INT_FIELD(wtParam);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readJoin
+ */
+static Join *
+_readJoin(void)
+{
+ READ_JOIN_FIELDS(Join);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readNestLoop
+ */
+static NestLoop *
+_readNestLoop(void)
+{
+ READ_JOIN_FIELDS(NestLoop);
+
+ READ_NODE_FIELD(nestParams);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readMergeJoin
+ */
+static MergeJoin *
+_readMergeJoin(void)
+{
+ int numCols;
+ int i;
+ READ_JOIN_FIELDS(MergeJoin);
+
+ READ_NODE_FIELD(mergeclauses);
+ numCols = list_length(local_node->mergeclauses);
+
+
+ token = pg_strtok(&length); /* skip :mergeFamilies */
+ local_node->mergeFamilies = (Oid *) palloc(numCols * sizeof(Oid));
+ for (i = 0; i < numCols; i++)
+ {
+ token = pg_strtok(&length);
+ local_node->mergeFamilies[i] = atooid(token);
+ }
+
+ token = pg_strtok(&length); /* skip :mergeCollations */
+ local_node->mergeCollations = (Oid *) palloc(numCols * sizeof(Oid));
+ for (i = 0; i < numCols; i++)
+ {
+ token = pg_strtok(&length);
+ if (portable_input)
+ {
+ char *nspname; /* namespace name */
+ char *collname; /* collation name */
+ int collencoding; /* collation encoding */
+ /* the token is already read */
+ nspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* get collname */
+ collname = nullable_string(token, length);
+ token = pg_strtok(&length); /* get nargs */
+ collencoding = atoi(token);
+ if (collname)
+ local_node->mergeCollations[i] = get_collid(collname,
+ collencoding,
+ NSP_OID(nspname));
+ else
+ local_node->mergeCollations[i] = InvalidOid;
+ }
+ else
+ local_node->mergeCollations[i] = atooid(token);
+ }
+
+ token = pg_strtok(&length); /* skip :mergeStrategies */
+ local_node->mergeStrategies = (int *) palloc(numCols * sizeof(int));
+ for (i = 0; i < numCols; i++)
+ {
+ token = pg_strtok(&length);
+ local_node->mergeStrategies[i] = atoi(token);
+ }
+
+ token = pg_strtok(&length); /* skip :mergeNullsFirst */
+ local_node->mergeNullsFirst = (bool *) palloc(numCols * sizeof(bool));
+ for (i = 0; i < numCols; i++)
+ {
+ token = pg_strtok(&length);
+ local_node->mergeNullsFirst[i] = strtobool(token);
+ }
+
+ READ_DONE();
+}
+
+
+/*
+ * _readHashJoin
+ */
+static HashJoin *
+_readHashJoin(void)
+{
+ READ_JOIN_FIELDS(HashJoin);
+
+ READ_NODE_FIELD(hashclauses);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readMaterial
+ */
+static Material *
+_readMaterial(void)
+{
+ READ_PLAN_FIELDS(Material);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readSort
+ */
+static Sort *
+_readSort(void)
+{
+ int i;
+ READ_PLAN_FIELDS(Sort);
+
+ READ_INT_FIELD(numCols);
+
+ token = pg_strtok(&length); /* skip :sortColIdx */
+ local_node->sortColIdx = (AttrNumber *) palloc(local_node->numCols * sizeof(AttrNumber));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ local_node->sortColIdx[i] = atoi(token);
+ }
+
+ token = pg_strtok(&length); /* skip :sortOperators */
+ local_node->sortOperators = (Oid *) palloc(local_node->numCols * sizeof(Oid));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ if (portable_input)
+ {
+ char *nspname; /* namespace name */
+ char *oprname; /* operator name */
+ char *leftnspname; /* left type namespace */
+ char *leftname; /* left type name */
+ Oid oprleft; /* left type */
+ char *rightnspname; /* right type namespace */
+ char *rightname; /* right type name */
+ Oid oprright; /* right type */
+ /* token is already set to nspname */
+ nspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* get operator name */
+ oprname = nullable_string(token, length);
+ token = pg_strtok(&length); /* left type namespace */
+ leftnspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* left type name */
+ leftname = nullable_string(token, length);
+ token = pg_strtok(&length); /* right type namespace */
+ rightnspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* right type name */
+ rightname = nullable_string(token, length);
+ if (leftname)
+ oprleft = get_typname_typid(leftname,
+ NSP_OID(leftnspname));
+ else
+ oprleft = InvalidOid;
+ if (rightname)
+ oprright = get_typname_typid(rightname,
+ NSP_OID(rightnspname));
+ else
+ oprright = InvalidOid;
+ local_node->sortOperators[i] = get_operid(oprname,
+ oprleft,
+ oprright,
+ NSP_OID(nspname));
+ }
+ else
+ local_node->sortOperators[i] = atooid(token);
+ }
+
+ token = pg_strtok(&length); /* skip :collations */
+ local_node->collations = (Oid *) palloc(local_node->numCols * sizeof(Oid));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ if (portable_input)
+ {
+ char *nspname; /* namespace name */
+ char *collname; /* collation name */
+ int collencoding; /* collation encoding */
+ /* the token is already read */
+ nspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* get collname */
+ collname = nullable_string(token, length);
+ token = pg_strtok(&length); /* get nargs */
+ collencoding = atoi(token);
+ if (collname)
+ local_node->collations[i] = get_collid(collname,
+ collencoding,
+ NSP_OID(nspname));
+ else
+ local_node->collations[i] = InvalidOid;
+ }
+ else
+ local_node->collations[i] = atooid(token);
+ }
+
+ token = pg_strtok(&length); /* skip :nullsFirst */
+ local_node->nullsFirst = (bool *) palloc(local_node->numCols * sizeof(bool));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ local_node->nullsFirst[i] = strtobool(token);
+ }
+
+ READ_DONE();
+}
+
+
+/*
+ * _readGroup
+ */
+static Group *
+_readGroup(void)
+{
+ int i;
+ READ_PLAN_FIELDS(Group);
+
+ READ_INT_FIELD(numCols);
+
+ token = pg_strtok(&length); /* skip :grpColIdx */
+ local_node->grpColIdx = (AttrNumber *) palloc(local_node->numCols * sizeof(AttrNumber));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ local_node->grpColIdx[i] = atoi(token);
+ }
+
+ token = pg_strtok(&length); /* skip :grpOperators */
+ local_node->grpOperators = (Oid *) palloc(local_node->numCols * sizeof(Oid));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ if (portable_input)
+ {
+ char *nspname; /* namespace name */
+ char *oprname; /* operator name */
+ char *leftnspname; /* left type namespace */
+ char *leftname; /* left type name */
+ Oid oprleft; /* left type */
+ char *rightnspname; /* right type namespace */
+ char *rightname; /* right type name */
+ Oid oprright; /* right type */
+ /* token is already set to nspname */
+ nspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* get operator name */
+ oprname = nullable_string(token, length);
+ token = pg_strtok(&length); /* left type namespace */
+ leftnspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* left type name */
+ leftname = nullable_string(token, length);
+ token = pg_strtok(&length); /* right type namespace */
+ rightnspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* right type name */
+ rightname = nullable_string(token, length);
+ if (leftname)
+ oprleft = get_typname_typid(leftname,
+ NSP_OID(leftnspname));
+ else
+ oprleft = InvalidOid;
+ if (rightname)
+ oprright = get_typname_typid(rightname,
+ NSP_OID(rightnspname));
+ else
+ oprright = InvalidOid;
+ local_node->grpOperators[i] = get_operid(oprname,
+ oprleft,
+ oprright,
+ NSP_OID(nspname));
+ }
+ else
+ local_node->grpOperators[i] = atooid(token);
+ }
+
+ READ_DONE();
+}
+
+
+/*
+ * _readAgg
+ */
+static Agg *
+_readAgg(void)
+{
+ int i;
+ READ_PLAN_FIELDS(Agg);
+
+ READ_ENUM_FIELD(aggstrategy, AggStrategy);
+ READ_ENUM_FIELD(aggdistribution, AggDistribution);
+ READ_INT_FIELD(numCols);
+
+ token = pg_strtok(&length); /* skip :grpColIdx */
+ local_node->grpColIdx = (AttrNumber *) palloc(local_node->numCols * sizeof(AttrNumber));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ local_node->grpColIdx[i] = atoi(token);
+ }
+
+ token = pg_strtok(&length); /* skip :grpOperators */
+ local_node->grpOperators = (Oid *) palloc(local_node->numCols * sizeof(Oid));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ if (portable_input)
+ {
+ char *nspname; /* namespace name */
+ char *oprname; /* operator name */
+ char *leftnspname; /* left type namespace */
+ char *leftname; /* left type name */
+ Oid oprleft; /* left type */
+ char *rightnspname; /* right type namespace */
+ char *rightname; /* right type name */
+ Oid oprright; /* right type */
+ /* token is already set to nspname */
+ nspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* get operator name */
+ oprname = nullable_string(token, length);
+ token = pg_strtok(&length); /* left type namespace */
+ leftnspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* left type name */
+ leftname = nullable_string(token, length);
+ token = pg_strtok(&length); /* right type namespace */
+ rightnspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* right type name */
+ rightname = nullable_string(token, length);
+ if (leftname)
+ oprleft = get_typname_typid(leftname,
+ NSP_OID(leftnspname));
+ else
+ oprleft = InvalidOid;
+ if (rightname)
+ oprright = get_typname_typid(rightname,
+ NSP_OID(rightnspname));
+ else
+ oprright = InvalidOid;
+ local_node->grpOperators[i] = get_operid(oprname,
+ oprleft,
+ oprright,
+ NSP_OID(nspname));
+ }
+ else
+ local_node->grpOperators[i] = atooid(token);
+ }
+
+ READ_LONG_FIELD(numGroups);
-
++ READ_BITMAPSET_FIELD(aggParams);
+ READ_NODE_FIELD(groupingSets);
+ READ_NODE_FIELD(chain);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readWindowAgg
+ */
+static WindowAgg *
+_readWindowAgg(void)
+{
+ int i;
+ READ_PLAN_FIELDS(WindowAgg);
+
+ READ_INT_FIELD(winref);
+ READ_INT_FIELD(partNumCols);
+
+ token = pg_strtok(&length); /* skip :partColIdx */
+ local_node->partColIdx = (AttrNumber *) palloc(local_node->partNumCols * sizeof(AttrNumber));
+ for (i = 0; i < local_node->partNumCols; i++)
+ {
+ token = pg_strtok(&length);
+ local_node->partColIdx[i] = atoi(token);
+ }
+
+ token = pg_strtok(&length); /* skip :partOperators */
+ local_node->partOperators = (Oid *) palloc(local_node->partNumCols * sizeof(Oid));
+ for (i = 0; i < local_node->partNumCols; i++)
+ {
+ token = pg_strtok(&length);
+ if (portable_input)
+ {
+ char *nspname; /* namespace name */
+ char *oprname; /* operator name */
+ char *leftnspname; /* left type namespace */
+ char *leftname; /* left type name */
+ Oid oprleft; /* left type */
+ char *rightnspname; /* right type namespace */
+ char *rightname; /* right type name */
+ Oid oprright; /* right type */
+ /* token is already set to nspname */
+ nspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* get operator name */
+ oprname = nullable_string(token, length);
+ token = pg_strtok(&length); /* left type namespace */
+ leftnspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* left type name */
+ leftname = nullable_string(token, length);
+ token = pg_strtok(&length); /* right type namespace */
+ rightnspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* right type name */
+ rightname = nullable_string(token, length);
+ if (leftname)
+ oprleft = get_typname_typid(leftname,
+ NSP_OID(leftnspname));
+ else
+ oprleft = InvalidOid;
+ if (rightname)
+ oprright = get_typname_typid(rightname,
+ NSP_OID(rightnspname));
+ else
+ oprright = InvalidOid;
+ local_node->partOperators[i] = get_operid(oprname,
+ oprleft,
+ oprright,
+ NSP_OID(nspname));
+ }
+ else
+ local_node->partOperators[i] = atooid(token);
+ }
+
+ READ_INT_FIELD(ordNumCols);
+
+ token = pg_strtok(&length); /* skip :ordColIdx */
+ local_node->ordColIdx = (AttrNumber *) palloc(local_node->ordNumCols * sizeof(AttrNumber));
+ for (i = 0; i < local_node->ordNumCols; i++)
+ {
+ token = pg_strtok(&length);
+ local_node->ordColIdx[i] = atoi(token);
+ }
+
+ token = pg_strtok(&length); /* skip :ordOperators */
+ local_node->ordOperators = (Oid *) palloc(local_node->ordNumCols * sizeof(Oid));
+ for (i = 0; i < local_node->ordNumCols; i++)
+ {
+ token = pg_strtok(&length);
+ if (portable_input)
+ {
+ char *nspname; /* namespace name */
+ char *oprname; /* operator name */
+ char *leftnspname; /* left type namespace */
+ char *leftname; /* left type name */
+ Oid oprleft; /* left type */
+ char *rightnspname; /* right type namespace */
+ char *rightname; /* right type name */
+ Oid oprright; /* right type */
+ /* token is already set to nspname */
+ nspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* get operator name */
+ oprname = nullable_string(token, length);
+ token = pg_strtok(&length); /* left type namespace */
+ leftnspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* left type name */
+ leftname = nullable_string(token, length);
+ token = pg_strtok(&length); /* right type namespace */
+ rightnspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* right type name */
+ rightname = nullable_string(token, length);
+ if (leftname)
+ oprleft = get_typname_typid(leftname,
+ NSP_OID(leftnspname));
+ else
+ oprleft = InvalidOid;
+ if (rightname)
+ oprright = get_typname_typid(rightname,
+ NSP_OID(rightnspname));
+ else
+ oprright = InvalidOid;
+ local_node->ordOperators[i] = get_operid(oprname,
+ oprleft,
+ oprright,
+ NSP_OID(nspname));
+ }
+ else
+ local_node->ordOperators[i] = atooid(token);
+ }
+
+ READ_INT_FIELD(frameOptions);
+ READ_NODE_FIELD(startOffset);
+ READ_NODE_FIELD(endOffset);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readUnique
+ */
+static Unique *
+_readUnique(void)
+{
+ int i;
+ READ_PLAN_FIELDS(Unique);
+
+ READ_INT_FIELD(numCols);
+
+ token = pg_strtok(&length); /* skip :uniqColIdx */
+ local_node->uniqColIdx = (AttrNumber *) palloc(local_node->numCols * sizeof(AttrNumber));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ local_node->uniqColIdx[i] = atoi(token);
+ }
+
+ token = pg_strtok(&length); /* skip :uniqOperators */
+ local_node->uniqOperators = (Oid *) palloc(local_node->numCols * sizeof(Oid));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ if (portable_input)
+ {
+ char *nspname; /* namespace name */
+ char *oprname; /* operator name */
+ char *leftnspname; /* left type namespace */
+ char *leftname; /* left type name */
+ Oid oprleft; /* left type */
+ char *rightnspname; /* right type namespace */
+ char *rightname; /* right type name */
+ Oid oprright; /* right type */
+ /* token is already set to nspname */
+ nspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* get operator name */
+ oprname = nullable_string(token, length);
+ token = pg_strtok(&length); /* left type namespace */
+ leftnspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* left type name */
+ leftname = nullable_string(token, length);
+ token = pg_strtok(&length); /* right type namespace */
+ rightnspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* right type name */
+ rightname = nullable_string(token, length);
+ if (leftname)
+ oprleft = get_typname_typid(leftname,
+ NSP_OID(leftnspname));
+ else
+ oprleft = InvalidOid;
+ if (rightname)
+ oprright = get_typname_typid(rightname,
+ NSP_OID(rightnspname));
+ else
+ oprright = InvalidOid;
+ local_node->uniqOperators[i] = get_operid(oprname,
+ oprleft,
+ oprright,
+ NSP_OID(nspname));
+ }
+ else
+ local_node->uniqOperators[i] = atooid(token);
+ }
+
+ READ_DONE();
+}
+
+
+/*
+ * _readHash
+ */
+static Hash *
+_readHash(void)
+{
+ READ_PLAN_FIELDS(Hash);
+
+ if (portable_input)
+ READ_RELID_FIELD(skewTable);
+ else
+ 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();
+}
+
+
+/*
+ * _readSetOp
+ */
+static SetOp *
+_readSetOp(void)
+{
+ int i;
+ READ_PLAN_FIELDS(SetOp);
+
+ READ_ENUM_FIELD(cmd, SetOpCmd);
+ READ_ENUM_FIELD(strategy, SetOpStrategy);
+ READ_INT_FIELD(numCols);
+
+ token = pg_strtok(&length); /* skip :dupColIdx */
+ local_node->dupColIdx = (AttrNumber *) palloc(local_node->numCols * sizeof(AttrNumber));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ local_node->dupColIdx[i] = atoi(token);
+ }
+
+ token = pg_strtok(&length); /* skip :dupOperators */
+ local_node->dupOperators = (Oid *) palloc(local_node->numCols * sizeof(Oid));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ local_node->dupOperators[i] = atooid(token);
+ }
+
+ READ_INT_FIELD(flagColIdx);
+ READ_INT_FIELD(firstFlag);
+ READ_LONG_FIELD(numGroups);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readLimit
+ */
+static Limit *
+_readLimit(void)
+{
+ READ_PLAN_FIELDS(Limit);
+
+ READ_NODE_FIELD(limitOffset);
+ READ_NODE_FIELD(limitCount);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readRemoteSubplan
+ */
+static RemoteSubplan *
+_readRemoteSubplan(void)
+{
+ READ_SCAN_FIELDS(RemoteSubplan);
+
+ READ_CHAR_FIELD(distributionType);
+ READ_INT_FIELD(distributionKey);
+ READ_NODE_FIELD(distributionNodes);
+ READ_NODE_FIELD(distributionRestrict);
+ READ_NODE_FIELD(nodeList);
+ READ_BOOL_FIELD(execOnAll);
+ READ_NODE_FIELD(sort);
+ READ_STRING_FIELD(cursor);
+ READ_INT_FIELD(unique);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readRemoteStmt
+ */
+static RemoteStmt *
+_readRemoteStmt(void)
+{
+ int i;
+ READ_LOCALS(RemoteStmt);
+
+ READ_ENUM_FIELD(commandType, CmdType);
+ READ_BOOL_FIELD(hasReturning);
+ READ_NODE_FIELD(planTree);
+ READ_NODE_FIELD(rtable);
+ READ_NODE_FIELD(resultRelations);
+ READ_NODE_FIELD(subplans);
+ READ_INT_FIELD(nParamExec);
+ READ_INT_FIELD(nParamRemote);
+ if (local_node->nParamRemote > 0)
+ {
+ local_node->remoteparams = (RemoteParam *) palloc(
+ local_node->nParamRemote * sizeof(RemoteParam));
+ for (i = 0; i < local_node->nParamRemote; i++)
+ {
+ RemoteParam *rparam = &(local_node->remoteparams[i]);
+ token = pg_strtok(&length); /* skip :paramkind */
+ token = pg_strtok(&length);
+ rparam->paramkind = (ParamKind) atoi(token);
+
+ token = pg_strtok(&length); /* skip :paramid */
+ token = pg_strtok(&length);
+ rparam->paramid = atoi(token);
+
+ token = pg_strtok(&length); /* skip :paramused */
+ token = pg_strtok(&length);
+ rparam->paramused = atoi(token);
+
+ token = pg_strtok(&length); /* skip :paramtype */
+ if (portable_input)
+ {
+ char *nspname; /* namespace name */
+ char *typname; /* data type name */
+ token = pg_strtok(&length); /* get nspname */
+ nspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* get typname */
+ typname = nullable_string(token, length);
+ if (typname)
+ rparam->paramtype = get_typname_typid(typname,
+ NSP_OID(nspname));
+ else
+ rparam->paramtype = InvalidOid;
+ }
+ else
+ {
+ token = pg_strtok(&length);
+ rparam->paramtype = atooid(token);
+ }
+ }
+ }
+ else
+ local_node->remoteparams = NULL;
+
+ READ_NODE_FIELD(rowMarks);
+ READ_CHAR_FIELD(distributionType);
+ READ_INT_FIELD(distributionKey);
+ READ_NODE_FIELD(distributionNodes);
+ READ_NODE_FIELD(distributionRestrict);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readSimpleSort
+ */
+static SimpleSort *
+_readSimpleSort(void)
+{
+ int i;
+ READ_LOCALS(SimpleSort);
+
+ READ_INT_FIELD(numCols);
+
+ token = pg_strtok(&length); /* skip :sortColIdx */
+ local_node->sortColIdx = (AttrNumber *) palloc(local_node->numCols * sizeof(AttrNumber));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ local_node->sortColIdx[i] = atoi(token);
+ }
+
+ token = pg_strtok(&length); /* skip :sortOperators */
+ local_node->sortOperators = (Oid *) palloc(local_node->numCols * sizeof(Oid));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ if (portable_input)
+ {
+ char *nspname; /* namespace name */
+ char *oprname; /* operator name */
+ char *leftnspname; /* left type namespace */
+ char *leftname; /* left type name */
+ Oid oprleft; /* left type */
+ char *rightnspname; /* right type namespace */
+ char *rightname; /* right type name */
+ Oid oprright; /* right type */
+ /* token is already set to nspname */
+ nspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* get operator name */
+ oprname = nullable_string(token, length);
+ token = pg_strtok(&length); /* left type namespace */
+ leftnspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* left type name */
+ leftname = nullable_string(token, length);
+ token = pg_strtok(&length); /* right type namespace */
+ rightnspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* right type name */
+ rightname = nullable_string(token, length);
+ if (leftname)
+ oprleft = get_typname_typid(leftname,
+ NSP_OID(leftnspname));
+ else
+ oprleft = InvalidOid;
+ if (rightname)
+ oprright = get_typname_typid(rightname,
+ NSP_OID(rightnspname));
+ else
+ oprright = InvalidOid;
+ local_node->sortOperators[i] = get_operid(oprname,
+ oprleft,
+ oprright,
+ NSP_OID(nspname));
+ }
+ else
+ local_node->sortOperators[i] = atooid(token);
+ }
+
+ token = pg_strtok(&length); /* skip :sortCollations */
+ local_node->sortCollations = (Oid *) palloc(local_node->numCols * sizeof(Oid));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ if (portable_input)
+ {
+ char *nspname; /* namespace name */
+ char *collname; /* collation name */
+ int collencoding; /* collation encoding */
+ /* the token is already read */
+ nspname = nullable_string(token, length);
+ token = pg_strtok(&length); /* get collname */
+ collname = nullable_string(token, length);
+ token = pg_strtok(&length); /* get nargs */
+ collencoding = atoi(token);
+ if (collname)
+ local_node->sortCollations[i] = get_collid(collname,
+ collencoding,
+ NSP_OID(nspname));
+ else
+ local_node->sortCollations[i] = InvalidOid;
+ }
+ else
+ local_node->sortCollations[i] = atooid(token);
+ }
+
+ token = pg_strtok(&length); /* skip :nullsFirst */
+ local_node->nullsFirst = (bool *) palloc(local_node->numCols * sizeof(bool));
+ for (i = 0; i < local_node->numCols; i++)
+ {
+ token = pg_strtok(&length);
+ local_node->nullsFirst[i] = strtobool(token);
+ }
+
+ READ_DONE();
+}
+
+
+/*
+ * _readNestLoopParam
+ */
+static NestLoopParam *
+_readNestLoopParam(void)
+{
+ READ_LOCALS(NestLoopParam);
+
+ READ_INT_FIELD(paramno);
+ READ_NODE_FIELD(paramval);
+
+ READ_DONE();
+}
+
+
+/*
+ * _readPlanRowMark
+ */
+static PlanRowMark *
+_readPlanRowMark(void)
+{
+ READ_LOCALS(PlanRowMark);
+
+ READ_UINT_FIELD(rti);
+ READ_UINT_FIELD(prti);
+ READ_UINT_FIELD(rowmarkId);
+ READ_ENUM_FIELD(markType, RowMarkType);
+ READ_INT_FIELD(allMarkTypes);
+ READ_ENUM_FIELD(strength, LockClauseStrength);
+ READ_ENUM_FIELD(waitPolicy, LockWaitPolicy);
+ READ_BOOL_FIELD(isParent);
+
+ READ_DONE();
+}
+
+/*
+ * _readLockRows
+ */
+static LockRows *
+_readLockRows(void)
+{
+ READ_PLAN_FIELDS(LockRows);
+
+ READ_NODE_FIELD(rowMarks);
+ READ_INT_FIELD(epqParam);
+
+ READ_DONE();
+}
+
+#endif /* XCP */
+
+
+/*
+ * parseNodeString
+ *
+ * Given a character string representing a node tree, parseNodeString creates
+ * the internal node structure.
+ *
+ * The string to be read must already have been loaded into pg_strtok().
+ */
+Node *
+parseNodeString(void)
+{
+ void *return_value;
+
+ READ_TEMP_LOCALS();
+
+ token = pg_strtok(&length);
+
+#define MATCH(tokname, namelen) \
+ (length == namelen && memcmp(token, tokname, namelen) == 0)
+
+ if (MATCH("QUERY", 5))
+ return_value = _readQuery();
+ else if (MATCH("WITHCHECKOPTION", 15))
+ return_value = _readWithCheckOption();
+ else if (MATCH("SORTGROUPCLAUSE", 15))
+ return_value = _readSortGroupClause();
+ else if (MATCH("GROUPINGSET", 11))
+ return_value = _readGroupingSet();
+ else if (MATCH("WINDOWCLAUSE", 12))
+ return_value = _readWindowClause();
+ else if (MATCH("ROWMARKCLAUSE", 13))
+ return_value = _readRowMarkClause();
+ else if (MATCH("COMMONTABLEEXPR", 15))
+ return_value = _readCommonTableExpr();
+ else if (MATCH("SETOPERATIONSTMT", 16))
+ return_value = _readSetOperationStmt();
+ else if (MATCH("ALIAS", 5))
+ return_value = _readAlias();
+ else if (MATCH("RANGEVAR", 8))
+ return_value = _readRangeVar();
+ else if (MATCH("INTOCLAUSE", 10))
+ return_value = _readIntoClause();
+ else if (MATCH("VAR", 3))
+ return_value = _readVar();
+ else if (MATCH("CONST", 5))
+ return_value = _readConst();
+ else if (MATCH("PARAM", 5))
+ return_value = _readParam();
+ else if (MATCH("AGGREF", 6))
+ return_value = _readAggref();
+ else if (MATCH("GROUPINGFUNC", 12))
+ return_value = _readGroupingFunc();
+ else if (MATCH("WINDOWFUNC", 10))
+ return_value = _readWindowFunc();
+ else if (MATCH("ARRAYREF", 8))
+ return_value = _readArrayRef();
+ else if (MATCH("FUNCEXPR", 8))
+ return_value = _readFuncExpr();
+ else if (MATCH("NAMEDARGEXPR", 12))
+ return_value = _readNamedArgExpr();
+ else if (MATCH("OPEXPR", 6))
+ return_value = _readOpExpr();
+ else if (MATCH("DISTINCTEXPR", 12))
+ return_value = _readDistinctExpr();
+ else if (MATCH("NULLIFEXPR", 10))
+ return_value = _readNullIfExpr();
+ else if (MATCH("SCALARARRAYOPEXPR", 17))
+ return_value = _readScalarArrayOpExpr();
+ else if (MATCH("BOOLEXPR", 8))
+ return_value = _readBoolExpr();
+ else if (MATCH("SUBLINK", 7))
+ return_value = _readSubLink();
+#ifdef XCP
+ else if (MATCH("SUBPLAN", 7))
+ return_value = _readSubPlan();
+#endif
+ else if (MATCH("FIELDSELECT", 11))
+ return_value = _readFieldSelect();
+ else if (MATCH("FIELDSTORE", 10))
+ return_value = _readFieldStore();
+ else if (MATCH("RELABELTYPE", 11))
+ return_value = _readRelabelType();
+ else if (MATCH("COERCEVIAIO", 11))
+ return_value = _readCoerceViaIO();
+ else if (MATCH("ARRAYCOERCEEXPR", 15))
+ return_value = _readArrayCoerceExpr();
+ else if (MATCH("CONVERTROWTYPEEXPR", 18))
+ return_value = _readConvertRowtypeExpr();
+ else if (MATCH("COLLATE", 7))
+ return_value = _readCollateExpr();
+ else if (MATCH("CASE", 4))
+ return_value = _readCaseExpr();
+ else if (MATCH("WHEN", 4))
+ return_value = _readCaseWhen();
+ else if (MATCH("CASETESTEXPR", 12))
+ return_value = _readCaseTestExpr();
+ else if (MATCH("ARRAY", 5))
+ return_value = _readArrayExpr();
+ else if (MATCH("ROW", 3))
+ return_value = _readRowExpr();
+ else if (MATCH("ROWCOMPARE", 10))
+ return_value = _readRowCompareExpr();
+ else if (MATCH("COALESCE", 8))
+ return_value = _readCoalesceExpr();
+ else if (MATCH("MINMAX", 6))
+ return_value = _readMinMaxExpr();
+ else if (MATCH("XMLEXPR", 7))
+ return_value = _readXmlExpr();
+ else if (MATCH("NULLTEST", 8))
+ return_value = _readNullTest();
+ else if (MATCH("BOOLEANTEST", 11))
+ return_value = _readBooleanTest();
+ else if (MATCH("COERCETODOMAIN", 14))
+ return_value = _readCoerceToDomain();
+ else if (MATCH("COERCETODOMAINVALUE", 19))
+ return_value = _readCoerceToDomainValue();
+ else if (MATCH("SETTODEFAULT", 12))
+ return_value = _readSetToDefault();
+ else if (MATCH("CURRENTOFEXPR", 13))
+ return_value = _readCurrentOfExpr();
+ else if (MATCH("INFERENCEELEM", 13))
return_value = _readInferenceElem();
else if (MATCH("TARGETENTRY", 11))
return_value = _readTargetEntry();
--- /dev/null
+CREATE TEMP TABLE x (
+ a serial,
+ b int,
+ c text not null default 'stuff',
+ d text,
+ e text
+) WITH OIDS;
+CREATE FUNCTION fn_x_before () RETURNS TRIGGER AS '
+ BEGIN
+ NEW.e := ''before trigger fired''::text;
+ return NEW;
+ END;
+' LANGUAGE plpgsql;
+CREATE FUNCTION fn_x_after () RETURNS TRIGGER AS '
+ BEGIN
+ UPDATE x set e=''after trigger fired'' where c=''stuff'';
+ return NULL;
+ END;
+' LANGUAGE plpgsql;
+CREATE TRIGGER trg_x_after AFTER INSERT ON x
+FOR EACH ROW EXECUTE PROCEDURE fn_x_after();
+ERROR: Postgres-XL does not support TRIGGER yet
+DETAIL: The feature is not currently supported
+CREATE TRIGGER trg_x_before BEFORE INSERT ON x
+FOR EACH ROW EXECUTE PROCEDURE fn_x_before();
+ERROR: Postgres-XL does not support TRIGGER yet
+DETAIL: The feature is not currently supported
+COPY x (a, b, c, d, e) from stdin;
+COPY x (b, d) from stdin;
+COPY x (b, d) from stdin;
+COPY x (a, b, c, d, e) from stdin;
+-- non-existent column in column list: should fail
+COPY x (xyz) from stdin;
+ERROR: column "xyz" of relation "x" does not exist
+-- too many columns in column list: should fail
+COPY x (a, b, c, d, e, d, c) from stdin;
+ERROR: column "d" specified more than once
+-- missing data: should fail
+COPY x from stdin;
+ERROR: invalid input syntax for integer: ""
+CONTEXT: COPY x, line 1, column a: ""
+COPY x from stdin;
+ERROR: missing data for column "e"
+CONTEXT: COPY x, line 1: "2000 230 23 23"
+COPY x from stdin;
+ERROR: missing data for column "e"
+CONTEXT: COPY x, line 1: "2001 231 \N \N"
+-- extra data: should fail
+COPY x from stdin;
+ERROR: extra data after last expected column
+CONTEXT: COPY x, line 1: "2002 232 40 50 60 70 80"
+-- various COPY options: delimiters, oids, NULL string, encoding
+COPY x (b, c, d, e) from stdin with oids delimiter ',' null 'x';
+COPY x from stdin WITH DELIMITER AS ';' NULL AS '';
+COPY x from stdin WITH DELIMITER AS ':' NULL AS E'\\X' ENCODING 'sql_ascii';
+-- check results of copy in
+SELECT * FROM x ORDER BY a, b;
+ a | b | c | d | e
+-------+----+------------+--------+----
+ 1 | 1 | stuff | test_1 |
+ 2 | 2 | stuff | test_2 |
+ 3 | 3 | stuff | test_3 |
+ 4 | 4 | stuff | test_4 |
+ 5 | 5 | stuff | test_5 |
+ 6 | | 45 | 80 | 90
+ 7 | | x | \x | \x
+ 8 | | , | \, | \
+ 3000 | | c | |
+ 4000 | | C | |
+ 4001 | 1 | empty | |
+ 4002 | 2 | null | |
+ 4003 | 3 | Backslash | \ | \
+ 4004 | 4 | BackslashX | \X | \X
+ 4005 | 5 | N | N | N
+ 4006 | 6 | BackslashN | \N | \N
+ 4007 | 7 | XX | XX | XX
+ 4008 | 8 | Delimiter | : | :
+ 9999 | | \N | NN |
+ 10000 | 21 | 31 | 41 | 51
+ 10001 | 22 | 32 | 42 | 52
+ 10002 | 23 | 33 | 43 | 53
+ 10003 | 24 | 34 | 44 | 54
+ 10004 | 25 | 35 | 45 | 55
+ 10005 | 26 | 36 | 46 | 56
+(25 rows)
+
+-- COPY w/ oids on a table w/o oids should fail
+CREATE TABLE no_oids (
+ a int,
+ b int
+) WITHOUT OIDS;
+INSERT INTO no_oids (a, b) VALUES (5, 10);
+INSERT INTO no_oids (a, b) VALUES (20, 30);
+-- should fail
+COPY no_oids FROM stdin WITH OIDS;
+ERROR: table "no_oids" does not have OIDs
+COPY no_oids TO stdout WITH OIDS;
+ERROR: table "no_oids" does not have OIDs
+-- check copy out
+COPY x TO stdout;
+9999 \N \\N NN \N
+1 1 stuff test_1 \N
+2 2 stuff test_2 \N
+5 5 stuff test_5 \N
+10001 22 32 42 52
+10002 23 33 43 53
+10004 25 35 45 55
+6 \N 45 80 90
+8 \N , \\, \\
+4000 \N C \N \N
+4002 2 null \N \N
+4003 3 Backslash \\ \\
+4005 5 N N N
+4007 7 XX XX XX
+4008 8 Delimiter : :
+10000 21 31 41 51
+3 3 stuff test_3 \N
+4 4 stuff test_4 \N
+10003 24 34 44 54
+10005 26 36 46 56
+7 \N x \\x \\x
+3000 \N c \N \N
+4001 1 empty
+4004 4 BackslashX \\X \\X
+4006 6 BackslashN \\N \\N
+COPY x (c, e) TO stdout;
+\\N \N
+stuff \N
+stuff \N
+stuff \N
+32 52
+33 53
+35 55
+45 90
+, \\
+C \N
+null \N
+Backslash \\
+N N
+XX XX
+Delimiter :
+31 51
+stuff \N
+stuff \N
+34 54
+36 56
+x \\x
+c \N
+empty
+BackslashX \\X
+BackslashN \\N
+COPY x (b, e) TO stdout WITH NULL 'I''m null';
+I'm null I'm null
+1 I'm null
+2 I'm null
+5 I'm null
+22 52
+23 53
+25 55
+I'm null 90
+I'm null \\
+I'm null I'm null
+2 I'm null
+3 \\
+5 N
+7 XX
+8 :
+21 51
+3 I'm null
+4 I'm null
+24 54
+26 56
+I'm null \\x
+I'm null I'm null
+1
+4 \\X
+6 \\N
+CREATE TEMP TABLE y (
+ col1 text,
+ col2 text
+);
+INSERT INTO y VALUES ('Jackson, Sam', E'\\h');
+INSERT INTO y VALUES ('It is "perfect".',E'\t');
+INSERT INTO y VALUES ('', NULL);
+COPY y TO stdout WITH CSV;
+"Jackson, Sam",\h
+"It is ""perfect"".",
+"",
+COPY y TO stdout WITH CSV QUOTE '''' DELIMITER '|';
+Jackson, Sam|\h
+It is "perfect".|
+''|
+COPY y TO stdout WITH CSV FORCE QUOTE col2 ESCAPE E'\\' ENCODING 'sql_ascii';
+"Jackson, Sam","\\h"
+"It is \"perfect\"."," "
+"",
+COPY y TO stdout WITH CSV FORCE QUOTE *;
+"Jackson, Sam",\h
+"It is ""perfect"".",
+"",
+-- Repeat above tests with new 9.0 option syntax
+COPY y TO stdout (FORMAT CSV);
+"Jackson, Sam",\h
+"It is ""perfect"".",
+"",
+COPY y TO stdout (FORMAT CSV, QUOTE '''', DELIMITER '|');
+Jackson, Sam|\h
+It is "perfect".|
+''|
+COPY y TO stdout (FORMAT CSV, FORCE_QUOTE (col2), ESCAPE E'\\');
+"Jackson, Sam","\\h"
+"It is \"perfect\"."," "
+"",
+COPY y TO stdout (FORMAT CSV, FORCE_QUOTE *);
+"Jackson, Sam",\h
+"It is ""perfect"".",
+"",
+\copy y TO stdout (FORMAT CSV)
+"Jackson, Sam",\h
+"It is ""perfect"".",
+"",
+\copy y TO stdout (FORMAT CSV, QUOTE '''', DELIMITER '|')
+Jackson, Sam|\h
+It is "perfect".|
+''|
+\copy y TO stdout (FORMAT CSV, FORCE_QUOTE (col2), ESCAPE E'\\')
+"Jackson, Sam","\\h"
+"It is \"perfect\"."," "
+"",
+\copy y TO stdout (FORMAT CSV, FORCE_QUOTE *)
+"Jackson, Sam",\h
+"It is ""perfect"".",
+"",
+--test that we read consecutive LFs properly
+CREATE TEMP TABLE testnl (a int, b text, c int);
+COPY testnl FROM stdin CSV;
+-- test end of copy marker
+CREATE TEMP TABLE testeoc (a text);
+COPY testeoc FROM stdin CSV;
+COPY testeoc TO stdout CSV;
+"\."
+a\.
+\.b
+c\.d
+-- test handling of nonstandard null marker that violates escaping rules
+CREATE TEMP TABLE testnull(a int, b text);
+INSERT INTO testnull VALUES (1, E'\\0'), (NULL, NULL);
+COPY testnull TO stdout WITH NULL AS E'\\0';
+1 \\0
+\0 \0
+COPY testnull FROM stdin WITH NULL AS E'\\0';
+SELECT * FROM testnull ORDER BY 1,2;
+ a | b
+----+----
+ 1 | \0
+ 42 | \0
+ |
+ |
+(4 rows)
+
+BEGIN;
+CREATE TABLE vistest (LIKE testeoc);
+ERROR: relation "testeoc" does not exist
+COPY vistest FROM stdin CSV;
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+a0
+b
+\.
+invalid command \.
+COMMIT;
+ERROR: syntax error at or near "a0"
+LINE 1: a0
+ ^
+SELECT * FROM vistest;
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+BEGIN;
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+TRUNCATE vistest;
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+COPY vistest FROM stdin CSV;
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+a1
+b
+\.
+invalid command \.
+SELECT * FROM vistest;
+ERROR: syntax error at or near "a1"
+LINE 1: a1
+ ^
+SAVEPOINT s1;
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+TRUNCATE vistest;
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+COPY vistest FROM stdin CSV;
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+d1
+e
+\.
+invalid command \.
+SELECT * FROM vistest;
+ERROR: syntax error at or near "d1"
+LINE 1: d1
+ ^
+COMMIT;
+SELECT * FROM vistest;
+ERROR: relation "vistest" does not exist
+LINE 1: SELECT * FROM vistest;
+ ^
+BEGIN;
+TRUNCATE vistest;
+ERROR: relation "vistest" does not exist
+COPY vistest FROM stdin CSV FREEZE;
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+a2
+b
+\.
+invalid command \.
+SELECT * FROM vistest;
+ERROR: syntax error at or near "a2"
+LINE 1: a2
+ ^
+SAVEPOINT s1;
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+TRUNCATE vistest;
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+COPY vistest FROM stdin CSV FREEZE;
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+d2
+e
+\.
+invalid command \.
+SELECT * FROM vistest;
+ERROR: syntax error at or near "d2"
+LINE 1: d2
+ ^
+COMMIT;
+SELECT * FROM vistest;
+ERROR: relation "vistest" does not exist
+LINE 1: SELECT * FROM vistest;
+ ^
+BEGIN;
+TRUNCATE vistest;
+ERROR: relation "vistest" does not exist
+COPY vistest FROM stdin CSV FREEZE;
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+x
+y
+\.
+invalid command \.
+SELECT * FROM vistest;
+ERROR: syntax error at or near "x"
+LINE 1: x
+ ^
+COMMIT;
+TRUNCATE vistest;
+ERROR: relation "vistest" does not exist
+COPY vistest FROM stdin CSV FREEZE;
+ERROR: relation "vistest" does not exist
+p
+g
+\.
+invalid command \.
+BEGIN;
+ERROR: syntax error at or near "p"
+LINE 1: p
+ ^
+TRUNCATE vistest;
+ERROR: relation "vistest" does not exist
+SAVEPOINT s1;
+ERROR: SAVEPOINT is not yet supported.
+COPY vistest FROM stdin CSV FREEZE;
+ERROR: relation "vistest" does not exist
+m
+k
+\.
+invalid command \.
+COMMIT;
+ERROR: syntax error at or near "m"
+LINE 1: m
+ ^
+BEGIN;
+INSERT INTO vistest VALUES ('z');
+ERROR: relation "vistest" does not exist
+LINE 1: INSERT INTO vistest VALUES ('z');
+ ^
+SAVEPOINT s1;
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+TRUNCATE vistest;
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+ROLLBACK TO SAVEPOINT s1;
+ERROR: no such savepoint
+COPY vistest FROM stdin CSV FREEZE;
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+d3
+e
+\.
+invalid command \.
+COMMIT;
+ERROR: syntax error at or near "d3"
+LINE 1: d3
+ ^
+CREATE FUNCTION truncate_in_subxact() RETURNS VOID AS
+$$
+BEGIN
+ TRUNCATE vistest;
+EXCEPTION
+ WHEN OTHERS THEN
+ INSERT INTO vistest VALUES ('subxact failure');
+END;
+$$ language plpgsql;
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+BEGIN;
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+INSERT INTO vistest VALUES ('z');
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+SELECT truncate_in_subxact();
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+COPY vistest FROM stdin CSV FREEZE;
+ERROR: current transaction is aborted, commands ignored until end of transaction block
+d4
+e
+\.
+invalid command \.
+SELECT * FROM vistest;
+ERROR: syntax error at or near "d4"
+LINE 1: d4
+ ^
+COMMIT;
+SELECT * FROM vistest;
+ERROR: relation "vistest" does not exist
+LINE 1: SELECT * FROM vistest;
+ ^
+-- Test FORCE_NOT_NULL and FORCE_NULL options
+CREATE TEMP TABLE forcetest (
+ a INT NOT NULL,
+ b TEXT NOT NULL,
+ c TEXT,
+ d TEXT,
+ e TEXT
+);
+\pset null NULL
+-- should succeed with no effect ("b" remains an empty string, "c" remains NULL)
+BEGIN;
+COPY forcetest (a, b, c) FROM STDIN WITH (FORMAT csv, FORCE_NOT_NULL(b), FORCE_NULL(c));
+COMMIT;
+SELECT b, c FROM forcetest WHERE a = 1;
+ b | c
+---+---
+ |
+(1 row)
+
+-- should succeed, FORCE_NULL and FORCE_NOT_NULL can be both specified
+BEGIN;
+COPY forcetest (a, b, c, d) FROM STDIN WITH (FORMAT csv, FORCE_NOT_NULL(c,d), FORCE_NULL(c,d));
+COMMIT;
+SELECT c, d FROM forcetest WHERE a = 2;
+ c | d
+---+---
+ |
+(1 row)
+
+-- should fail with not-null constraint violation
+BEGIN;
+COPY forcetest (a, b, c) FROM STDIN WITH (FORMAT csv, FORCE_NULL(b), FORCE_NOT_NULL(c));
+ERROR: null value in column "b" violates not-null constraint
+DETAIL: Failing row contains (3, null, , null, null).
+ROLLBACK;
+-- should fail with "not referenced by COPY" error
+BEGIN;
+COPY forcetest (d, e) FROM STDIN WITH (FORMAT csv, FORCE_NOT_NULL(b));
+ERROR: FORCE NOT NULL column "b" not referenced by COPY
+ROLLBACK;
+-- should fail with "not referenced by COPY" error
+BEGIN;
+COPY forcetest (d, e) FROM STDIN WITH (FORMAT csv, FORCE_NULL(b));
+ERROR: FORCE NULL column "b" not referenced by COPY
+ROLLBACK;
+\pset null ''
+-- test case with whole-row Var in a check constraint
+create table check_con_tbl (f1 int);
+create function check_con_function(check_con_tbl) returns bool as $$
+begin
+ raise notice 'input = %', row_to_json($1);
+ return $1.f1 > 0;
+end $$ language plpgsql immutable;
+alter table check_con_tbl add check (check_con_function(check_con_tbl.*));
+\d+ check_con_tbl
+ Table "public.check_con_tbl"
+ Column | Type | Modifiers | Storage | Stats target | Description
+--------+---------+-----------+---------+--------------+-------------
+ f1 | integer | | plain | |
+Check constraints:
+ "check_con_tbl_check" CHECK (check_con_function(check_con_tbl.*))
+Distribute By: HASH(f1)
+Location Nodes: ALL DATANODES
+
+copy check_con_tbl from stdin;
+copy check_con_tbl from stdin;
+ERROR: new row for relation "check_con_tbl" violates check constraint "check_con_tbl_check"
+DETAIL: Failing row contains (0).
+select * from check_con_tbl;
+ f1
+----
+ 1
+
+(2 rows)
+
++-- test with RLS enabled.
++CREATE ROLE regress_rls_copy_user;
++CREATE ROLE regress_rls_copy_user_colperms;
++CREATE TABLE rls_t1 (a int, b int, c int);
++COPY rls_t1 (a, b, c) from stdin;
++CREATE POLICY p1 ON rls_t1 FOR SELECT USING (a % 2 = 0);
++ALTER TABLE rls_t1 ENABLE ROW LEVEL SECURITY;
++ALTER TABLE rls_t1 FORCE ROW LEVEL SECURITY;
++GRANT SELECT ON TABLE rls_t1 TO regress_rls_copy_user;
++GRANT SELECT (a, b) ON TABLE rls_t1 TO regress_rls_copy_user_colperms;
++-- all columns
++COPY rls_t1 TO stdout;
++1 4 1
++2 3 2
++3 2 3
++4 1 4
++COPY rls_t1 (a, b, c) TO stdout;
++1 4 1
++2 3 2
++3 2 3
++4 1 4
++-- subset of columns
++COPY rls_t1 (a) TO stdout;
++1
++2
++3
++4
++COPY rls_t1 (a, b) TO stdout;
++1 4
++2 3
++3 2
++4 1
++-- column reordering
++COPY rls_t1 (b, a) TO stdout;
++4 1
++3 2
++2 3
++1 4
++SET SESSION AUTHORIZATION regress_rls_copy_user;
++-- all columns
++COPY rls_t1 TO stdout;
++2 3 2
++4 1 4
++COPY rls_t1 (a, b, c) TO stdout;
++2 3 2
++4 1 4
++-- subset of columns
++COPY rls_t1 (a) TO stdout;
++2
++4
++COPY rls_t1 (a, b) TO stdout;
++2 3
++4 1
++-- column reordering
++COPY rls_t1 (b, a) TO stdout;
++3 2
++1 4
++RESET SESSION AUTHORIZATION;
++SET SESSION AUTHORIZATION regress_rls_copy_user_colperms;
++-- attempt all columns (should fail)
++COPY rls_t1 TO stdout;
++ERROR: permission denied for relation rls_t1
++COPY rls_t1 (a, b, c) TO stdout;
++ERROR: permission denied for relation rls_t1
++-- try to copy column with no privileges (should fail)
++COPY rls_t1 (c) TO stdout;
++ERROR: permission denied for relation rls_t1
++-- subset of columns (should succeed)
++COPY rls_t1 (a) TO stdout;
++2
++4
++COPY rls_t1 (a, b) TO stdout;
++2 3
++4 1
++RESET SESSION AUTHORIZATION;
+DROP TABLE forcetest;
+DROP TABLE vistest;
+ERROR: table "vistest" does not exist
+DROP FUNCTION truncate_in_subxact();
+ERROR: function truncate_in_subxact() does not exist
+DROP TABLE x, y;
++DROP TABLE rls_t1 CASCADE;
++DROP ROLE regress_rls_copy_user;
++DROP ROLE regress_rls_copy_user_colperms;
+DROP FUNCTION fn_x_before();
+DROP FUNCTION fn_x_after();