-PostgreSQL Database Management System
-(formerly known as Postgres, then as Postgres95)
+Postgres-XL Cluster Database Management System
- Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
+Portions Copyright (c) 2012-2014, TransLattice, Inc.
+Portions Copyright (c) 2010-2013, Postgres-XC Development Group
+ Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
+Portions Copyright (c) 2015, 2ndQuadrant Limited
Portions Copyright (c) 1994, The Regents of the University of California
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
- # Generated by GNU Autoconf 2.69 for PostgreSQL 9.5beta1 (Postgres-XL 9.5beta1).
-# Generated by GNU Autoconf 2.69 for PostgreSQL 9.5.0.
++# Generated by GNU Autoconf 2.69 for PostgreSQL 9.5.0 (Postgres-XL 9.5beta1).
#
-# Report bugs to <pgsql-bugs@postgresql.org>.
+# Report bugs to <bugs@postgres-xl.org>.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
# Identity of this package.
PACKAGE_NAME='PostgreSQL'
PACKAGE_TARNAME='postgresql'
- PACKAGE_VERSION='9.5beta1 (Postgres-XL 9.5beta1)'
-PACKAGE_VERSION='9.5.0'
-PACKAGE_STRING='PostgreSQL 9.5.0'
++PACKAGE_VERSION='9.5.0 (Postgres-XL 9.5beta1)'
+PACKAGE_XC_VERSION='9.5beta1'
- PACKAGE_STRING='PostgreSQL 9.5beta1 (Postgres-XL 9.5beta1)'
++PACKAGE_STRING='PostgreSQL 9.5.0 (Postgres-XL 9.5beta1)'
PACKAGE_URL=''
ac_unique_file="src/backend/access/common/heaptuple.c"
# 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.5beta1 (Postgres-XL 9.5beta1) to adapt to many kinds of systems.
-\`configure' configures PostgreSQL 9.5.0 to adapt to many kinds of systems.
++\`configure' configures PostgreSQL 9.5.0 (Postgres-XL 9.5beta1) 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.5beta1 (Postgres-XL 9.5beta1):";;
- short | recursive ) echo "Configuration of PostgreSQL 9.5.0:";;
++ short | recursive ) echo "Configuration of PostgreSQL 9.5.0 (Postgres-XL 9.5beta1):";;
esac
cat <<\_ACEOF
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
++<<<<<<< HEAD
+PostgreSQL configure 9.5beta1 (Postgres-XL 9.5beta1)
++=======
+ PostgreSQL configure 9.5.0
++>>>>>>> cdd4ed5449bf317cc71b45a8deee0173822e7592
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
++<<<<<<< HEAD
+It was created by PostgreSQL $as_me 9.5beta1 (Postgres-XL 9.5beta1), which was
++=======
+ It was created by PostgreSQL $as_me 9.5.0, which was
++>>>>>>> cdd4ed5449bf317cc71b45a8deee0173822e7592
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
++<<<<<<< HEAD
+This file was extended by PostgreSQL $as_me 9.5beta1 (Postgres-XL 9.5beta1), which was
++=======
+ This file was extended by PostgreSQL $as_me 9.5.0, which was
++>>>>>>> cdd4ed5449bf317cc71b45a8deee0173822e7592
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
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.5beta1 (Postgres-XL 9.5beta1)
-PostgreSQL config.status 9.5.0
++PostgreSQL config.status 9.5.0 (Postgres-XL 9.5beta1)
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
dnl
m4_pattern_forbid(^PGAC_)dnl to catch undefined macros
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
Operating System (example: Linux 2.4.18) :
- PostgreSQL version (example: PostgreSQL 9.5beta1): Postgres-XL 9.5beta1
- PostgreSQL version (example: PostgreSQL 9.5.0): PostgreSQL 9.5.0
++ PostgreSQL version (example: PostgreSQL 9.5.0): Postgres-XL 9.5beta1
Compiler used (example: gcc 3.3.5) :
<!-- doc/src/sgml/legal.sgml -->
- <date>2015</date>
+ <date>2016</date>
<copyright>
- <year>1996-2015</year>
+ <year>1996-2016</year>
<holder>The PostgreSQL Global Development Group</holder>
</copyright>
+<copyright>
+ <year>2009-2012</year>
+ <holder>Postgres-XC Development Group</holder>
+</copyright>
+<copyright>
+ <year>2012-2014</year>
+ <holder>TransLattice, Inc.</holder>
+</copyright>
+<copyright>
+ <year>2015</year>
+ <holder>2ndQuadrant Ltd</holder>
+</copyright>
<legalnotice id="legalnotice">
<title>Legal Notice</title>
#include "executor/executor.h"
#include "executor/nodeForeignscan.h"
#include "foreign/fdwapi.h"
+ #include "utils/memutils.h"
#include "utils/rel.h"
+#ifdef PGXC
+#include "utils/lsyscache.h"
+#include "pgxc/pgxc.h"
+#endif
+
static TupleTableSlot *ForeignNext(ForeignScanState *node);
static bool ForeignRecheck(ForeignScanState *node, TupleTableSlot *slot);
Index scanrelid,
List *fdw_exprs,
List *fdw_private,
- List *fdw_scan_tlist)
+ List *fdw_scan_tlist,
+ List *fdw_recheck_quals,
+ Plan *outer_plan)
{
ForeignScan *node = makeNode(ForeignScan);
+
Plan *plan = &node->scan.plan;
/* cost will be filled in by create_foreignscan_plan */
/* Adjust tlist, qual, fdw_exprs to reference custom scan tuple */
indexed_tlist *itlist = build_tlist_index(fscan->fdw_scan_tlist);
+#ifdef XCP
+ fscan->scan.plan.targetlist = (List *)
+ fix_upper_expr(root,
+ (Node *) fscan->scan.plan.targetlist,
+ itlist,
+ INDEX_VAR,
+ rtoffset,
+ false);
+ fscan->scan.plan.qual = (List *)
+ fix_upper_expr(root,
+ (Node *) fscan->scan.plan.qual,
+ itlist,
+ INDEX_VAR,
+ rtoffset,
+ false);
+ fscan->fdw_exprs = (List *)
+ fix_upper_expr(root,
+ (Node *) fscan->fdw_exprs,
+ itlist,
+ INDEX_VAR,
+ rtoffset,
+ false);
++ fscan->fdw_recheck_quals = (List *)
++ fix_upper_expr(root,
++ (Node *) fscan->fdw_recheck_quals,
++ itlist,
++ INDEX_VAR,
++ rtoffset,
++ false);
+#else
fscan->scan.plan.targetlist = (List *)
fix_upper_expr(root,
(Node *) fscan->scan.plan.targetlist,
itlist,
INDEX_VAR,
rtoffset);
+ fscan->fdw_recheck_quals = (List *)
+ fix_upper_expr(root,
+ (Node *) fscan->fdw_recheck_quals,
+ itlist,
+ INDEX_VAR,
+ rtoffset);
+#endif
pfree(itlist);
/* fdw_scan_tlist itself just needs fix_scan_list() adjustments */
fscan->fdw_scan_tlist =
#include "commands/tablespace.h"
#include "executor/spi.h"
#include "funcapi.h"
+#ifdef PGXC
+#include "nodes/execnodes.h"
+#endif
+ #include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
int tcp_keepalives_interval;
int tcp_keepalives_count;
+#ifdef XCP
+char *storm_catalog_remap_string;
+#endif
+ /*
+ * SSL renegotiation was been removed in PostgreSQL 9.5, but we tolerate it
+ * being set to zero (meaning never renegotiate) for backward compatibility.
+ * This avoids breaking compatibility with clients that have never supported
+ * renegotiation and therefore always try to zero it.
+ */
+ int ssl_renegotiation_limit;
+
/*
* This really belongs in pg_shmem.c, but is defined here so that it doesn't
* need to be duplicated in all the different implementations of pg_shmem.c.
/*
* Since there might be quotes to handle here, it is easier simply to pass
- * everything to a shell to process them.
- *
- * XXX it would be better to fork and exec so that we would know the child
- * postmaster's PID directly; then test_postmaster_connection could use
- * the PID without having to rely on reading it back from the pidfile.
+ * everything to a shell to process them. Use exec so that the postmaster
+ * has the same PID as the current child process.
*/
if (log_file != NULL)
- snprintf(cmd, MAXPGPATH, "\"%s\" %s %s%s < \"%s\" >> \"%s\" 2>&1 &",
+#ifdef PGXC
- snprintf(cmd, MAXPGPATH, "\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1 &",
++ snprintf(cmd, MAXPGPATH, "exec \"%s\" %s %s%s < \"%s\" >> \"%s\" 2>&1",
+ exec_path, pgxcCommand, pgdata_opt, post_opts,
+ DEVNULL, log_file);
+#else
+ snprintf(cmd, MAXPGPATH, "exec \"%s\" %s%s < \"%s\" >> \"%s\" 2>&1",
exec_path, pgdata_opt, post_opts,
DEVNULL, log_file);
+#endif
else
- snprintf(cmd, MAXPGPATH, "\"%s\" %s %s%s < \"%s\" 2>&1 &",
+#ifdef PGXC
- snprintf(cmd, MAXPGPATH, "\"%s\" %s%s < \"%s\" 2>&1 &",
++ snprintf(cmd, MAXPGPATH, "exec \"%s\" %s %s%s < \"%s\" 2>&1",
+ exec_path, pgxcCommand, pgdata_opt, post_opts, DEVNULL);
+#else
+ snprintf(cmd, MAXPGPATH, "exec \"%s\" %s%s < \"%s\" 2>&1",
exec_path, pgdata_opt, post_opts, DEVNULL);
+#endif
- return system(cmd);
+ (void) execl("/bin/sh", "/bin/sh", "-c", cmd, (char *) NULL);
+
+ /* exec failed */
+ write_stderr(_("%s: could not start server: %s\n"),
+ progname, strerror(errno));
+ exit(1);
+
+ return 0; /* keep dumb compilers quiet */
+
#else /* WIN32 */
/*
"d.refobjid AS owning_tab, "
"d.refobjsubid AS owning_col, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
- "array_to_string(array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded'), ', ') AS reloptions, "
+#ifdef PGXC
+ "(SELECT pclocatortype from pgxc_class v where v.pcrelid = c.oid) AS pgxclocatortype,"
+ "(SELECT pcattnum from pgxc_class v where v.pcrelid = c.oid) AS pgxcattnum,"
+ "(SELECT string_agg(node_name,',') AS pgxc_node_names from pgxc_node n where n.oid in (select unnest(nodeoids) from pgxc_class v where v.pcrelid=c.oid) ) , "
+#endif
+ "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
"CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
"WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "
- "array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
+ "tc.reloptions AS toast_reloptions "
"FROM pg_class c "
"LEFT JOIN pg_depend d ON "
"(c.relkind = '%c' AND "
"d.refobjid AS owning_tab, "
"d.refobjsubid AS owning_col, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
- "array_to_string(array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded'), ', ') AS reloptions, "
+#ifdef PGXC
+ "(SELECT pclocatortype from pgxc_class v where v.pcrelid = c.oid) AS pgxclocatortype,"
+ "(SELECT pcattnum from pgxc_class v where v.pcrelid = c.oid) AS pgxcattnum,"
+ "(SELECT string_agg(node_name,',') AS pgxc_node_names from pgxc_node n where n.oid in (select unnest(nodeoids) from pgxc_class v where v.pcrelid=c.oid) ) , "
+#endif
+ "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
"CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
"WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "
- "array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
+ "tc.reloptions AS toast_reloptions "
"FROM pg_class c "
"LEFT JOIN pg_depend d ON "
"(c.relkind = '%c' AND "
"d.refobjid AS owning_tab, "
"d.refobjsubid AS owning_col, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
- "array_to_string(array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded'), ', ') AS reloptions, "
+#ifdef PGXC
+ "(SELECT pclocatortype from pgxc_class v where v.pcrelid = c.oid) AS pgxclocatortype,"
+ "(SELECT pcattnum from pgxc_class v where v.pcrelid = c.oid) AS pgxcattnum,"
+ "(SELECT string_agg(node_name,',') AS pgxc_node_names from pgxc_node n where n.oid in (select unnest(nodeoids) from pgxc_class v where v.pcrelid=c.oid) ) , "
+#endif
+ "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, "
"CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text "
"WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption, "
- "array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
+ "tc.reloptions AS toast_reloptions "
"FROM pg_class c "
"LEFT JOIN pg_depend d ON "
"(c.relkind = '%c' AND "
"d.refobjid AS owning_tab, "
"d.refobjsubid AS owning_col, "
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
- "array_to_string(c.reloptions, ', ') AS reloptions, "
- "array_to_string(array(SELECT 'toast.' || x FROM unnest(tc.reloptions) x), ', ') AS toast_reloptions "
+#ifdef PGXC
+ "(SELECT pclocatortype from pgxc_class v where v.pcrelid = c.oid) AS pgxclocatortype,"
+ "(SELECT pcattnum from pgxc_class v where v.pcrelid = c.oid) AS pgxcattnum,"
+ "(SELECT string_agg(node_name,',') AS pgxc_node_names from pgxc_node n where n.oid in (select unnest(nodeoids) from pgxc_class v where v.pcrelid=c.oid) ) , "
+#endif
+ "c.reloptions AS reloptions, "
+ "tc.reloptions AS toast_reloptions "
"FROM pg_class c "
"LEFT JOIN pg_depend d ON "
"(c.relkind = '%c' AND "
Index scanrelid, Plan *subplan);
extern ForeignScan *make_foreignscan(List *qptlist, List *qpqual,
Index scanrelid, List *fdw_exprs, List *fdw_private,
- List *fdw_scan_tlist);
+ List *fdw_scan_tlist, List *fdw_recheck_quals,
+ Plan *outer_plan);
extern Append *make_append(List *appendplans, List *tlist);
-extern RecursiveUnion *make_recursive_union(List *tlist,
+extern RecursiveUnion *make_recursive_union(PlannerInfo *root, List *tlist,
Plan *lefttree, Plan *righttree, int wtParam,
List *distinctList, long numGroups);
extern Sort *make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree,
#define MEMSET_LOOP_LIMIT 1024
/* Define to the address where bug reports for this package should be sent. */
/* 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.0"
+#define PACKAGE_STRING "Postgres-XL 9.5beta1"
/* Define to the version of this package. */
- #define PACKAGE_VERSION "9.5beta1"
+ #define PACKAGE_VERSION "9.5.0"
/* Define to the name of a signed 128-bit integer type. */
#undef PG_INT128_TYPE
ERROR: column "f1" does not exist
LINE 1: select f1 from c1;
^
- HINT: Perhaps you meant to reference the column "c1"."f2".
+ HINT: Perhaps you meant to reference the column "c1.f2".
drop table p1 cascade;
NOTICE: drop cascades to table c1
-create table p1 (f1 int, f2 int);
-create table c1 () inherits(p1);
+create table p1 (f1 int, f2 int) distribute by roundrobin;
+create table c1 () inherits(p1) distribute by roundrobin;
-- should be rejected since c1.f1 is inherited
alter table c1 drop column f1;
ERROR: cannot drop inherited column "f1"
ERROR: column "f1" does not exist
LINE 1: select f1 from c1;
^
- HINT: Perhaps you meant to reference the column "c1"."f2".
+ HINT: Perhaps you meant to reference the column "c1.f2".
drop table p1 cascade;
NOTICE: drop cascades to table c1
-create table p1 (f1 int, f2 int);
-create table c1 () inherits(p1);
+create table p1 (f1 int, f2 int) distribute by roundrobin;
+create table c1 () inherits(p1) distribute by roundrobin;
-- should be rejected since c1.f1 is inherited
alter table c1 drop column f1;
ERROR: cannot drop inherited column "f1"
DROP FOREIGN TABLE IF EXISTS no_table;
NOTICE: foreign table "no_table" does not exist, skipping
DROP FOREIGN TABLE foreign_schema.foreign_table_1;
+ERROR: foreign table "foreign_table_1" does not exist
+ -- REASSIGN OWNED/DROP OWNED of foreign objects
+ REASSIGN OWNED BY regress_test_role TO regress_test_role2;
+ DROP OWNED BY regress_test_role2;
+ ERROR: cannot drop desired object(s) because other objects depend on them
+ DETAIL: user mapping for regress_test_role on server s5 depends on server s5
+ HINT: Use DROP ... CASCADE to drop the dependent objects too.
+ DROP OWNED BY regress_test_role2 CASCADE;
+ NOTICE: drop cascades to user mapping for regress_test_role on server s5
-- Cleanup
DROP SCHEMA foreign_schema CASCADE;
DROP ROLE regress_test_role; -- ERROR
DETAIL: privileges for server s4
privileges for foreign-data wrapper foo
owner of user mapping for regress_test_role on server s6
- owner of user mapping for regress_test_role on server s5
- owner of server s5
- owner of server t2
- DROP SERVER s5 CASCADE;
- NOTICE: drop cascades to user mapping for regress_test_role on server s5
DROP SERVER t1 CASCADE;
NOTICE: drop cascades to user mapping for public on server t1
+DROP SERVER t2;
+ERROR: server "t2" does not exist
DROP USER MAPPING FOR regress_test_role SERVER s6;
+ERROR: role "regress_test_role" does not exist
-- This test causes some order dependent cascade detail output,
--- so switch to terse mode for it.
+-- so switch to terse mode for it.
\set VERBOSITY terse
DROP FOREIGN DATA WRAPPER foo CASCADE;
-NOTICE: drop cascades to 5 other objects
+ERROR: foreign-data wrapper "foo" does not exist
\set VERBOSITY default
DROP SERVER s8 CASCADE;
NOTICE: drop cascades to 2 other objects
on i8.q1 = i4.f1;
f1 | q1 | q2 | f1 | f1
------+-----+-----+-------------------+----
- doh! | 123 | 456 | doh! |
doh! | 123 | 456 | hi de ho neighbor |
+ doh! | 123 | 456 | doh! |
(2 rows)
+ --
+ -- test for appropriate join order in the presence of lateral references
+ --
+ explain (verbose, costs off)
+ select * from
+ text_tbl t1
+ left join int8_tbl i8
+ on i8.q2 = 123,
+ lateral (select i8.q1, t2.f1 from text_tbl t2 limit 1) as ss
+ where t1.f1 = ss.f1;
+ QUERY PLAN
+ --------------------------------------------------
+ Nested Loop
+ Output: t1.f1, i8.q1, i8.q2, (i8.q1), t2.f1
+ Join Filter: (t1.f1 = t2.f1)
+ -> Nested Loop Left Join
+ Output: t1.f1, i8.q1, i8.q2
+ -> Seq Scan on public.text_tbl t1
+ Output: t1.f1
+ -> Materialize
+ Output: i8.q1, i8.q2
+ -> Seq Scan on public.int8_tbl i8
+ Output: i8.q1, i8.q2
+ Filter: (i8.q2 = 123)
+ -> Limit
+ Output: (i8.q1), t2.f1
+ -> Seq Scan on public.text_tbl t2
+ Output: i8.q1, t2.f1
+ (16 rows)
+
+ select * from
+ text_tbl t1
+ left join int8_tbl i8
+ on i8.q2 = 123,
+ lateral (select i8.q1, t2.f1 from text_tbl t2 limit 1) as ss
+ where t1.f1 = ss.f1;
+ f1 | q1 | q2 | q1 | f1
+ ------+------------------+-----+------------------+------
+ doh! | 4567890123456789 | 123 | 4567890123456789 | doh!
+ (1 row)
+
+ explain (verbose, costs off)
+ select * from
+ text_tbl t1
+ left join int8_tbl i8
+ on i8.q2 = 123,
+ lateral (select i8.q1, t2.f1 from text_tbl t2 limit 1) as ss1,
+ lateral (select ss1.* from text_tbl t3 limit 1) as ss2
+ where t1.f1 = ss2.f1;
+ QUERY PLAN
+ -------------------------------------------------------------------
+ Nested Loop
+ Output: t1.f1, i8.q1, i8.q2, (i8.q1), t2.f1, ((i8.q1)), (t2.f1)
+ Join Filter: (t1.f1 = (t2.f1))
+ -> Nested Loop
+ Output: t1.f1, i8.q1, i8.q2, (i8.q1), t2.f1
+ -> Nested Loop Left Join
+ Output: t1.f1, i8.q1, i8.q2
+ -> Seq Scan on public.text_tbl t1
+ Output: t1.f1
+ -> Materialize
+ Output: i8.q1, i8.q2
+ -> Seq Scan on public.int8_tbl i8
+ Output: i8.q1, i8.q2
+ Filter: (i8.q2 = 123)
+ -> Limit
+ Output: (i8.q1), t2.f1
+ -> Seq Scan on public.text_tbl t2
+ Output: i8.q1, t2.f1
+ -> Limit
+ Output: ((i8.q1)), (t2.f1)
+ -> Seq Scan on public.text_tbl t3
+ Output: (i8.q1), t2.f1
+ (22 rows)
+
+ select * from
+ text_tbl t1
+ left join int8_tbl i8
+ on i8.q2 = 123,
+ lateral (select i8.q1, t2.f1 from text_tbl t2 limit 1) as ss1,
+ lateral (select ss1.* from text_tbl t3 limit 1) as ss2
+ where t1.f1 = ss2.f1;
+ f1 | q1 | q2 | q1 | f1 | q1 | f1
+ ------+------------------+-----+------------------+------+------------------+------
+ doh! | 4567890123456789 | 123 | 4567890123456789 | doh! | 4567890123456789 | doh!
+ (1 row)
+
+ explain (verbose, costs off)
+ select 1 from
+ text_tbl as tt1
+ inner join text_tbl as tt2 on (tt1.f1 = 'foo')
+ left join text_tbl as tt3 on (tt3.f1 = 'foo')
+ left join text_tbl as tt4 on (tt3.f1 = tt4.f1),
+ lateral (select tt4.f1 as c0 from text_tbl as tt5 limit 1) as ss1
+ where tt1.f1 = ss1.c0;
+ QUERY PLAN
+ ----------------------------------------------------------
+ Nested Loop
+ Output: 1
+ -> Nested Loop Left Join
+ Output: tt1.f1, tt4.f1
+ -> Nested Loop
+ Output: tt1.f1
+ -> Seq Scan on public.text_tbl tt1
+ Output: tt1.f1
+ Filter: (tt1.f1 = 'foo'::text)
+ -> Seq Scan on public.text_tbl tt2
+ Output: tt2.f1
+ -> Materialize
+ Output: tt4.f1
+ -> Nested Loop Left Join
+ Output: tt4.f1
+ Join Filter: (tt3.f1 = tt4.f1)
+ -> Seq Scan on public.text_tbl tt3
+ Output: tt3.f1
+ Filter: (tt3.f1 = 'foo'::text)
+ -> Seq Scan on public.text_tbl tt4
+ Output: tt4.f1
+ Filter: (tt4.f1 = 'foo'::text)
+ -> Subquery Scan on ss1
+ Output: ss1.c0
+ Filter: (ss1.c0 = 'foo'::text)
+ -> Limit
+ Output: (tt4.f1)
+ -> Seq Scan on public.text_tbl tt5
+ Output: tt4.f1
+ (29 rows)
+
+ select 1 from
+ text_tbl as tt1
+ inner join text_tbl as tt2 on (tt1.f1 = 'foo')
+ left join text_tbl as tt3 on (tt3.f1 = 'foo')
+ left join text_tbl as tt4 on (tt3.f1 = tt4.f1),
+ lateral (select tt4.f1 as c0 from text_tbl as tt5 limit 1) as ss1
+ where tt1.f1 = ss1.c0;
+ ?column?
+ ----------
+ (0 rows)
+
+ --
+ -- check a case in which a PlaceHolderVar forces join order
+ --
+ explain (verbose, costs off)
+ select ss2.* from
+ int4_tbl i41
+ left join int8_tbl i8
+ join (select i42.f1 as c1, i43.f1 as c2, 42 as c3
+ from int4_tbl i42, int4_tbl i43) ss1
+ on i8.q1 = ss1.c2
+ on i41.f1 = ss1.c1,
+ lateral (select i41.*, i8.*, ss1.* from text_tbl limit 1) ss2
+ where ss1.c2 = 0;
+ QUERY PLAN
+ ------------------------------------------------------------------------
+ Nested Loop
+ Output: (i41.f1), (i8.q1), (i8.q2), (i42.f1), (i43.f1), ((42))
+ -> Hash Join
+ Output: i41.f1, i42.f1, i8.q1, i8.q2, i43.f1, 42
+ Hash Cond: (i41.f1 = i42.f1)
+ -> Nested Loop
+ Output: i8.q1, i8.q2, i43.f1, i41.f1
+ -> Nested Loop
+ Output: i8.q1, i8.q2, i43.f1
+ -> Seq Scan on public.int8_tbl i8
+ Output: i8.q1, i8.q2
+ Filter: (i8.q1 = 0)
+ -> Seq Scan on public.int4_tbl i43
+ Output: i43.f1
+ Filter: (i43.f1 = 0)
+ -> Seq Scan on public.int4_tbl i41
+ Output: i41.f1
+ -> Hash
+ Output: i42.f1
+ -> Seq Scan on public.int4_tbl i42
+ Output: i42.f1
+ -> Limit
+ Output: (i41.f1), (i8.q1), (i8.q2), (i42.f1), (i43.f1), ((42))
+ -> Seq Scan on public.text_tbl
+ Output: i41.f1, i8.q1, i8.q2, i42.f1, i43.f1, (42)
+ (25 rows)
+
+ select ss2.* from
+ int4_tbl i41
+ left join int8_tbl i8
+ join (select i42.f1 as c1, i43.f1 as c2, 42 as c3
+ from int4_tbl i42, int4_tbl i43) ss1
+ on i8.q1 = ss1.c2
+ on i41.f1 = ss1.c1,
+ lateral (select i41.*, i8.*, ss1.* from text_tbl limit 1) ss2
+ where ss1.c2 = 0;
+ f1 | q1 | q2 | c1 | c2 | c3
+ ----+----+----+----+----+----
+ (0 rows)
+
--
-- test ability to push constants through outer join clauses
--
-- RLS policies are checked before constraints
INSERT INTO document VALUES (8, 44, 1, 'rls_regress_user2', 'my third manga'); -- Should fail with RLS check violation, not duplicate key violation
- ERROR: new row violates row level security policy for "document"
+ ERROR: new row violates row-level security policy for table "document"
UPDATE document SET did = 8, dauthor = 'rls_regress_user2' WHERE did = 5; -- Should fail with RLS check violation, not duplicate key violation
-ERROR: new row violates row-level security policy for table "document"
+ERROR: could not plan this distributed update
+DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-- database superuser does bypass RLS policy when enabled
RESET SESSION AUTHORIZATION;
SET row_security TO ON;
-> LockRows
-> Result
-> Append
- -> Seq Scan on t1 t1_1
- Filter: ((a % 2) = 0)
- -> Seq Scan on t2
- Filter: ((a % 2) = 0)
- -> Seq Scan on t3
- Filter: ((a % 2) = 0)
-(12 rows)
+ -> Remote Subquery Scan on all (datanode_1,datanode_2)
+ -> Seq Scan on t1 t1_1
+ Filter: ((a % 2) = 0)
+ -> Remote Subquery Scan on all (datanode_1,datanode_2)
+ -> Seq Scan on t2
+ Filter: ((a % 2) = 0)
+ -> Remote Subquery Scan on all (datanode_1,datanode_2)
+ -> Seq Scan on t3
+ Filter: ((a % 2) = 0)
+(15 rows)
+ -- union all query
+ SELECT a, b, oid FROM t2 UNION ALL SELECT a, b, oid FROM t3;
+ a | b | oid
+ ---+-----+-----
+ 1 | abc | 201
+ 3 | cde | 203
+ 1 | xxx | 301
+ 2 | yyy | 302
+ 3 | zzz | 303
+ (5 rows)
+
+ EXPLAIN (COSTS OFF) SELECT a, b, oid FROM t2 UNION ALL SELECT a, b, oid FROM t3;
+ QUERY PLAN
+ -------------------------------
+ Append
+ -> Seq Scan on t2
+ Filter: ((a % 2) = 1)
+ -> Seq Scan on t3
+ (4 rows)
+
-- superuser is allowed to bypass RLS checks
RESET SESSION AUTHORIZATION;
SET row_security TO OFF;
(5 rows)
INSERT INTO bv1 VALUES (-1, 'xxx'); -- should fail view WCO
- ERROR: new row violates row level security policy for "b1"
+ ERROR: new row violates row-level security policy for table "b1"
INSERT INTO bv1 VALUES (11, 'xxx'); -- should fail RLS check
- ERROR: new row violates row level security policy for "b1"
+ ERROR: new row violates row-level security policy for table "b1"
INSERT INTO bv1 VALUES (12, 'xxx'); -- ok
EXPLAIN (COSTS OFF) UPDATE bv1 SET b = 'yyy' WHERE a = 4 AND f_leak(b);
- QUERY PLAN
----------------------------------------------------------------------------
- Update on b1 b1_1
- -> Subquery Scan on b1
- Filter: f_leak(b1.b)
- -> Subquery Scan on b1_2
- -> LockRows
- -> Seq Scan on b1 b1_3
- Filter: ((a > 0) AND (a = 4) AND ((a % 2) = 0))
-(7 rows)
+ QUERY PLAN
+---------------------------------------------------------------------------------
+ Remote Subquery Scan on all (datanode_2)
+ -> Update on b1 b1_1
+ -> Subquery Scan on b1
+ Filter: f_leak(b1.b)
+ -> Subquery Scan on b1_2
+ -> LockRows
+ -> Seq Scan on b1 b1_3
+ Filter: ((a > 0) AND (a = 4) AND ((a % 2) = 0))
+(8 rows)
UPDATE bv1 SET b = 'yyy' WHERE a = 4 AND f_leak(b);
-NOTICE: f_leak => a87ff679a2f3e71d9181a67b7542122c
EXPLAIN (COSTS OFF) DELETE FROM bv1 WHERE a = 6 AND f_leak(b);
- QUERY PLAN
----------------------------------------------------------------------------
- Delete on b1 b1_1
- -> Subquery Scan on b1
- Filter: f_leak(b1.b)
- -> Subquery Scan on b1_2
- -> LockRows
- -> Seq Scan on b1 b1_3
- Filter: ((a > 0) AND (a = 6) AND ((a % 2) = 0))
-(7 rows)
+ QUERY PLAN
+---------------------------------------------------------------------------------
+ Remote Subquery Scan on all (datanode_1)
+ -> Delete on b1 b1_1
+ -> Subquery Scan on b1
+ Filter: f_leak(b1.b)
+ -> Subquery Scan on b1_2
+ -> LockRows
+ -> Seq Scan on b1 b1_3
+ Filter: ((a > 0) AND (a = 6) AND ((a % 2) = 0))
+(8 rows)
DELETE FROM bv1 WHERE a = 6 AND f_leak(b);
-NOTICE: f_leak => 1679091c5a880faf6fb5e6087eb1b2dc
SET SESSION AUTHORIZATION rls_regress_user0;
SELECT * FROM b1;
a | b
(2 rows)
EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b);
- QUERY PLAN
--------------------------------
- Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 0)
-(4 rows)
+ QUERY PLAN
+-----------------------------------------------------
+ Remote Subquery Scan on all (datanode_1,datanode_2)
+ -> Subquery Scan on z1
+ Filter: f_leak(z1.b)
+ -> Seq Scan on z1 z1_1
+ Filter: ((a % 2) = 0)
+(5 rows)
+ PREPARE plancache_test AS SELECT * FROM z1 WHERE f_leak(b);
+ EXPLAIN (COSTS OFF) EXECUTE plancache_test;
+ QUERY PLAN
+ -------------------------------
+ Subquery Scan on z1
+ Filter: f_leak(z1.b)
+ -> Seq Scan on z1 z1_1
+ Filter: ((a % 2) = 0)
+ (4 rows)
+
+ PREPARE plancache_test2 AS WITH q AS (SELECT * FROM z1 WHERE f_leak(b)) SELECT * FROM q,z2;
+ EXPLAIN (COSTS OFF) EXECUTE plancache_test2;
+ QUERY PLAN
+ ---------------------------------------
+ Nested Loop
+ CTE q
+ -> Subquery Scan on z1
+ Filter: f_leak(z1.b)
+ -> Seq Scan on z1 z1_1
+ Filter: ((a % 2) = 0)
+ -> CTE Scan on q
+ -> Materialize
+ -> Seq Scan on z2
+ (9 rows)
+
+ PREPARE plancache_test3 AS WITH q AS (SELECT * FROM z2) SELECT * FROM q,z1 WHERE f_leak(z1.b);
+ EXPLAIN (COSTS OFF) EXECUTE plancache_test3;
+ QUERY PLAN
+ -------------------------------------------
+ Nested Loop
+ CTE q
+ -> Seq Scan on z2
+ -> CTE Scan on q
+ -> Materialize
+ -> Subquery Scan on z1
+ Filter: f_leak(z1.b)
+ -> Seq Scan on z1 z1_1
+ Filter: ((a % 2) = 0)
+ (9 rows)
+
SET ROLE rls_regress_group1;
SELECT * FROM z1 WHERE f_leak(b);
-NOTICE: f_leak => bbb
-NOTICE: f_leak => ddd
a | b
---+-----
2 | bbb
(2 rows)
EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b);
- QUERY PLAN
--------------------------------
- Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 0)
-(4 rows)
+ QUERY PLAN
+-----------------------------------------------------
+ Remote Subquery Scan on all (datanode_1,datanode_2)
+ -> Subquery Scan on z1
+ Filter: f_leak(z1.b)
+ -> Seq Scan on z1 z1_1
+ Filter: ((a % 2) = 0)
+(5 rows)
+ EXPLAIN (COSTS OFF) EXECUTE plancache_test;
+ QUERY PLAN
+ -------------------------------
+ Subquery Scan on z1
+ Filter: f_leak(z1.b)
+ -> Seq Scan on z1 z1_1
+ Filter: ((a % 2) = 0)
+ (4 rows)
+
+ EXPLAIN (COSTS OFF) EXECUTE plancache_test2;
+ QUERY PLAN
+ ---------------------------------------
+ Nested Loop
+ CTE q
+ -> Subquery Scan on z1
+ Filter: f_leak(z1.b)
+ -> Seq Scan on z1 z1_1
+ Filter: ((a % 2) = 0)
+ -> CTE Scan on q
+ -> Materialize
+ -> Seq Scan on z2
+ (9 rows)
+
+ EXPLAIN (COSTS OFF) EXECUTE plancache_test3;
+ QUERY PLAN
+ -------------------------------------------
+ Nested Loop
+ CTE q
+ -> Seq Scan on z2
+ -> CTE Scan on q
+ -> Materialize
+ -> Subquery Scan on z1
+ Filter: f_leak(z1.b)
+ -> Seq Scan on z1 z1_1
+ Filter: ((a % 2) = 0)
+ (9 rows)
+
SET SESSION AUTHORIZATION rls_regress_user2;
SELECT * FROM z1 WHERE f_leak(b);
-NOTICE: f_leak => aaa
-NOTICE: f_leak => ccc
a | b
---+-----
1 | aaa
(2 rows)
EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b);
- QUERY PLAN
--------------------------------
- Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 1)
-(4 rows)
+ QUERY PLAN
+-----------------------------------------------------
+ Remote Subquery Scan on all (datanode_1,datanode_2)
+ -> Subquery Scan on z1
+ Filter: f_leak(z1.b)
+ -> Seq Scan on z1 z1_1
+ Filter: ((a % 2) = 1)
+(5 rows)
+ EXPLAIN (COSTS OFF) EXECUTE plancache_test;
+ QUERY PLAN
+ -------------------------------
+ Subquery Scan on z1
+ Filter: f_leak(z1.b)
+ -> Seq Scan on z1 z1_1
+ Filter: ((a % 2) = 1)
+ (4 rows)
+
+ EXPLAIN (COSTS OFF) EXECUTE plancache_test2;
+ QUERY PLAN
+ ---------------------------------------
+ Nested Loop
+ CTE q
+ -> Subquery Scan on z1
+ Filter: f_leak(z1.b)
+ -> Seq Scan on z1 z1_1
+ Filter: ((a % 2) = 1)
+ -> CTE Scan on q
+ -> Materialize
+ -> Seq Scan on z2
+ (9 rows)
+
+ EXPLAIN (COSTS OFF) EXECUTE plancache_test3;
+ QUERY PLAN
+ -------------------------------------------
+ Nested Loop
+ CTE q
+ -> Seq Scan on z2
+ -> CTE Scan on q
+ -> Materialize
+ -> Subquery Scan on z1
+ Filter: f_leak(z1.b)
+ -> Seq Scan on z1 z1_1
+ Filter: ((a % 2) = 1)
+ (9 rows)
+
SET ROLE rls_regress_group2;
SELECT * FROM z1 WHERE f_leak(b);
-NOTICE: f_leak => aaa
-NOTICE: f_leak => ccc
a | b
---+-----
1 | aaa
(2 rows)
EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b);
- QUERY PLAN
--------------------------------
- Subquery Scan on z1
- Filter: f_leak(z1.b)
- -> Seq Scan on z1 z1_1
- Filter: ((a % 2) = 1)
-(4 rows)
+ QUERY PLAN
+-----------------------------------------------------
+ Remote Subquery Scan on all (datanode_1,datanode_2)
+ -> Subquery Scan on z1
+ Filter: f_leak(z1.b)
+ -> Seq Scan on z1 z1_1
+ Filter: ((a % 2) = 1)
+(5 rows)
+ EXPLAIN (COSTS OFF) EXECUTE plancache_test;
+ QUERY PLAN
+ -------------------------------
+ Subquery Scan on z1
+ Filter: f_leak(z1.b)
+ -> Seq Scan on z1 z1_1
+ Filter: ((a % 2) = 1)
+ (4 rows)
+
+ EXPLAIN (COSTS OFF) EXECUTE plancache_test2;
+ QUERY PLAN
+ ---------------------------------------
+ Nested Loop
+ CTE q
+ -> Subquery Scan on z1
+ Filter: f_leak(z1.b)
+ -> Seq Scan on z1 z1_1
+ Filter: ((a % 2) = 1)
+ -> CTE Scan on q
+ -> Materialize
+ -> Seq Scan on z2
+ (9 rows)
+
+ EXPLAIN (COSTS OFF) EXECUTE plancache_test3;
+ QUERY PLAN
+ -------------------------------------------
+ Nested Loop
+ CTE q
+ -> Seq Scan on z2
+ -> CTE Scan on q
+ -> Materialize
+ -> Subquery Scan on z1
+ Filter: f_leak(z1.b)
+ -> Seq Scan on z1 z1_1
+ Filter: ((a % 2) = 1)
+ (9 rows)
+
--
-- Views should follow policy for view owner.
--
-- r2 is read-only
INSERT INTO r2 VALUES (2); -- Not allowed
- ERROR: new row violates row level security policy for "r2"
+ ERROR: new row violates row-level security policy for table "r2"
UPDATE r2 SET a = 2 RETURNING *; -- Updates nothing
- a
----
-(0 rows)
-
+ERROR: could not plan this distributed update
+DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
DELETE FROM r2 RETURNING *; -- Deletes nothing
a
---
-- RLS error
INSERT INTO r1 VALUES (1);
- ERROR: new row violates row level security policy for "r1"
+ ERROR: new row violates row-level security policy for table "r1"
-- No error (unable to see any rows to update)
UPDATE r1 SET a = 1;
+ERROR: could not plan this distributed update
+DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
TABLE r1;
a
---
(0 rows)
SET row_security = off;
- -- Shows all rows
+ -- these all fail, would be affected by RLS
TABLE r1;
- a
- ----
- 10
- 20
- (2 rows)
-
- -- Update all rows
+ ERROR: query would be affected by row-level security policy for table "r1"
+ HINT: To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY.
UPDATE r1 SET a = 1;
-ERROR: query would be affected by row-level security policy for table "r1"
-HINT: To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY.
+ERROR: could not plan this distributed update
+DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
+TABLE r1;
+ a
+----
+ 10
+ 20
+(2 rows)
+
+-- Delete all rows
DELETE FROM r1;
- TABLE r1;
- a
- ---
- (0 rows)
-
+ ERROR: query would be affected by row-level security policy for table "r1"
+ HINT: To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY.
DROP TABLE r1;
--
-- FORCE ROW LEVEL SECURITY does not break RI
ALTER TABLE r1 FORCE ROW LEVEL SECURITY;
-- Works fine
UPDATE r1 SET a = 30;
+ERROR: could not plan this distributed update
+DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
-- Show updated rows
- SET row_security = off;
+ ALTER TABLE r1 NO FORCE ROW LEVEL SECURITY;
TABLE r1;
a
----
10
(1 row)
- SET row_security = on;
+ ALTER TABLE r1 FORCE ROW LEVEL SECURITY;
-- Error
UPDATE r1 SET a = 30 RETURNING *;
-ERROR: new row violates row-level security policy for table "r1"
+ERROR: could not plan this distributed update
+DETAIL: correlated UPDATE or updating distribution column currently not supported in Postgres-XL.
DROP TABLE r1;
+ -- Check dependency handling
+ RESET SESSION AUTHORIZATION;
+ CREATE TABLE dep1 (c1 int);
+ CREATE TABLE dep2 (c1 int);
+ CREATE POLICY dep_p1 ON dep1 TO rls_regress_user1 USING (c1 > (select max(dep2.c1) from dep2));
+ ALTER POLICY dep_p1 ON dep1 TO rls_regress_user1,rls_regress_user2;
+ -- Should return one
+ SELECT count(*) = 1 FROM pg_depend
+ WHERE objid = (SELECT oid FROM pg_policy WHERE polname = 'dep_p1')
+ AND refobjid = (SELECT oid FROM pg_class WHERE relname = 'dep2');
+ ?column?
+ ----------
+ t
+ (1 row)
+
+ ALTER POLICY dep_p1 ON dep1 USING (true);
+ -- Should return one
+ SELECT count(*) = 1 FROM pg_shdepend
+ WHERE objid = (SELECT oid FROM pg_policy WHERE polname = 'dep_p1')
+ AND refobjid = (SELECT oid FROM pg_authid WHERE rolname = 'rls_regress_user1');
+ ?column?
+ ----------
+ t
+ (1 row)
+
+ -- Should return one
+ SELECT count(*) = 1 FROM pg_shdepend
+ WHERE objid = (SELECT oid FROM pg_policy WHERE polname = 'dep_p1')
+ AND refobjid = (SELECT oid FROM pg_authid WHERE rolname = 'rls_regress_user2');
+ ?column?
+ ----------
+ t
+ (1 row)
+
+ -- Should return zero
+ SELECT count(*) = 0 FROM pg_depend
+ WHERE objid = (SELECT oid FROM pg_policy WHERE polname = 'dep_p1')
+ AND refobjid = (SELECT oid FROM pg_class WHERE relname = 'dep2');
+ ?column?
+ ----------
+ t
+ (1 row)
+
+ -- DROP OWNED BY testing
+ RESET SESSION AUTHORIZATION;
+ CREATE ROLE dob_role1;
+ CREATE ROLE dob_role2;
+ CREATE TABLE dob_t1 (c1 int);
+ CREATE POLICY p1 ON dob_t1 TO dob_role1 USING (true);
+ DROP OWNED BY dob_role1;
+ DROP POLICY p1 ON dob_t1; -- should fail, already gone
+ ERROR: policy "p1" for table "dob_t1" does not exist
+ CREATE POLICY p1 ON dob_t1 TO dob_role1,dob_role2 USING (true);
+ DROP OWNED BY dob_role1;
+ DROP POLICY p1 ON dob_t1; -- should succeed
+ DROP USER dob_role1;
+ DROP USER dob_role2;
--
-- Clean up objects
--
DETAIL: Failing row contains (15).
UPDATE rw_view1 SET a = a + 5; -- ok
UPDATE rw_view1 SET a = a + 5; -- should fail
- ERROR: new row violates WITH CHECK OPTION for "rw_view1"
+ ERROR: new row violates check option for view "rw_view1"
DETAIL: Failing row contains (15).
EXPLAIN (costs off) INSERT INTO rw_view1 VALUES (5);
- QUERY PLAN
----------------------------------------------------------------
- Insert on base_tbl b
- -> Result
- SubPlan 1
- -> Index Only Scan using ref_tbl_pkey on ref_tbl r
- Index Cond: (a = b.a)
- SubPlan 2
- -> Seq Scan on ref_tbl r_1
-(7 rows)
+ QUERY PLAN
+---------------------------------------------------------------------------
+ Remote Subquery Scan on any (datanode_1,datanode_2)
+ -> Insert on base_tbl b
+ -> Remote Subquery Scan on all (datanode_1)
+ Distribute results by R
+ -> Result
+ SubPlan 1
+ -> Remote Subquery Scan on all (datanode_2)
+ -> Index Only Scan using ref_tbl_pkey on ref_tbl r
+ Index Cond: (a = b.a)
+(9 rows)
EXPLAIN (costs off) UPDATE rw_view1 SET a = a + 5;
- QUERY PLAN
------------------------------------------------------------------
- Update on base_tbl b
- -> Hash Semi Join
- Hash Cond: (b.a = r.a)
- -> Seq Scan on base_tbl b
- -> Hash
- -> Seq Scan on ref_tbl r
- SubPlan 1
- -> Index Only Scan using ref_tbl_pkey on ref_tbl r_1
- Index Cond: (a = b.a)
- SubPlan 2
- -> Seq Scan on ref_tbl r_2
+ QUERY PLAN
+-----------------------------------------------------------------------------
+ Remote Subquery Scan on any (datanode_1,datanode_2)
+ -> Update on base_tbl b
+ -> Hash Semi Join
+ Hash Cond: (b.a = r.a)
+ -> Seq Scan on base_tbl b
+ -> Hash
+ -> Seq Scan on ref_tbl r
+ SubPlan 1
+ -> Remote Subquery Scan on all (datanode_1)
+ -> Index Only Scan using ref_tbl_pkey on ref_tbl r_1
+ Index Cond: (a = b.a)
(11 rows)
DROP TABLE base_tbl, ref_tbl CASCADE;
SELECT * FROM pxtest2;
-- There should be two prepared transactions
-SELECT gid FROM pg_prepared_xacts;
+SELECT gid FROM pg_prepared_xacts ORDER BY gid;
+-- Check prepared transactions in the cluster
+SELECT pgxc_prepared_xact FROM pgxc_prepared_xacts ORDER by 1;
-- pxtest3 should be locked because of the pending DROP
+ begin;
set statement_timeout to 2000;
SELECT * FROM pxtest3;
- reset statement_timeout;
+ rollback;
-- Disconnect, we will continue testing in a different backend
\c -
-- There should still be two prepared transactions
-SELECT gid FROM pg_prepared_xacts;
+SELECT gid FROM pg_prepared_xacts ORDER BY gid;
+-- Check prepared transactions in the cluster
+SELECT pgxc_prepared_xact FROM pgxc_prepared_xacts ORDER by 1;
-- pxtest3 should still be locked because of the pending DROP
+ begin;
set statement_timeout to 2000;
SELECT * FROM pxtest3;
- reset statement_timeout;
+ rollback;
-- Commit table creation
COMMIT PREPARED 'regress-one';