From: Pavan Deolasee Date: Tue, 22 Nov 2016 10:47:44 +0000 (+0530) Subject: Merge tag 'REL9_5_5' into XL9_5_STABLE X-Git-Tag: XL9_5_R1_4~4 X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=1eeea97980e72d3a2ff34354f244d14800db9e52;p=postgres-xl.git Merge tag 'REL9_5_5' into XL9_5_STABLE --- 1eeea97980e72d3a2ff34354f244d14800db9e52 diff --cc configure index 3c10aa5a3e,2275ad677e..8d20510ce6 --- a/configure +++ b/configure @@@ -1,8 -1,8 +1,8 @@@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. - # Generated by GNU Autoconf 2.69 for PostgreSQL 9.5.4 (Postgres-XL 9.5r1.3). -# Generated by GNU Autoconf 2.69 for PostgreSQL 9.5.5. ++# Generated by GNU Autoconf 2.69 for PostgreSQL 9.5.5 (Postgres-XL 9.5r1.3). # -# Report bugs to . +# Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@@ -582,10 -582,9 +582,10 @@@ MAKEFLAGS # Identity of this package. PACKAGE_NAME='PostgreSQL' PACKAGE_TARNAME='postgresql' - PACKAGE_VERSION='9.5.4 (Postgres-XL 9.5r1.3)' -PACKAGE_VERSION='9.5.5' -PACKAGE_STRING='PostgreSQL 9.5.5' -PACKAGE_BUGREPORT='pgsql-bugs@postgresql.org' ++PACKAGE_VERSION='9.5.5 (Postgres-XL 9.5r1.3)' +PACKAGE_XC_VERSION='9.5r1.3' - PACKAGE_STRING='PostgreSQL 9.5.4 (Postgres-XL 9.5r1.3)' ++PACKAGE_STRING='PostgreSQL 9.5.5 (Postgres-XL 9.5r1.3)' +PACKAGE_BUGREPORT='bugs@postgres-xl.org' PACKAGE_URL='' ac_unique_file="src/backend/access/common/heaptuple.c" @@@ -1399,7 -1395,7 +1399,7 @@@ if test "$ac_init_help" = "long"; the # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF - \`configure' configures PostgreSQL 9.5.4 (Postgres-XL 9.5r1.3) to adapt to many kinds of systems. -\`configure' configures PostgreSQL 9.5.5 to adapt to many kinds of systems. ++\`configure' configures PostgreSQL 9.5.5 (Postgres-XL 9.5r1.3) to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@@ -1464,7 -1460,7 +1464,7 @@@ f if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of PostgreSQL 9.5.4 (Postgres-XL 9.5r1.3):";; - short | recursive ) echo "Configuration of PostgreSQL 9.5.5:";; ++ short | recursive ) echo "Configuration of PostgreSQL 9.5.5 (Postgres-XL 9.5r1.3):";; esac cat <<\_ACEOF @@@ -1614,7 -1610,7 +1614,7 @@@ f test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF - PostgreSQL configure 9.5.4 (Postgres-XL 9.5r1.3) -PostgreSQL configure 9.5.5 ++PostgreSQL configure 9.5.5 (Postgres-XL 9.5r1.3) generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@@ -2325,7 -2321,7 +2325,7 @@@ cat >config.log <<_ACEO This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. - It was created by PostgreSQL $as_me 9.5.4 (Postgres-XL 9.5r1.3), which was -It was created by PostgreSQL $as_me 9.5.5, which was ++It was created by PostgreSQL $as_me 9.5.5 (Postgres-XL 9.5r1.3), which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@@ -16245,7 -16226,7 +16276,7 @@@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_wr # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" - This file was extended by PostgreSQL $as_me 9.5.4 (Postgres-XL 9.5r1.3), which was -This file was extended by PostgreSQL $as_me 9.5.5, which was ++This file was extended by PostgreSQL $as_me 9.5.5 (Postgres-XL 9.5r1.3), which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@@ -16315,7 -16296,7 +16346,7 @@@ _ACEO cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ - PostgreSQL config.status 9.5.4 (Postgres-XL 9.5r1.3) -PostgreSQL config.status 9.5.5 ++PostgreSQL config.status 9.5.5 (Postgres-XL 9.5r1.3) configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --cc configure.in index 55762acade,51525bacf9..142ebe9fc6 --- a/configure.in +++ b/configure.in @@@ -17,7 -17,7 +17,7 @@@ dnl Read the Autoconf manual for detail dnl m4_pattern_forbid(^PGAC_)dnl to catch undefined macros - AC_INIT([PostgreSQL], [9.5.4 (Postgres-XL 9.5r1.3)], [bugs@postgres-xl.org]) -AC_INIT([PostgreSQL], [9.5.5], [pgsql-bugs@postgresql.org]) ++AC_INIT([PostgreSQL], [9.5.5 (Postgres-XL 9.5r1.3)], [bugs@postgres-xl.org]) m4_if(m4_defn([m4_PACKAGE_VERSION]), [2.69], [], [m4_fatal([Autoconf version 2.69 is required. Untested combinations of 'autoconf' and PostgreSQL versions are not diff --cc doc/bug.template index a08bcc16c7,07b62847c5..6d4d456e94 --- a/doc/bug.template +++ b/doc/bug.template @@@ -27,7 -27,7 +27,7 @@@ System Configuration Operating System (example: Linux 2.4.18) : - PostgreSQL version (example: PostgreSQL 9.5.4): Postgres-XL 9.5r1.3 - PostgreSQL version (example: PostgreSQL 9.5.5): PostgreSQL 9.5.5 ++ PostgreSQL version (example: PostgreSQL 9.5.5): Postgres-XL 9.5r1.3 Compiler used (example: gcc 3.3.5) : diff --cc doc/src/sgml/ddl.sgml index 98df43338e,e139f643f3..dabc03c888 mode 100755,100644..100755 --- a/doc/src/sgml/ddl.sgml +++ b/doc/src/sgml/ddl.sgml diff --cc doc/src/sgml/maintenance.sgml index 216ca83cd4,74f5de835e..a72c37f3af --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@@ -410,13 -385,9 +410,14 @@@ of transaction IDs + + Please note that this section describes the tasks of individual + Coordinators and Datanodes. It should be done for each of them. + + - PostgreSQL's MVCC transaction semantics + PostgreSQL's + MVCC transaction semantics depend on being able to compare transaction ID (XID) numbers: a row version with an insertion XID greater than the current transaction's XID is in the future and should not be visible diff --cc src/backend/nodes/readfuncs.c index 16a78e7234,32b23fff09..1267a8c179 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@@ -2069,1462 -1367,123 +2069,1462 @@@ _readTableSampleClause(void } +#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(); diff --cc src/backend/utils/error/elog.c index 909e2667e6,afe41ff645..59320a4d61 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@@ -1658,18 -1599,15 +1661,19 @@@ ThrowErrorData(ErrorData *edata MemoryContext oldcontext; if (!errstart(edata->elevel, edata->filename, edata->lineno, +#ifdef USE_MODULE_MSGIDS + edata->moduleid, + edata->fileid, edata->msgid, +#endif edata->funcname, NULL)) - return; + return; /* error is not to be reported at all */ newedata = &errordata[errordata_stack_depth]; - oldcontext = MemoryContextSwitchTo(edata->assoc_context); + recursion_depth++; + oldcontext = MemoryContextSwitchTo(newedata->assoc_context); - /* Copy the supplied fields to the error stack. */ - if (edata->sqlerrcode > 0) + /* Copy the supplied fields to the error stack entry. */ + if (edata->sqlerrcode != 0) newedata->sqlerrcode = edata->sqlerrcode; if (edata->message) newedata->message = pstrdup(edata->message); diff --cc src/bin/psql/command.c index bd79626f85,19ac065530..649e4dbe86 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@@ -1886,17 -1891,16 +1891,20 @@@ connection_warnings(bool in_startup } /* For version match, only print psql banner on startup. */ else if (in_startup) +#ifdef PGXC + printf("%s (PGXL %s, based on PG %s)\n", pset.progname, PGXC_VERSION, PG_VERSION); +#else printf("%s (%s)\n", pset.progname, PG_VERSION); +#endif if (pset.sversion / 100 > client_ver / 100) - printf(_("WARNING: %s major version %d.%d, server major version %d.%d.\n" + printf(_("WARNING: %s major version %s, server major version %s.\n" " Some psql features might not work.\n"), - pset.progname, client_ver / 10000, (client_ver / 100) % 100, - pset.sversion / 10000, (pset.sversion / 100) % 100); + pset.progname, + formatPGVersionNumber(client_ver, false, + cverbuf, sizeof(cverbuf)), + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); #ifdef WIN32 checkWin32Codepage(); diff --cc src/include/pg_config.h.win32 index 3fc5522e4f,64cc86a07e..6b2785883e --- a/src/include/pg_config.h.win32 +++ b/src/include/pg_config.h.win32 @@@ -557,16 -557,16 +557,16 @@@ #define MEMSET_LOOP_LIMIT 1024 /* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "pgsql-bugs@postgresql.org" +#define PACKAGE_BUGREPORT "postgres-xl-bugs@lists.sourceforge.net" /* Define to the full name of this package. */ -#define PACKAGE_NAME "PostgreSQL" +#define PACKAGE_NAME "Postgres-XL" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "PostgreSQL 9.5.5" +#define PACKAGE_STRING "Postgres-XL 9.5r1.3" /* Define to the version of this package. */ - #define PACKAGE_VERSION "9.5.4" + #define PACKAGE_VERSION "9.5.5" /* Define to the name of a signed 128-bit integer type. */ #undef PG_INT128_TYPE @@@ -575,19 -575,13 +575,19 @@@ #define PG_INT64_TYPE long long int /* PostgreSQL version as a string */ - #define PG_VERSION "9.5.4" + #define PG_VERSION "9.5.5" /* PostgreSQL version as a number */ - #define PG_VERSION_NUM 90504 + #define PG_VERSION_NUM 90505 /* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "postgresql" +#define PACKAGE_TARNAME "postgres-xl" + +/* Postgres-XC version as a string */ +#define PGXC_VERSION "1.1devel" + +/* Postgres-XC version as a number */ +#define PGXC_VERSION_NUM 10100 /* Define to the name of the default PostgreSQL service principal in Kerberos. (--with-krb-srvnam=NAME) */ diff --cc src/test/regress/expected/case_1.out index 4fbff97f32,0000000000..6f31fa8c10 mode 100644,000000..100644 --- a/src/test/regress/expected/case_1.out +++ b/src/test/regress/expected/case_1.out @@@ -1,361 -1,0 +1,360 @@@ +-- +-- CASE +-- Test the case statement +-- +CREATE TABLE CASE_TBL ( + i integer, + f double precision +); +CREATE TABLE CASE2_TBL ( + i integer, + j integer +); +INSERT INTO CASE_TBL VALUES (1, 10.1); +INSERT INTO CASE_TBL VALUES (2, 20.2); +INSERT INTO CASE_TBL VALUES (3, -30.3); +INSERT INTO CASE_TBL VALUES (4, NULL); +INSERT INTO CASE2_TBL VALUES (1, -1); +INSERT INTO CASE2_TBL VALUES (2, -2); +INSERT INTO CASE2_TBL VALUES (3, -3); +INSERT INTO CASE2_TBL VALUES (2, -4); +INSERT INTO CASE2_TBL VALUES (1, NULL); +INSERT INTO CASE2_TBL VALUES (NULL, -6); +-- +-- Simplest examples without tables +-- +SELECT '3' AS "One", + CASE + WHEN 1 < 2 THEN 3 + END AS "Simple WHEN"; + One | Simple WHEN +-----+------------- + 3 | 3 +(1 row) + +SELECT '' AS "One", + CASE + WHEN 1 > 2 THEN 3 + END AS "Simple default"; + One | Simple default +--------+---------------- + | +(1 row) + +SELECT '3' AS "One", + CASE + WHEN 1 < 2 THEN 3 + ELSE 4 + END AS "Simple ELSE"; + One | Simple ELSE +-----+------------- + 3 | 3 +(1 row) + +SELECT '4' AS "One", + CASE + WHEN 1 > 2 THEN 3 + ELSE 4 + END AS "ELSE default"; + One | ELSE default +-----+-------------- + 4 | 4 +(1 row) + +SELECT '6' AS "One", + CASE + WHEN 1 > 2 THEN 3 + WHEN 4 < 5 THEN 6 + ELSE 7 + END AS "Two WHEN with default"; + One | Two WHEN with default +-----+----------------------- + 6 | 6 +(1 row) + +-- Constant-expression folding shouldn't evaluate unreachable subexpressions +SELECT CASE WHEN 1=0 THEN 1/0 WHEN 1=1 THEN 1 ELSE 2/0 END; + case +------ + 1 +(1 row) + +SELECT CASE 1 WHEN 0 THEN 1/0 WHEN 1 THEN 1 ELSE 2/0 END; + case +------ + 1 +(1 row) + +-- However we do not currently suppress folding of potentially +-- reachable subexpressions +SELECT CASE WHEN i > 100 THEN 1/0 ELSE 0 END FROM case_tbl; +ERROR: division by zero +-- Test for cases involving untyped literals in test expression +SELECT CASE 'a' WHEN 'a' THEN 1 ELSE 2 END; + case +------ + 1 +(1 row) + +-- +-- Examples of targets involving tables +-- +SELECT '' AS "Five", + CASE + WHEN i >= 3 THEN i + END AS ">= 3 or Null" + FROM CASE_TBL + ORDER BY 2; + Five | >= 3 or Null +------+-------------- + | 3 + | 4 + | + | +(4 rows) + +SELECT '' AS "Five", + CASE WHEN i >= 3 THEN (i + i) + ELSE i + END AS "Simplest Math" + FROM CASE_TBL + ORDER BY 2; + Five | Simplest Math +------+--------------- + | 1 + | 2 + | 6 + | 8 +(4 rows) + +SELECT '' AS "Five", i AS "Value", + CASE WHEN (i < 0) THEN 'small' + WHEN (i = 0) THEN 'zero' + WHEN (i = 1) THEN 'one' + WHEN (i = 2) THEN 'two' + ELSE 'big' + END AS "Category" + FROM CASE_TBL + ORDER BY 2, 3; + Five | Value | Category +------+-------+---------- + | 1 | one + | 2 | two + | 3 | big + | 4 | big +(4 rows) + +SELECT '' AS "Five", + CASE WHEN ((i < 0) or (i < 0)) THEN 'small' + WHEN ((i = 0) or (i = 0)) THEN 'zero' + WHEN ((i = 1) or (i = 1)) THEN 'one' + WHEN ((i = 2) or (i = 2)) THEN 'two' + ELSE 'big' + END AS "Category" + FROM CASE_TBL + ORDER BY 2; + Five | Category +------+---------- + | big + | big + | one + | two +(4 rows) + +-- +-- Examples of qualifications involving tables +-- +-- +-- NULLIF() and COALESCE() +-- Shorthand forms for typical CASE constructs +-- defined in the SQL standard. +-- +SELECT * FROM CASE_TBL WHERE COALESCE(f,i) = 4; + i | f +---+--- + 4 | +(1 row) + +SELECT * FROM CASE_TBL WHERE NULLIF(f,i) = 2; + i | f +---+--- +(0 rows) + +SELECT COALESCE(a.f, b.i, b.j) + FROM CASE_TBL a, CASE2_TBL b + ORDER BY coalesce; + coalesce +---------- + -30.3 + -30.3 + -30.3 + -30.3 + -30.3 + -30.3 + -6 + 1 + 1 + 2 + 2 + 3 + 10.1 + 10.1 + 10.1 + 10.1 + 10.1 + 10.1 + 20.2 + 20.2 + 20.2 + 20.2 + 20.2 + 20.2 +(24 rows) + +SELECT * + FROM CASE_TBL a, CASE2_TBL b + WHERE COALESCE(a.f, b.i, b.j) = 2 + ORDER BY a.i, a.f, b.i, b.j; + i | f | i | j +---+---+---+---- + 4 | | 2 | -4 + 4 | | 2 | -2 +(2 rows) + +SELECT '' AS Five, NULLIF(a.i,b.i) AS "NULLIF(a.i,b.i)", + NULLIF(b.i, 4) AS "NULLIF(b.i,4)" + FROM CASE_TBL a, CASE2_TBL b + ORDER BY 2, 3; + five | NULLIF(a.i,b.i) | NULLIF(b.i,4) +------+-----------------+--------------- + | 1 | 2 + | 1 | 2 + | 1 | 3 + | 1 | + | 2 | 1 + | 2 | 1 + | 2 | 3 + | 2 | + | 3 | 1 + | 3 | 1 + | 3 | 2 + | 3 | 2 + | 3 | + | 4 | 1 + | 4 | 1 + | 4 | 2 + | 4 | 2 + | 4 | 3 + | 4 | + | | 1 + | | 1 + | | 2 + | | 2 + | | 3 +(24 rows) + +SELECT '' AS "Two", * + FROM CASE_TBL a, CASE2_TBL b + WHERE COALESCE(f,b.i) = 2 + ORDER BY a.i, a.f, b.i, b.j; + Two | i | f | i | j +-----+---+---+---+---- + | 4 | | 2 | -4 + | 4 | | 2 | -2 +(2 rows) + +-- +-- Examples of updates involving tables +-- +UPDATE CASE_TBL + SET i = CASE WHEN i >= 3 THEN (- i) + ELSE (2 * i) END; +ERROR: could not plan this distributed update +DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL. +SELECT * FROM CASE_TBL ORDER BY i, f; + i | f +---+------- + 1 | 10.1 + 2 | 20.2 + 3 | -30.3 + 4 | +(4 rows) + +UPDATE CASE_TBL + SET i = CASE WHEN i >= 2 THEN (2 * i) + ELSE (3 * i) END; +ERROR: could not plan this distributed update +DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL. +SELECT * FROM CASE_TBL ORDER BY i, f; + i | f +---+------- + 1 | 10.1 + 2 | 20.2 + 3 | -30.3 + 4 | +(4 rows) + +UPDATE CASE_TBL + SET i = CASE WHEN b.i >= 2 THEN (2 * j) + ELSE (3 * j) END + FROM CASE2_TBL b + WHERE j = -CASE_TBL.i; +ERROR: could not plan this distributed update +DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL. +SELECT * FROM CASE_TBL ORDER BY i, f; + i | f +---+------- + 1 | 10.1 + 2 | 20.2 + 3 | -30.3 + 4 | +(4 rows) + +-- +-- Nested CASE expressions +-- +-- This test exercises a bug caused by aliasing econtext->caseValue_isNull +-- with the isNull argument of the inner CASE's ExecEvalCase() call. After +-- evaluating the vol(null) expression in the inner CASE's second WHEN-clause, +-- the isNull flag for the case test value incorrectly became true, causing +-- the third WHEN-clause not to match. The volatile function calls are needed +-- to prevent constant-folding in the planner, which would hide the bug. ++-- Wrap this in a single transaction so the transient '=' operator doesn't ++-- cause problems in concurrent sessions ++BEGIN; +CREATE FUNCTION vol(text) returns text as + 'begin return $1; end' language plpgsql volatile; +SELECT CASE + (CASE vol('bar') + WHEN 'foo' THEN 'it was foo!' + WHEN vol(null) THEN 'null input' + WHEN 'bar' THEN 'it was bar!' END + ) + WHEN 'it was foo!' THEN 'foo recognized' + WHEN 'it was bar!' THEN 'bar recognized' + ELSE 'unrecognized' END; + case +---------------- + bar recognized +(1 row) + +-- In this case, we can't inline the SQL function without confusing things. +CREATE DOMAIN foodomain AS text; +CREATE FUNCTION volfoo(text) returns foodomain as + 'begin return $1::foodomain; end' language plpgsql volatile; +CREATE FUNCTION inline_eq(foodomain, foodomain) returns boolean as + 'SELECT CASE $2::text WHEN $1::text THEN true ELSE false END' language sql; +CREATE OPERATOR = (procedure = inline_eq, + leftarg = foodomain, rightarg = foodomain); +SELECT CASE volfoo('bar') WHEN 'foo'::foodomain THEN 'is foo' ELSE 'is not foo' END; + case +------------ + is not foo +(1 row) + ++ROLLBACK; +-- +-- Clean up +-- +DROP TABLE CASE_TBL; +DROP TABLE CASE2_TBL; - DROP OPERATOR = (foodomain, foodomain); - DROP FUNCTION inline_eq(foodomain, foodomain); - DROP FUNCTION volfoo(text); - DROP DOMAIN foodomain; - DROP FUNCTION vol(text); diff --cc src/test/regress/expected/combocid_1.out index 71191dd544,0000000000..9bfdfe7579 mode 100644,000000..100644 --- a/src/test/regress/expected/combocid_1.out +++ b/src/test/regress/expected/combocid_1.out @@@ -1,103 -1,0 +1,129 @@@ +-- +-- Tests for some likely failure cases with combo cmin/cmax mechanism +-- +CREATE TEMP TABLE combocidtest (foobar int); +BEGIN; +-- a few dummy ops to push up the CommandId counter +INSERT INTO combocidtest SELECT 1 LIMIT 0; +INSERT INTO combocidtest SELECT 1 LIMIT 0; +INSERT INTO combocidtest SELECT 1 LIMIT 0; +INSERT INTO combocidtest SELECT 1 LIMIT 0; +INSERT INTO combocidtest SELECT 1 LIMIT 0; +INSERT INTO combocidtest SELECT 1 LIMIT 0; +INSERT INTO combocidtest SELECT 1 LIMIT 0; +INSERT INTO combocidtest SELECT 1 LIMIT 0; +INSERT INTO combocidtest SELECT 1 LIMIT 0; +INSERT INTO combocidtest SELECT 1 LIMIT 0; +INSERT INTO combocidtest VALUES (1); +INSERT INTO combocidtest VALUES (2); +SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid; + ctid | cmin | foobar +-------+------+-------- + (0,1) | 10 | 1 + (0,2) | 11 | 2 +(2 rows) + +SAVEPOINT s1; +ERROR: SAVEPOINT is not yet supported. +UPDATE combocidtest SET foobar = foobar + 10; +ERROR: current transaction is aborted, commands ignored until end of transaction block +-- here we should see only updated tuples +SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid; +ERROR: current transaction is aborted, commands ignored until end of transaction block +ROLLBACK TO s1; +ERROR: no such savepoint +-- now we should see old tuples, but with combo CIDs starting at 0 +SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid; +ERROR: current transaction is aborted, commands ignored until end of transaction block +COMMIT; +-- combo data is not there anymore, but should still see tuples +SELECT ctid,cmin,* FROM combocidtest; + ctid | cmin | foobar +------+------+-------- +(0 rows) + +-- Test combo cids with portals +BEGIN; +INSERT INTO combocidtest VALUES (333); +DECLARE c CURSOR FOR SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid; +DELETE FROM combocidtest; +FETCH ALL FROM c; + ctid | cmin | foobar +-------+------+-------- + (0,3) | 0 | 333 +(1 row) + +ROLLBACK; +SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid; + ctid | cmin | foobar +------+------+-------- +(0 rows) + +-- check behavior with locked tuples +BEGIN; +-- a few dummy ops to push up the CommandId counter +INSERT INTO combocidtest SELECT 1 LIMIT 0; +INSERT INTO combocidtest SELECT 1 LIMIT 0; +INSERT INTO combocidtest SELECT 1 LIMIT 0; +INSERT INTO combocidtest SELECT 1 LIMIT 0; +INSERT INTO combocidtest SELECT 1 LIMIT 0; +INSERT INTO combocidtest SELECT 1 LIMIT 0; +INSERT INTO combocidtest SELECT 1 LIMIT 0; +INSERT INTO combocidtest SELECT 1 LIMIT 0; +INSERT INTO combocidtest SELECT 1 LIMIT 0; +INSERT INTO combocidtest SELECT 1 LIMIT 0; +INSERT INTO combocidtest VALUES (444); +SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid; + ctid | cmin | foobar +-------+------+-------- + (0,4) | 10 | 444 +(1 row) + +SAVEPOINT s1; +ERROR: SAVEPOINT is not yet supported. +-- this doesn't affect cmin +SELECT ctid,cmin,* FROM combocidtest FOR UPDATE; +ERROR: current transaction is aborted, commands ignored until end of transaction block +SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid; +ERROR: current transaction is aborted, commands ignored until end of transaction block +-- but this does +UPDATE combocidtest SET foobar = foobar + 10; +ERROR: current transaction is aborted, commands ignored until end of transaction block +SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid; +ERROR: current transaction is aborted, commands ignored until end of transaction block +ROLLBACK TO s1; +ERROR: no such savepoint +SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid; +ERROR: current transaction is aborted, commands ignored until end of transaction block +COMMIT; +SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid; + ctid | cmin | foobar +------+------+-------- +(0 rows) + ++-- test for bug reported in ++-- CABRT9RC81YUf1=jsmWopcKJEro=VoeG2ou6sPwyOUTx_qteRsg@mail.gmail.com ++CREATE TABLE IF NOT EXISTS testcase( ++ id int PRIMARY KEY, ++ balance numeric ++); ++INSERT INTO testcase VALUES (1, 0); ++BEGIN; ++SELECT * FROM testcase WHERE testcase.id = 1 FOR UPDATE; ++ id | balance ++----+--------- ++ 1 | 0 ++(1 row) ++ ++UPDATE testcase SET balance = balance + 400 WHERE id=1; ++SAVEPOINT subxact; ++ERROR: SAVEPOINT is not yet supported. ++UPDATE testcase SET balance = balance - 100 WHERE id=1; ++ERROR: current transaction is aborted, commands ignored until end of transaction block ++ROLLBACK TO SAVEPOINT subxact; ++ERROR: no such savepoint ++-- should return one tuple ++SELECT * FROM testcase WHERE id = 1 FOR UPDATE; ++ERROR: current transaction is aborted, commands ignored until end of transaction block ++ROLLBACK; ++DROP TABLE testcase; diff --cc src/test/regress/expected/copy2_1.out index cbe870339c,0000000000..10334d9045 mode 100644,000000..100644 --- a/src/test/regress/expected/copy2_1.out +++ b/src/test/regress/expected/copy2_1.out @@@ -1,515 -1,0 +1,593 @@@ +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(); diff --cc src/test/regress/expected/foreign_key.out index 928d662d77,20e5fcf0a6..d6d21bde66 --- a/src/test/regress/expected/foreign_key.out +++ b/src/test/regress/expected/foreign_key.out @@@ -1356,12 -1354,29 +1356,37 @@@ create temp table cc (f1 int reference insert into pp values(12); insert into pp values(11); update pp set f1=f1+1; +ERROR: could not plan this distributed update +DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL. insert into cc values(13); +ERROR: insert or update on table "cc" violates foreign key constraint "cc_f1_fkey" +DETAIL: Key (f1)=(13) is not present in table "pp". update pp set f1=f1+1; -- fail -ERROR: update or delete on table "pp" violates foreign key constraint "cc_f1_fkey" on table "cc" -DETAIL: Key (f1)=(13) is still referenced from table "cc". +ERROR: could not plan this distributed update +DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL. drop table pp, cc; + -- + -- Test deferred FK check on a tuple deleted by a rolled-back subtransaction + -- + create table pktable2(f1 int primary key); + create table fktable2(f1 int references pktable2 deferrable initially deferred); + insert into pktable2 values(1); + begin; + insert into fktable2 values(1); + savepoint x; ++ERROR: SAVEPOINT is not yet supported. + delete from fktable2; ++ERROR: current transaction is aborted, commands ignored until end of transaction block + rollback to x; ++ERROR: no such savepoint + commit; + begin; + insert into fktable2 values(2); + savepoint x; ++ERROR: SAVEPOINT is not yet supported. + delete from fktable2; ++ERROR: current transaction is aborted, commands ignored until end of transaction block + rollback to x; ++ERROR: no such savepoint + commit; -- fail -ERROR: insert or update on table "fktable2" violates foreign key constraint "fktable2_f1_fkey" -DETAIL: Key (f1)=(2) is not present in table "pktable2". + drop table pktable2, fktable2; diff --cc src/test/regress/expected/matview.out index 0992ff6a21,ec11c852ad..d9ae854cb0 --- a/src/test/regress/expected/matview.out +++ b/src/test/regress/expected/matview.out @@@ -565,5 -554,31 +565,30 @@@ NOTICE: relation "mv_foo" already exis CREATE UNIQUE INDEX ON mv_foo (i); RESET ROLE; REFRESH MATERIALIZED VIEW mv_foo; -REFRESH MATERIALIZED VIEW CONCURRENTLY mv_foo; DROP OWNED BY user_dw CASCADE; DROP ROLE user_dw; + -- make sure that create WITH NO DATA works via SPI + BEGIN; + CREATE FUNCTION mvtest_func() + RETURNS void AS $$ + BEGIN + CREATE MATERIALIZED VIEW mvtest1 AS SELECT 1 AS x; + CREATE MATERIALIZED VIEW mvtest2 AS SELECT 1 AS x WITH NO DATA; + END; + $$ LANGUAGE plpgsql; + SELECT mvtest_func(); + mvtest_func + ------------- + + (1 row) + + SELECT * FROM mvtest1; + x + --- + 1 + (1 row) + + SELECT * FROM mvtest2; + ERROR: materialized view "mvtest2" has not been populated + HINT: Use the REFRESH MATERIALIZED VIEW command. + ROLLBACK; diff --cc src/test/regress/expected/stats.out index 057ccb24a5,f5be70fe7c..6c056feaff --- a/src/test/regress/expected/stats.out +++ b/src/test/regress/expected/stats.out @@@ -165,10 -148,10 +165,10 @@@ SELECT relname, n_tup_ins, n_tup_upd, n WHERE relname like 'trunc_stats_test%' order by relname; relname | n_tup_ins | n_tup_upd | n_tup_del | n_live_tup | n_dead_tup -------------------+-----------+-----------+-----------+------------+------------ - trunc_stats_test | 3 | 0 | 0 | 3 | 0 + trunc_stats_test | 3 | 0 | 0 | 0 | 0 - trunc_stats_test1 | 4 | 2 | 1 | 1 | 0 - trunc_stats_test2 | 1 | 0 | 0 | 1 | 0 - trunc_stats_test3 | 4 | 0 | 0 | 2 | 2 + trunc_stats_test1 | 3 | 0 | 1 | 2 | 1 + trunc_stats_test2 | 2 | 0 | 0 | 0 | 2 + trunc_stats_test3 | 2 | 0 | 0 | 0 | 2 trunc_stats_test4 | 2 | 0 | 0 | 0 | 2 (5 rows) diff --cc src/test/regress/sql/combocid.sql index 709ca4d5b0,4faea36f41..c2cdee7235 --- a/src/test/regress/sql/combocid.sql +++ b/src/test/regress/sql/combocid.sql @@@ -90,4 -90,22 +90,22 @@@ SELECT ctid,cmin,* FROM combocidtest OR COMMIT; -SELECT ctid,cmin,* FROM combocidtest; +SELECT ctid,cmin,* FROM combocidtest ORDER BY ctid; + + -- test for bug reported in + -- CABRT9RC81YUf1=jsmWopcKJEro=VoeG2ou6sPwyOUTx_qteRsg@mail.gmail.com + CREATE TABLE IF NOT EXISTS testcase( + id int PRIMARY KEY, + balance numeric + ); + INSERT INTO testcase VALUES (1, 0); + BEGIN; + SELECT * FROM testcase WHERE testcase.id = 1 FOR UPDATE; + UPDATE testcase SET balance = balance + 400 WHERE id=1; + SAVEPOINT subxact; + UPDATE testcase SET balance = balance - 100 WHERE id=1; + ROLLBACK TO SAVEPOINT subxact; + -- should return one tuple + SELECT * FROM testcase WHERE id = 1 FOR UPDATE; + ROLLBACK; + DROP TABLE testcase; diff --cc src/test/regress/sql/matview.sql index ec66be15a9,8e623cc1eb..d2ad1bedeb --- a/src/test/regress/sql/matview.sql +++ b/src/test/regress/sql/matview.sql @@@ -219,5 -223,20 +219,19 @@@ CREATE MATERIALIZED VIEW IF NOT EXISTS CREATE UNIQUE INDEX ON mv_foo (i); RESET ROLE; REFRESH MATERIALIZED VIEW mv_foo; -REFRESH MATERIALIZED VIEW CONCURRENTLY mv_foo; DROP OWNED BY user_dw CASCADE; DROP ROLE user_dw; + + -- make sure that create WITH NO DATA works via SPI + BEGIN; + CREATE FUNCTION mvtest_func() + RETURNS void AS $$ + BEGIN + CREATE MATERIALIZED VIEW mvtest1 AS SELECT 1 AS x; + CREATE MATERIALIZED VIEW mvtest2 AS SELECT 1 AS x WITH NO DATA; + END; + $$ LANGUAGE plpgsql; + SELECT mvtest_func(); + SELECT * FROM mvtest1; + SELECT * FROM mvtest2; + ROLLBACK;