Merge tag 'REL9_5_5' into XL9_5_STABLE
authorPavan Deolasee <[email protected]>
Tue, 22 Nov 2016 10:47:44 +0000 (16:17 +0530)
committerPavan Deolasee <[email protected]>
Tue, 22 Nov 2016 10:47:44 +0000 (16:17 +0530)
69 files changed:
1  2 
configure
configure.in
doc/bug.template
doc/src/sgml/catalogs.sgml
doc/src/sgml/ddl.sgml
doc/src/sgml/func.sgml
doc/src/sgml/installation.sgml
doc/src/sgml/maintenance.sgml
doc/src/sgml/ref/alter_user_mapping.sgml
doc/src/sgml/ref/create_view.sgml
doc/src/sgml/runtime.sgml
src/Makefile
src/Makefile.global.in
src/backend/access/heap/heapam.c
src/backend/access/heap/tuptoaster.c
src/backend/access/transam/xlog.c
src/backend/catalog/heap.c
src/backend/commands/copy.c
src/backend/commands/explain.c
src/backend/commands/tablecmds.c
src/backend/executor/nodeAgg.c
src/backend/executor/nodeModifyTable.c
src/backend/executor/spi.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/outfuncs.c
src/backend/nodes/readfuncs.c
src/backend/optimizer/plan/createplan.c
src/backend/optimizer/plan/subselect.c
src/backend/postmaster/pgstat.c
src/backend/postmaster/postmaster.c
src/backend/replication/syncrep.c
src/backend/utils/adt/numeric.c
src/backend/utils/adt/ri_triggers.c
src/backend/utils/error/elog.c
src/backend/utils/misc/guc.c
src/backend/utils/sort/tuplesort.c
src/backend/utils/time/tqual.c
src/bin/pg_dump/pg_dump.c
src/bin/pgbench/pgbench.c
src/bin/psql/command.c
src/bin/psql/describe.c
src/include/nodes/plannodes.h
src/include/pg_config.h.in
src/include/pg_config.h.win32
src/include/utils/elog.h
src/include/utils/guc.h
src/test/regress/expected/aggregates.out
src/test/regress/expected/case.out
src/test/regress/expected/case_1.out
src/test/regress/expected/combocid.out
src/test/regress/expected/combocid_1.out
src/test/regress/expected/copy2.out
src/test/regress/expected/copy2_1.out
src/test/regress/expected/foreign_key.out
src/test/regress/expected/inherit.out
src/test/regress/expected/insert_conflict.out
src/test/regress/expected/matview.out
src/test/regress/expected/sanity_check.out
src/test/regress/expected/stats.out
src/test/regress/expected/timestamptz.out
src/test/regress/sql/aggregates.sql
src/test/regress/sql/case.sql
src/test/regress/sql/combocid.sql
src/test/regress/sql/copy2.sql
src/test/regress/sql/foreign_key.sql
src/test/regress/sql/inherit.sql
src/test/regress/sql/insert_conflict.sql
src/test/regress/sql/matview.sql
src/test/regress/sql/timestamptz.sql

diff --cc configure
index 3c10aa5a3ebce9f55a8cf31779e6313a8674dc23,2275ad677e2a23cc7f299e3efcc8b646c84b56af..8d20510ce64255d158643669b8ad9ce76b459b0c
+++ 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 <pgsql-bugs@postgresql.org>.
 +# Report bugs to <bugs@postgres-xl.org>.
  #
  #
  # 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='[email protected]'
++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='[email protected]'
  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]...
  
  
  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
  
  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 55762acade0860bef7bce3fde172e8f4a9a0d4ba,51525bacf94d9ae043d917f09872e977f21bee31..142ebe9fc6445ae5880f1af8b80014ac5426d600
@@@ -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)], [[email protected]])
 -AC_INIT([PostgreSQL], [9.5.5], [[email protected]])
++AC_INIT([PostgreSQL], [9.5.5 (Postgres-XL 9.5r1.3)], [[email protected]])
  
  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
index a08bcc16c74d187e6d7fc884c039902e72980486,07b62847c5f66a1398f2c573140692fb929afc36..6d4d456e9476150e8a99b237d5642824030aab59
@@@ -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)          :
  
Simple merge
index 98df43338e95f08fe09c78322c8b293319526099,e139f643f35e6aa2ea36cdec2e2d17737ebfad80..dabc03c88859ae7246e48e742c4129209723ba4a
mode 100755,100644..100755
Simple merge
Simple merge
index 216ca83cd448565034a60975e961ab1a54986e01,74f5de835ebeedd9592fa0021d547a1d8a6d535f..a72c37f3af96932ce61a2f7a3f3dca3952243020
       <secondary>of transaction IDs</secondary>
      </indexterm>
  
 +   <para>
 +    Please note that this section describes the tasks of individual
 +    Coordinators and Datanodes.  It should be done for each of them.
 +   </para>
 +
     <para>
