diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 49316d3159c1..3a31aace8449 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -162,7 +162,6 @@ static void remove_unused_subquery_outputs(Query *subquery, RelOptInfo *rel); static void bring_to_outer_query(PlannerInfo *root, RelOptInfo *rel, List *outer_quals); static void bring_to_singleQE(PlannerInfo *root, RelOptInfo *rel); static bool is_query_contain_limit_groupby(Query *parse); -static void handle_gen_seggen_volatile_path(PlannerInfo *root, RelOptInfo *rel); /* @@ -645,40 +644,6 @@ bring_to_singleQE(PlannerInfo *root, RelOptInfo *rel) set_cheapest(rel); } -/* - * handle_gen_seggen_volatile_path - * - * Only use for base replicated rel. - * Change the path in its pathlist if match the pattern - * (segmentgeneral or general path contains volatile restrictions). - */ -static void -handle_gen_seggen_volatile_path(PlannerInfo *root, RelOptInfo *rel) -{ - List *origpathlist; - ListCell *lc; - - origpathlist = rel->pathlist; - rel->cheapest_startup_path = NULL; - rel->cheapest_total_path = NULL; - rel->cheapest_unique_path = NULL; - rel->cheapest_parameterized_paths = NIL; - rel->pathlist = NIL; - - foreach(lc, origpathlist) - { - Path *origpath = (Path *) lfirst(lc); - Path *path; - - path = turn_volatile_seggen_to_singleqe(root, - origpath, - (Node *) (rel->baserestrictinfo)); - add_path(rel, path); - } - - set_cheapest(rel); -} - /* * set_rel_pathlist * Build access paths for a base relation @@ -750,14 +715,6 @@ set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, } } - /* - * Greenplum specific behavior: - * Change the path in pathlist if it is a general or segmentgeneral - * path that contains volatile restrictions. - */ - if (rel->reloptkind == RELOPT_BASEREL) - handle_gen_seggen_volatile_path(root, rel); - /* * Allow a plugin to editorialize on the set of Paths for this base * relation. It could add new paths (such as CustomPaths) by calling diff --git a/src/test/regress/expected/bfv_planner.out b/src/test/regress/expected/bfv_planner.out index ae6834d3aee7..b22e2ff79ae1 100644 --- a/src/test/regress/expected/bfv_planner.out +++ b/src/test/regress/expected/bfv_planner.out @@ -407,13 +407,12 @@ where x.a > random(); ---------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop - -> Broadcast Motion 1:3 (slice2; segments: 1) - -> Function Scan on generate_series a - Filter: ((a)::double precision > random()) + -> Function Scan on generate_series a + Filter: ((a)::double precision > random()) -> Materialize -> Seq Scan on t_hashdist Optimizer: Postgres query optimizer -(8 rows) +(7 rows) ---- join qual explain (costs off) select * from diff --git a/src/test/regress/expected/rpt.out b/src/test/regress/expected/rpt.out index 6a5e39213d52..e676d6016280 100644 --- a/src/test/regress/expected/rpt.out +++ b/src/test/regress/expected/rpt.out @@ -741,16 +741,14 @@ create table t_replicate_volatile(a int, b int, c int) distributed replicated; explain (costs off) select * from t_replicate_volatile, t_hashdist where t_replicate_volatile.a > random(); QUERY PLAN ---------------------------------------------------------------------- - Nested Loop - -> Gather Motion 3:1 (slice1; segments: 3) - -> Seq Scan on t_hashdist - -> Materialize - -> Result - -> Gather Motion 1:1 (slice2; segments: 1) - -> Seq Scan on t_replicate_volatile - Filter: ((a)::double precision > random()) + Gather Motion 3:1 (slice1; segments: 3) + -> Nested Loop + -> Seq Scan on t_replicate_volatile + Filter: ((a)::double precision > random()) + -> Materialize + -> Seq Scan on t_hashdist Optimizer: Postgres query optimizer -(9 rows) +(7 rows) -- join qual explain (costs off) select * from t_hashdist, t_replicate_volatile x, t_replicate_volatile y where x.a + y.a > random(); @@ -958,15 +956,79 @@ explain (costs off) create table rpt_ctas as select a from generate_series(1, 10 Optimizer: Postgres query optimizer (6 rows) +-- insert into table with serial column +create table t_replicate_dst(id serial, i integer) distributed replicated; +create table t_replicate_src(i integer) distributed replicated; +insert into t_replicate_src select i from generate_series(1, 5) i; +explain (costs off, verbose) insert into t_replicate_dst (i) select i from t_replicate_src; + QUERY PLAN +--------------------------------------------------------------------------------------------- + Insert on rpt.t_replicate_dst + -> Broadcast Motion 1:3 (slice1; segments: 1) + Output: ((nextval('t_replicate_dst_id_seq'::regclass))::integer), t_replicate_src.i + -> Seq Scan on rpt.t_replicate_src + Output: nextval('t_replicate_dst_id_seq'::regclass), t_replicate_src.i + Optimizer: Postgres-based planner + Settings: enable_seqscan = 'off' +(7 rows) + +explain (costs off, verbose) with s as (select i from t_replicate_src group by i having random() > 0) insert into t_replicate_dst (i) select i from s; + QUERY PLAN +---------------------------------------------------------------------------------------- + Insert on rpt.t_replicate_dst + -> Broadcast Motion 1:3 (slice1; segments: 1) + Output: ((nextval('t_replicate_dst_id_seq'::regclass))::integer), "*SELECT*".i + -> Subquery Scan on "*SELECT*" + Output: nextval('t_replicate_dst_id_seq'::regclass), "*SELECT*".i + -> Result + Output: t_replicate_src.i + -> GroupAggregate + Output: t_replicate_src.i + Group Key: t_replicate_src.i + Filter: (random() > '0'::double precision) + -> Sort + Output: t_replicate_src.i + Sort Key: t_replicate_src.i + -> Seq Scan on rpt.t_replicate_src + Output: t_replicate_src.i + Optimizer: Postgres-based planner + Settings: enable_seqscan = 'off' +(18 rows) + +insert into t_replicate_dst (i) select i from t_replicate_src; +select distinct id from gp_dist_random('t_replicate_dst') order by id; + id +---- + 1 + 2 + 3 + 4 + 5 +(5 rows) + -- update & delete explain (costs off) update t_replicate_volatile set a = 1 where b > random(); -ERROR: could not devise a plan (cdbpath.c:2578) + QUERY PLAN +---------------------------------------------------- + Update on t_replicate_volatile + -> Seq Scan on t_replicate_volatile + Filter: ((b)::double precision > random()) + Optimizer: Postgres-based planner +(4 rows) + explain (costs off) update t_replicate_volatile set a = 1 from t_replicate_volatile x where x.a + random() = t_replicate_volatile.b; ERROR: could not devise a plan (cdbpath.c:2578) explain (costs off) update t_replicate_volatile set a = 1 from t_hashdist x where x.a + random() = t_replicate_volatile.b; ERROR: could not devise a plan (cdbpath.c:2578) explain (costs off) delete from t_replicate_volatile where a < random(); -ERROR: could not devise a plan (cdbpath.c:2578) + QUERY PLAN +---------------------------------------------------- + Delete on t_replicate_volatile + -> Seq Scan on t_replicate_volatile + Filter: ((a)::double precision < random()) + Optimizer: Postgres-based planner +(4 rows) + explain (costs off) delete from t_replicate_volatile using t_replicate_volatile x where t_replicate_volatile.a + x.b < random(); ERROR: could not devise a plan (cdbpath.c:2578) explain (costs off) update t_replicate_volatile set a = random(); @@ -1174,33 +1236,29 @@ create index idx_t2_13532 on t2_13532(b); explain (costs off) select * from t1_13532 x, t2_13532 y where y.a < random() and x.b = y.b; QUERY PLAN ---------------------------------------------------------------------- - Hash Join - Hash Cond: (x.b = y.b) - -> Gather Motion 1:1 (slice1; segments: 1) + Gather Motion 1:1 (slice1; segments: 1) + -> Hash Join + Hash Cond: (x.b = y.b) -> Seq Scan on t1_13532 x - -> Hash - -> Result - -> Gather Motion 1:1 (slice2; segments: 1) - -> Index Scan using idx_t2_13532 on t2_13532 y - Filter: ((a)::double precision < random()) + -> Hash + -> Index Scan using idx_t2_13532 on t2_13532 y + Filter: ((a)::double precision < random()) Optimizer: Postgres query optimizer -(10 rows) +(8 rows) set enable_bitmapscan = off; explain (costs off) select * from t1_13532 x, t2_13532 y where y.a < random() and x.b = y.b; QUERY PLAN ---------------------------------------------------------------------- - Hash Join - Hash Cond: (x.b = y.b) - -> Gather Motion 1:1 (slice1; segments: 1) + Gather Motion 1:1 (slice1; segments: 1) + -> Hash Join + Hash Cond: (x.b = y.b) -> Seq Scan on t1_13532 x - -> Hash - -> Result - -> Gather Motion 1:1 (slice2; segments: 1) - -> Index Scan using idx_t2_13532 on t2_13532 y - Filter: ((a)::double precision < random()) + -> Hash + -> Index Scan using idx_t2_13532 on t2_13532 y + Filter: ((a)::double precision < random()) Optimizer: Postgres query optimizer -(10 rows) +(8 rows) -- test for optimizer_enable_replicated_table explain (costs off) select * from rep_tab; @@ -1608,6 +1666,182 @@ drop table t1; drop table t2; drop table r; drop table d; +-- +-- Check sub-selects with distributed replicated tables and volatile functions +-- +create table t (i int) distributed replicated; +create table t1 (a int) distributed by (a); +create table t2 (a int, b float) distributed replicated; +create or replace function f(i int) returns int language sql security definer as $$ select i; $$; +-- ensure we make gather motion when volatile functions in subplan +explain (costs off, verbose) select (select f(i) from t); + QUERY PLAN +------------------------------------------------------------- + Result + Output: $0 + InitPlan 1 (returns $0) (slice1) + -> Gather Motion 1:1 (slice2; segments: 1) + Output: (f(t.i)) + -> Seq Scan on rpt.t + Output: f(t.i) + Optimizer: Postgres-based planner + Settings: enable_bitmapscan = 'off', enable_seqscan = 'off' +(9 rows) + +explain (costs off, verbose) select (select f(i) from t group by f(i)); + QUERY PLAN +------------------------------------------------------------- + Result + Output: $0 + InitPlan 1 (returns $0) (slice1) + -> Gather Motion 1:1 (slice2; segments: 1) + Output: (f(t.i)) + -> GroupAggregate + Output: (f(t.i)) + Group Key: (f(t.i)) + -> Sort + Output: (f(t.i)) + Sort Key: (f(t.i)) + -> Seq Scan on rpt.t + Output: f(t.i) + Optimizer: Postgres-based planner + Settings: enable_bitmapscan = 'off', enable_seqscan = 'off' +(15 rows) + +explain (costs off, verbose) select (select i from t group by i having f(i) > 0); + QUERY PLAN +------------------------------------------------------------- + Result + Output: $0 + InitPlan 1 (returns $0) (slice1) + -> Gather Motion 1:1 (slice2; segments: 1) + Output: t.i + -> GroupAggregate + Output: t.i + Group Key: t.i + Filter: (f(t.i) > 0) + -> Sort + Output: t.i + Sort Key: t.i + -> Seq Scan on rpt.t + Output: t.i + Optimizer: Postgres-based planner + Settings: enable_bitmapscan = 'off', enable_seqscan = 'off' +(16 rows) + +-- ensure we do not make broadcast motion +explain (costs off, verbose) select * from t1 where a in (select random() from t where i=a group by i); + QUERY PLAN +----------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Output: t1.a + -> Seq Scan on rpt.t1 + Output: t1.a + Filter: (SubPlan 1) + SubPlan 1 + -> Result + Output: random(), t.i + Filter: (t.i = t1.a) + -> Materialize + Output: t.i + -> Broadcast Motion 1:3 (slice2; segments: 1) + Output: t.i + -> Seq Scan on rpt.t + Output: t.i + Optimizer: Postgres-based planner + Settings: enable_bitmapscan = 'off', enable_seqscan = 'off' +(17 rows) + +explain (costs off, verbose) select * from t1 where a in (select random() from t where i=a); + QUERY PLAN +----------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Output: t1.a + -> Seq Scan on rpt.t1 + Output: t1.a + Filter: (SubPlan 1) + SubPlan 1 + -> Result + Output: random() + Filter: (t.i = t1.a) + -> Materialize + Output: t.i + -> Broadcast Motion 1:3 (slice2; segments: 1) + Output: t.i + -> Seq Scan on rpt.t + Output: t.i + Optimizer: Postgres-based planner + Settings: enable_bitmapscan = 'off', enable_seqscan = 'off' +(17 rows) + +-- ensure we make broadcast motion when volatile function in deleting motion flow +explain (costs off, verbose) insert into t2 (a, b) select i, random() from t; + QUERY PLAN +------------------------------------------------------------- + Insert on rpt.t2 + -> Broadcast Motion 1:3 (slice1; segments: 1) + Output: t.i, (random()) + -> Result + Output: t.i, (random()) + -> Seq Scan on rpt.t + Output: t.i, random() + Optimizer: Postgres-based planner + Settings: enable_bitmapscan = 'off', enable_seqscan = 'off' +(9 rows) + +-- ensure we make broadcast motion when volatile function in correlated subplan qual +explain (costs off, verbose) select * from t1 where a in (select f(i) from t where i=a and f(i) > 0); + QUERY PLAN +----------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Output: t1.a + -> Seq Scan on rpt.t1 + Output: t1.a + Filter: (SubPlan 1) + SubPlan 1 + -> Result + Output: f(t.i) + Filter: (t.i = t1.a) + -> Materialize + Output: t.i + -> Broadcast Motion 1:3 (slice2; segments: 1) + Output: t.i + -> Seq Scan on rpt.t + Output: t.i + Filter: (f(t.i) > 0) + Optimizer: Postgres-based planner + Settings: enable_bitmapscan = 'off', enable_seqscan = 'off' +(18 rows) + +-- ensure we do not break broadcast motion +explain (costs off, verbose) select * from t1 where 1 <= ALL (select i from t group by i having random() > 0); + QUERY PLAN +------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Output: t1.a + -> Seq Scan on rpt.t1 + Output: t1.a + Filter: (SubPlan 1) + SubPlan 1 + -> Materialize + Output: t.i + -> Broadcast Motion 1:3 (slice2; segments: 1) + Output: t.i + -> GroupAggregate + Output: t.i + Group Key: t.i + Filter: (random() > '0'::double precision) + -> Sort + Output: t.i + Sort Key: t.i + -> Seq Scan on rpt.t + Output: t.i + Optimizer: Postgres-based planner + Settings: enable_bitmapscan = 'off', enable_seqscan = 'off' +(21 rows) + +drop table if exists t, t1, t2; +drop function if exists f(i int); -- start_ignore drop schema rpt cascade; NOTICE: drop cascades to 7 other objects diff --git a/src/test/regress/expected/rpt_optimizer.out b/src/test/regress/expected/rpt_optimizer.out index 65e39b390f14..d26afa1a460e 100644 --- a/src/test/regress/expected/rpt_optimizer.out +++ b/src/test/regress/expected/rpt_optimizer.out @@ -953,15 +953,81 @@ ___________ Optimizer: Pivotal Optimizer (GPORCA) GP_IGNORE:(9 rows) +-- insert into table with serial column +create table t_replicate_dst(id serial, i integer) distributed replicated; +create table t_replicate_src(i integer) distributed replicated; +insert into t_replicate_src select i from generate_series(1, 5) i; +explain (costs off, verbose) insert into t_replicate_dst (i) select i from t_replicate_src; + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Insert on rpt.t_replicate_dst + -> Result + Output: (int4(nextval('t_replicate_dst_id_seq'::regclass))), t_replicate_src.i + -> Broadcast Motion 1:3 (slice1; segments: 1) + Output: t_replicate_src.i, (int4(nextval('t_replicate_dst_id_seq'::regclass))) + -> Seq Scan on rpt.t_replicate_src + Output: t_replicate_src.i, int4(nextval('t_replicate_dst_id_seq'::regclass)) + Optimizer: GPORCA + Settings: enable_seqscan = 'off' +(9 rows) + +explain (costs off, verbose) with s as (select i from t_replicate_src group by i having random() > 0) insert into t_replicate_dst (i) select i from s; + QUERY PLAN +---------------------------------------------------------------------------------------- + Insert on rpt.t_replicate_dst + -> Broadcast Motion 1:3 (slice1; segments: 1) + Output: ((nextval('t_replicate_dst_id_seq'::regclass))::integer), "*SELECT*".i + -> Subquery Scan on "*SELECT*" + Output: nextval('t_replicate_dst_id_seq'::regclass), "*SELECT*".i + -> Result + Output: t_replicate_src.i + -> GroupAggregate + Output: t_replicate_src.i + Group Key: t_replicate_src.i + Filter: (random() > '0'::double precision) + -> Sort + Output: t_replicate_src.i + Sort Key: t_replicate_src.i + -> Seq Scan on rpt.t_replicate_src + Output: t_replicate_src.i + Optimizer: Postgres-based planner + Settings: enable_seqscan = 'off' +(18 rows) + +insert into t_replicate_dst (i) select i from t_replicate_src; +select distinct id from gp_dist_random('t_replicate_dst') order by id; + id +---- + 1 + 2 + 3 + 4 + 5 +(5 rows) + -- update & delete explain (costs off) update t_replicate_volatile set a = 1 where b > random(); -ERROR: could not devise a plan (cdbpath.c:2578) + QUERY PLAN +---------------------------------------------------- + Update on t_replicate_volatile + -> Seq Scan on t_replicate_volatile + Filter: ((b)::double precision > random()) + Optimizer: Postgres-based planner +(4 rows) + explain (costs off) update t_replicate_volatile set a = 1 from t_replicate_volatile x where x.a + random() = t_replicate_volatile.b; ERROR: could not devise a plan (cdbpath.c:2578) explain (costs off) update t_replicate_volatile set a = 1 from t_hashdist x where x.a + random() = t_replicate_volatile.b; ERROR: could not devise a plan (cdbpath.c:2578) explain (costs off) delete from t_replicate_volatile where a < random(); -ERROR: could not devise a plan (cdbpath.c:2578) + QUERY PLAN +---------------------------------------------------- + Delete on t_replicate_volatile + -> Seq Scan on t_replicate_volatile + Filter: ((a)::double precision < random()) + Optimizer: Postgres-based planner +(4 rows) + explain (costs off) delete from t_replicate_volatile using t_replicate_volatile x where t_replicate_volatile.a + x.b < random(); ERROR: could not devise a plan (cdbpath.c:2578) explain (costs off) update t_replicate_volatile set a = random(); @@ -1619,6 +1685,182 @@ drop table t1; drop table t2; drop table r; drop table d; +-- +-- Check sub-selects with distributed replicated tables and volatile functions +-- +create table t (i int) distributed replicated; +create table t1 (a int) distributed by (a); +create table t2 (a int, b float) distributed replicated; +create or replace function f(i int) returns int language sql security definer as $$ select i; $$; +-- ensure we make gather motion when volatile functions in subplan +explain (costs off, verbose) select (select f(i) from t); + QUERY PLAN +------------------------------------------------------------- + Result + Output: $0 + InitPlan 1 (returns $0) (slice1) + -> Gather Motion 1:1 (slice2; segments: 1) + Output: (f(t.i)) + -> Seq Scan on rpt.t + Output: f(t.i) + Optimizer: Postgres-based planner + Settings: enable_bitmapscan = 'off', enable_seqscan = 'off' +(9 rows) + +explain (costs off, verbose) select (select f(i) from t group by f(i)); + QUERY PLAN +------------------------------------------------------------- + Result + Output: $0 + InitPlan 1 (returns $0) (slice1) + -> Gather Motion 1:1 (slice2; segments: 1) + Output: (f(t.i)) + -> GroupAggregate + Output: (f(t.i)) + Group Key: (f(t.i)) + -> Sort + Output: (f(t.i)) + Sort Key: (f(t.i)) + -> Seq Scan on rpt.t + Output: f(t.i) + Optimizer: Postgres-based planner + Settings: enable_bitmapscan = 'off', enable_seqscan = 'off' +(15 rows) + +explain (costs off, verbose) select (select i from t group by i having f(i) > 0); + QUERY PLAN +------------------------------------------------------------- + Result + Output: $0 + InitPlan 1 (returns $0) (slice1) + -> Gather Motion 1:1 (slice2; segments: 1) + Output: t.i + -> GroupAggregate + Output: t.i + Group Key: t.i + Filter: (f(t.i) > 0) + -> Sort + Output: t.i + Sort Key: t.i + -> Seq Scan on rpt.t + Output: t.i + Optimizer: Postgres-based planner + Settings: enable_bitmapscan = 'off', enable_seqscan = 'off' +(16 rows) + +-- ensure we do not make broadcast motion +explain (costs off, verbose) select * from t1 where a in (select random() from t where i=a group by i); + QUERY PLAN +------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Output: t1.a + -> Hash Semi Join + Output: t1.a + Hash Cond: (t1.a = t.i) + -> Seq Scan on rpt.t1 + Output: t1.a + Filter: ((t1.a)::double precision = random()) + -> Hash + Output: t.i + -> GroupAggregate + Output: t.i + Group Key: t.i + -> Sort + Output: t.i + Sort Key: t.i + -> Seq Scan on rpt.t + Output: t.i + Optimizer: GPORCA + Settings: enable_bitmapscan = 'off', enable_seqscan = 'off' +(20 rows) + +explain (costs off, verbose) select * from t1 where a in (select random() from t where i=a); + QUERY PLAN +---------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Output: t1.a + -> Hash Semi Join + Output: t1.a + Hash Cond: (t1.a = t.i) + -> Seq Scan on rpt.t1 + Output: t1.a + Filter: ((NOT (t1.a IS NULL)) AND ((t1.a)::double precision = random())) + -> Hash + Output: t.i + -> Seq Scan on rpt.t + Output: t.i + Optimizer: GPORCA + Settings: enable_bitmapscan = 'off', enable_seqscan = 'off' +(14 rows) + +-- ensure we make broadcast motion when volatile function in deleting motion flow +explain (costs off, verbose) insert into t2 (a, b) select i, random() from t; + QUERY PLAN +------------------------------------------------------------- + Insert on rpt.t2 + -> Result + Output: t.i, (random()) + -> Broadcast Motion 1:3 (slice1; segments: 1) + Output: t.i, (random()) + -> Seq Scan on rpt.t + Output: t.i, random() + Optimizer: GPORCA + Settings: enable_bitmapscan = 'off', enable_seqscan = 'off' +(9 rows) + +-- ensure we make broadcast motion when volatile function in correlated subplan qual +explain (costs off, verbose) select * from t1 where a in (select f(i) from t where i=a and f(i) > 0); + QUERY PLAN +------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Output: t1.a + -> Hash Semi Join + Output: t1.a + Hash Cond: ((t1.a = t.i) AND (t1.a = (f(t.i)))) + -> Seq Scan on rpt.t1 + Output: t1.a + Filter: (NOT (t1.a IS NULL)) + -> Hash + Output: (f(t.i)), t.i + -> Result + Output: f(t.i), t.i + -> Redistribute Motion 1:3 (slice2; segments: 1) + Output: t.i + Hash Key: t.i + -> Seq Scan on rpt.t + Output: t.i + Filter: (f(t.i) > 0) + Optimizer: GPORCA + Settings: enable_bitmapscan = 'off', enable_seqscan = 'off' +(20 rows) + +-- ensure we do not break broadcast motion +explain (costs off, verbose) select * from t1 where 1 <= ALL (select i from t group by i having random() > 0); + QUERY PLAN +------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Output: t1.a + -> Seq Scan on rpt.t1 + Output: t1.a + Filter: (SubPlan 1) + SubPlan 1 + -> Result + Output: t.i + Filter: (random() > '0'::double precision) + -> GroupAggregate + Output: t.i + Group Key: t.i + -> Sort + Output: t.i + Sort Key: t.i + -> Seq Scan on rpt.t + Output: t.i + Optimizer: GPORCA + Settings: enable_bitmapscan = 'off', enable_seqscan = 'off' +(19 rows) + +drop table if exists t, t1, t2; +drop function if exists f(i int); -- start_ignore drop schema rpt cascade; NOTICE: drop cascades to 7 other objects diff --git a/src/test/regress/sql/rpt.sql b/src/test/regress/sql/rpt.sql index 4b94a08c0240..e0abc1e476e6 100644 --- a/src/test/regress/sql/rpt.sql +++ b/src/test/regress/sql/rpt.sql @@ -425,6 +425,15 @@ explain (costs off) select a from t_replicate_volatile union all select * from n explain (costs off) create table rpt_ctas as select random() from generate_series(1, 10) distributed replicated; explain (costs off) create table rpt_ctas as select a from generate_series(1, 10) a group by a having sum(a) > random() distributed replicated; +-- insert into table with serial column +create table t_replicate_dst(id serial, i integer) distributed replicated; +create table t_replicate_src(i integer) distributed replicated; +insert into t_replicate_src select i from generate_series(1, 5) i; +explain (costs off, verbose) insert into t_replicate_dst (i) select i from t_replicate_src; +explain (costs off, verbose) with s as (select i from t_replicate_src group by i having random() > 0) insert into t_replicate_dst (i) select i from s; +insert into t_replicate_dst (i) select i from t_replicate_src; +select distinct id from gp_dist_random('t_replicate_dst') order by id; + -- update & delete explain (costs off) update t_replicate_volatile set a = 1 where b > random(); explain (costs off) update t_replicate_volatile set a = 1 from t_replicate_volatile x where x.a + random() = t_replicate_volatile.b; @@ -617,6 +626,32 @@ drop table t2; drop table r; drop table d; +-- +-- Check sub-selects with distributed replicated tables and volatile functions +-- +-- start_ignore +drop table if exists t, t1, t2; +-- end_ignore +create table t (i int) distributed replicated; +create table t1 (a int) distributed by (a); +create table t2 (a int, b float) distributed replicated; +create or replace function f(i int) returns int language sql security definer as $$ select i; $$; +-- ensure we make gather motion when volatile functions in subplan +explain (costs off, verbose) select (select f(i) from t); +explain (costs off, verbose) select (select f(i) from t group by f(i)); +explain (costs off, verbose) select (select i from t group by i having f(i) > 0); +-- ensure we do not make broadcast motion +explain (costs off, verbose) select * from t1 where a in (select random() from t where i=a group by i); +explain (costs off, verbose) select * from t1 where a in (select random() from t where i=a); +-- ensure we make broadcast motion when volatile function in deleting motion flow +explain (costs off, verbose) insert into t2 (a, b) select i, random() from t; +-- ensure we make broadcast motion when volatile function in correlated subplan qual +explain (costs off, verbose) select * from t1 where a in (select f(i) from t where i=a and f(i) > 0); +-- ensure we do not break broadcast motion +explain (costs off, verbose) select * from t1 where 1 <= ALL (select i from t group by i having random() > 0); +drop table if exists t, t1, t2; +drop function if exists f(i int); + -- start_ignore drop schema rpt cascade; -- end_ignore