summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/tcop/utility.c82
-rw-r--r--src/test/regress/expected/rowsecurity.out18
-rw-r--r--src/test/regress/expected/rowtypes.out20
-rw-r--r--src/test/regress/expected/subselect.out24
-rw-r--r--src/test/regress/expected/updatable_views.out32
-rw-r--r--src/test/regress/sql/rangefuncs.sql4
6 files changed, 88 insertions, 92 deletions
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 0749400ccf..6dd3845153 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -1231,8 +1231,8 @@ ProcessUtilityPost(PlannedStmt *pstmt,
if (IS_PGXC_LOCAL_COORDINATOR)
{
ViewStmt *stmt = (ViewStmt *) parsetree;
- if (stmt->view->relpersistence != RELPERSISTENCE_TEMP)
- exec_type = EXEC_ON_COORDS;
+ is_temp = stmt->view->relpersistence == RELPERSISTENCE_TEMP;
+ exec_type = is_temp ? EXEC_ON_DATANODES : EXEC_ON_ALL_NODES;
}
break;
@@ -1252,7 +1252,7 @@ ProcessUtilityPost(PlannedStmt *pstmt,
/* In case this query is related to a SERIAL execution, just bypass */
if (!stmt->is_serial)
is_temp = stmt->sequence->relpersistence == RELPERSISTENCE_TEMP;
- exec_type = EXEC_ON_ALL_NODES;
+ exec_type = is_temp ? EXEC_ON_DATANODES : EXEC_ON_ALL_NODES;
}
break;
@@ -1287,8 +1287,8 @@ ProcessUtilityPost(PlannedStmt *pstmt,
* CREATE TABLE + SELECT INTO
*/
Assert(stmt->relkind == OBJECT_MATVIEW);
- if (stmt->into->rel->relpersistence != RELPERSISTENCE_TEMP)
- exec_type = EXEC_ON_COORDS;
+ is_temp = stmt->into->rel->relpersistence == RELPERSISTENCE_TEMP;
+ exec_type = is_temp ? EXEC_ON_DATANODES : EXEC_ON_ALL_NODES;
}
break;
@@ -2578,9 +2578,14 @@ ProcessUtilitySlow(ParseState *pstate,
break;
case T_CreateTableAsStmt:
- address = ExecCreateTableAs((CreateTableAsStmt *) parsetree,
- queryString, params, queryEnv,
- completionTag);
+ {
+ CreateTableAsStmt *stmt = (CreateTableAsStmt *) parsetree;
+ if (IS_PGXC_DATANODE && stmt->relkind == OBJECT_MATVIEW)
+ stmt->into->skipData = true;
+ address = ExecCreateTableAs((CreateTableAsStmt *) parsetree,
+ queryString, params, queryEnv,
+ completionTag);
+ }
break;
case T_RefreshMatViewStmt:
@@ -4697,55 +4702,18 @@ ExecUtilityFindNodes(ObjectType object_type,
{
case OBJECT_SEQUENCE:
*is_temp = IsTempTable(object_id);
- exec_type = EXEC_ON_ALL_NODES;
+ if (*is_temp)
+ exec_type = EXEC_ON_DATANODES;
+ else
+ exec_type = EXEC_ON_ALL_NODES;
break;
case OBJECT_TABLE:
- /* Do the check on relation kind */
- exec_type = ExecUtilityFindNodesRelkind(object_id, is_temp);
- break;
-
- /*
- * Views and rules, both permanent or temporary are created
- * on Coordinators only.
- */
case OBJECT_RULE:
case OBJECT_VIEW:
case OBJECT_MATVIEW:
- /* Check if object is a temporary view */
- if ((*is_temp = IsTempTable(object_id)))
- exec_type = EXEC_ON_NONE;
- else
- exec_type = EXEC_ON_COORDS;
- break;
-
case OBJECT_INDEX:
- /* Check if given index uses temporary tables */
- {
- Relation rel;
- bool is_matview;
-
- rel = relation_open(object_id, NoLock);
-
- *is_temp = (rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP);
- is_matview = (rel->rd_rel->relkind == RELKIND_MATVIEW);
-
- relation_close(rel, NoLock);
-
- exec_type = EXEC_ON_NONE;
- if (*is_temp)
- {
- if (!is_matview)
- exec_type = EXEC_ON_DATANODES;
- }
- else
- {
- if (!is_matview)
- exec_type = EXEC_ON_ALL_NODES;
- else
- exec_type = EXEC_ON_COORDS;
- }
- }
+ exec_type = ExecUtilityFindNodesRelkind(object_id, is_temp);
break;
default:
@@ -4771,7 +4739,6 @@ ExecUtilityFindNodesRelkind(Oid relid, bool *is_temp)
switch (relkind_str)
{
- case RELKIND_SEQUENCE:
case RELKIND_RELATION:
case RELKIND_PARTITIONED_TABLE:
if ((*is_temp = IsTempTable(relid)))
@@ -4798,7 +4765,7 @@ ExecUtilityFindNodesRelkind(Oid relid, bool *is_temp)
/* Release system cache BEFORE looking at the parent table */
ReleaseSysCache(tuple);
- return ExecUtilityFindNodesRelkind(table_relid, is_temp);
+ exec_type = ExecUtilityFindNodesRelkind(table_relid, is_temp);
}
else
{
@@ -4809,18 +4776,13 @@ ExecUtilityFindNodesRelkind(Oid relid, bool *is_temp)
break;
case RELKIND_VIEW:
- if ((*is_temp = IsTempTable(relid)))
- exec_type = EXEC_ON_NONE;
- else
- exec_type = EXEC_ON_COORDS;
- break;
-
+ case RELKIND_SEQUENCE:
case RELKIND_MATVIEW:
/* Check if object is a temporary view */
if ((*is_temp = IsTempTable(relid)))
- exec_type = EXEC_ON_NONE;
+ exec_type = EXEC_ON_DATANODES;
else
- exec_type = EXEC_ON_COORDS;
+ exec_type = EXEC_ON_ALL_NODES;
break;
default:
diff --git a/src/test/regress/expected/rowsecurity.out b/src/test/regress/expected/rowsecurity.out
index 6a6492f3fb..2a40b072ab 100644
--- a/src/test/regress/expected/rowsecurity.out
+++ b/src/test/regress/expected/rowsecurity.out
@@ -1275,9 +1275,7 @@ CREATE VIEW rec1v AS SELECT * FROM rec1;
CREATE VIEW rec2v AS SELECT * FROM rec2;
SET SESSION AUTHORIZATION regress_rls_alice;
ALTER POLICY r1 ON rec1 USING (x = (SELECT a FROM rec2v WHERE b = y));
-ERROR: relation "rec2v" does not exist
ALTER POLICY r2 ON rec2 USING (a = (SELECT x FROM rec1v WHERE y = b));
-ERROR: relation "rec1v" does not exist
SET SESSION AUTHORIZATION regress_rls_bob;
SELECT * FROM rec1; -- fail, mutual recursion via views
ERROR: infinite recursion detected in policy for relation "rec1"
@@ -1287,14 +1285,13 @@ ERROR: infinite recursion detected in policy for relation "rec1"
SET SESSION AUTHORIZATION regress_rls_bob;
\set VERBOSITY terse \\ -- suppress cascade details
DROP VIEW rec1v, rec2v CASCADE;
+NOTICE: drop cascades to 2 other objects
\set VERBOSITY default
CREATE VIEW rec1v WITH (security_barrier) AS SELECT * FROM rec1;
CREATE VIEW rec2v WITH (security_barrier) AS SELECT * FROM rec2;
SET SESSION AUTHORIZATION regress_rls_alice;
CREATE POLICY r1 ON rec1 USING (x = (SELECT a FROM rec2v WHERE b = y));
-ERROR: policy "r1" for table "rec1" already exists
CREATE POLICY r2 ON rec2 USING (a = (SELECT x FROM rec1v WHERE y = b));
-ERROR: policy "r2" for table "rec2" already exists
SET SESSION AUTHORIZATION regress_rls_bob;
SELECT * FROM rec1; -- fail, mutual recursion via s.b. views
ERROR: infinite recursion detected in policy for relation "rec1"
@@ -1343,13 +1340,12 @@ EXPLAIN (COSTS OFF) SELECT * FROM only s1 WHERE f_leak(b);
SET SESSION AUTHORIZATION regress_rls_alice;
ALTER POLICY p1 ON s1 USING (a in (select x from v2)); -- using VIEW in RLS policy
-ERROR: relation "v2" does not exist
SET SESSION AUTHORIZATION regress_rls_bob;
SELECT * FROM s1 WHERE f_leak(b); -- OK
- a | b
----+----------------------------------
- 2 | c81e728d9d4c2f636f067f89cc14862c
- 4 | a87ff679a2f3e71d9181a67b7542122c
+ a | b
+----+----------------------------------
+ -4 | 0267aaf632e87a63288a08331f22c7c3
+ 6 | 1679091c5a880faf6fb5e6087eb1b2dc
(2 rows)
EXPLAIN (COSTS OFF) SELECT * FROM s1 WHERE f_leak(b);
@@ -1361,7 +1357,7 @@ EXPLAIN (COSTS OFF) SELECT * FROM s1 WHERE f_leak(b);
SubPlan 1
-> Remote Subquery Scan on all (datanode_1,datanode_2)
-> Seq Scan on s2
- Filter: (((x % 2) = 0) AND (y ~~ '%2f%'::text))
+ Filter: (((x % 2) = 0) AND (y ~~ '%af%'::text))
(7 rows)
SELECT (SELECT x FROM s1 LIMIT 1) xx, * FROM s2 WHERE y like '%28%';
@@ -1387,7 +1383,7 @@ EXPLAIN (COSTS OFF) SELECT (SELECT x FROM s1 LIMIT 1) xx, * FROM s2 WHERE y like
SubPlan 1
-> Remote Subquery Scan on all (datanode_1,datanode_2)
-> Seq Scan on s2 s2_1
- Filter: (((x % 2) = 0) AND (y ~~ '%2f%'::text))
+ Filter: (((x % 2) = 0) AND (y ~~ '%af%'::text))
(13 rows)
SET SESSION AUTHORIZATION regress_rls_alice;
diff --git a/src/test/regress/expected/rowtypes.out b/src/test/regress/expected/rowtypes.out
index 635039fac9..86df2bcc2d 100644
--- a/src/test/regress/expected/rowtypes.out
+++ b/src/test/regress/expected/rowtypes.out
@@ -525,9 +525,25 @@ select row_to_json(i) from int8_tbl i(x,y);
create temp view vv1 as select * from int8_tbl;
select row_to_json(i) from vv1 i;
-ERROR: cache lookup failed for type 0
+ row_to_json
+------------------------------------------------
+ {"q1":123,"q2":456}
+ {"q1":123,"q2":4567890123456789}
+ {"q1":4567890123456789,"q2":123}
+ {"q1":4567890123456789,"q2":4567890123456789}
+ {"q1":4567890123456789,"q2":-4567890123456789}
+(5 rows)
+
select row_to_json(i) from vv1 i(x,y);
-ERROR: cache lookup failed for type 0
+ row_to_json
+----------------------------------------------
+ {"x":123,"y":456}
+ {"x":123,"y":4567890123456789}
+ {"x":4567890123456789,"y":123}
+ {"x":4567890123456789,"y":4567890123456789}
+ {"x":4567890123456789,"y":-4567890123456789}
+(5 rows)
+
select row_to_json(ss) from
(select q1, q2 from int8_tbl) as ss;
row_to_json
diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out
index c355f10c4c..a5d78d029d 100644
--- a/src/test/regress/expected/subselect.out
+++ b/src/test/regress/expected/subselect.out
@@ -650,13 +650,29 @@ create temp table table_a(id integer);
insert into table_a values (42);
create temp view view_a as select * from table_a;
select view_a from view_a;
-ERROR: cache lookup failed for type 0
+ view_a
+--------
+ (42)
+(1 row)
+
select (select view_a) from view_a;
-ERROR: cache lookup failed for type 0
+ view_a
+--------
+ (42)
+(1 row)
+
select (select (select view_a)) from view_a;
-ERROR: cache lookup failed for type 0
+ view_a
+--------
+ (42)
+(1 row)
+
select (select (a.*)::text) from view_a a;
-ERROR: cache lookup failed for type 0
+ a
+------
+ (42)
+(1 row)
+
--
-- Check that whole-row Vars reading the result of a subselect don't include
-- any junk columns therein
diff --git a/src/test/regress/expected/updatable_views.out b/src/test/regress/expected/updatable_views.out
index 647d8cf3f7..b9a54376ac 100644
--- a/src/test/regress/expected/updatable_views.out
+++ b/src/test/regress/expected/updatable_views.out
@@ -911,32 +911,38 @@ INSERT INTO base_tbl SELECT i, 'Row ' || i FROM generate_series(-2, 2) g(i);
CREATE VIEW rw_view1 AS SELECT b AS bb, a AS aa FROM base_tbl;
CREATE FUNCTION rw_view1_aa(x rw_view1)
RETURNS int AS $$ SELECT x.aa $$ LANGUAGE sql;
-ERROR: type rw_view1 does not exist
UPDATE rw_view1 v SET bb='Updated row 2' WHERE rw_view1_aa(v)=2
RETURNING rw_view1_aa(v), v.bb;
-ERROR: function rw_view1_aa(rw_view1) does not exist
-LINE 1: UPDATE rw_view1 v SET bb='Updated row 2' WHERE rw_view1_aa(v...
- ^
-HINT: No function matches the given name and argument types. You might need to add explicit type casts.
+ rw_view1_aa | bb
+-------------+---------------
+ 2 | Updated row 2
+(1 row)
+
SELECT * FROM base_tbl;
- a | b
-----+--------
+ a | b
+----+---------------
-2 | Row -2
-1 | Row -1
0 | Row 0
1 | Row 1
- 2 | Row 2
+ 2 | Updated row 2
(5 rows)
EXPLAIN (costs off, nodes off)
UPDATE rw_view1 v SET bb='Updated row 2' WHERE rw_view1_aa(v)=2
RETURNING rw_view1_aa(v), v.bb;
-ERROR: function rw_view1_aa(rw_view1) does not exist
-LINE 2: UPDATE rw_view1 v SET bb='Updated row 2' WHERE rw_view1_aa(v...
- ^
-HINT: No function matches the given name and argument types. You might need to add explicit type casts.
+ QUERY PLAN
+--------------------------------------------------------
+ Remote Subquery Scan on any
+ -> Update on base_tbl
+ -> Index Scan using base_tbl_pkey on base_tbl
+ Index Cond: (a = 2)
+(4 rows)
+
DROP TABLE base_tbl CASCADE;
-NOTICE: drop cascades to view rw_view1
+NOTICE: drop cascades to 2 other objects
+DETAIL: drop cascades to view rw_view1
+drop cascades to function rw_view1_aa(rw_view1)
-- permissions checks
CREATE USER regress_view_user1;
CREATE USER regress_view_user2;
diff --git a/src/test/regress/sql/rangefuncs.sql b/src/test/regress/sql/rangefuncs.sql
index e309f4f838..4e30a02fa0 100644
--- a/src/test/regress/sql/rangefuncs.sql
+++ b/src/test/regress/sql/rangefuncs.sql
@@ -228,8 +228,8 @@ DROP TABLE foo2;
DROP TABLE foo;
-- Rescan tests --
-CREATE TEMPORARY SEQUENCE foo_rescan_seq1;
-CREATE TEMPORARY SEQUENCE foo_rescan_seq2;
+CREATE SEQUENCE foo_rescan_seq1;
+CREATE SEQUENCE foo_rescan_seq2;
CREATE TYPE foo_rescan_t AS (i integer, s bigint);
CREATE FUNCTION foo_sql(int,int) RETURNS setof foo_rescan_t AS 'SELECT i, nextval(''foo_rescan_seq1'') FROM generate_series($1,$2) i;' LANGUAGE SQL;