-     <productname>PostgreSQL</productname>'s MVCC transaction semantics
+     <productname>PostgreSQL</productname>'s
+     <link linkend="mvcc-intro">MVCC</link> transaction semantics
      depend on being able to compare transaction ID (<acronym>XID</>)
      numbers: a row version with an insertion XID greater than the current
      transaction's XID is <quote>in the future</> and should not be visible
Simple merge
Simple merge
diff --cc src/Makefile
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 16a78e72347a7fae9ede581b1a6d35eb43ca8ea8,32b23fff097ca576e20f928ed8da3b2b6437600a..1267a8c179b162fb108f0155b601e26ea71e320c
@@@ -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();
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 909e2667e6f855c468f991d80a13907906f9cfd6,afe41ff645f88e8b08a732d664c9654ea04d6280..59320a4d61b93cd2ea7e70cc3fa6119f19baca3a
@@@ -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);
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index bd79626f854ae322c4d7d27161a1db639d80e07d,19ac065530d01a636adc0e253df8bf05c0484946..649e4dbe8670c0d061a5421f752c0034cbb835cb
@@@ -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();
Simple merge
Simple merge
Simple merge
index 3fc5522e4fee9c367a01da66ad979bb61017bc12,64cc86a07e62cd559ab46e47334bffbcebc74d00..6b2785883ee87726496a6be99e4e66dd9896a377
  #define MEMSET_LOOP_LIMIT 1024
  
  /* Define to the address where bug reports for this package should be sent. */
 -#define PACKAGE_BUGREPORT "p[email protected]"
 +#define PACKAGE_BUGREPORT "p[email protected]"
  
  /* 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
  #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) */
Simple merge
Simple merge
Simple merge
index 4fbff97f321b49b858b68a0422d8d76c2f9065bb,0000000000000000000000000000000000000000..6f31fa8c105f214e01da5c37b2d7db1915690300
mode 100644,000000..100644
--- /dev/null
@@@ -1,361 -1,0 +1,360 @@@
- DROP OPERATOR = (foodomain, foodomain);
- DROP FUNCTION inline_eq(foodomain, foodomain);
- DROP FUNCTION volfoo(text);
- DROP DOMAIN foodomain;
- DROP FUNCTION vol(text);
 +--
 +-- 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 '<NULL>' AS "One",
 +  CASE
 +    WHEN 1 > 2 THEN 3
 +  END AS "Simple default";
 +  One   | Simple default 
 +--------+----------------
 + <NULL> |               
 +(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;
index 71191dd54493b35a6eac8e2f68dd1e1aa52d6e0b,0000000000000000000000000000000000000000..9bfdfe7579def8f0ab9a5ac105ba98d76203dee2
mode 100644,000000..100644
--- /dev/null
@@@ -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;
Simple merge
index cbe870339c128af7866febe535013fb50831ce40,0000000000000000000000000000000000000000..10334d90453948fe189aa2beaa49ffc07f394ca7
mode 100644,000000..100644
--- /dev/null
@@@ -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();
index 928d662d777857d7e23abe4bc66e1d0b12f151fd,20e5fcf0a68ba2a5190ecd78975122501d7bd8ae..d6d21bde6656509c03aa7c573997a5c3f4ef451b
@@@ -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;
 -ERROR:  insert or update on table "fktable2" violates foreign key constraint "fktable2_f1_fkey"
 -DETAIL:  Key (f1)=(2) is not present in table "pktable2".
+ --
+ -- 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
+ drop table pktable2, fktable2;
Simple merge
index 0992ff6a215514c112b53015fec9e8ea256be8e7,ec11c852ad12b1b2a425488bbaaec1a0a462d61a..d9ae854cb07b0a0802f43664e08ef386303e52a5
@@@ -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;
index 057ccb24a50d5c7ab3e3b5ae1fd75600f955920d,f5be70fe7c4948941abe35a8d6b22f6df5ec1757..6c056feafffe9e80523a3adb10049cba90b30c37
@@@ -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)
  
Simple merge
Simple merge
index 709ca4d5b00f73e103ff6a9778cd960ff820adac,4faea36f41a45906c49a9bebfe73ff81e3d3ad8e..c2cdee72351049ac4e0f4b491f475484022e033d
@@@ -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;
Simple merge
Simple merge
Simple merge
index ec66be15a9fa08e145356b41967065f18175f3fe,8e623cc1ebcceb1f9698b649aeffbc337323bca5..d2ad1bedeb5931e6b110a48834d4e6f98fa1330f
@@@ -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;
Simple merge