From d5183d9f831ac5ddc5e3b8417e24e6c29db11011 Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy Date: Tue, 22 Dec 2020 13:19:22 +0530 Subject: [PATCH v14 3/4] Tests For Parallel Inserts in CTAS --- src/test/regress/expected/write_parallel.out | 577 +++++++++++++++++++ src/test/regress/sql/write_parallel.sql | 216 +++++++ 2 files changed, 793 insertions(+) diff --git a/src/test/regress/expected/write_parallel.out b/src/test/regress/expected/write_parallel.out index 0c4da2591a..357fbbbe8d 100644 --- a/src/test/regress/expected/write_parallel.out +++ b/src/test/regress/expected/write_parallel.out @@ -76,4 +76,581 @@ explain (costs off) create table parallel_write as execute prep_stmt; create table parallel_write as execute prep_stmt; drop table parallel_write; +-- +-- Test parallel inserts in create table as/select into/create materialized +-- view. +-- +-- Parallel queries won't necessarily get as many workers as the planner +-- asked for. This affects not only the "Workers Launched:" field of EXPLAIN +-- results, but also row counts and loop counts for parallel scans, Gathers, +-- and everything in between. This function filters out the values we can't +-- rely on to be stable. +-- This removes enough info that you might wonder why bother with EXPLAIN +-- ANALYZE at all. The answer is that we need to see whether the parallel +-- inserts are being done by the workers, the only way is that +-- Create <> appears in the explain output. +create function explain_pictas(text) returns setof text +language plpgsql as +$$ +declare + ln text; +begin + for ln in + execute format('explain (analyze, costs off, summary off, timing off) %s', + $1) + loop + ln := regexp_replace(ln, 'Workers Launched: \d+', 'Workers Launched: N'); + ln := regexp_replace(ln, 'actual rows=\d+ loops=\d+', 'actual rows=N loops=N'); + ln := regexp_replace(ln, 'Rows Removed by Filter: \d+', 'Rows Removed by Filter: N'); + return next ln; + end loop; +end; +$$; +-- parallel inserts must occur +select explain_pictas( +'create table parallel_write as select length(stringu1) from tenk1;'); + explain_pictas +---------------------------------------------------------- + Gather (actual rows=N loops=N) + Workers Planned: 4 + Workers Launched: N + -> Create parallel_write + -> Parallel Seq Scan on tenk1 (actual rows=N loops=N) +(5 rows) + +select count(*) from parallel_write; + count +------- + 10000 +(1 row) + +drop table parallel_write; +-- parallel inserts must not occur as the table is temporary +select explain_pictas( +'create temporary table parallel_write as select length(stringu1) from tenk1;'); + explain_pictas +---------------------------------------------------------- + Gather (actual rows=N loops=N) + Workers Planned: 4 + Workers Launched: N + -> Parallel Seq Scan on tenk1 (actual rows=N loops=N) +(4 rows) + +select count(*) from parallel_write; + count +------- + 10000 +(1 row) + +drop table parallel_write; +-- parallel inserts must occur +select explain_pictas( +'create unlogged table parallel_write as select length(stringu1) from tenk1;'); + explain_pictas +---------------------------------------------------------- + Gather (actual rows=N loops=N) + Workers Planned: 4 + Workers Launched: N + -> Create parallel_write + -> Parallel Seq Scan on tenk1 (actual rows=N loops=N) +(5 rows) + +select count(*) from parallel_write; + count +------- + 10000 +(1 row) + +drop table parallel_write; +-- parallel inserts must occur +select explain_pictas( +'select length(stringu1) into parallel_write from tenk1;'); + explain_pictas +---------------------------------------------------------- + Gather (actual rows=N loops=N) + Workers Planned: 4 + Workers Launched: N + -> Create parallel_write + -> Parallel Seq Scan on tenk1 (actual rows=N loops=N) +(5 rows) + +select count(*) from parallel_write; + count +------- + 10000 +(1 row) + +drop table parallel_write; +-- parallel inserts must not occur as the table is temporary +select explain_pictas( +'select length(stringu1) into temporary parallel_write from tenk1;'); + explain_pictas +---------------------------------------------------------- + Gather (actual rows=N loops=N) + Workers Planned: 4 + Workers Launched: N + -> Parallel Seq Scan on tenk1 (actual rows=N loops=N) +(4 rows) + +select count(*) from parallel_write; + count +------- + 10000 +(1 row) + +drop table parallel_write; +-- parallel inserts must occur +select explain_pictas( +'select length(stringu1) into unlogged parallel_write from tenk1;'); + explain_pictas +---------------------------------------------------------- + Gather (actual rows=N loops=N) + Workers Planned: 4 + Workers Launched: N + -> Create parallel_write + -> Parallel Seq Scan on tenk1 (actual rows=N loops=N) +(5 rows) + +select count(*) from parallel_write; + count +------- + 10000 +(1 row) + +drop table parallel_write; +-- parallel inserts must not occur as the parallelism will not be picked +-- for select part because of for update clause +select explain_pictas( +'create table parallel_write as select length(stringu1) from tenk1 for update;'); + explain_pictas +------------------------------------------------- + LockRows (actual rows=N loops=N) + -> Seq Scan on tenk1 (actual rows=N loops=N) +(2 rows) + +select count(*) from parallel_write; + count +------- + 10000 +(1 row) + +drop table parallel_write; +-- parallel inserts must occur +select explain_pictas( +'create materialized view parallel_mat_view as + select length(stringu1) from tenk1;'); + explain_pictas +---------------------------------------------------------- + Gather (actual rows=N loops=N) + Workers Planned: 4 + Workers Launched: N + -> Create parallel_mat_view + -> Parallel Seq Scan on tenk1 (actual rows=N loops=N) +(5 rows) + +select count(*) from parallel_mat_view; + count +------- + 10000 +(1 row) + +drop materialized view parallel_mat_view; +-- parallel inserts must occur +prepare parallel_write_prep as select length(stringu1) from tenk1; +select explain_pictas( +'create table parallel_write as execute parallel_write_prep;'); + explain_pictas +---------------------------------------------------------- + Gather (actual rows=N loops=N) + Workers Planned: 4 + Workers Launched: N + -> Create parallel_write + -> Parallel Seq Scan on tenk1 (actual rows=N loops=N) +(5 rows) + +select count(*) from parallel_write; + count +------- + 10000 +(1 row) + +deallocate parallel_write_prep; +drop table parallel_write; +-- parallel inserts must occur +select explain_pictas( +'create table parallel_write as select now(), four from tenk1;'); + explain_pictas +---------------------------------------------------------- + Gather (actual rows=N loops=N) + Workers Planned: 4 + Workers Launched: N + -> Create parallel_write + -> Parallel Seq Scan on tenk1 (actual rows=N loops=N) +(5 rows) + +select count(*) from parallel_write; + count +------- + 10000 +(1 row) + +drop table parallel_write; +-- parallel inserts must not occur as the parallelism will not be picked +-- for select part because of the parallel unsafe function +create sequence parallel_write_sequence; +select explain_pictas( +E'create table parallel_write as + select nextval(\'parallel_write_sequence\'), four from tenk1;'); + explain_pictas +------------------------------------------- + Seq Scan on tenk1 (actual rows=N loops=N) +(1 row) + +select count(*) from parallel_write; + count +------- + 10000 +(1 row) + +drop table parallel_write; +drop sequence parallel_write_sequence; +-- parallel inserts must occur, as there is init plan that gets executed by +-- each parallel worker +select explain_pictas( +'create table parallel_write as select two col1, + (select two from (select * from tenk2) as tt limit 1) col2 + from tenk1 where tenk1.four = 3;'); + explain_pictas +------------------------------------------------------------------------ + Gather (actual rows=N loops=N) + Workers Planned: 4 + Params Evaluated: $1 + Workers Launched: N + -> Create parallel_write + InitPlan 1 (returns $1) + -> Limit (actual rows=N loops=N) + -> Gather (actual rows=N loops=N) + Workers Planned: 4 + Workers Launched: N + -> Parallel Seq Scan on tenk2 (actual rows=N loops=N) + -> Parallel Seq Scan on tenk1 (actual rows=N loops=N) + Filter: (four = 3) + Rows Removed by Filter: N +(14 rows) + +select count(*) from parallel_write; + count +------- + 2500 +(1 row) + +drop table parallel_write; +-- parallel inserts must not occur, as there is sub plan that gets executed by +-- the Gather node in leader +select explain_pictas( +'create table parallel_write as select two col1, + (select tenk1.two from generate_series(1,1)) col2 + from tenk1 where tenk1.four = 3;'); + explain_pictas +------------------------------------------------------------------ + Gather (actual rows=N loops=N) + Workers Planned: 4 + Workers Launched: N + -> Parallel Seq Scan on tenk1 (actual rows=N loops=N) + Filter: (four = 3) + Rows Removed by Filter: N + SubPlan 1 + -> Function Scan on generate_series (actual rows=N loops=N) +(8 rows) + +select count(*) from parallel_write; + count +------- + 2500 +(1 row) + +drop table parallel_write; +create table temp1(col1) as select * from generate_series(1,5); +create table temp2(col2) as select * from temp1; +create table temp3(col3) as select * from temp1; +-- parallel inserts must not occur, as there is a limit clause +select explain_pictas( +'create table parallel_write as select * from temp1 limit 4;'); + explain_pictas +---------------------------------------------------------------- + Limit (actual rows=N loops=N) + -> Gather (actual rows=N loops=N) + Workers Planned: 3 + Workers Launched: N + -> Parallel Seq Scan on temp1 (actual rows=N loops=N) +(5 rows) + +select count(*) from parallel_write; + count +------- + 4 +(1 row) + +drop table parallel_write; +-- parallel inserts must not occur, as there is an order by clause +select explain_pictas( +'create table parallel_write as select * from temp1 order by 1;'); + explain_pictas +---------------------------------------------------------------- + Gather Merge (actual rows=N loops=N) + Workers Planned: 3 + Workers Launched: N + -> Sort (actual rows=N loops=N) + Sort Key: col1 + Sort Method: quicksort Memory: 25kB + Worker 0: Sort Method: quicksort Memory: 25kB + Worker 1: Sort Method: quicksort Memory: 25kB + Worker 2: Sort Method: quicksort Memory: 25kB + -> Parallel Seq Scan on temp1 (actual rows=N loops=N) +(10 rows) + +select count(*) from parallel_write; + count +------- + 5 +(1 row) + +drop table parallel_write; +-- parallel inserts must not occur, as there is an order by clause +select explain_pictas( +'create table parallel_write as select * from temp1 order by 1;'); + explain_pictas +---------------------------------------------------------------- + Gather Merge (actual rows=N loops=N) + Workers Planned: 3 + Workers Launched: N + -> Sort (actual rows=N loops=N) + Sort Key: col1 + Sort Method: quicksort Memory: 25kB + Worker 0: Sort Method: quicksort Memory: 25kB + Worker 1: Sort Method: quicksort Memory: 25kB + Worker 2: Sort Method: quicksort Memory: 25kB + -> Parallel Seq Scan on temp1 (actual rows=N loops=N) +(10 rows) + +select count(*) from parallel_write; + count +------- + 5 +(1 row) + +drop table parallel_write; +-- parallel inserts must not occur, as there is a distinct clause +select explain_pictas( +'create table parallel_write as select distinct * from temp1;'); + explain_pictas +---------------------------------------------------------------- + HashAggregate (actual rows=N loops=N) + Group Key: col1 + Batches: 1 Memory Usage: 40kB + -> Gather (actual rows=N loops=N) + Workers Planned: 3 + Workers Launched: N + -> Parallel Seq Scan on temp1 (actual rows=N loops=N) +(7 rows) + +select count(*) from parallel_write; + count +------- + 5 +(1 row) + +drop table parallel_write; +-- parallel inserts must not occur, as there is an aggregate and group clause +select explain_pictas( +'create table parallel_write as select count(*) from temp1 group by col1;'); + explain_pictas +---------------------------------------------------------------------- + Finalize HashAggregate (actual rows=N loops=N) + Group Key: col1 + Batches: 1 Memory Usage: 40kB + -> Gather (actual rows=N loops=N) + Workers Planned: 3 + Workers Launched: N + -> Partial HashAggregate (actual rows=N loops=N) + Group Key: col1 + Batches: 1 Memory Usage: 40kB + Worker 0: Batches: 1 Memory Usage: 40kB + Worker 1: Batches: 1 Memory Usage: 40kB + Worker 2: Batches: 1 Memory Usage: 40kB + -> Parallel Seq Scan on temp1 (actual rows=N loops=N) +(13 rows) + +select count(*) from parallel_write; + count +------- + 5 +(1 row) + +drop table parallel_write; +-- parallel inserts must not occur, as there is an aggregate, group and having +-- clauses +select explain_pictas( +'create table parallel_write as + select count(col1), (select col3 from + (select * from temp3) as tt limit 1) col4 from temp1, temp2 + where temp1.col1 = temp2.col2 group by col4 having count(col1) > 0;'); + explain_pictas +---------------------------------------------------------------------------------- + Finalize GroupAggregate (actual rows=N loops=N) + Group Key: ($1) + Filter: (count(temp1.col1) > 0) + InitPlan 1 (returns $1) + -> Limit (actual rows=N loops=N) + -> Gather (actual rows=N loops=N) + Workers Planned: 3 + Workers Launched: N + -> Parallel Seq Scan on temp3 (actual rows=N loops=N) + -> Gather (actual rows=N loops=N) + Workers Planned: 3 + Params Evaluated: $1 + Workers Launched: N + -> Partial GroupAggregate (actual rows=N loops=N) + Group Key: $1 + -> Parallel Hash Join (actual rows=N loops=N) + Hash Cond: (temp1.col1 = temp2.col2) + -> Parallel Seq Scan on temp1 (actual rows=N loops=N) + -> Parallel Hash (actual rows=N loops=N) + Buckets: 4096 Batches: 1 Memory Usage: 64kB + -> Parallel Seq Scan on temp2 (actual rows=N loops=N) +(21 rows) + +select count(*) from parallel_write; + count +------- + 1 +(1 row) + +drop table parallel_write; +-- parallel inserts must not occur, as there is a window function +select explain_pictas( +'create table parallel_write as + select avg(col1) OVER (PARTITION BY col1) from temp1;'); + explain_pictas +---------------------------------------------------------------------- + WindowAgg (actual rows=N loops=N) + -> Gather Merge (actual rows=N loops=N) + Workers Planned: 3 + Workers Launched: N + -> Sort (actual rows=N loops=N) + Sort Key: col1 + Sort Method: quicksort Memory: 25kB + Worker 0: Sort Method: quicksort Memory: 25kB + Worker 1: Sort Method: quicksort Memory: 25kB + Worker 2: Sort Method: quicksort Memory: 25kB + -> Parallel Seq Scan on temp1 (actual rows=N loops=N) +(11 rows) + +select count(*) from parallel_write; + count +------- + 5 +(1 row) + +drop table parallel_write; +-- nested loop join is the top node under which Gather node exists, so parallel +-- inserts must not occur +set enable_nestloop to on; +set enable_mergejoin to off; +set enable_hashjoin to off; +select explain_pictas( +'create table parallel_write as + select * from temp1, temp2 where temp1.col1 = temp2.col2;'); + explain_pictas +---------------------------------------------------------------------- + Nested Loop (actual rows=N loops=N) + Join Filter: (temp1.col1 = temp2.col2) + Rows Removed by Join Filter: 20 + -> Gather (actual rows=N loops=N) + Workers Planned: 3 + Workers Launched: N + -> Parallel Seq Scan on temp1 (actual rows=N loops=N) + -> Materialize (actual rows=N loops=N) + -> Gather (actual rows=N loops=N) + Workers Planned: 3 + Workers Launched: N + -> Parallel Seq Scan on temp2 (actual rows=N loops=N) +(12 rows) + +select count(*) from parallel_write; + count +------- + 5 +(1 row) + +drop table parallel_write; +-- the top node is Gather under which merge join happens, so parallel inserts +-- must occur +set enable_nestloop to off; +set enable_mergejoin to on; +select explain_pictas( +'create table parallel_write as + select * from temp1, temp2 where temp1.col1 = temp2.col2;'); + explain_pictas +---------------------------------------------------------------------- + Gather (actual rows=N loops=N) + Workers Planned: 3 + Workers Launched: N + -> Create parallel_write + -> Merge Join (actual rows=N loops=N) + Merge Cond: (temp1.col1 = temp2.col2) + -> Sort (actual rows=N loops=N) + Sort Key: temp1.col1 + Sort Method: quicksort Memory: 25kB + Worker 0: Sort Method: quicksort Memory: 25kB + Worker 1: Sort Method: quicksort Memory: 25kB + Worker 2: Sort Method: quicksort Memory: 25kB + -> Parallel Seq Scan on temp1 (actual rows=N loops=N) + -> Sort (actual rows=N loops=N) + Sort Key: temp2.col2 + Sort Method: quicksort Memory: 25kB + -> Seq Scan on temp2 (actual rows=N loops=N) +(17 rows) + +select count(*) from parallel_write; + count +------- + 5 +(1 row) + +drop table parallel_write; +-- parallel hash join happens under Gather node, so parallel inserts must occur +set enable_mergejoin to off; +set enable_hashjoin to on; +select explain_pictas( +'create table parallel_write as + select * from temp1, temp2 where temp1.col1 = temp2.col2;'); + explain_pictas +---------------------------------------------------------------------- + Gather (actual rows=N loops=N) + Workers Planned: 3 + Workers Launched: N + -> Create parallel_write + -> Parallel Hash Join (actual rows=N loops=N) + Hash Cond: (temp1.col1 = temp2.col2) + -> Parallel Seq Scan on temp1 (actual rows=N loops=N) + -> Parallel Hash (actual rows=N loops=N) + Buckets: 4096 Batches: 1 Memory Usage: 64kB + -> Parallel Seq Scan on temp2 (actual rows=N loops=N) +(10 rows) + +select count(*) from parallel_write; + count +------- + 5 +(1 row) + +drop table parallel_write; +reset enable_nestloop; +reset enable_mergejoin; +reset enable_hashjoin; +drop table temp1; +drop table temp2; +drop table temp3; +drop function explain_pictas(text); rollback; diff --git a/src/test/regress/sql/write_parallel.sql b/src/test/regress/sql/write_parallel.sql index 78b479cedf..46b958014a 100644 --- a/src/test/regress/sql/write_parallel.sql +++ b/src/test/regress/sql/write_parallel.sql @@ -39,4 +39,220 @@ explain (costs off) create table parallel_write as execute prep_stmt; create table parallel_write as execute prep_stmt; drop table parallel_write; +-- +-- Test parallel inserts in create table as/select into/create materialized +-- view. +-- + +-- Parallel queries won't necessarily get as many workers as the planner +-- asked for. This affects not only the "Workers Launched:" field of EXPLAIN +-- results, but also row counts and loop counts for parallel scans, Gathers, +-- and everything in between. This function filters out the values we can't +-- rely on to be stable. +-- This removes enough info that you might wonder why bother with EXPLAIN +-- ANALYZE at all. The answer is that we need to see whether the parallel +-- inserts are being done by the workers, the only way is that +-- Create <> appears in the explain output. +create function explain_pictas(text) returns setof text +language plpgsql as +$$ +declare + ln text; +begin + for ln in + execute format('explain (analyze, costs off, summary off, timing off) %s', + $1) + loop + ln := regexp_replace(ln, 'Workers Launched: \d+', 'Workers Launched: N'); + ln := regexp_replace(ln, 'actual rows=\d+ loops=\d+', 'actual rows=N loops=N'); + ln := regexp_replace(ln, 'Rows Removed by Filter: \d+', 'Rows Removed by Filter: N'); + return next ln; + end loop; +end; +$$; + +-- parallel inserts must occur +select explain_pictas( +'create table parallel_write as select length(stringu1) from tenk1;'); +select count(*) from parallel_write; +drop table parallel_write; + +-- parallel inserts must not occur as the table is temporary +select explain_pictas( +'create temporary table parallel_write as select length(stringu1) from tenk1;'); +select count(*) from parallel_write; +drop table parallel_write; + +-- parallel inserts must occur +select explain_pictas( +'create unlogged table parallel_write as select length(stringu1) from tenk1;'); +select count(*) from parallel_write; +drop table parallel_write; + +-- parallel inserts must occur +select explain_pictas( +'select length(stringu1) into parallel_write from tenk1;'); +select count(*) from parallel_write; +drop table parallel_write; + +-- parallel inserts must not occur as the table is temporary +select explain_pictas( +'select length(stringu1) into temporary parallel_write from tenk1;'); +select count(*) from parallel_write; +drop table parallel_write; + +-- parallel inserts must occur +select explain_pictas( +'select length(stringu1) into unlogged parallel_write from tenk1;'); +select count(*) from parallel_write; +drop table parallel_write; + +-- parallel inserts must not occur as the parallelism will not be picked +-- for select part because of for update clause +select explain_pictas( +'create table parallel_write as select length(stringu1) from tenk1 for update;'); +select count(*) from parallel_write; +drop table parallel_write; + +-- parallel inserts must occur +select explain_pictas( +'create materialized view parallel_mat_view as + select length(stringu1) from tenk1;'); +select count(*) from parallel_mat_view; +drop materialized view parallel_mat_view; + +-- parallel inserts must occur +prepare parallel_write_prep as select length(stringu1) from tenk1; +select explain_pictas( +'create table parallel_write as execute parallel_write_prep;'); +select count(*) from parallel_write; +deallocate parallel_write_prep; +drop table parallel_write; + +-- parallel inserts must occur +select explain_pictas( +'create table parallel_write as select now(), four from tenk1;'); +select count(*) from parallel_write; +drop table parallel_write; + +-- parallel inserts must not occur as the parallelism will not be picked +-- for select part because of the parallel unsafe function +create sequence parallel_write_sequence; +select explain_pictas( +E'create table parallel_write as + select nextval(\'parallel_write_sequence\'), four from tenk1;'); +select count(*) from parallel_write; +drop table parallel_write; +drop sequence parallel_write_sequence; + +-- parallel inserts must occur, as there is init plan that gets executed by +-- each parallel worker +select explain_pictas( +'create table parallel_write as select two col1, + (select two from (select * from tenk2) as tt limit 1) col2 + from tenk1 where tenk1.four = 3;'); +select count(*) from parallel_write; +drop table parallel_write; + +-- parallel inserts must not occur, as there is sub plan that gets executed by +-- the Gather node in leader +select explain_pictas( +'create table parallel_write as select two col1, + (select tenk1.two from generate_series(1,1)) col2 + from tenk1 where tenk1.four = 3;'); +select count(*) from parallel_write; +drop table parallel_write; + +create table temp1(col1) as select * from generate_series(1,5); +create table temp2(col2) as select * from temp1; +create table temp3(col3) as select * from temp1; + +-- parallel inserts must not occur, as there is a limit clause +select explain_pictas( +'create table parallel_write as select * from temp1 limit 4;'); +select count(*) from parallel_write; +drop table parallel_write; + +-- parallel inserts must not occur, as there is an order by clause +select explain_pictas( +'create table parallel_write as select * from temp1 order by 1;'); +select count(*) from parallel_write; +drop table parallel_write; + +-- parallel inserts must not occur, as there is an order by clause +select explain_pictas( +'create table parallel_write as select * from temp1 order by 1;'); +select count(*) from parallel_write; +drop table parallel_write; + +-- parallel inserts must not occur, as there is a distinct clause +select explain_pictas( +'create table parallel_write as select distinct * from temp1;'); +select count(*) from parallel_write; +drop table parallel_write; + +-- parallel inserts must not occur, as there is an aggregate and group clause +select explain_pictas( +'create table parallel_write as select count(*) from temp1 group by col1;'); +select count(*) from parallel_write; +drop table parallel_write; + +-- parallel inserts must not occur, as there is an aggregate, group and having +-- clauses +select explain_pictas( +'create table parallel_write as + select count(col1), (select col3 from + (select * from temp3) as tt limit 1) col4 from temp1, temp2 + where temp1.col1 = temp2.col2 group by col4 having count(col1) > 0;'); +select count(*) from parallel_write; +drop table parallel_write; + +-- parallel inserts must not occur, as there is a window function +select explain_pictas( +'create table parallel_write as + select avg(col1) OVER (PARTITION BY col1) from temp1;'); +select count(*) from parallel_write; +drop table parallel_write; + +-- nested loop join is the top node under which Gather node exists, so parallel +-- inserts must not occur +set enable_nestloop to on; +set enable_mergejoin to off; +set enable_hashjoin to off; + +select explain_pictas( +'create table parallel_write as + select * from temp1, temp2 where temp1.col1 = temp2.col2;'); +select count(*) from parallel_write; +drop table parallel_write; + +-- the top node is Gather under which merge join happens, so parallel inserts +-- must occur +set enable_nestloop to off; +set enable_mergejoin to on; + +select explain_pictas( +'create table parallel_write as + select * from temp1, temp2 where temp1.col1 = temp2.col2;'); +select count(*) from parallel_write; +drop table parallel_write; + +-- parallel hash join happens under Gather node, so parallel inserts must occur +set enable_mergejoin to off; +set enable_hashjoin to on; + +select explain_pictas( +'create table parallel_write as + select * from temp1, temp2 where temp1.col1 = temp2.col2;'); +select count(*) from parallel_write; +drop table parallel_write; + +reset enable_nestloop; +reset enable_mergejoin; +reset enable_hashjoin; + +drop table temp1; +drop table temp2; +drop table temp3; +drop function explain_pictas(text); rollback; -- 2.25.1