diff --git a/contrib/pax_storage/src/test/regress/expected/bfv_partition_plans.out b/contrib/pax_storage/src/test/regress/expected/bfv_partition_plans.out index 034624e6d17..932fe2199dd 100644 --- a/contrib/pax_storage/src/test/regress/expected/bfv_partition_plans.out +++ b/contrib/pax_storage/src/test/regress/expected/bfv_partition_plans.out @@ -24,7 +24,7 @@ SET optimizer_trace_fallback=on; -- -- start_ignore create language plpython3u; -ERROR: language "plpython3u" already exists +ERROR: extension "plpython3u" already exists -- end_ignore create or replace function count_operator(query text, operator text) returns int as $$ @@ -98,10 +98,10 @@ insert into mpp7980 values('2009-03-03','xyz','zyz','4',1,3,'1'); select cust_type, subscription_status,count(distinct subscription_id),sum(voice_call_min),sum(minute_per_call) from mpp7980 where month_id ='2009-04-01' group by rollup(1,2); cust_type | subscription_status | count | sum | sum -----------+---------------------+-------+------+------ - | | 1 | 3.00 | 2.00 - zyz | | 1 | 3.00 | 2.00 zyz | 1 | 1 | 1.00 | 1.00 zyz | 2 | 1 | 2.00 | 1.00 + zyz | | 1 | 3.00 | 2.00 + | | 1 | 3.00 | 2.00 (4 rows) -- CLEANUP @@ -113,6 +113,7 @@ drop table mpp7980; -- SETUP -- start_ignore set optimizer_enable_bitmapscan=on; +set optimizer_enable_dynamicbitmapscan=on; set optimizer_enable_indexjoin=on; drop table if exists mpp23195_t1; NOTICE: table "mpp23195_t1" does not exist, skipping @@ -157,6 +158,7 @@ select * from mpp23195_t1,mpp23195_t2 where mpp23195_t1.i < mpp23195_t2.i; drop table if exists mpp23195_t1; drop table if exists mpp23195_t2; set optimizer_enable_bitmapscan=off; +set optimizer_enable_dynamicbitmapscan=off; set optimizer_enable_indexjoin=off; -- end_ignore -- @@ -795,6 +797,7 @@ reset optimizer_segments; -- SETUP -- start_ignore DROP TABLE IF EXISTS bar; +NOTICE: table "bar" does not exist, skipping -- end_ignore CREATE TABLE bar (b int, c int) PARTITION BY RANGE (b) @@ -809,26 +812,26 @@ ANALYZE bar; SELECT b FROM bar GROUP BY b; b ---- - 7 - 4 + 8 19 - 3 - 5 + 7 18 - 6 - 11 - 9 - 8 - 12 - 10 - 17 - 1 - 0 + 4 2 16 + 3 15 - 14 + 0 + 1 + 12 + 17 + 11 13 + 10 + 9 + 5 + 6 + 14 (20 rows) EXPLAIN SELECT b FROM bar GROUP BY b; @@ -845,6 +848,7 @@ EXPLAIN SELECT b FROM bar GROUP BY b; -- CLEANUP DROP TABLE IF EXISTS foo; +NOTICE: table "foo" does not exist, skipping DROP TABLE IF EXISTS bar; -- Test EXPLAIN ANALYZE on a partitioned table. There used to be a bug, where -- you got an internal error with this, because the EXPLAIN ANALYZE sends the @@ -867,26 +871,26 @@ HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sur explain analyze select a.* from mpp8031 a, mpp8031 b where a.oid = b.oid; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2743.00..2475974.00 rows=80883360 width=16) (actual time=0.707..0.709 rows=0 loops=1) - -> Hash Join (cost=2743.00..1397529.20 rows=26961120 width=16) (actual time=0.024..0.028 rows=0 loops=1) + Gather Motion 3:1 (slice1; segments: 3) (cost=2743.00..2475974.00 rows=80883360 width=16) (actual time=5.088..5.091 rows=0 loops=1) + -> Hash Join (cost=2743.00..1397529.20 rows=26961120 width=16) (actual time=0.223..0.225 rows=0 loops=1) Hash Cond: (a.oid = b.oid) - -> Append (cost=0.00..1558.00 rows=94800 width=16) (actual time=0.021..0.023 rows=0 loops=1) - -> Seq Scan on mpp8031_1_prt_foo_1 a_1 (cost=0.00..271.00 rows=23700 width=16) (actual time=0.010..0.010 rows=0 loops=1) - -> Seq Scan on mpp8031_1_prt_2 a_2 (cost=0.00..271.00 rows=23700 width=16) (actual time=0.003..0.004 rows=0 loops=1) - -> Seq Scan on mpp8031_1_prt_3 a_3 (cost=0.00..271.00 rows=23700 width=16) (actual time=0.003..0.003 rows=0 loops=1) - -> Seq Scan on mpp8031_1_prt_4 a_4 (cost=0.00..271.00 rows=23700 width=16) (actual time=0.003..0.003 rows=0 loops=1) + -> Append (cost=0.00..1558.00 rows=94800 width=16) (actual time=0.221..0.223 rows=0 loops=1) + -> Seq Scan on mpp8031_1_prt_foo_1 a_1 (cost=0.00..271.00 rows=23700 width=16) (actual time=0.102..0.102 rows=0 loops=1) + -> Seq Scan on mpp8031_1_prt_2 a_2 (cost=0.00..271.00 rows=23700 width=16) (actual time=0.031..0.031 rows=0 loops=1) + -> Seq Scan on mpp8031_1_prt_3 a_3 (cost=0.00..271.00 rows=23700 width=16) (actual time=0.037..0.037 rows=0 loops=1) + -> Seq Scan on mpp8031_1_prt_4 a_4 (cost=0.00..271.00 rows=23700 width=16) (actual time=0.051..0.051 rows=0 loops=1) -> Hash (cost=1558.00..1558.00 rows=94800 width=4) (never executed) -> Append (cost=0.00..1558.00 rows=94800 width=4) (never executed) -> Seq Scan on mpp8031_1_prt_foo_1 b_1 (cost=0.00..271.00 rows=23700 width=4) (never executed) -> Seq Scan on mpp8031_1_prt_2 b_2 (cost=0.00..271.00 rows=23700 width=4) (never executed) -> Seq Scan on mpp8031_1_prt_3 b_3 (cost=0.00..271.00 rows=23700 width=4) (never executed) -> Seq Scan on mpp8031_1_prt_4 b_4 (cost=0.00..271.00 rows=23700 width=4) (never executed) - Planning Time: 2.080 ms - (slice0) Executor memory: 122K bytes. - (slice1) Executor memory: 121K bytes avg x 3x(0) workers, 121K bytes max (seg0). + Planning Time: 0.374 ms + (slice0) Executor memory: 52K bytes. + (slice1) Executor memory: 149K bytes avg x 3x(0) workers, 149K bytes max (seg0). Memory used: 128000kB Optimizer: Postgres query optimizer - Execution Time: 1.279 ms + Execution Time: 5.529 ms (20 rows) drop table mpp8031; @@ -915,6 +919,9 @@ INSERT INTO part_tbl VALUES (2015111000, 479534741, 99999999); INSERT INTO part_tbl VALUES (2015111000, 479534742, 99999999); CREATE INDEX part_tbl_idx ON part_tbl(profile_key); +-- start_ignore +analyze part_tbl; +-- end_ignore EXPLAIN SELECT * FROM part_tbl WHERE profile_key = 99999999; QUERY PLAN --------------------------------------------------------------------------------------------------------------------- @@ -1140,9 +1147,9 @@ explain select * from fact where dd < current_date; --partitions eliminated ----------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=40) -> Seq Scan on fact_1_prt_1 fact (cost=0.00..1.01 rows=1 width=40) - Filter: (dd < '04-28-2022'::date) + Filter: (dd < '06-21-2026'::date) Optimizer: Postgres query optimizer -(6 rows) +(4 rows) -- Test partition elimination in prepared statements prepare f1(date) as select * from fact where dd < $1; @@ -1227,39 +1234,37 @@ INSERT INTO delete_from_pt SELECT i, i%6 FROM generate_series(1, 10)i; INSERT INTO t VALUES (1); ANALYZE delete_from_pt, t; EXPLAIN (COSTS OFF, TIMING OFF, SUMMARY OFF, ANALYZE) DELETE FROM delete_from_pt WHERE b IN (SELECT b FROM delete_from_pt, t WHERE t.a=delete_from_pt.b); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +----------------------------------------------------------------------------------------------------------- Delete on delete_from_pt (actual rows=0 loops=1) Delete on delete_from_pt_1_prt_1 delete_from_pt_2 Delete on delete_from_pt_1_prt_2 delete_from_pt_3 Delete on delete_from_pt_1_prt_3 delete_from_pt_4 - -> Hash Semi Join (actual rows=1 loops=1) - Hash Cond: (delete_from_pt.b = t.a) - Extra Text: (seg0) Hash chain length 2.0 avg, 2 max, using 1 of 131072 buckets. - -> Append (actual rows=3 loops=1) - Partition Selectors: $1 - -> Seq Scan on delete_from_pt_1_prt_1 delete_from_pt_2 (actual rows=3 loops=1) - -> Seq Scan on delete_from_pt_1_prt_2 delete_from_pt_3 (never executed) - -> Seq Scan on delete_from_pt_1_prt_3 delete_from_pt_4 (never executed) - -> Hash (actual rows=2 loops=1) + -> Hash Right Semi Join (actual rows=1 loops=1) + Hash Cond: (t.a = delete_from_pt.b) + Extra Text: (seg0) Hash chain length 1.2 avg, 2 max, using 4 of 131072 buckets. + -> Broadcast Motion 3:3 (slice1; segments: 3) (actual rows=2 loops=1) + -> Hash Join (actual rows=1 loops=1) + Hash Cond: (delete_from_pt_1.b = t.a) + Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 1 of 262144 buckets. + -> Append (actual rows=3 loops=1) + Partition Selectors: $1 + -> Seq Scan on delete_from_pt_1_prt_1 delete_from_pt_5 (actual rows=3 loops=1) + -> Seq Scan on delete_from_pt_1_prt_2 delete_from_pt_6 (never executed) + -> Seq Scan on delete_from_pt_1_prt_3 delete_from_pt_7 (never executed) + -> Hash (actual rows=1 loops=1) + Buckets: 262144 Batches: 1 Memory Usage: 2049kB + -> Partition Selector (selector id: $1) (actual rows=1 loops=1) + -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=1 loops=1) + -> Seq Scan on t (actual rows=1 loops=1) + -> Hash (actual rows=5 loops=1) Buckets: 131072 Batches: 1 Memory Usage: 1025kB - -> Partition Selector (selector id: $1) (actual rows=2 loops=1) - -> Broadcast Motion 3:3 (slice1; segments: 3) (actual rows=2 loops=1) - -> Hash Join (actual rows=1 loops=1) - Hash Cond: (delete_from_pt_1.b = t.a) - Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 1 of 262144 buckets. - -> Append (actual rows=3 loops=1) - Partition Selectors: $2 - -> Seq Scan on delete_from_pt_1_prt_1 delete_from_pt_5 (actual rows=3 loops=1) - -> Seq Scan on delete_from_pt_1_prt_2 delete_from_pt_6 (never executed) - -> Seq Scan on delete_from_pt_1_prt_3 delete_from_pt_7 (never executed) - -> Hash (actual rows=1 loops=1) - Buckets: 262144 Batches: 1 Memory Usage: 2049kB - -> Partition Selector (selector id: $2) (actual rows=1 loops=1) - -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=1 loops=1) - -> Seq Scan on t (actual rows=1 loops=1) + -> Append (actual rows=5 loops=1) + -> Seq Scan on delete_from_pt_1_prt_1 delete_from_pt_2 (actual rows=3 loops=1) + -> Seq Scan on delete_from_pt_1_prt_2 delete_from_pt_3 (actual rows=3 loops=1) + -> Seq Scan on delete_from_pt_1_prt_3 delete_from_pt_4 (actual rows=0 loops=1) Optimizer: Postgres query optimizer -(30 rows) +(28 rows) SELECT * FROM delete_from_pt order by a; a | b @@ -1278,7 +1283,10 @@ RESET optimizer_trace_fallback; -- CLEANUP -- start_ignore drop schema if exists bfv_partition_plans cascade; -NOTICE: drop cascades to 2 other objects +NOTICE: drop cascades to 5 other objects DETAIL: drop cascades to function count_operator(text,text) drop cascades to function find_operator(text,text) +drop cascades to table delete_from_indexed_pt +drop cascades to table delete_from_pt +drop cascades to table t -- end_ignore diff --git a/contrib/pax_storage/src/test/regress/expected/bfv_partition_plans_optimizer.out b/contrib/pax_storage/src/test/regress/expected/bfv_partition_plans_optimizer.out index 06f0bab1c56..d17e7b29d93 100644 --- a/contrib/pax_storage/src/test/regress/expected/bfv_partition_plans_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/bfv_partition_plans_optimizer.out @@ -912,18 +912,6 @@ ANALYZE bar; SELECT b FROM bar GROUP BY b; b ---- - 17 - 11 - 13 - 10 - 9 - 5 - 6 - 14 - 15 - 0 - 1 - 12 8 19 7 @@ -932,6 +920,18 @@ SELECT b FROM bar GROUP BY b; 2 16 3 + 15 + 0 + 1 + 12 + 17 + 11 + 13 + 10 + 9 + 5 + 6 + 14 (20 rows) EXPLAIN SELECT b FROM bar GROUP BY b; @@ -972,22 +972,22 @@ NOTICE: One or more columns in the following table(s) do not have statistics: m HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=1 width=16) (actual time=9.030..9.036 rows=0 loops=1) - -> Hash Join (cost=0.00..862.00 rows=1 width=16) (actual time=6.122..6.132 rows=0 loops=1) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=1 width=16) (actual time=23.173..23.176 rows=0 loops=1) + -> Hash Join (cost=0.00..862.00 rows=1 width=16) (actual time=25.182..25.185 rows=0 loops=1) Hash Cond: (a.oid = b.oid) -> Dynamic Seq Scan on mpp8031 a (cost=0.00..431.00 rows=1 width=16) (never executed) Number of partitions to scan: 4 (out of 4) - -> Hash (cost=431.00..431.00 rows=1 width=4) (actual time=2.660..2.667 rows=0 loops=1) + -> Hash (cost=431.00..431.00 rows=1 width=4) (actual time=2.599..2.600 rows=0 loops=1) Buckets: 524288 Batches: 1 Memory Usage: 4096kB - -> Dynamic Seq Scan on mpp8031 b (cost=0.00..431.00 rows=1 width=4) (actual time=2.658..2.658 rows=0 loops=1) + -> Dynamic Seq Scan on mpp8031 b (cost=0.00..431.00 rows=1 width=4) (actual time=2.596..2.597 rows=0 loops=1) Number of partitions to scan: 4 (out of 4) Partitions scanned: Avg 4.0 x 3 workers. Max 4 parts (seg0). - Planning Time: 47.729 ms - (slice0) Executor memory: 113K bytes. - (slice1) Executor memory: 4231K bytes avg x 3x(0) workers, 4231K bytes max (seg0). Work_mem: 4096K bytes max. + Planning Time: 7.956 ms + (slice0) Executor memory: 25K bytes. + (slice1) Executor memory: 4229K bytes avg x 3x(0) workers, 4229K bytes max (seg0). Work_mem: 4096K bytes max. Memory used: 128000kB Optimizer: GPORCA - Execution Time: 11.130 ms + Execution Time: 30.860 ms (16 rows) drop table mpp8031; @@ -1230,8 +1230,6 @@ select '2009-01-02'::date = to_date('2009-01-02','YYYY-MM-DD'); -- ensure that b (1 row) explain select * from fact where dd < '2009-01-02'::date; -- partitions eliminated -NOTICE: One or more columns in the following table(s) do not have statistics: fact -HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN ------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=16) @@ -1242,8 +1240,6 @@ HINT: For non-partitioned tables, run analyze (). For (5 rows) explain select * from fact where dd < to_date('2009-01-02','YYYY-MM-DD'); -- partitions eliminated -NOTICE: One or more columns in the following table(s) do not have statistics: fact -HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN ------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=16) @@ -1254,14 +1250,12 @@ HINT: For non-partitioned tables, run analyze (). For (5 rows) explain select * from fact where dd < current_date; --partitions eliminated -NOTICE: One or more columns in the following table(s) do not have statistics: fact -HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN ------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=16) -> Dynamic Seq Scan on fact (cost=0.00..431.00 rows=1 width=16) Number of partitions to scan: 1 (out of 4) - Filter: (dd < '04-10-2026'::date) + Filter: (dd < '06-21-2026'::date) Optimizer: GPORCA (5 rows) @@ -1269,8 +1263,6 @@ HINT: For non-partitioned tables, run analyze (). For prepare f1(date) as select * from fact where dd < $1; -- force_explain explain execute f1('2009-01-02'::date); -- should eliminate partitions -NOTICE: One or more columns in the following table(s) do not have statistics: fact -HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN ------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=16) @@ -1282,8 +1274,6 @@ HINT: For non-partitioned tables, run analyze (). For -- force_explain explain execute f1(to_date('2009-01-02', 'YYYY-MM-DD')); -- should eliminate partitions -NOTICE: One or more columns in the following table(s) do not have statistics: fact -HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN ------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=16) @@ -1366,39 +1356,37 @@ ANALYZE delete_from_pt, t; EXPLAIN (COSTS OFF, TIMING OFF, SUMMARY OFF, ANALYZE) DELETE FROM delete_from_pt WHERE b IN (SELECT b FROM delete_from_pt, t WHERE t.a=delete_from_pt.b); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: DML(delete) on partitioned tables - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +----------------------------------------------------------------------------------------------------------- Delete on delete_from_pt (actual rows=0 loops=1) Delete on delete_from_pt_1_prt_1 delete_from_pt_2 Delete on delete_from_pt_1_prt_2 delete_from_pt_3 Delete on delete_from_pt_1_prt_3 delete_from_pt_4 - -> Hash Semi Join (actual rows=1 loops=1) - Hash Cond: (delete_from_pt.b = t.a) - Extra Text: (seg0) Hash chain length 2.0 avg, 2 max, using 1 of 131072 buckets. - -> Append (actual rows=3 loops=1) - Partition Selectors: $1 - -> Seq Scan on delete_from_pt_1_prt_1 delete_from_pt_2 (actual rows=3 loops=1) - -> Seq Scan on delete_from_pt_1_prt_2 delete_from_pt_3 (never executed) - -> Seq Scan on delete_from_pt_1_prt_3 delete_from_pt_4 (never executed) - -> Hash (actual rows=2 loops=1) + -> Hash Right Semi Join (actual rows=1 loops=1) + Hash Cond: (t.a = delete_from_pt.b) + Extra Text: (seg0) Hash chain length 1.2 avg, 2 max, using 4 of 131072 buckets. + -> Broadcast Motion 3:3 (slice1; segments: 3) (actual rows=2 loops=1) + -> Hash Join (actual rows=1 loops=1) + Hash Cond: (delete_from_pt_1.b = t.a) + Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 1 of 262144 buckets. + -> Append (actual rows=3 loops=1) + Partition Selectors: $1 + -> Seq Scan on delete_from_pt_1_prt_1 delete_from_pt_5 (actual rows=3 loops=1) + -> Seq Scan on delete_from_pt_1_prt_2 delete_from_pt_6 (never executed) + -> Seq Scan on delete_from_pt_1_prt_3 delete_from_pt_7 (never executed) + -> Hash (actual rows=1 loops=1) + Buckets: 262144 Batches: 1 Memory Usage: 2049kB + -> Partition Selector (selector id: $1) (actual rows=1 loops=1) + -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=1 loops=1) + -> Seq Scan on t (actual rows=1 loops=1) + -> Hash (actual rows=5 loops=1) Buckets: 131072 Batches: 1 Memory Usage: 1025kB - -> Partition Selector (selector id: $1) (actual rows=2 loops=1) - -> Broadcast Motion 3:3 (slice1; segments: 3) (actual rows=2 loops=1) - -> Hash Join (actual rows=1 loops=1) - Hash Cond: (delete_from_pt_1.b = t.a) - Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 1 of 262144 buckets. - -> Append (actual rows=3 loops=1) - Partition Selectors: $2 - -> Seq Scan on delete_from_pt_1_prt_1 delete_from_pt_5 (actual rows=3 loops=1) - -> Seq Scan on delete_from_pt_1_prt_2 delete_from_pt_6 (never executed) - -> Seq Scan on delete_from_pt_1_prt_3 delete_from_pt_7 (never executed) - -> Hash (actual rows=1 loops=1) - Buckets: 262144 Batches: 1 Memory Usage: 2049kB - -> Partition Selector (selector id: $2) (actual rows=1 loops=1) - -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=1 loops=1) - -> Seq Scan on t (actual rows=1 loops=1) + -> Append (actual rows=5 loops=1) + -> Seq Scan on delete_from_pt_1_prt_1 delete_from_pt_2 (actual rows=3 loops=1) + -> Seq Scan on delete_from_pt_1_prt_2 delete_from_pt_3 (actual rows=3 loops=1) + -> Seq Scan on delete_from_pt_1_prt_3 delete_from_pt_4 (actual rows=0 loops=1) Optimizer: Postgres query optimizer -(30 rows) +(28 rows) SELECT * FROM delete_from_pt order by a; a | b diff --git a/contrib/pax_storage/src/test/regress/expected/bfv_planner_optimizer.out b/contrib/pax_storage/src/test/regress/expected/bfv_planner_optimizer.out index d72103210ec..71ed5be10e0 100644 --- a/contrib/pax_storage/src/test/regress/expected/bfv_planner_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/bfv_planner_optimizer.out @@ -205,11 +205,11 @@ delete from p where b = 1 or (b=2 and a in (select r.a from r)); select * from p; a | b ---+--- + 2 | 2 + 2 | 3 3 | 3 1 | 2 1 | 3 - 2 | 2 - 2 | 3 (5 rows) delete from p where b = 1 or (b=2 and a in (select b from r)); @@ -234,8 +234,8 @@ select * from booltest a, booltest b where (a.b = b.b) is not false; b | b ---+--- | - | t t | + | t t | t (4 rows) @@ -245,7 +245,7 @@ select * from booltest a, booltest b where (a.b = b.b) is not false; create table tstest (t tsvector); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause, and no column type is suitable for a distribution key. Creating a NULL policy entry. create index i_tstest on tstest using gist (t) WHERE t @@ 'bar'; -ERROR: pax only support btree/hash/gin/bitmap indexes (pax_access_handle.cc:###) +ERROR: pax only support btree/hash/gin/bitmap indexes (pax_access_handle.cc:588) insert into tstest values ('foo'); insert into tstest values ('bar'); set enable_bitmapscan =off; @@ -340,7 +340,7 @@ INSERT INTO oneoffplantest VALUES (0), (0), (0); -- cached. So we expect the NOTICE to be printed only once, -- regardless of the number of tuples in the table. select volatilefunc(a) from oneoffplantest; -NOTICE: immutablefunc executed (seg0 slice1 127.0.1.1:25432 pid=6257) +NOTICE: immutablefunc executed (seg1 slice1 172.18.0.2:7003 pid=63971) volatilefunc -------------- 0 @@ -354,7 +354,6 @@ CREATE TABLE bfv_planner_t2 (f int,g int) DISTRIBUTED BY (f) PARTITION BY RANGE( ( PARTITION "201612" START (1) END (10) ); -NOTICE: CREATE TABLE will create partition "bfv_planner_t2_1_prt_201612" for table "bfv_planner_t2" insert into bfv_planner_t1 values(1,2,3), (2,3,4), (3,4,5); insert into bfv_planner_t2 values(3,1), (4,2), (5,2); select count(*) from @@ -363,6 +362,8 @@ join (select f,g from bfv_planner_t2) T2 on T1.a=T2.g and T1.c=T2.f; +NOTICE: One or more columns in the following table(s) do not have statistics: bfv_planner_t2 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. count ------- 2 @@ -434,7 +435,7 @@ where x.a + y.a > random(); Join Filter: (((generate_series_1.generate_series + generate_series.generate_series))::double precision > random()) -> Function Scan on generate_series generate_series_1 -> Function Scan on generate_series - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) ---- sublink & subquery @@ -450,28 +451,28 @@ explain (costs off) select * from t_hashdist where a > All (select random() from Filter: ((CASE WHEN (sum((CASE WHEN ((t_hashdist.a)::double precision <= random()) THEN 1 ELSE 0 END)) IS NULL) THEN true WHEN (sum((CASE WHEN (random() IS NULL) THEN 1 ELSE 0 END)) > '0'::bigint) THEN NULL::boolean WHEN ((t_hashdist.a)::double precision IS NULL) THEN NULL::boolean WHEN (sum((CASE WHEN ((t_hashdist.a)::double precision <= random()) THEN 1 ELSE 0 END)) = '0'::bigint) THEN true ELSE false END) = true) -> Aggregate -> Function Scan on generate_series - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) explain (costs off) select * from t_hashdist where a in (select random()::int from generate_series(1, 10)); - QUERY PLAN ----------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join + -> Hash Right Semi Join Hash Cond: (t_hashdist.a = ((random())::integer)) - -> Seq Scan on t_hashdist + -> Redistribute Motion 1:3 (slice2) + Hash Key: ((random())::integer) + -> Function Scan on generate_series -> Hash - -> Redistribute Motion 1:3 (slice2) - Hash Key: ((random())::integer) - -> Function Scan on generate_series - Optimizer: Pivotal Optimizer (GPORCA) + -> Seq Scan on t_hashdist + Optimizer: GPORCA (9 rows) -- subplan explain (costs off, verbose) select * from t_hashdist left join (select a from generate_series(1, 10) a) x on t_hashdist.a > any (select random() from generate_series(1, 10)); - QUERY PLAN ------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: t_hashdist.a, t_hashdist.b, t_hashdist.c, a.a -> Nested Loop Left Join @@ -490,8 +491,8 @@ t_hashdist left join (select a from generate_series(1, 10) a) x on t_hashdist.a -> Function Scan on pg_catalog.generate_series a Output: a.a Function Call: generate_series(1, 10) + Settings: optimizer = 'on', enable_bitmapscan = 'off', enable_seqscan = 'off' Optimizer: Postgres query optimizer - Settings: enable_bitmapscan=off, enable_seqscan=off, optimizer=on (20 rows) -- targetlist @@ -507,7 +508,7 @@ explain (costs off) select * from t_hashdist cross join (select random () from g -> Result One-Time Filter: (gp_execution_segment() = 2) -> Function Scan on generate_series - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) explain (costs off) select * from t_hashdist cross join (select a, sum(random()) from generate_series(1, 10) a group by a) x; @@ -523,7 +524,7 @@ explain (costs off) select * from t_hashdist cross join (select a, sum(random()) -> HashAggregate Group Key: generate_series.generate_series -> Function Scan on generate_series - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) explain (costs off) select * from t_hashdist cross join (select random() as k, sum(a) from generate_series(1, 10) a group by k) x; @@ -540,7 +541,7 @@ explain (costs off) select * from t_hashdist cross join (select random() as k, s -> Materialize -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on t_hashdist - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) explain (costs off) select * from t_hashdist cross join (select a, count(1) as s from generate_series(1, 10) a group by a having count(1) > random() order by a) x ; @@ -555,7 +556,7 @@ explain (costs off) select * from t_hashdist cross join (select a, count(1) as s Group Key: generate_series.generate_series -> Function Scan on generate_series -> Seq Scan on t_hashdist - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) -- limit @@ -568,20 +569,20 @@ explain (costs off) select * from t_hashdist cross join (select * from generate_ -> Seq Scan on t_hashdist -> Limit -> Function Scan on generate_series - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) -- CTAS on general locus into replicated table create temp SEQUENCE test_seq; explain (costs off) create table t_rep as select nextval('test_seq') from (select generate_series(1, 10)) t1 distributed replicated; - QUERY PLAN ---------------------------------------- + QUERY PLAN +-------------------------------------- Result -> Broadcast Motion 1:3 (slice1) -> Result -> ProjectSet -> Result - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (6 rows) create table t_rep1 as select nextval('test_seq') from (select generate_series(1, 10)) t1 distributed replicated; @@ -610,7 +611,7 @@ explain (costs off) create table t_rep as select i from generate_series(5, 15) a Group Key: generate_series -> Result -> Function Scan on generate_series - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) create table t_rep2 as select i from generate_series(5, 15) as i group by i having i < nextval('test_seq') distributed replicated; @@ -640,7 +641,7 @@ explain (costs off) create table t_rep as select i > nextval('test_seq') from ge -> Redistribute Motion 1:3 (slice2) Hash Key: ((generate_series > nextval('test_seq'::regclass))) -> Function Scan on generate_series - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) create table t_rep3 as select i > nextval('test_seq') as a from generate_series(5, 15) as i group by i > nextval('test_seq') distributed replicated; @@ -665,7 +666,7 @@ explain (costs off) create table t_rep as select nextval('test_seq') from rep_tb Result -> Broadcast Motion 1:3 (slice1; segments: 1) -> Seq Scan on rep_tbl - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) create table t_rep4 as select nextval('test_seq') from rep_tbl distributed replicated; @@ -737,25 +738,25 @@ from ) x; QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------- - Finalize Aggregate (cost=60000000416.93..60000000416.94 rows=1 width=8) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=60000000416.88..60000000416.93 rows=3 width=8) - -> Partial Aggregate (cost=60000000416.88..60000000416.89 rows=1 width=8) - -> Append (cost=20000000001.29..60000000391.87 rows=10003 width=0) - -> Subquery Scan on "*SELECT* 1" (cost=20000000001.29..20000000169.80 rows=5000 width=0) - -> Hash Left Join (cost=20000000001.29..20000000119.80 rows=5000 width=16) + Finalize Aggregate (cost=60000000358.91..60000000358.92 rows=1 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=60000000358.85..60000000358.90 rows=3 width=8) + -> Partial Aggregate (cost=60000000358.85..60000000358.86 rows=1 width=8) + -> Append (cost=20000000001.29..60000000333.84 rows=10003 width=0) + -> Subquery Scan on "*SELECT* 1" (cost=20000000001.29..20000000140.80 rows=5000 width=0) + -> Hash Left Join (cost=20000000001.29..20000000115.80 rows=5000 width=16) Hash Cond: (t1_12146.b = t3_12146.b) - -> Seq Scan on t1_12146 (cost=10000000000.00..10000000056.00 rows=5000 width=4) + -> Seq Scan on t1_12146 (cost=10000000000.00..10000000052.00 rows=5000 width=4) -> Hash (cost=10000000001.17..10000000001.17 rows=10 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=10000000000.00..10000000001.17 rows=10 width=4) -> Seq Scan on t3_12146 (cost=10000000000.00..10000000001.03 rows=3 width=4) - -> Subquery Scan on "*SELECT* 2" (cost=20000000001.29..20000000169.80 rows=5000 width=0) - -> Hash Left Join (cost=20000000001.29..20000000119.80 rows=5000 width=16) + -> Subquery Scan on "*SELECT* 2" (cost=20000000001.29..20000000140.80 rows=5000 width=0) + -> Hash Left Join (cost=20000000001.29..20000000115.80 rows=5000 width=16) Hash Cond: (t2_12146.b = t4_12146.b) - -> Seq Scan on t2_12146 (cost=10000000000.00..10000000056.00 rows=5000 width=4) + -> Seq Scan on t2_12146 (cost=10000000000.00..10000000052.00 rows=5000 width=4) -> Hash (cost=10000000001.17..10000000001.17 rows=10 width=4) -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=10000000000.00..10000000001.17 rows=10 width=4) -> Seq Scan on t4_12146 (cost=10000000000.00..10000000001.03 rows=3 width=4) - -> Subquery Scan on "*SELECT* 3" (cost=20000000001.08..20000000002.25 rows=3 width=0) + -> Subquery Scan on "*SELECT* 3" (cost=20000000001.08..20000000002.23 rows=3 width=0) -> Hash Join (cost=20000000001.08..20000000002.22 rows=3 width=16) Hash Cond: (t3_12146_1.b = t4_12146_1.a) -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=10000000000.00..10000000001.10 rows=3 width=4) @@ -810,9 +811,13 @@ reset allow_system_table_mods; -- CREATE TABLE t0_issue_593(c0 bigserial PRIMARY KEY) USING heap WITH (autovacuum_vacuum_threshold=1468046284, autovacuum_analyze_threshold=1889118206, autovacuum_vacuum_cost_delay=9, fillfactor=25, autovacuum_freeze_max_age=1860760049, autovacuum_enabled=0, autovacuum_freeze_min_age=402702412, autovacuum_vacuum_cost_limit=2500); CREATE TABLE IF NOT EXISTS t1_issue_593(LIKE t0_issue_593); +NOTICE: table doesn't have 'DISTRIBUTED BY' clause, defaulting to distribution columns from LIKE table CREATE TABLE IF NOT EXISTS t2_issue_593(LIKE t0_issue_593 INCLUDING INDEXES); +NOTICE: table doesn't have 'DISTRIBUTED BY' clause, defaulting to distribution columns from LIKE table CREATE UNLOGGED TABLE IF NOT EXISTS t3_issue_593(LIKE t2_issue_593); +NOTICE: table doesn't have 'DISTRIBUTED BY' clause, defaulting to distribution columns from LIKE table CREATE TEMPORARY TABLE IF NOT EXISTS t4_issue_593(LIKE t3_issue_593); +NOTICE: table doesn't have 'DISTRIBUTED BY' clause, defaulting to distribution columns from LIKE table SELECT '100.147.127.36' FROM t1_issue_593, ONLY t2_issue_593, t4_issue_593* CROSS JOIN t0_issue_593* CROSS JOIN ONLY t3_issue_593 GROUP BY pg_jit_available() HAVING inet_same_family('148.199.107.23', '214.26.36.61') UNION ALL diff --git a/contrib/pax_storage/src/test/regress/expected/dpe_optimizer.out b/contrib/pax_storage/src/test/regress/expected/dpe_optimizer.out index debb61445a6..7b6124c1d90 100644 --- a/contrib/pax_storage/src/test/regress/expected/dpe_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/dpe_optimizer.out @@ -72,7 +72,11 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'dist' HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into t1 select i, i % 6, 'hello' || i, 'bar' from generate_series(1,2) i; insert into pt1 select * from pt; +NOTICE: One or more columns in the following table(s) do not have statistics: pt +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. insert into pt1 select dist, pt1, pt2, pt3, ptid-100 from pt; +NOTICE: One or more columns in the following table(s) do not have statistics: pt +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. alter table pt1 set with(REORGANIZE=false) DISTRIBUTED RANDOMLY; vacuum analyze pt; analyze pt1; @@ -102,24 +106,24 @@ explain (costs off, timing off, summary off, analyze) select * from t, pt where select * from t, pt where tid = ptid; dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid ------+-----+--------+-----+------+---------+-------+-----------+------ - 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 - 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 + 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 - 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 - 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 - 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 - 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 - 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 - 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 - 0 | 0 | hello0 | bar | 12 | hello12 | world | drop this | 0 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 + 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 + 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 + 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 + 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 + 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 + 0 | 0 | hello0 | bar | 12 | hello12 | world | drop this | 0 0 | 0 | hello0 | bar | 30 | hello30 | world | drop this | 0 0 | 0 | hello0 | bar | 36 | hello36 | world | drop this | 0 - 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 0 | 0 | hello0 | bar | 48 | hello48 | world | drop this | 0 + 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 + 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 + 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 (18 rows) explain (costs off, timing off, summary off, analyze) select * from t, pt where tid + 1 = ptid; @@ -143,24 +147,24 @@ explain (costs off, timing off, summary off, analyze) select * from t, pt where select * from t, pt where tid + 1 = ptid; dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid ------+-----+--------+-----+------+---------+-------+-----------+------ - 0 | 0 | hello0 | bar | 1 | hello1 | world | drop this | 1 - 0 | 0 | hello0 | bar | 7 | hello7 | world | drop this | 1 0 | 0 | hello0 | bar | 13 | hello13 | world | drop this | 1 - 0 | 0 | hello0 | bar | 19 | hello19 | world | drop this | 1 0 | 0 | hello0 | bar | 25 | hello25 | world | drop this | 1 - 0 | 0 | hello0 | bar | 31 | hello31 | world | drop this | 1 - 0 | 0 | hello0 | bar | 37 | hello37 | world | drop this | 1 0 | 0 | hello0 | bar | 43 | hello43 | world | drop this | 1 - 0 | 0 | hello0 | bar | 49 | hello49 | world | drop this | 1 - 1 | 1 | hello1 | bar | 2 | hello2 | world | drop this | 2 - 1 | 1 | hello1 | bar | 8 | hello8 | world | drop this | 2 1 | 1 | hello1 | bar | 14 | hello14 | world | drop this | 2 + 1 | 1 | hello1 | bar | 32 | hello32 | world | drop this | 2 + 0 | 0 | hello0 | bar | 1 | hello1 | world | drop this | 1 + 0 | 0 | hello0 | bar | 31 | hello31 | world | drop this | 1 + 0 | 0 | hello0 | bar | 49 | hello49 | world | drop this | 1 1 | 1 | hello1 | bar | 20 | hello20 | world | drop this | 2 1 | 1 | hello1 | bar | 26 | hello26 | world | drop this | 2 - 1 | 1 | hello1 | bar | 32 | hello32 | world | drop this | 2 1 | 1 | hello1 | bar | 38 | hello38 | world | drop this | 2 1 | 1 | hello1 | bar | 44 | hello44 | world | drop this | 2 1 | 1 | hello1 | bar | 50 | hello50 | world | drop this | 2 + 0 | 0 | hello0 | bar | 7 | hello7 | world | drop this | 1 + 0 | 0 | hello0 | bar | 19 | hello19 | world | drop this | 1 + 0 | 0 | hello0 | bar | 37 | hello37 | world | drop this | 1 + 1 | 1 | hello1 | bar | 2 | hello2 | world | drop this | 2 + 1 | 1 | hello1 | bar | 8 | hello8 | world | drop this | 2 (18 rows) explain (costs off, timing off, summary off, analyze) select * from t, pt where tid = ptid and t1 = 'hello' || tid; @@ -185,38 +189,38 @@ explain (costs off, timing off, summary off, analyze) select * from t, pt where select * from t, pt where tid = ptid and t1 = 'hello' || tid; dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid ------+-----+--------+-----+------+---------+-------+-----------+------ + 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 + 0 | 0 | hello0 | bar | 12 | hello12 | world | drop this | 0 + 0 | 0 | hello0 | bar | 30 | hello30 | world | drop this | 0 + 0 | 0 | hello0 | bar | 36 | hello36 | world | drop this | 0 + 0 | 0 | hello0 | bar | 48 | hello48 | world | drop this | 0 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 - 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 - 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 - 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 - 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 - 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 - 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 - 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 - 0 | 0 | hello0 | bar | 12 | hello12 | world | drop this | 0 + 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 + 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 + 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 - 0 | 0 | hello0 | bar | 30 | hello30 | world | drop this | 0 - 0 | 0 | hello0 | bar | 36 | hello36 | world | drop this | 0 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 - 0 | 0 | hello0 | bar | 48 | hello48 | world | drop this | 0 + 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 + 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 + 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 (18 rows) explain (costs off, timing off, summary off, analyze) select * from t, pt where t1 = pt1 and ptid = tid; - QUERY PLAN ------------------------------------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=2 loops=1) -> Hash Join (actual rows=2 loops=1) Hash Cond: ((pt.pt1 = t.t1) AND (pt.ptid = t.tid)) - Extra Text: ### Hash chain length ###, using ## of ### buckets. + Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 2 of 262144 buckets. -> Dynamic Seq Scan on pt (actual rows=8 loops=1) Number of partitions to scan: 6 (out of 6) Partitions scanned: Avg 2.0 x 3 workers. Max 2 parts (seg0). -> Hash (actual rows=2 loops=1) - Buckets: ### Batches: ### Memory Usage: ###B + Buckets: 262144 Batches: 1 Memory Usage: 2049kB -> Partition Selector (selector id: $0) (actual rows=2 loops=1) -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) -> Seq Scan on t (actual rows=2 loops=1) @@ -255,46 +259,45 @@ explain (costs off, timing off, summary off, analyze) select * from pt where pti select * from pt where ptid in (select tid from t where t1 = 'hello' || tid); dist | pt1 | pt2 | pt3 | ptid ------+---------+-------+-----------+------ + 0 | hello0 | world | drop this | 0 + 12 | hello12 | world | drop this | 0 + 30 | hello30 | world | drop this | 0 + 36 | hello36 | world | drop this | 0 + 48 | hello48 | world | drop this | 0 1 | hello1 | world | drop this | 1 - 7 | hello7 | world | drop this | 1 - 13 | hello13 | world | drop this | 1 - 19 | hello19 | world | drop this | 1 - 25 | hello25 | world | drop this | 1 31 | hello31 | world | drop this | 1 - 37 | hello37 | world | drop this | 1 - 43 | hello43 | world | drop this | 1 49 | hello49 | world | drop this | 1 - 0 | hello0 | world | drop this | 0 6 | hello6 | world | drop this | 0 - 12 | hello12 | world | drop this | 0 + 13 | hello13 | world | drop this | 1 + 25 | hello25 | world | drop this | 1 + 43 | hello43 | world | drop this | 1 18 | hello18 | world | drop this | 0 24 | hello24 | world | drop this | 0 - 30 | hello30 | world | drop this | 0 - 36 | hello36 | world | drop this | 0 42 | hello42 | world | drop this | 0 - 48 | hello48 | world | drop this | 0 + 7 | hello7 | world | drop this | 1 + 19 | hello19 | world | drop this | 1 + 37 | hello37 | world | drop this | 1 (18 rows) explain (costs off, timing off, summary off, analyze) select ptid from pt where ptid in (select tid from t where t1 = 'hello' || tid) and pt1 = 'hello1'; - QUERY PLAN ---------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=1 loops=1) - -> Hash Semi Join (actual rows=1 loops=1) + -> Hash Right Semi Join (actual rows=1 loops=1) Hash Cond: (pt.ptid = t.tid) - Extra Text: ### Hash chain length ###, using ## of ### buckets. - -> Dynamic Index Only Scan on ptid_pt1_idx on pt (actual rows=1 loops=1) - Index Cond: (pt1 = 'hello1'::text) - Heap Fetches: 0 - Number of partitions to scan: 6 (out of 6) - Partitions scanned: Avg 2.0 x 3 workers. Max 2 parts (seg0). - -> Hash (actual rows=2 loops=1) - Buckets: ### Batches: ### Memory Usage: ###B - -> Partition Selector (selector id: $0) (actual rows=2 loops=1) - -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) - -> Seq Scan on t (actual rows=2 loops=1) - Filter: (t1 = ('hello'::text || (tid)::text)) + Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 1 of 524288 buckets. + -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) + -> Seq Scan on t (actual rows=2 loops=1) + Filter: (t1 = ('hello'::text || (tid)::text)) + -> Hash (actual rows=1 loops=1) + Buckets: 524288 Batches: 1 Memory Usage: 4097kB + -> Dynamic Index Only Scan on ptid_pt1_idx on pt (actual rows=1 loops=1) + Index Cond: (pt1 = 'hello1'::text) + Heap Fetches: 0 + Number of partitions to scan: 6 (out of 6) + Partitions scanned: Avg 6.0 x 3 workers. Max 6 parts (seg0). Optimizer: GPORCA -(16 rows) +(15 rows) select ptid from pt where ptid in (select tid from t where t1 = 'hello' || tid) and pt1 = 'hello1'; ptid @@ -336,24 +339,24 @@ explain (costs off, timing off, summary off, analyze) select * from pt where exi select * from pt where exists (select 1 from t where tid = ptid and t1 = 'hello' || tid); dist | pt1 | pt2 | pt3 | ptid ------+---------+-------+-----------+------ - 49 | hello49 | world | drop this | 1 - 43 | hello43 | world | drop this | 1 - 37 | hello37 | world | drop this | 1 - 31 | hello31 | world | drop this | 1 - 25 | hello25 | world | drop this | 1 - 19 | hello19 | world | drop this | 1 - 13 | hello13 | world | drop this | 1 - 7 | hello7 | world | drop this | 1 - 1 | hello1 | world | drop this | 1 - 48 | hello48 | world | drop this | 0 - 42 | hello42 | world | drop this | 0 - 36 | hello36 | world | drop this | 0 + 0 | hello0 | world | drop this | 0 + 12 | hello12 | world | drop this | 0 30 | hello30 | world | drop this | 0 - 24 | hello24 | world | drop this | 0 + 36 | hello36 | world | drop this | 0 + 48 | hello48 | world | drop this | 0 + 1 | hello1 | world | drop this | 1 + 31 | hello31 | world | drop this | 1 + 49 | hello49 | world | drop this | 1 18 | hello18 | world | drop this | 0 - 12 | hello12 | world | drop this | 0 + 24 | hello24 | world | drop this | 0 + 42 | hello42 | world | drop this | 0 + 7 | hello7 | world | drop this | 1 + 19 | hello19 | world | drop this | 1 + 37 | hello37 | world | drop this | 1 6 | hello6 | world | drop this | 0 - 0 | hello0 | world | drop this | 0 + 13 | hello13 | world | drop this | 1 + 25 | hello25 | world | drop this | 1 + 43 | hello43 | world | drop this | 1 (18 rows) -- enable xform @@ -402,7 +405,7 @@ explain (costs off, timing off, summary off, analyze) select *, rank() over (ord Merge Key: pt.ptid, pt.pt1 -> Sort (actual rows=8 loops=1) Sort Key: pt.ptid, pt.pt1 - Sort Method: quicksort Memory: 76kB + Sort Method: quicksort Memory: 75kB -> Hash Join (actual rows=8 loops=1) Hash Cond: (pt.ptid = t.tid) Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 2 of 131072 buckets. @@ -480,42 +483,42 @@ select * from t, pt where tid = ptid select * from t, pt where tid + 2 = ptid; dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid ------+-----+--------+-----+------+---------+-------+-----------+------ - 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 + 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 + 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 + 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 - 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 - 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 - 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 - 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 - 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 + 0 | 0 | hello0 | bar | 2 | hello2 | world | drop this | 2 + 0 | 0 | hello0 | bar | 8 | hello8 | world | drop this | 2 1 | 1 | hello1 | bar | 3 | hello3 | world | drop this | 3 - 1 | 1 | hello1 | bar | 9 | hello9 | world | drop this | 3 - 1 | 1 | hello1 | bar | 15 | hello15 | world | drop this | 3 - 1 | 1 | hello1 | bar | 21 | hello21 | world | drop this | 3 1 | 1 | hello1 | bar | 27 | hello27 | world | drop this | 3 - 1 | 1 | hello1 | bar | 33 | hello33 | world | drop this | 3 1 | 1 | hello1 | bar | 39 | hello39 | world | drop this | 3 1 | 1 | hello1 | bar | 45 | hello45 | world | drop this | 3 1 | 1 | hello1 | bar | 51 | hello51 | world | drop this | 3 - 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 + 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 + 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 + 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 + 0 | 0 | hello0 | bar | 14 | hello14 | world | drop this | 2 + 0 | 0 | hello0 | bar | 32 | hello32 | world | drop this | 2 + 1 | 1 | hello1 | bar | 9 | hello9 | world | drop this | 3 + 1 | 1 | hello1 | bar | 21 | hello21 | world | drop this | 3 + 1 | 1 | hello1 | bar | 33 | hello33 | world | drop this | 3 + 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 0 | 0 | hello0 | bar | 12 | hello12 | world | drop this | 0 - 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 - 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 0 | 0 | hello0 | bar | 30 | hello30 | world | drop this | 0 0 | 0 | hello0 | bar | 36 | hello36 | world | drop this | 0 - 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 0 | 0 | hello0 | bar | 48 | hello48 | world | drop this | 0 - 0 | 0 | hello0 | bar | 2 | hello2 | world | drop this | 2 - 0 | 0 | hello0 | bar | 8 | hello8 | world | drop this | 2 - 0 | 0 | hello0 | bar | 14 | hello14 | world | drop this | 2 + 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 + 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 + 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 0 | 0 | hello0 | bar | 20 | hello20 | world | drop this | 2 0 | 0 | hello0 | bar | 26 | hello26 | world | drop this | 2 - 0 | 0 | hello0 | bar | 32 | hello32 | world | drop this | 2 0 | 0 | hello0 | bar | 38 | hello38 | world | drop this | 2 0 | 0 | hello0 | bar | 44 | hello44 | world | drop this | 2 0 | 0 | hello0 | bar | 50 | hello50 | world | drop this | 2 + 1 | 1 | hello1 | bar | 15 | hello15 | world | drop this | 3 (36 rows) -- @@ -594,24 +597,24 @@ explain (costs off, timing off, summary off, analyze) select * from t, pt where select * from t, pt where tid = ptid; dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid ------+-----+--------+-----+------+---------+-------+-----------+------ + 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 + 0 | 0 | hello0 | bar | 12 | hello12 | world | drop this | 0 + 0 | 0 | hello0 | bar | 30 | hello30 | world | drop this | 0 + 0 | 0 | hello0 | bar | 36 | hello36 | world | drop this | 0 + 0 | 0 | hello0 | bar | 48 | hello48 | world | drop this | 0 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 - 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 - 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 - 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 - 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 - 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 - 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 - 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 - 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 - 0 | 0 | hello0 | bar | 12 | hello12 | world | drop this | 0 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 - 0 | 0 | hello0 | bar | 30 | hello30 | world | drop this | 0 - 0 | 0 | hello0 | bar | 36 | hello36 | world | drop this | 0 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 - 0 | 0 | hello0 | bar | 48 | hello48 | world | drop this | 0 + 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 + 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 + 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 + 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 + 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 + 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 + 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 (18 rows) -- @@ -626,15 +629,15 @@ set enable_hashjoin=off; -- Known_opt_diff: MPP-21322 -- end_ignore explain (costs off, timing off, summary off, analyze) select * from t, pt where tid = ptid and pt1 = 'hello0'; - QUERY PLAN ------------------------------------------------------------------------------------------ + QUERY PLAN +-------------------------------------------------------------------------------------- Hash Join (actual rows=1 loops=1) Hash Cond: (t.tid = pt.ptid) - Extra Text: Hash chain length ###, using ## of ### buckets. + Extra Text: Hash chain length 1.0 avg, 1 max, using 1 of 262144 buckets. -> Gather Motion 3:1 (slice1; segments: 3) (actual rows=2 loops=1) -> Seq Scan on t (actual rows=2 loops=1) -> Hash (actual rows=1 loops=1) - Buckets: ### Batches: ### Memory Usage: ###B + Buckets: 262144 Batches: 1 Memory Usage: 2049kB -> Gather Motion 3:1 (slice2; segments: 3) (actual rows=1 loops=1) -> Dynamic Bitmap Heap Scan on pt (actual rows=1 loops=1) Number of partitions to scan: 6 (out of 6) @@ -681,24 +684,24 @@ explain (costs off, timing off, summary off, analyze) select * from t, pt where select * from t, pt where tid = ptid; dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid ------+-----+--------+-----+------+---------+-------+-----------+------ - 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 + 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 + 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 + 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 - 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 - 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 - 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 - 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 - 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 - 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 0 | 0 | hello0 | bar | 12 | hello12 | world | drop this | 0 - 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 - 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 0 | 0 | hello0 | bar | 30 | hello30 | world | drop this | 0 0 | 0 | hello0 | bar | 36 | hello36 | world | drop this | 0 - 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 0 | 0 | hello0 | bar | 48 | hello48 | world | drop this | 0 + 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 + 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 + 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 + 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 + 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 + 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 + 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 (18 rows) -- @@ -730,8 +733,8 @@ explain (costs off, timing off, summary off, analyze) select * from t, pt where select * from t, pt where t1 = pt1; dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid ------+-----+--------+-----+------+--------+-------+-----------+------ - 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 + 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 (2 rows) explain (costs off, timing off, summary off, analyze) select * from t, pt where tid < ptid; @@ -752,87 +755,87 @@ explain (costs off, timing off, summary off, analyze) select * from t, pt where select * from t, pt where tid < ptid; dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid ------+-----+--------+-----+------+---------+-------+-----------+------ - 1 | 1 | hello1 | bar | 2 | hello2 | world | drop this | 2 + 0 | 0 | hello0 | bar | 7 | hello7 | world | drop this | 1 + 0 | 0 | hello0 | bar | 19 | hello19 | world | drop this | 1 + 0 | 0 | hello0 | bar | 37 | hello37 | world | drop this | 1 0 | 0 | hello0 | bar | 2 | hello2 | world | drop this | 2 - 1 | 1 | hello1 | bar | 8 | hello8 | world | drop this | 2 0 | 0 | hello0 | bar | 8 | hello8 | world | drop this | 2 - 1 | 1 | hello1 | bar | 14 | hello14 | world | drop this | 2 - 0 | 0 | hello0 | bar | 14 | hello14 | world | drop this | 2 - 1 | 1 | hello1 | bar | 20 | hello20 | world | drop this | 2 + 0 | 0 | hello0 | bar | 3 | hello3 | world | drop this | 3 + 0 | 0 | hello0 | bar | 27 | hello27 | world | drop this | 3 + 0 | 0 | hello0 | bar | 39 | hello39 | world | drop this | 3 + 0 | 0 | hello0 | bar | 45 | hello45 | world | drop this | 3 + 0 | 0 | hello0 | bar | 51 | hello51 | world | drop this | 3 + 0 | 0 | hello0 | bar | 4 | hello4 | world | drop this | 4 + 0 | 0 | hello0 | bar | 16 | hello16 | world | drop this | 4 + 0 | 0 | hello0 | bar | 22 | hello22 | world | drop this | 4 + 0 | 0 | hello0 | bar | 34 | hello34 | world | drop this | 4 + 0 | 0 | hello0 | bar | 29 | hello29 | world | drop this | 5 + 0 | 0 | hello0 | bar | 41 | hello41 | world | drop this | 5 + 0 | 0 | hello0 | bar | 53 | hello53 | world | drop this | 5 + 1 | 1 | hello1 | bar | 2 | hello2 | world | drop this | 2 + 1 | 1 | hello1 | bar | 8 | hello8 | world | drop this | 2 + 1 | 1 | hello1 | bar | 3 | hello3 | world | drop this | 3 + 1 | 1 | hello1 | bar | 27 | hello27 | world | drop this | 3 + 1 | 1 | hello1 | bar | 39 | hello39 | world | drop this | 3 + 1 | 1 | hello1 | bar | 45 | hello45 | world | drop this | 3 + 1 | 1 | hello1 | bar | 51 | hello51 | world | drop this | 3 + 1 | 1 | hello1 | bar | 4 | hello4 | world | drop this | 4 + 1 | 1 | hello1 | bar | 16 | hello16 | world | drop this | 4 + 1 | 1 | hello1 | bar | 22 | hello22 | world | drop this | 4 + 1 | 1 | hello1 | bar | 34 | hello34 | world | drop this | 4 + 1 | 1 | hello1 | bar | 29 | hello29 | world | drop this | 5 + 1 | 1 | hello1 | bar | 41 | hello41 | world | drop this | 5 + 1 | 1 | hello1 | bar | 53 | hello53 | world | drop this | 5 + 0 | 0 | hello0 | bar | 1 | hello1 | world | drop this | 1 + 0 | 0 | hello0 | bar | 31 | hello31 | world | drop this | 1 + 0 | 0 | hello0 | bar | 49 | hello49 | world | drop this | 1 0 | 0 | hello0 | bar | 20 | hello20 | world | drop this | 2 - 1 | 1 | hello1 | bar | 26 | hello26 | world | drop this | 2 0 | 0 | hello0 | bar | 26 | hello26 | world | drop this | 2 - 1 | 1 | hello1 | bar | 32 | hello32 | world | drop this | 2 - 0 | 0 | hello0 | bar | 32 | hello32 | world | drop this | 2 - 1 | 1 | hello1 | bar | 38 | hello38 | world | drop this | 2 0 | 0 | hello0 | bar | 38 | hello38 | world | drop this | 2 - 1 | 1 | hello1 | bar | 44 | hello44 | world | drop this | 2 0 | 0 | hello0 | bar | 44 | hello44 | world | drop this | 2 - 1 | 1 | hello1 | bar | 50 | hello50 | world | drop this | 2 0 | 0 | hello0 | bar | 50 | hello50 | world | drop this | 2 - 1 | 1 | hello1 | bar | 4 | hello4 | world | drop this | 4 - 0 | 0 | hello0 | bar | 4 | hello4 | world | drop this | 4 - 1 | 1 | hello1 | bar | 10 | hello10 | world | drop this | 4 - 0 | 0 | hello0 | bar | 10 | hello10 | world | drop this | 4 - 1 | 1 | hello1 | bar | 16 | hello16 | world | drop this | 4 - 0 | 0 | hello0 | bar | 16 | hello16 | world | drop this | 4 - 1 | 1 | hello1 | bar | 22 | hello22 | world | drop this | 4 - 0 | 0 | hello0 | bar | 22 | hello22 | world | drop this | 4 - 1 | 1 | hello1 | bar | 28 | hello28 | world | drop this | 4 - 0 | 0 | hello0 | bar | 28 | hello28 | world | drop this | 4 - 1 | 1 | hello1 | bar | 34 | hello34 | world | drop this | 4 - 0 | 0 | hello0 | bar | 34 | hello34 | world | drop this | 4 - 1 | 1 | hello1 | bar | 40 | hello40 | world | drop this | 4 + 0 | 0 | hello0 | bar | 15 | hello15 | world | drop this | 3 0 | 0 | hello0 | bar | 40 | hello40 | world | drop this | 4 - 1 | 1 | hello1 | bar | 46 | hello46 | world | drop this | 4 0 | 0 | hello0 | bar | 46 | hello46 | world | drop this | 4 - 1 | 1 | hello1 | bar | 52 | hello52 | world | drop this | 4 - 0 | 0 | hello0 | bar | 52 | hello52 | world | drop this | 4 - 1 | 1 | hello1 | bar | 5 | hello5 | world | drop this | 5 - 0 | 0 | hello0 | bar | 5 | hello5 | world | drop this | 5 - 1 | 1 | hello1 | bar | 11 | hello11 | world | drop this | 5 - 0 | 0 | hello0 | bar | 11 | hello11 | world | drop this | 5 - 1 | 1 | hello1 | bar | 17 | hello17 | world | drop this | 5 - 0 | 0 | hello0 | bar | 17 | hello17 | world | drop this | 5 - 1 | 1 | hello1 | bar | 23 | hello23 | world | drop this | 5 0 | 0 | hello0 | bar | 23 | hello23 | world | drop this | 5 - 1 | 1 | hello1 | bar | 29 | hello29 | world | drop this | 5 - 0 | 0 | hello0 | bar | 29 | hello29 | world | drop this | 5 - 1 | 1 | hello1 | bar | 35 | hello35 | world | drop this | 5 0 | 0 | hello0 | bar | 35 | hello35 | world | drop this | 5 - 1 | 1 | hello1 | bar | 41 | hello41 | world | drop this | 5 - 0 | 0 | hello0 | bar | 41 | hello41 | world | drop this | 5 - 1 | 1 | hello1 | bar | 47 | hello47 | world | drop this | 5 0 | 0 | hello0 | bar | 47 | hello47 | world | drop this | 5 - 1 | 1 | hello1 | bar | 53 | hello53 | world | drop this | 5 - 0 | 0 | hello0 | bar | 53 | hello53 | world | drop this | 5 - 0 | 0 | hello0 | bar | 1 | hello1 | world | drop this | 1 - 0 | 0 | hello0 | bar | 7 | hello7 | world | drop this | 1 + 1 | 1 | hello1 | bar | 20 | hello20 | world | drop this | 2 + 1 | 1 | hello1 | bar | 26 | hello26 | world | drop this | 2 + 1 | 1 | hello1 | bar | 38 | hello38 | world | drop this | 2 + 1 | 1 | hello1 | bar | 44 | hello44 | world | drop this | 2 + 1 | 1 | hello1 | bar | 50 | hello50 | world | drop this | 2 + 1 | 1 | hello1 | bar | 15 | hello15 | world | drop this | 3 + 1 | 1 | hello1 | bar | 40 | hello40 | world | drop this | 4 + 1 | 1 | hello1 | bar | 46 | hello46 | world | drop this | 4 + 1 | 1 | hello1 | bar | 23 | hello23 | world | drop this | 5 + 1 | 1 | hello1 | bar | 35 | hello35 | world | drop this | 5 + 1 | 1 | hello1 | bar | 47 | hello47 | world | drop this | 5 0 | 0 | hello0 | bar | 13 | hello13 | world | drop this | 1 - 0 | 0 | hello0 | bar | 19 | hello19 | world | drop this | 1 0 | 0 | hello0 | bar | 25 | hello25 | world | drop this | 1 - 0 | 0 | hello0 | bar | 31 | hello31 | world | drop this | 1 - 0 | 0 | hello0 | bar | 37 | hello37 | world | drop this | 1 0 | 0 | hello0 | bar | 43 | hello43 | world | drop this | 1 - 0 | 0 | hello0 | bar | 49 | hello49 | world | drop this | 1 - 1 | 1 | hello1 | bar | 3 | hello3 | world | drop this | 3 - 0 | 0 | hello0 | bar | 3 | hello3 | world | drop this | 3 - 1 | 1 | hello1 | bar | 9 | hello9 | world | drop this | 3 + 0 | 0 | hello0 | bar | 14 | hello14 | world | drop this | 2 + 0 | 0 | hello0 | bar | 32 | hello32 | world | drop this | 2 0 | 0 | hello0 | bar | 9 | hello9 | world | drop this | 3 - 1 | 1 | hello1 | bar | 15 | hello15 | world | drop this | 3 - 0 | 0 | hello0 | bar | 15 | hello15 | world | drop this | 3 - 1 | 1 | hello1 | bar | 21 | hello21 | world | drop this | 3 0 | 0 | hello0 | bar | 21 | hello21 | world | drop this | 3 - 1 | 1 | hello1 | bar | 27 | hello27 | world | drop this | 3 - 0 | 0 | hello0 | bar | 27 | hello27 | world | drop this | 3 - 1 | 1 | hello1 | bar | 33 | hello33 | world | drop this | 3 0 | 0 | hello0 | bar | 33 | hello33 | world | drop this | 3 - 1 | 1 | hello1 | bar | 39 | hello39 | world | drop this | 3 - 0 | 0 | hello0 | bar | 39 | hello39 | world | drop this | 3 - 1 | 1 | hello1 | bar | 45 | hello45 | world | drop this | 3 - 0 | 0 | hello0 | bar | 45 | hello45 | world | drop this | 3 - 1 | 1 | hello1 | bar | 51 | hello51 | world | drop this | 3 - 0 | 0 | hello0 | bar | 51 | hello51 | world | drop this | 3 + 0 | 0 | hello0 | bar | 10 | hello10 | world | drop this | 4 + 0 | 0 | hello0 | bar | 28 | hello28 | world | drop this | 4 + 0 | 0 | hello0 | bar | 52 | hello52 | world | drop this | 4 + 0 | 0 | hello0 | bar | 5 | hello5 | world | drop this | 5 + 0 | 0 | hello0 | bar | 11 | hello11 | world | drop this | 5 + 0 | 0 | hello0 | bar | 17 | hello17 | world | drop this | 5 + 1 | 1 | hello1 | bar | 14 | hello14 | world | drop this | 2 + 1 | 1 | hello1 | bar | 32 | hello32 | world | drop this | 2 + 1 | 1 | hello1 | bar | 9 | hello9 | world | drop this | 3 + 1 | 1 | hello1 | bar | 21 | hello21 | world | drop this | 3 + 1 | 1 | hello1 | bar | 33 | hello33 | world | drop this | 3 + 1 | 1 | hello1 | bar | 10 | hello10 | world | drop this | 4 + 1 | 1 | hello1 | bar | 28 | hello28 | world | drop this | 4 + 1 | 1 | hello1 | bar | 52 | hello52 | world | drop this | 4 + 1 | 1 | hello1 | bar | 5 | hello5 | world | drop this | 5 + 1 | 1 | hello1 | bar | 11 | hello11 | world | drop this | 5 + 1 | 1 | hello1 | bar | 17 | hello17 | world | drop this | 5 (81 rows) reset enable_indexscan; @@ -947,15 +950,15 @@ explain (costs off, timing off, summary off, analyze) select * from t, t1, pt wh select * from t, t1, pt where t1.tid = ptid and t.tid = ptid; dist | tid | t1 | t2 | dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid ------+-----+--------+-----+------+-----+--------+-----+------+---------+-------+-----------+------ - 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 - 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 + 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 + 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 + 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 - 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 - 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 + 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 + 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 - 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 - 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 - 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 + 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 + 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 (9 rows) rollback; @@ -1042,8 +1045,8 @@ select * from pt, pt1 where pt.ptid = pt1.ptid and pt.pt1 = 'hello0' order by pt (9 rows) explain (costs off, timing off, summary off, analyze) select count(*) from pt, pt1 where pt.ptid = pt1.ptid and pt.pt1 = 'hello0'; - QUERY PLAN --------------------------------------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- Finalize Aggregate (actual rows=1 loops=1) -> Gather Motion 3:1 (slice1; segments: 3) (actual rows=3 loops=1) -> Partial Aggregate (actual rows=1 loops=1) @@ -1111,11 +1114,11 @@ explain (costs off, timing off, summary off, analyze) select * from t, pt where select * from t, pt where a = b; id | a | id | b ----+---+----+--- - 0 | 0 | 0 | 0 - 1 | 1 | 1 | 1 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 + 0 | 0 | 0 | 0 + 1 | 1 | 1 | 1 (5 rows) rollback; @@ -1209,10 +1212,10 @@ explain (costs off, timing off, summary off, analyze) select * from dim1 inner j Merge Key: fact1.u -> Sort (actual rows=50 loops=1) Sort Key: fact1.u - Sort Method: quicksort Memory: 79kB + Sort Method: quicksort Memory: 78kB -> Hash Join (actual rows=50 loops=1) Hash Cond: ((fact1.pid = dim1.pid) AND (fact1.code = dim1.code)) - Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 262144 buckets. + Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 131072 buckets. -> Append (actual rows=200 loops=1) -> Seq Scan on fact1_1_prt_1_2_prt_ca fact1_1 (actual rows=25 loops=1) -> Seq Scan on fact1_1_prt_1_2_prt_oh fact1_2 (actual rows=25 loops=1) @@ -1227,7 +1230,7 @@ explain (costs off, timing off, summary off, analyze) select * from dim1 inner j -> Seq Scan on fact1_1_prt_4_2_prt_oh fact1_11 (actual rows=25 loops=1) -> Seq Scan on fact1_1_prt_4_2_prt_wa fact1_12 (actual rows=0 loops=1) -> Hash (actual rows=3 loops=1) - Buckets: 262144 Batches: 1 Memory Usage: 2049kB + Buckets: 131072 Batches: 1 Memory Usage: 1025kB -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=3 loops=1) -> Seq Scan on dim1 (actual rows=3 loops=1) Optimizer: Postgres query optimizer @@ -1296,7 +1299,7 @@ explain (costs off, timing off, summary off, analyze) select * from dim1 inner j Merge Key: fact1.u -> Sort (actual rows=50 loops=1) Sort Key: fact1.u - Sort Method: quicksort Memory: 158kB + Sort Method: quicksort Memory: 78kB -> Hash Join (actual rows=50 loops=1) Hash Cond: ((fact1.pid = dim1.pid) AND (fact1.code = dim1.code)) Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 131072 buckets. @@ -1320,7 +1323,7 @@ explain (costs off, timing off, summary off, analyze) select * from dim1 inner j -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=3 loops=1) -> Seq Scan on dim1 (actual rows=3 loops=1) Optimizer: Postgres query optimizer -(27 rows) +(28 rows) select * from dim1 inner join fact1 on (dim1.pid=fact1.pid and dim1.code=fact1.code) order by fact1.u; dist | pid | code | t1 | dist | pid | code | u @@ -1388,10 +1391,10 @@ explain (costs off, timing off, summary off, analyze) select * from dim1 inner j Merge Key: fact1.u -> Sort (actual rows=100 loops=1) Sort Key: fact1.u - Sort Method: quicksort Memory: 83kB + Sort Method: quicksort Memory: 81kB -> Hash Join (actual rows=100 loops=1) Hash Cond: (fact1.pid = dim1.pid) - Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 262144 buckets. + Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 131072 buckets. -> Append (actual rows=200 loops=1) -> Seq Scan on fact1_1_prt_1_2_prt_ca fact1_1 (actual rows=25 loops=1) -> Seq Scan on fact1_1_prt_1_2_prt_oh fact1_2 (actual rows=25 loops=1) @@ -1406,7 +1409,7 @@ explain (costs off, timing off, summary off, analyze) select * from dim1 inner j -> Seq Scan on fact1_1_prt_4_2_prt_oh fact1_11 (actual rows=25 loops=1) -> Seq Scan on fact1_1_prt_4_2_prt_wa fact1_12 (actual rows=0 loops=1) -> Hash (actual rows=3 loops=1) - Buckets: 262144 Batches: 1 Memory Usage: 2049kB + Buckets: 131072 Batches: 1 Memory Usage: 1025kB -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=3 loops=1) -> Seq Scan on dim1 (actual rows=3 loops=1) Optimizer: Postgres query optimizer @@ -1525,7 +1528,7 @@ explain (costs off, timing off, summary off, analyze) select * from dim1 inner j Merge Key: fact1.u -> Sort (actual rows=100 loops=1) Sort Key: fact1.u - Sort Method: quicksort Memory: 166kB + Sort Method: quicksort Memory: 81kB -> Hash Join (actual rows=100 loops=1) Hash Cond: (fact1.pid = dim1.pid) Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 131072 buckets. @@ -1544,7 +1547,7 @@ explain (costs off, timing off, summary off, analyze) select * from dim1 inner j -> Seq Scan on fact1_1_prt_4_2_prt_oh fact1_11 (never executed) -> Seq Scan on fact1_1_prt_4_2_prt_wa fact1_12 (never executed) -> Hash (actual rows=3 loops=1) - Buckets: 262144 Batches: 1 Memory Usage: 2049kB + Buckets: 131072 Batches: 1 Memory Usage: 1025kB -> Partition Selector (selector id: $0) (actual rows=3 loops=1) -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=3 loops=1) -> Seq Scan on dim1 (actual rows=3 loops=1) @@ -1682,7 +1685,7 @@ select * from dim1 inner join fact1 on (dim1.dist = fact1.dist and dim1.code=fac -> Seq Scan on fact1_1_prt_4_2_prt_oh fact1_11 (actual rows=25 loops=1) -> Seq Scan on fact1_1_prt_4_2_prt_wa fact1_12 (actual rows=0 loops=1) -> Hash (actual rows=3 loops=1) - Buckets: 524288 Batches: 1 Memory Usage: 4097kB + Buckets: 262144 Batches: 1 Memory Usage: 2049kB -> Seq Scan on dim1 (actual rows=3 loops=1) Optimizer: Postgres query optimizer (21 rows) @@ -1895,8 +1898,8 @@ select * from dim1 inner join fact1 on (dim1.dist = fact1.dist and dim1.code=fac set gp_dynamic_partition_pruning=on; explain (costs off, timing off, summary off, analyze) select * from dim1 inner join fact1 on (dim1.dist = fact1.dist and dim1.code=fact1.code); - QUERY PLAN ----------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=200 loops=1) -> Hash Join (actual rows=200 loops=1) Hash Cond: ((fact1.dist = dim1.dist) AND (fact1.code = dim1.code)) @@ -1920,7 +1923,7 @@ select * from dim1 inner join fact1 on (dim1.dist = fact1.dist and dim1.code=fac -> Partition Selector (selector id: $0) (actual rows=3 loops=1) -> Seq Scan on dim1 (actual rows=3 loops=1) Optimizer: Postgres query optimizer -(22 rows) +(23 rows) select * from dim1 inner join fact1 on (dim1.dist = fact1.dist and dim1.code=fact1.code); dist | pid | code | t1 | dist | pid | code | u @@ -2132,13 +2135,13 @@ select * from dim1 inner join fact1 on (dim1.dist = fact1.dist and dim1.code=fac -- set gp_dynamic_partition_pruning=off; explain (costs off, timing off, summary off, analyze) select * from dim1 inner join fact1 on (dim1.pid=fact1.pid) and fact1.code = 'OH' order by fact1.u; - QUERY PLAN ---------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=50 loops=1) Merge Key: fact1.u -> Sort (actual rows=50 loops=1) Sort Key: fact1.u - Sort Method: quicksort Memory: 158kB + Sort Method: quicksort Memory: 78kB -> Hash Join (actual rows=50 loops=1) Hash Cond: (fact1.pid = dim1.pid) Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 131072 buckets. @@ -2156,7 +2159,7 @@ explain (costs off, timing off, summary off, analyze) select * from dim1 inner j -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=3 loops=1) -> Seq Scan on dim1 (actual rows=3 loops=1) Optimizer: Postgres query optimizer -(21 rows) +(22 rows) select * from dim1 inner join fact1 on (dim1.pid=fact1.pid) and fact1.code = 'OH' order by fact1.u; dist | pid | code | t1 | dist | pid | code | u @@ -2221,7 +2224,7 @@ explain (costs off, timing off, summary off, analyze) select * from dim1 inner j Merge Key: fact1.u -> Sort (actual rows=50 loops=1) Sort Key: fact1.u - Sort Method: quicksort Memory: 158kB + Sort Method: quicksort Memory: 78kB -> Hash Join (actual rows=50 loops=1) Hash Cond: (fact1.pid = dim1.pid) Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 131072 buckets. @@ -2241,7 +2244,7 @@ explain (costs off, timing off, summary off, analyze) select * from dim1 inner j -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=3 loops=1) -> Seq Scan on dim1 (actual rows=3 loops=1) Optimizer: Postgres query optimizer -(23 rows) +(24 rows) select * from dim1 inner join fact1 on (dim1.pid=fact1.pid) and fact1.code = 'OH' order by fact1.u; dist | pid | code | t1 | dist | pid | code | u @@ -2311,7 +2314,7 @@ explain (costs off, timing off, summary off, analyze) select fact1.code, count(* Group Key: fact1.code -> Sort (actual rows=100 loops=1) Sort Key: fact1.code - Sort Method: quicksort Memory: 160kB + Sort Method: quicksort Memory: 76kB -> Redistribute Motion 3:3 (slice2; segments: 3) (actual rows=100 loops=1) Hash Key: fact1.code -> Hash Join (actual rows=100 loops=1) @@ -2331,7 +2334,7 @@ explain (costs off, timing off, summary off, analyze) select fact1.code, count(* -> Seq Scan on fact1_1_prt_4_2_prt_oh fact1_11 (actual rows=25 loops=1) -> Seq Scan on fact1_1_prt_4_2_prt_wa fact1_12 (actual rows=0 loops=1) -> Hash (actual rows=3 loops=1) - Buckets: 524288 Batches: 1 Memory Usage: 4097kB + Buckets: 262144 Batches: 1 Memory Usage: 2049kB -> Broadcast Motion 3:3 (slice3; segments: 3) (actual rows=3 loops=1) -> Seq Scan on dim1 (actual rows=3 loops=1) Optimizer: Postgres query optimizer @@ -2354,7 +2357,7 @@ explain (costs off, timing off, summary off, analyze) select fact1.code, count(* Group Key: fact1.code -> Sort (actual rows=100 loops=1) Sort Key: fact1.code - Sort Method: quicksort Memory: 160kB + Sort Method: quicksort Memory: 76kB -> Redistribute Motion 3:3 (slice2; segments: 3) (actual rows=100 loops=1) Hash Key: fact1.code -> Hash Join (actual rows=100 loops=1) @@ -2375,7 +2378,7 @@ explain (costs off, timing off, summary off, analyze) select fact1.code, count(* -> Seq Scan on fact1_1_prt_4_2_prt_oh fact1_11 (never executed) -> Seq Scan on fact1_1_prt_4_2_prt_wa fact1_12 (never executed) -> Hash (actual rows=3 loops=1) - Buckets: 524288 Batches: 1 Memory Usage: 4097kB + Buckets: 262144 Batches: 1 Memory Usage: 2049kB -> Partition Selector (selector id: $0) (actual rows=3 loops=1) -> Broadcast Motion 3:3 (slice3; segments: 3) (actual rows=3 loops=1) -> Seq Scan on dim1 (actual rows=3 loops=1) @@ -2428,8 +2431,8 @@ analyze dim; -- ORCA doesn't do multi-attribute partitioning currently,so this falls -- back to the Postgres planner explain (costs off, timing off, summary off, analyze) select * from dim inner join malp on (dim.i = malp.i); - QUERY PLAN --------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=3 loops=1) -> Hash Join (actual rows=3 loops=1) Hash Cond: (malp.i = dim.i) @@ -2439,7 +2442,7 @@ explain (costs off, timing off, summary off, analyze) select * from dim inner jo -> Seq Scan on malp_p2 malp_2 (actual rows=0 loops=1) -> Seq Scan on malp_p3 malp_3 (actual rows=0 loops=1) -> Hash (actual rows=1 loops=1) - Buckets: 1048576 Batches: 1 Memory Usage: 8193kB + Buckets: 524288 Batches: 1 Memory Usage: 4097kB -> Redistribute Motion 3:3 (slice2; segments: 3) (actual rows=1 loops=1) Hash Key: dim.i -> Seq Scan on dim (actual rows=1 loops=1) @@ -2521,11 +2524,11 @@ explain (costs off, timing off, summary off, analyze) select * from apart as a, select * from apart as a, b, c where a.t = b.t and a.id = c.id; id | t | id | t | id | t ----+---+----+---+----+--- + 5 | 5 | 5 | 5 | 5 | 5 + 2 | 2 | 2 | 2 | 2 | 2 3 | 3 | 3 | 3 | 3 | 3 4 | 4 | 4 | 4 | 4 | 4 - 5 | 5 | 5 | 5 | 5 | 5 1 | 1 | 1 | 1 | 1 | 1 - 2 | 2 | 2 | 2 | 2 | 2 (5 rows) set gp_dynamic_partition_pruning = on; @@ -2556,11 +2559,11 @@ explain (costs off, timing off, summary off, analyze) select * from apart as a, select * from apart as a, b, c where a.t = b.t and a.id = c.id; id | t | id | t | id | t ----+---+----+---+----+--- + 2 | 2 | 2 | 2 | 2 | 2 3 | 3 | 3 | 3 | 3 | 3 4 | 4 | 4 | 4 | 4 | 4 - 5 | 5 | 5 | 5 | 5 | 5 1 | 1 | 1 | 1 | 1 | 1 - 2 | 2 | 2 | 2 | 2 | 2 + 5 | 5 | 5 | 5 | 5 | 5 (5 rows) -- @@ -2585,6 +2588,8 @@ analyze jpat; -- Known_opt_diff: MPP-21323 -- end_ignore explain (costs off, timing off, summary off, analyze) select * from (select count(*) over (order by a rows between 1 preceding and 1 following), a, b from jpat)jpat inner join pat using(b); +NOTICE: One or more columns in the following table(s) do not have statistics: pat +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN ------------------------------------------------------------------------------------ Hash Join (actual rows=1 loops=1) @@ -2608,6 +2613,8 @@ explain (costs off, timing off, summary off, analyze) select * from (select coun (18 rows) select * from (select count(*) over (order by a rows between 1 preceding and 1 following), a, b from jpat)jpat inner join pat using(b); +NOTICE: One or more columns in the following table(s) do not have statistics: pat +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. b | count | a | a ------------+-------+---+--- 01-02-2010 | 1 | 1 | 1 @@ -2648,8 +2655,8 @@ analyze pt; -- Prune on the simple partition columns, but not on the expression explain (analyze, costs off, timing off, summary off) select * from pt, t where t.id = pt.id; - QUERY PLAN --------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=2 loops=1) -> Hash Join (actual rows=1 loops=1) Hash Cond: (pt.id = t.id) @@ -2666,13 +2673,13 @@ select * from pt, t where t.id = pt.id; -> Partition Selector (selector id: $0) (actual rows=1 loops=1) -> Seq Scan on t (actual rows=1 loops=1) Optimizer: Postgres query optimizer -(15 rows) +(16 rows) insert into t values (4, 4), (6, 6), (8, 8), (10, 10); explain (analyze, costs off, timing off, summary off) select * from pt, t where t.id = pt.id; - QUERY PLAN --------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=4 loops=1) -> Hash Join (actual rows=2 loops=1) Hash Cond: (pt.id = t.id) @@ -2689,14 +2696,14 @@ select * from pt, t where t.id = pt.id; -> Partition Selector (selector id: $0) (actual rows=3 loops=1) -> Seq Scan on t (actual rows=3 loops=1) Optimizer: Postgres query optimizer -(15 rows) +(16 rows) -- Plan-time pruning based on the 'id' partitioning column, and -- run-time join pruning based on the expression explain (analyze, costs off, timing off, summary off) select * from pt, t where pt.id = 4 and t.id = 4 and (t.b % 2) = (pt.b % 2); - QUERY PLAN --------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------- Gather Motion 1:1 (slice1; segments: 1) (actual rows=1 loops=1) -> Hash Join (actual rows=1 loops=1) Hash Cond: ((pt.b % 2) = (t.b % 2)) @@ -2714,14 +2721,14 @@ select * from pt, t where pt.id = 4 and t.id = 4 and (t.b % 2) = (pt.b % 2); Filter: (id = 4) Rows Removed by Filter: 2 Optimizer: Postgres query optimizer -(16 rows) +(17 rows) -- Mixed case insert into pt values (4, 5); explain (analyze, costs off, timing off, summary off) select * from pt, t where t.id = pt.id and (t.b % 2) = (pt.b % 2); - QUERY PLAN --------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=4 loops=1) -> Hash Join (actual rows=2 loops=1) Hash Cond: ((pt.id = t.id) AND ((pt.b % 2) = (t.b % 2))) @@ -2738,7 +2745,7 @@ select * from pt, t where t.id = pt.id and (t.b % 2) = (pt.b % 2); -> Partition Selector (selector id: $0) (actual rows=3 loops=1) -> Seq Scan on t (actual rows=3 loops=1) Optimizer: Postgres query optimizer -(15 rows) +(16 rows) -- -- Join pruning on an inequality qual @@ -2824,7 +2831,7 @@ select * from pt, t where t.dist = pt.dist and t.tid = pt.ptid order by t.tid, t Join Filter: true -> Sort (cost=0.00..431.02 rows=33 width=12) (actual rows=37 loops=1) Sort Key: t.tid, t.sk - Sort Method: quicksort Memory: 79kB + Sort Method: quicksort Memory: 77kB -> Seq Scan on t (cost=0.00..431.00 rows=33 width=12) (actual rows=37 loops=1) -> Dynamic Bitmap Heap Scan on pt (cost=0.00..394.45 rows=1 width=12) (actual rows=0 loops=36) Number of partitions to scan: 6 (out of 6) diff --git a/contrib/pax_storage/src/test/regress/expected/gporca_optimizer.out b/contrib/pax_storage/src/test/regress/expected/gporca_optimizer.out index de85e6ac814..db8002fea03 100644 --- a/contrib/pax_storage/src/test/regress/expected/gporca_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/gporca_optimizer.out @@ -1,6 +1,9 @@ -- -- ORCA tests -- +-- start_ignore +set gp_use_streaming_hashagg = off; +-- end_ignore -- show version SELECT count(*) from gp_opt_version(); count @@ -22,6 +25,10 @@ set optimizer_segments = 3; set optimizer_enable_master_only_queries = on; -- master only tables create schema orca; +-- start_ignore +GRANT ALL ON SCHEMA orca TO PUBLIC; +SET search_path to orca, public; +-- end_ignore create table orca.r(); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause, and no column type is suitable for a distribution key. Creating a NULL policy entry. set allow_system_table_mods=true; @@ -1920,12 +1927,12 @@ select b from orca.r group by b having count(*) > 2; select b from orca.r group by b having count(*) <= avg(a) + (select count(*) from orca.s where s.c = r.b); b --- - 3 + 1 2 + 3 + 4 5 6 - 1 - 4 (6 rows) select sum(a) from orca.r group by b having count(*) > 2 order by b+1; @@ -2167,14 +2174,14 @@ analyze orca.bar2; select x2 from orca.foo where x1 in (select x2 from orca.bar1); x2 ---- - 4 - 6 - 8 - 10 3 + 4 5 - 7 + 8 9 + 6 + 7 + 10 11 (9 rows) @@ -2241,13 +2248,13 @@ select distinct 1, sum(x1) from orca.foo; select distinct x1, rank() over(order by x1) from (select x1 from orca.foo order by x1) x; --order none x1 | rank ----+------ - 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 - 6 | 6 7 | 7 + 1 | 1 + 6 | 6 8 | 8 9 | 9 10 | 10 @@ -2257,30 +2264,30 @@ select distinct x1, sum(x3) from orca.foo group by x1,x2; x1 | sum ----+----- 1 | 3 + 5 | 7 + 6 | 8 + 9 | 11 + 10 | 12 2 | 4 3 | 5 4 | 6 - 5 | 7 - 6 | 8 7 | 9 8 | 10 - 9 | 11 - 10 | 12 (10 rows) select distinct s from (select sum(x2) s from orca.foo group by x1) x; s ---- - 3 - 5 - 7 - 9 - 11 2 + 3 4 - 6 + 7 8 + 5 + 6 + 9 10 + 11 (10 rows) select * from orca.foo a where a.x1 = (select distinct sum(b.x1)+avg(b.x1) sa from orca.bar1 b group by b.x3 order by sa limit 1); @@ -2299,16 +2306,16 @@ select distinct a.x1 from orca.foo a where a.x1 <= (select distinct sum(b.x1)+av select * from orca.foo a where a.x1 = (select distinct b.x1 from orca.bar1 b where b.x1=a.x1 limit 1); x1 | x2 | x3 ----+----+---- - 1 | 2 | 3 - 3 | 4 | 5 5 | 6 | 7 - 7 | 8 | 9 + 6 | 7 | 8 9 | 10 | 11 + 10 | 11 | 12 2 | 3 | 4 + 3 | 4 | 5 4 | 5 | 6 - 6 | 7 | 8 + 7 | 8 | 9 8 | 9 | 10 - 10 | 11 | 12 + 1 | 2 | 3 (10 rows) -- with clause @@ -2316,15 +2323,15 @@ with cte1 as (select * from orca.foo) select a.x1+1 from (select * from cte1) a ?column? ---------- 3 + 4 5 - 7 + 8 9 - 11 2 - 4 6 - 8 + 7 10 + 11 (10 rows) select count(*)+1 from orca.bar1 b where b.x1 < any (with cte1 as (select * from orca.foo) select a.x1+1 from (select * from cte1) a group by a.x1); @@ -2461,31 +2468,31 @@ analyze orca.s; select * from orca.r, orca.s where r.a=s.c; a | b | c | d ---+---+---+--- + 5 | 2 | 5 | 1 + 6 | 0 | 6 | 0 + 5 | 2 | 5 | 0 + 6 | 0 | 6 | 1 + 5 | 2 | 5 | 1 + 6 | 0 | 6 | 0 + 5 | 2 | 5 | 0 + 6 | 0 | 6 | 1 2 | 2 | 2 | 0 + 3 | 0 | 3 | 1 4 | 1 | 4 | 0 - 6 | 0 | 6 | 0 2 | 2 | 2 | 1 + 3 | 0 | 3 | 0 4 | 1 | 4 | 1 - 6 | 0 | 6 | 1 2 | 2 | 2 | 0 + 3 | 0 | 3 | 1 4 | 1 | 4 | 0 - 6 | 0 | 6 | 0 2 | 2 | 2 | 1 + 3 | 0 | 3 | 0 4 | 1 | 4 | 1 - 6 | 0 | 6 | 1 2 | 2 | 2 | 0 1 | 1 | 1 | 1 - 3 | 0 | 3 | 1 - 5 | 2 | 5 | 1 1 | 1 | 1 | 0 - 3 | 0 | 3 | 0 - 5 | 2 | 5 | 0 1 | 1 | 1 | 1 - 3 | 0 | 3 | 1 - 5 | 2 | 5 | 1 1 | 1 | 1 | 0 - 3 | 0 | 3 | 0 - 5 | 2 | 5 | 0 1 | 1 | 1 | 1 (26 rows) @@ -2493,605 +2500,605 @@ select * from orca.r, orca.s where r.a=s.c; select * from orca.r, orca.s where r.as.c; a | b | c | d ----+---+---+--- - 1 | 1 | 1 | 1 - 3 | 0 | 1 | 1 5 | 2 | 1 | 1 - 7 | 1 | 1 | 1 + 6 | 0 | 1 | 1 9 | 0 | 1 | 1 + 10 | 1 | 1 | 1 11 | 2 | 1 | 1 13 | 1 | 1 | 1 - 15 | 0 | 1 | 1 + 14 | 2 | 1 | 1 17 | 2 | 1 | 1 - 19 | 1 | 1 | 1 2 | 2 | 1 | 1 + 3 | 0 | 1 | 1 4 | 1 | 1 | 1 - 6 | 0 | 1 | 1 + 7 | 1 | 1 | 1 8 | 2 | 1 | 1 - 10 | 1 | 1 | 1 - 12 | 0 | 1 | 1 - 14 | 2 | 1 | 1 16 | 1 | 1 | 1 18 | 0 | 1 | 1 + 19 | 1 | 1 | 1 + 1 | 1 | 1 | 1 + 12 | 0 | 1 | 1 + 15 | 0 | 1 | 1 20 | 2 | 1 | 1 - 1 | 1 | 3 | 1 - 3 | 0 | 3 | 1 - 5 | 2 | 3 | 1 - 7 | 1 | 3 | 1 - 9 | 0 | 3 | 1 - 11 | 2 | 3 | 1 - 13 | 1 | 3 | 1 - 15 | 0 | 3 | 1 - 17 | 2 | 3 | 1 - 19 | 1 | 3 | 1 - 2 | 2 | 3 | 1 - 4 | 1 | 3 | 1 - 6 | 0 | 3 | 1 - 8 | 2 | 3 | 1 - 10 | 1 | 3 | 1 - 12 | 0 | 3 | 1 - 14 | 2 | 3 | 1 - 16 | 1 | 3 | 1 - 18 | 0 | 3 | 1 - 20 | 2 | 3 | 1 - 1 | 1 | 5 | 1 - 3 | 0 | 5 | 1 - 5 | 2 | 5 | 1 - 7 | 1 | 5 | 1 - 9 | 0 | 5 | 1 - 11 | 2 | 5 | 1 - 13 | 1 | 5 | 1 - 15 | 0 | 5 | 1 - 17 | 2 | 5 | 1 - 19 | 1 | 5 | 1 - 2 | 2 | 5 | 1 - 4 | 1 | 5 | 1 - 6 | 0 | 5 | 1 - 8 | 2 | 5 | 1 - 10 | 1 | 5 | 1 - 12 | 0 | 5 | 1 - 14 | 2 | 5 | 1 - 16 | 1 | 5 | 1 - 18 | 0 | 5 | 1 - 20 | 2 | 5 | 1 - 1 | 1 | 1 | 0 - 3 | 0 | 1 | 0 + 5 | 2 | 0 | 1 + 6 | 0 | 0 | 1 + 9 | 0 | 0 | 1 + 10 | 1 | 0 | 1 + 11 | 2 | 0 | 1 + 13 | 1 | 0 | 1 + 14 | 2 | 0 | 1 + 17 | 2 | 0 | 1 + 2 | 2 | 0 | 1 + 3 | 0 | 0 | 1 + 4 | 1 | 0 | 1 + 7 | 1 | 0 | 1 + 8 | 2 | 0 | 1 + 16 | 1 | 0 | 1 + 18 | 0 | 0 | 1 + 19 | 1 | 0 | 1 + 1 | 1 | 0 | 1 + 12 | 0 | 0 | 1 + 15 | 0 | 0 | 1 + 20 | 2 | 0 | 1 5 | 2 | 1 | 0 - 7 | 1 | 1 | 0 + 6 | 0 | 1 | 0 9 | 0 | 1 | 0 + 10 | 1 | 1 | 0 11 | 2 | 1 | 0 13 | 1 | 1 | 0 - 15 | 0 | 1 | 0 + 14 | 2 | 1 | 0 17 | 2 | 1 | 0 - 19 | 1 | 1 | 0 2 | 2 | 1 | 0 + 3 | 0 | 1 | 0 4 | 1 | 1 | 0 - 6 | 0 | 1 | 0 + 7 | 1 | 1 | 0 8 | 2 | 1 | 0 - 10 | 1 | 1 | 0 - 12 | 0 | 1 | 0 - 14 | 2 | 1 | 0 16 | 1 | 1 | 0 18 | 0 | 1 | 0 + 19 | 1 | 1 | 0 + 1 | 1 | 1 | 0 + 12 | 0 | 1 | 0 + 15 | 0 | 1 | 0 20 | 2 | 1 | 0 - 1 | 1 | 3 | 0 - 3 | 0 | 3 | 0 - 5 | 2 | 3 | 0 - 7 | 1 | 3 | 0 - 9 | 0 | 3 | 0 - 11 | 2 | 3 | 0 - 13 | 1 | 3 | 0 - 15 | 0 | 3 | 0 - 17 | 2 | 3 | 0 - 19 | 1 | 3 | 0 - 2 | 2 | 3 | 0 - 4 | 1 | 3 | 0 - 6 | 0 | 3 | 0 - 8 | 2 | 3 | 0 - 10 | 1 | 3 | 0 - 12 | 0 | 3 | 0 - 14 | 2 | 3 | 0 - 16 | 1 | 3 | 0 - 18 | 0 | 3 | 0 - 20 | 2 | 3 | 0 - 1 | 1 | 5 | 0 - 3 | 0 | 5 | 0 - 5 | 2 | 5 | 0 - 7 | 1 | 5 | 0 - 9 | 0 | 5 | 0 - 11 | 2 | 5 | 0 - 13 | 1 | 5 | 0 - 15 | 0 | 5 | 0 - 17 | 2 | 5 | 0 - 19 | 1 | 5 | 0 - 2 | 2 | 5 | 0 - 4 | 1 | 5 | 0 - 6 | 0 | 5 | 0 - 8 | 2 | 5 | 0 - 10 | 1 | 5 | 0 - 12 | 0 | 5 | 0 - 14 | 2 | 5 | 0 - 16 | 1 | 5 | 0 - 18 | 0 | 5 | 0 - 20 | 2 | 5 | 0 - 1 | 1 | 1 | 1 - 3 | 0 | 1 | 1 + 5 | 2 | 0 | 0 + 6 | 0 | 0 | 0 + 9 | 0 | 0 | 0 + 10 | 1 | 0 | 0 + 11 | 2 | 0 | 0 + 13 | 1 | 0 | 0 + 14 | 2 | 0 | 0 + 17 | 2 | 0 | 0 + 2 | 2 | 0 | 0 + 3 | 0 | 0 | 0 + 4 | 1 | 0 | 0 + 7 | 1 | 0 | 0 + 8 | 2 | 0 | 0 + 16 | 1 | 0 | 0 + 18 | 0 | 0 | 0 + 19 | 1 | 0 | 0 + 1 | 1 | 0 | 0 + 12 | 0 | 0 | 0 + 15 | 0 | 0 | 0 + 20 | 2 | 0 | 0 5 | 2 | 1 | 1 - 7 | 1 | 1 | 1 + 6 | 0 | 1 | 1 9 | 0 | 1 | 1 + 10 | 1 | 1 | 1 11 | 2 | 1 | 1 13 | 1 | 1 | 1 - 15 | 0 | 1 | 1 + 14 | 2 | 1 | 1 17 | 2 | 1 | 1 - 19 | 1 | 1 | 1 2 | 2 | 1 | 1 + 3 | 0 | 1 | 1 4 | 1 | 1 | 1 - 6 | 0 | 1 | 1 + 7 | 1 | 1 | 1 8 | 2 | 1 | 1 - 10 | 1 | 1 | 1 - 12 | 0 | 1 | 1 - 14 | 2 | 1 | 1 16 | 1 | 1 | 1 18 | 0 | 1 | 1 + 19 | 1 | 1 | 1 + 1 | 1 | 1 | 1 + 12 | 0 | 1 | 1 + 15 | 0 | 1 | 1 20 | 2 | 1 | 1 - 1 | 1 | 3 | 1 - 3 | 0 | 3 | 1 - 5 | 2 | 3 | 1 - 7 | 1 | 3 | 1 - 9 | 0 | 3 | 1 - 11 | 2 | 3 | 1 - 13 | 1 | 3 | 1 - 15 | 0 | 3 | 1 - 17 | 2 | 3 | 1 - 19 | 1 | 3 | 1 - 2 | 2 | 3 | 1 - 4 | 1 | 3 | 1 - 6 | 0 | 3 | 1 - 8 | 2 | 3 | 1 - 10 | 1 | 3 | 1 - 12 | 0 | 3 | 1 - 14 | 2 | 3 | 1 - 16 | 1 | 3 | 1 - 18 | 0 | 3 | 1 - 20 | 2 | 3 | 1 - 1 | 1 | 5 | 1 - 3 | 0 | 5 | 1 - 5 | 2 | 5 | 1 - 7 | 1 | 5 | 1 - 9 | 0 | 5 | 1 - 11 | 2 | 5 | 1 - 13 | 1 | 5 | 1 - 15 | 0 | 5 | 1 - 17 | 2 | 5 | 1 - 19 | 1 | 5 | 1 - 2 | 2 | 5 | 1 - 4 | 1 | 5 | 1 - 6 | 0 | 5 | 1 - 8 | 2 | 5 | 1 - 10 | 1 | 5 | 1 - 12 | 0 | 5 | 1 - 14 | 2 | 5 | 1 - 16 | 1 | 5 | 1 - 18 | 0 | 5 | 1 - 20 | 2 | 5 | 1 - 1 | 1 | 1 | 0 - 3 | 0 | 1 | 0 + 5 | 2 | 0 | 1 + 6 | 0 | 0 | 1 + 9 | 0 | 0 | 1 + 10 | 1 | 0 | 1 + 11 | 2 | 0 | 1 + 13 | 1 | 0 | 1 + 14 | 2 | 0 | 1 + 17 | 2 | 0 | 1 + 2 | 2 | 0 | 1 + 3 | 0 | 0 | 1 + 4 | 1 | 0 | 1 + 7 | 1 | 0 | 1 + 8 | 2 | 0 | 1 + 16 | 1 | 0 | 1 + 18 | 0 | 0 | 1 + 19 | 1 | 0 | 1 + 1 | 1 | 0 | 1 + 12 | 0 | 0 | 1 + 15 | 0 | 0 | 1 + 20 | 2 | 0 | 1 5 | 2 | 1 | 0 - 7 | 1 | 1 | 0 + 6 | 0 | 1 | 0 9 | 0 | 1 | 0 + 10 | 1 | 1 | 0 11 | 2 | 1 | 0 13 | 1 | 1 | 0 - 15 | 0 | 1 | 0 + 14 | 2 | 1 | 0 17 | 2 | 1 | 0 - 19 | 1 | 1 | 0 2 | 2 | 1 | 0 + 3 | 0 | 1 | 0 4 | 1 | 1 | 0 - 6 | 0 | 1 | 0 + 7 | 1 | 1 | 0 8 | 2 | 1 | 0 - 10 | 1 | 1 | 0 - 12 | 0 | 1 | 0 - 14 | 2 | 1 | 0 16 | 1 | 1 | 0 18 | 0 | 1 | 0 + 19 | 1 | 1 | 0 + 1 | 1 | 1 | 0 + 12 | 0 | 1 | 0 + 15 | 0 | 1 | 0 20 | 2 | 1 | 0 - 1 | 1 | 3 | 0 - 3 | 0 | 3 | 0 - 5 | 2 | 3 | 0 - 7 | 1 | 3 | 0 - 9 | 0 | 3 | 0 - 11 | 2 | 3 | 0 - 13 | 1 | 3 | 0 - 15 | 0 | 3 | 0 - 17 | 2 | 3 | 0 - 19 | 1 | 3 | 0 - 2 | 2 | 3 | 0 - 4 | 1 | 3 | 0 - 6 | 0 | 3 | 0 - 8 | 2 | 3 | 0 - 10 | 1 | 3 | 0 - 12 | 0 | 3 | 0 - 14 | 2 | 3 | 0 - 16 | 1 | 3 | 0 - 18 | 0 | 3 | 0 - 20 | 2 | 3 | 0 - 1 | 1 | 5 | 0 - 3 | 0 | 5 | 0 - 5 | 2 | 5 | 0 - 7 | 1 | 5 | 0 - 9 | 0 | 5 | 0 - 11 | 2 | 5 | 0 - 13 | 1 | 5 | 0 - 15 | 0 | 5 | 0 - 17 | 2 | 5 | 0 - 19 | 1 | 5 | 0 - 2 | 2 | 5 | 0 - 4 | 1 | 5 | 0 - 6 | 0 | 5 | 0 - 8 | 2 | 5 | 0 - 10 | 1 | 5 | 0 - 12 | 0 | 5 | 0 - 14 | 2 | 5 | 0 - 16 | 1 | 5 | 0 - 18 | 0 | 5 | 0 - 20 | 2 | 5 | 0 - 1 | 1 | 1 | 1 - 3 | 0 | 1 | 1 + 5 | 2 | 0 | 0 + 6 | 0 | 0 | 0 + 9 | 0 | 0 | 0 + 10 | 1 | 0 | 0 + 11 | 2 | 0 | 0 + 13 | 1 | 0 | 0 + 14 | 2 | 0 | 0 + 17 | 2 | 0 | 0 + 2 | 2 | 0 | 0 + 3 | 0 | 0 | 0 + 4 | 1 | 0 | 0 + 7 | 1 | 0 | 0 + 8 | 2 | 0 | 0 + 16 | 1 | 0 | 0 + 18 | 0 | 0 | 0 + 19 | 1 | 0 | 0 + 1 | 1 | 0 | 0 + 12 | 0 | 0 | 0 + 15 | 0 | 0 | 0 + 20 | 2 | 0 | 0 5 | 2 | 1 | 1 - 7 | 1 | 1 | 1 + 6 | 0 | 1 | 1 9 | 0 | 1 | 1 + 10 | 1 | 1 | 1 11 | 2 | 1 | 1 13 | 1 | 1 | 1 - 15 | 0 | 1 | 1 + 14 | 2 | 1 | 1 17 | 2 | 1 | 1 - 19 | 1 | 1 | 1 2 | 2 | 1 | 1 + 3 | 0 | 1 | 1 4 | 1 | 1 | 1 - 6 | 0 | 1 | 1 + 7 | 1 | 1 | 1 8 | 2 | 1 | 1 - 10 | 1 | 1 | 1 - 12 | 0 | 1 | 1 - 14 | 2 | 1 | 1 16 | 1 | 1 | 1 18 | 0 | 1 | 1 + 19 | 1 | 1 | 1 + 1 | 1 | 1 | 1 + 12 | 0 | 1 | 1 + 15 | 0 | 1 | 1 20 | 2 | 1 | 1 - 1 | 1 | 2 | 0 - 3 | 0 | 2 | 0 - 5 | 2 | 2 | 0 - 7 | 1 | 2 | 0 - 9 | 0 | 2 | 0 - 11 | 2 | 2 | 0 - 13 | 1 | 2 | 0 - 15 | 0 | 2 | 0 - 17 | 2 | 2 | 0 - 19 | 1 | 2 | 0 - 2 | 2 | 2 | 0 - 4 | 1 | 2 | 0 - 6 | 0 | 2 | 0 - 8 | 2 | 2 | 0 - 10 | 1 | 2 | 0 - 12 | 0 | 2 | 0 - 14 | 2 | 2 | 0 - 16 | 1 | 2 | 0 - 18 | 0 | 2 | 0 - 20 | 2 | 2 | 0 - 1 | 1 | 4 | 0 - 3 | 0 | 4 | 0 - 5 | 2 | 4 | 0 - 7 | 1 | 4 | 0 - 9 | 0 | 4 | 0 - 11 | 2 | 4 | 0 - 13 | 1 | 4 | 0 - 15 | 0 | 4 | 0 - 17 | 2 | 4 | 0 - 19 | 1 | 4 | 0 - 2 | 2 | 4 | 0 - 4 | 1 | 4 | 0 - 6 | 0 | 4 | 0 - 8 | 2 | 4 | 0 - 10 | 1 | 4 | 0 - 12 | 0 | 4 | 0 - 14 | 2 | 4 | 0 - 16 | 1 | 4 | 0 - 18 | 0 | 4 | 0 - 20 | 2 | 4 | 0 - 1 | 1 | 6 | 0 - 3 | 0 | 6 | 0 + 5 | 2 | 5 | 1 + 6 | 0 | 5 | 1 + 9 | 0 | 5 | 1 + 10 | 1 | 5 | 1 + 11 | 2 | 5 | 1 + 13 | 1 | 5 | 1 + 14 | 2 | 5 | 1 + 17 | 2 | 5 | 1 + 2 | 2 | 5 | 1 + 3 | 0 | 5 | 1 + 4 | 1 | 5 | 1 + 7 | 1 | 5 | 1 + 8 | 2 | 5 | 1 + 16 | 1 | 5 | 1 + 18 | 0 | 5 | 1 + 19 | 1 | 5 | 1 + 1 | 1 | 5 | 1 + 12 | 0 | 5 | 1 + 15 | 0 | 5 | 1 + 20 | 2 | 5 | 1 5 | 2 | 6 | 0 - 7 | 1 | 6 | 0 + 6 | 0 | 6 | 0 9 | 0 | 6 | 0 + 10 | 1 | 6 | 0 11 | 2 | 6 | 0 13 | 1 | 6 | 0 - 15 | 0 | 6 | 0 + 14 | 2 | 6 | 0 17 | 2 | 6 | 0 - 19 | 1 | 6 | 0 2 | 2 | 6 | 0 + 3 | 0 | 6 | 0 4 | 1 | 6 | 0 - 6 | 0 | 6 | 0 + 7 | 1 | 6 | 0 8 | 2 | 6 | 0 - 10 | 1 | 6 | 0 - 12 | 0 | 6 | 0 - 14 | 2 | 6 | 0 16 | 1 | 6 | 0 18 | 0 | 6 | 0 + 19 | 1 | 6 | 0 + 1 | 1 | 6 | 0 + 12 | 0 | 6 | 0 + 15 | 0 | 6 | 0 20 | 2 | 6 | 0 - 1 | 1 | 0 | 1 - 3 | 0 | 0 | 1 - 5 | 2 | 0 | 1 - 7 | 1 | 0 | 1 - 9 | 0 | 0 | 1 - 11 | 2 | 0 | 1 - 13 | 1 | 0 | 1 - 15 | 0 | 0 | 1 - 17 | 2 | 0 | 1 - 19 | 1 | 0 | 1 - 2 | 2 | 0 | 1 - 4 | 1 | 0 | 1 - 6 | 0 | 0 | 1 - 8 | 2 | 0 | 1 - 10 | 1 | 0 | 1 - 12 | 0 | 0 | 1 - 14 | 2 | 0 | 1 - 16 | 1 | 0 | 1 - 18 | 0 | 0 | 1 - 20 | 2 | 0 | 1 - 1 | 1 | 2 | 1 - 3 | 0 | 2 | 1 - 5 | 2 | 2 | 1 - 7 | 1 | 2 | 1 - 9 | 0 | 2 | 1 - 11 | 2 | 2 | 1 - 13 | 1 | 2 | 1 - 15 | 0 | 2 | 1 - 17 | 2 | 2 | 1 - 19 | 1 | 2 | 1 - 2 | 2 | 2 | 1 - 4 | 1 | 2 | 1 - 6 | 0 | 2 | 1 - 8 | 2 | 2 | 1 - 10 | 1 | 2 | 1 - 12 | 0 | 2 | 1 - 14 | 2 | 2 | 1 - 16 | 1 | 2 | 1 - 18 | 0 | 2 | 1 - 20 | 2 | 2 | 1 - 1 | 1 | 4 | 1 - 3 | 0 | 4 | 1 - 5 | 2 | 4 | 1 - 7 | 1 | 4 | 1 - 9 | 0 | 4 | 1 - 11 | 2 | 4 | 1 - 13 | 1 | 4 | 1 - 15 | 0 | 4 | 1 - 17 | 2 | 4 | 1 - 19 | 1 | 4 | 1 - 2 | 2 | 4 | 1 - 4 | 1 | 4 | 1 - 6 | 0 | 4 | 1 - 8 | 2 | 4 | 1 - 10 | 1 | 4 | 1 - 12 | 0 | 4 | 1 - 14 | 2 | 4 | 1 - 16 | 1 | 4 | 1 - 18 | 0 | 4 | 1 - 20 | 2 | 4 | 1 - 1 | 1 | 6 | 1 - 3 | 0 | 6 | 1 + 5 | 2 | 5 | 0 + 6 | 0 | 5 | 0 + 9 | 0 | 5 | 0 + 10 | 1 | 5 | 0 + 11 | 2 | 5 | 0 + 13 | 1 | 5 | 0 + 14 | 2 | 5 | 0 + 17 | 2 | 5 | 0 + 2 | 2 | 5 | 0 + 3 | 0 | 5 | 0 + 4 | 1 | 5 | 0 + 7 | 1 | 5 | 0 + 8 | 2 | 5 | 0 + 16 | 1 | 5 | 0 + 18 | 0 | 5 | 0 + 19 | 1 | 5 | 0 + 1 | 1 | 5 | 0 + 12 | 0 | 5 | 0 + 15 | 0 | 5 | 0 + 20 | 2 | 5 | 0 5 | 2 | 6 | 1 - 7 | 1 | 6 | 1 + 6 | 0 | 6 | 1 9 | 0 | 6 | 1 + 10 | 1 | 6 | 1 11 | 2 | 6 | 1 13 | 1 | 6 | 1 - 15 | 0 | 6 | 1 + 14 | 2 | 6 | 1 17 | 2 | 6 | 1 - 19 | 1 | 6 | 1 2 | 2 | 6 | 1 + 3 | 0 | 6 | 1 4 | 1 | 6 | 1 - 6 | 0 | 6 | 1 + 7 | 1 | 6 | 1 8 | 2 | 6 | 1 - 10 | 1 | 6 | 1 + 16 | 1 | 6 | 1 + 18 | 0 | 6 | 1 + 19 | 1 | 6 | 1 + 1 | 1 | 6 | 1 12 | 0 | 6 | 1 + 15 | 0 | 6 | 1 + 20 | 2 | 6 | 1 + 5 | 2 | 5 | 1 + 6 | 0 | 5 | 1 + 9 | 0 | 5 | 1 + 10 | 1 | 5 | 1 + 11 | 2 | 5 | 1 + 13 | 1 | 5 | 1 + 14 | 2 | 5 | 1 + 17 | 2 | 5 | 1 + 2 | 2 | 5 | 1 + 3 | 0 | 5 | 1 + 4 | 1 | 5 | 1 + 7 | 1 | 5 | 1 + 8 | 2 | 5 | 1 + 16 | 1 | 5 | 1 + 18 | 0 | 5 | 1 + 19 | 1 | 5 | 1 + 1 | 1 | 5 | 1 + 12 | 0 | 5 | 1 + 15 | 0 | 5 | 1 + 20 | 2 | 5 | 1 + 5 | 2 | 6 | 0 + 6 | 0 | 6 | 0 + 9 | 0 | 6 | 0 + 10 | 1 | 6 | 0 + 11 | 2 | 6 | 0 + 13 | 1 | 6 | 0 + 14 | 2 | 6 | 0 + 17 | 2 | 6 | 0 + 2 | 2 | 6 | 0 + 3 | 0 | 6 | 0 + 4 | 1 | 6 | 0 + 7 | 1 | 6 | 0 + 8 | 2 | 6 | 0 + 16 | 1 | 6 | 0 + 18 | 0 | 6 | 0 + 19 | 1 | 6 | 0 + 1 | 1 | 6 | 0 + 12 | 0 | 6 | 0 + 15 | 0 | 6 | 0 + 20 | 2 | 6 | 0 + 5 | 2 | 5 | 0 + 6 | 0 | 5 | 0 + 9 | 0 | 5 | 0 + 10 | 1 | 5 | 0 + 11 | 2 | 5 | 0 + 13 | 1 | 5 | 0 + 14 | 2 | 5 | 0 + 17 | 2 | 5 | 0 + 2 | 2 | 5 | 0 + 3 | 0 | 5 | 0 + 4 | 1 | 5 | 0 + 7 | 1 | 5 | 0 + 8 | 2 | 5 | 0 + 16 | 1 | 5 | 0 + 18 | 0 | 5 | 0 + 19 | 1 | 5 | 0 + 1 | 1 | 5 | 0 + 12 | 0 | 5 | 0 + 15 | 0 | 5 | 0 + 20 | 2 | 5 | 0 + 5 | 2 | 6 | 1 + 6 | 0 | 6 | 1 + 9 | 0 | 6 | 1 + 10 | 1 | 6 | 1 + 11 | 2 | 6 | 1 + 13 | 1 | 6 | 1 14 | 2 | 6 | 1 + 17 | 2 | 6 | 1 + 2 | 2 | 6 | 1 + 3 | 0 | 6 | 1 + 4 | 1 | 6 | 1 + 7 | 1 | 6 | 1 + 8 | 2 | 6 | 1 16 | 1 | 6 | 1 18 | 0 | 6 | 1 + 19 | 1 | 6 | 1 + 1 | 1 | 6 | 1 + 12 | 0 | 6 | 1 + 15 | 0 | 6 | 1 20 | 2 | 6 | 1 - 1 | 1 | 0 | 0 - 3 | 0 | 0 | 0 - 5 | 2 | 0 | 0 - 7 | 1 | 0 | 0 - 9 | 0 | 0 | 0 - 11 | 2 | 0 | 0 - 13 | 1 | 0 | 0 - 15 | 0 | 0 | 0 - 17 | 2 | 0 | 0 - 19 | 1 | 0 | 0 - 2 | 2 | 0 | 0 - 4 | 1 | 0 | 0 - 6 | 0 | 0 | 0 - 8 | 2 | 0 | 0 - 10 | 1 | 0 | 0 - 12 | 0 | 0 | 0 - 14 | 2 | 0 | 0 - 16 | 1 | 0 | 0 - 18 | 0 | 0 | 0 - 20 | 2 | 0 | 0 - 1 | 1 | 2 | 0 - 3 | 0 | 2 | 0 5 | 2 | 2 | 0 - 7 | 1 | 2 | 0 + 6 | 0 | 2 | 0 9 | 0 | 2 | 0 + 10 | 1 | 2 | 0 11 | 2 | 2 | 0 13 | 1 | 2 | 0 - 15 | 0 | 2 | 0 + 14 | 2 | 2 | 0 17 | 2 | 2 | 0 - 19 | 1 | 2 | 0 2 | 2 | 2 | 0 + 3 | 0 | 2 | 0 4 | 1 | 2 | 0 - 6 | 0 | 2 | 0 + 7 | 1 | 2 | 0 8 | 2 | 2 | 0 - 10 | 1 | 2 | 0 - 12 | 0 | 2 | 0 - 14 | 2 | 2 | 0 16 | 1 | 2 | 0 18 | 0 | 2 | 0 + 19 | 1 | 2 | 0 + 1 | 1 | 2 | 0 + 12 | 0 | 2 | 0 + 15 | 0 | 2 | 0 20 | 2 | 2 | 0 - 1 | 1 | 4 | 0 - 3 | 0 | 4 | 0 + 5 | 2 | 3 | 1 + 6 | 0 | 3 | 1 + 9 | 0 | 3 | 1 + 10 | 1 | 3 | 1 + 11 | 2 | 3 | 1 + 13 | 1 | 3 | 1 + 14 | 2 | 3 | 1 + 17 | 2 | 3 | 1 + 2 | 2 | 3 | 1 + 3 | 0 | 3 | 1 + 4 | 1 | 3 | 1 + 7 | 1 | 3 | 1 + 8 | 2 | 3 | 1 + 16 | 1 | 3 | 1 + 18 | 0 | 3 | 1 + 19 | 1 | 3 | 1 + 1 | 1 | 3 | 1 + 12 | 0 | 3 | 1 + 15 | 0 | 3 | 1 + 20 | 2 | 3 | 1 5 | 2 | 4 | 0 - 7 | 1 | 4 | 0 + 6 | 0 | 4 | 0 9 | 0 | 4 | 0 + 10 | 1 | 4 | 0 11 | 2 | 4 | 0 13 | 1 | 4 | 0 - 15 | 0 | 4 | 0 + 14 | 2 | 4 | 0 17 | 2 | 4 | 0 - 19 | 1 | 4 | 0 2 | 2 | 4 | 0 + 3 | 0 | 4 | 0 4 | 1 | 4 | 0 - 6 | 0 | 4 | 0 + 7 | 1 | 4 | 0 8 | 2 | 4 | 0 - 10 | 1 | 4 | 0 - 12 | 0 | 4 | 0 - 14 | 2 | 4 | 0 16 | 1 | 4 | 0 18 | 0 | 4 | 0 + 19 | 1 | 4 | 0 + 1 | 1 | 4 | 0 + 12 | 0 | 4 | 0 + 15 | 0 | 4 | 0 20 | 2 | 4 | 0 - 1 | 1 | 6 | 0 - 3 | 0 | 6 | 0 - 5 | 2 | 6 | 0 - 7 | 1 | 6 | 0 - 9 | 0 | 6 | 0 - 11 | 2 | 6 | 0 - 13 | 1 | 6 | 0 - 15 | 0 | 6 | 0 - 17 | 2 | 6 | 0 - 19 | 1 | 6 | 0 - 2 | 2 | 6 | 0 - 4 | 1 | 6 | 0 - 6 | 0 | 6 | 0 - 8 | 2 | 6 | 0 - 10 | 1 | 6 | 0 - 12 | 0 | 6 | 0 - 14 | 2 | 6 | 0 - 16 | 1 | 6 | 0 - 18 | 0 | 6 | 0 - 20 | 2 | 6 | 0 - 1 | 1 | 0 | 1 - 3 | 0 | 0 | 1 - 5 | 2 | 0 | 1 - 7 | 1 | 0 | 1 - 9 | 0 | 0 | 1 - 11 | 2 | 0 | 1 - 13 | 1 | 0 | 1 - 15 | 0 | 0 | 1 - 17 | 2 | 0 | 1 - 19 | 1 | 0 | 1 - 2 | 2 | 0 | 1 - 4 | 1 | 0 | 1 - 6 | 0 | 0 | 1 - 8 | 2 | 0 | 1 - 10 | 1 | 0 | 1 - 12 | 0 | 0 | 1 - 14 | 2 | 0 | 1 - 16 | 1 | 0 | 1 - 18 | 0 | 0 | 1 - 20 | 2 | 0 | 1 - 1 | 1 | 2 | 1 - 3 | 0 | 2 | 1 5 | 2 | 2 | 1 - 7 | 1 | 2 | 1 + 6 | 0 | 2 | 1 9 | 0 | 2 | 1 + 10 | 1 | 2 | 1 11 | 2 | 2 | 1 13 | 1 | 2 | 1 - 15 | 0 | 2 | 1 + 14 | 2 | 2 | 1 17 | 2 | 2 | 1 - 19 | 1 | 2 | 1 2 | 2 | 2 | 1 + 3 | 0 | 2 | 1 4 | 1 | 2 | 1 - 6 | 0 | 2 | 1 + 7 | 1 | 2 | 1 8 | 2 | 2 | 1 - 10 | 1 | 2 | 1 - 12 | 0 | 2 | 1 - 14 | 2 | 2 | 1 16 | 1 | 2 | 1 18 | 0 | 2 | 1 + 19 | 1 | 2 | 1 + 1 | 1 | 2 | 1 + 12 | 0 | 2 | 1 + 15 | 0 | 2 | 1 20 | 2 | 2 | 1 - 1 | 1 | 4 | 1 - 3 | 0 | 4 | 1 + 5 | 2 | 3 | 0 + 6 | 0 | 3 | 0 + 9 | 0 | 3 | 0 + 10 | 1 | 3 | 0 + 11 | 2 | 3 | 0 + 13 | 1 | 3 | 0 + 14 | 2 | 3 | 0 + 17 | 2 | 3 | 0 + 2 | 2 | 3 | 0 + 3 | 0 | 3 | 0 + 4 | 1 | 3 | 0 + 7 | 1 | 3 | 0 + 8 | 2 | 3 | 0 + 16 | 1 | 3 | 0 + 18 | 0 | 3 | 0 + 19 | 1 | 3 | 0 + 1 | 1 | 3 | 0 + 12 | 0 | 3 | 0 + 15 | 0 | 3 | 0 + 20 | 2 | 3 | 0 5 | 2 | 4 | 1 - 7 | 1 | 4 | 1 + 6 | 0 | 4 | 1 9 | 0 | 4 | 1 + 10 | 1 | 4 | 1 11 | 2 | 4 | 1 13 | 1 | 4 | 1 - 15 | 0 | 4 | 1 + 14 | 2 | 4 | 1 17 | 2 | 4 | 1 - 19 | 1 | 4 | 1 2 | 2 | 4 | 1 + 3 | 0 | 4 | 1 4 | 1 | 4 | 1 - 6 | 0 | 4 | 1 + 7 | 1 | 4 | 1 8 | 2 | 4 | 1 - 10 | 1 | 4 | 1 - 12 | 0 | 4 | 1 - 14 | 2 | 4 | 1 16 | 1 | 4 | 1 18 | 0 | 4 | 1 + 19 | 1 | 4 | 1 + 1 | 1 | 4 | 1 + 12 | 0 | 4 | 1 + 15 | 0 | 4 | 1 20 | 2 | 4 | 1 - 1 | 1 | 6 | 1 - 3 | 0 | 6 | 1 - 5 | 2 | 6 | 1 - 7 | 1 | 6 | 1 - 9 | 0 | 6 | 1 - 11 | 2 | 6 | 1 - 13 | 1 | 6 | 1 - 15 | 0 | 6 | 1 - 17 | 2 | 6 | 1 - 19 | 1 | 6 | 1 - 2 | 2 | 6 | 1 - 4 | 1 | 6 | 1 - 6 | 0 | 6 | 1 - 8 | 2 | 6 | 1 - 10 | 1 | 6 | 1 - 12 | 0 | 6 | 1 - 14 | 2 | 6 | 1 - 16 | 1 | 6 | 1 - 18 | 0 | 6 | 1 - 20 | 2 | 6 | 1 - 1 | 1 | 0 | 0 - 3 | 0 | 0 | 0 - 5 | 2 | 0 | 0 - 7 | 1 | 0 | 0 - 9 | 0 | 0 | 0 - 11 | 2 | 0 | 0 - 13 | 1 | 0 | 0 - 15 | 0 | 0 | 0 - 17 | 2 | 0 | 0 - 19 | 1 | 0 | 0 - 2 | 2 | 0 | 0 - 4 | 1 | 0 | 0 - 6 | 0 | 0 | 0 - 8 | 2 | 0 | 0 - 10 | 1 | 0 | 0 - 12 | 0 | 0 | 0 - 14 | 2 | 0 | 0 - 16 | 1 | 0 | 0 - 18 | 0 | 0 | 0 - 20 | 2 | 0 | 0 - 1 | 1 | 2 | 0 - 3 | 0 | 2 | 0 5 | 2 | 2 | 0 - 7 | 1 | 2 | 0 + 6 | 0 | 2 | 0 9 | 0 | 2 | 0 + 10 | 1 | 2 | 0 11 | 2 | 2 | 0 13 | 1 | 2 | 0 - 15 | 0 | 2 | 0 + 14 | 2 | 2 | 0 17 | 2 | 2 | 0 - 19 | 1 | 2 | 0 2 | 2 | 2 | 0 + 3 | 0 | 2 | 0 4 | 1 | 2 | 0 - 6 | 0 | 2 | 0 + 7 | 1 | 2 | 0 8 | 2 | 2 | 0 - 10 | 1 | 2 | 0 + 16 | 1 | 2 | 0 + 18 | 0 | 2 | 0 + 19 | 1 | 2 | 0 + 1 | 1 | 2 | 0 12 | 0 | 2 | 0 + 15 | 0 | 2 | 0 + 20 | 2 | 2 | 0 + 5 | 2 | 3 | 1 + 6 | 0 | 3 | 1 + 9 | 0 | 3 | 1 + 10 | 1 | 3 | 1 + 11 | 2 | 3 | 1 + 13 | 1 | 3 | 1 + 14 | 2 | 3 | 1 + 17 | 2 | 3 | 1 + 2 | 2 | 3 | 1 + 3 | 0 | 3 | 1 + 4 | 1 | 3 | 1 + 7 | 1 | 3 | 1 + 8 | 2 | 3 | 1 + 16 | 1 | 3 | 1 + 18 | 0 | 3 | 1 + 19 | 1 | 3 | 1 + 1 | 1 | 3 | 1 + 12 | 0 | 3 | 1 + 15 | 0 | 3 | 1 + 20 | 2 | 3 | 1 + 5 | 2 | 4 | 0 + 6 | 0 | 4 | 0 + 9 | 0 | 4 | 0 + 10 | 1 | 4 | 0 + 11 | 2 | 4 | 0 + 13 | 1 | 4 | 0 + 14 | 2 | 4 | 0 + 17 | 2 | 4 | 0 + 2 | 2 | 4 | 0 + 3 | 0 | 4 | 0 + 4 | 1 | 4 | 0 + 7 | 1 | 4 | 0 + 8 | 2 | 4 | 0 + 16 | 1 | 4 | 0 + 18 | 0 | 4 | 0 + 19 | 1 | 4 | 0 + 1 | 1 | 4 | 0 + 12 | 0 | 4 | 0 + 15 | 0 | 4 | 0 + 20 | 2 | 4 | 0 + 5 | 2 | 2 | 1 + 6 | 0 | 2 | 1 + 9 | 0 | 2 | 1 + 10 | 1 | 2 | 1 + 11 | 2 | 2 | 1 + 13 | 1 | 2 | 1 + 14 | 2 | 2 | 1 + 17 | 2 | 2 | 1 + 2 | 2 | 2 | 1 + 3 | 0 | 2 | 1 + 4 | 1 | 2 | 1 + 7 | 1 | 2 | 1 + 8 | 2 | 2 | 1 + 16 | 1 | 2 | 1 + 18 | 0 | 2 | 1 + 19 | 1 | 2 | 1 + 1 | 1 | 2 | 1 + 12 | 0 | 2 | 1 + 15 | 0 | 2 | 1 + 20 | 2 | 2 | 1 + 5 | 2 | 3 | 0 + 6 | 0 | 3 | 0 + 9 | 0 | 3 | 0 + 10 | 1 | 3 | 0 + 11 | 2 | 3 | 0 + 13 | 1 | 3 | 0 + 14 | 2 | 3 | 0 + 17 | 2 | 3 | 0 + 2 | 2 | 3 | 0 + 3 | 0 | 3 | 0 + 4 | 1 | 3 | 0 + 7 | 1 | 3 | 0 + 8 | 2 | 3 | 0 + 16 | 1 | 3 | 0 + 18 | 0 | 3 | 0 + 19 | 1 | 3 | 0 + 1 | 1 | 3 | 0 + 12 | 0 | 3 | 0 + 15 | 0 | 3 | 0 + 20 | 2 | 3 | 0 + 5 | 2 | 4 | 1 + 6 | 0 | 4 | 1 + 9 | 0 | 4 | 1 + 10 | 1 | 4 | 1 + 11 | 2 | 4 | 1 + 13 | 1 | 4 | 1 + 14 | 2 | 4 | 1 + 17 | 2 | 4 | 1 + 2 | 2 | 4 | 1 + 3 | 0 | 4 | 1 + 4 | 1 | 4 | 1 + 7 | 1 | 4 | 1 + 8 | 2 | 4 | 1 + 16 | 1 | 4 | 1 + 18 | 0 | 4 | 1 + 19 | 1 | 4 | 1 + 1 | 1 | 4 | 1 + 12 | 0 | 4 | 1 + 15 | 0 | 4 | 1 + 20 | 2 | 4 | 1 + 5 | 2 | 2 | 0 + 6 | 0 | 2 | 0 + 9 | 0 | 2 | 0 + 10 | 1 | 2 | 0 + 11 | 2 | 2 | 0 + 13 | 1 | 2 | 0 14 | 2 | 2 | 0 + 17 | 2 | 2 | 0 + 2 | 2 | 2 | 0 + 3 | 0 | 2 | 0 + 4 | 1 | 2 | 0 + 7 | 1 | 2 | 0 + 8 | 2 | 2 | 0 16 | 1 | 2 | 0 18 | 0 | 2 | 0 + 19 | 1 | 2 | 0 + 1 | 1 | 2 | 0 + 12 | 0 | 2 | 0 + 15 | 0 | 2 | 0 20 | 2 | 2 | 0 (600 rows) @@ -3104,36 +3111,26 @@ select r.* from orca.r, orca.s where s.c=2; 2 | 2 2 | 2 2 | 2 + 3 | 0 + 3 | 0 + 3 | 0 + 3 | 0 + 3 | 0 4 | 1 4 | 1 4 | 1 4 | 1 4 | 1 - 6 | 0 - 6 | 0 - 6 | 0 - 6 | 0 - 6 | 0 + 7 | 1 + 7 | 1 + 7 | 1 + 7 | 1 + 7 | 1 8 | 2 8 | 2 8 | 2 8 | 2 8 | 2 - 10 | 1 - 10 | 1 - 10 | 1 - 10 | 1 - 10 | 1 - 12 | 0 - 12 | 0 - 12 | 0 - 12 | 0 - 12 | 0 - 14 | 2 - 14 | 2 - 14 | 2 - 14 | 2 - 14 | 2 16 | 1 16 | 1 16 | 1 @@ -3144,36 +3141,51 @@ select r.* from orca.r, orca.s where s.c=2; 18 | 0 18 | 0 18 | 0 - 20 | 2 - 20 | 2 - 20 | 2 - 20 | 2 - 20 | 2 + 19 | 1 + 19 | 1 + 19 | 1 + 19 | 1 + 19 | 1 1 | 1 1 | 1 1 | 1 1 | 1 1 | 1 - 3 | 0 - 3 | 0 - 3 | 0 - 3 | 0 - 3 | 0 + 12 | 0 + 12 | 0 + 12 | 0 + 12 | 0 + 12 | 0 + 15 | 0 + 15 | 0 + 15 | 0 + 15 | 0 + 15 | 0 + 20 | 2 + 20 | 2 + 20 | 2 + 20 | 2 + 20 | 2 5 | 2 5 | 2 5 | 2 5 | 2 5 | 2 - 7 | 1 - 7 | 1 - 7 | 1 - 7 | 1 - 7 | 1 + 6 | 0 + 6 | 0 + 6 | 0 + 6 | 0 + 6 | 0 9 | 0 9 | 0 9 | 0 9 | 0 9 | 0 + 10 | 1 + 10 | 1 + 10 | 1 + 10 | 1 + 10 | 1 11 | 2 11 | 2 11 | 2 @@ -3184,21 +3196,16 @@ select r.* from orca.r, orca.s where s.c=2; 13 | 1 13 | 1 13 | 1 - 15 | 0 - 15 | 0 - 15 | 0 - 15 | 0 - 15 | 0 + 14 | 2 + 14 | 2 + 14 | 2 + 14 | 2 + 14 | 2 17 | 2 17 | 2 17 | 2 17 | 2 17 | 2 - 19 | 1 - 19 | 1 - 19 | 1 - 19 | 1 - 19 | 1 (100 rows) create table orca.m(); @@ -3221,42 +3228,42 @@ select r.a, s.c from orca.r left outer join orca.s on(r.a=s.c); 2 | 2 2 | 2 2 | 2 + 3 | 3 + 3 | 3 + 3 | 3 + 3 | 3 4 | 4 4 | 4 4 | 4 4 | 4 + 7 | + 8 | + 16 | + 18 | + 19 | + | + 5 | 5 + 5 | 5 + 5 | 5 + 5 | 5 6 | 6 6 | 6 6 | 6 6 | 6 - 8 | + 9 | 10 | - 12 | + 11 | + 13 | 14 | - 16 | - 18 | - 20 | + 17 | 1 | 1 1 | 1 1 | 1 1 | 1 1 | 1 - 3 | 3 - 3 | 3 - 3 | 3 - 3 | 3 - 5 | 5 - 5 | 5 - 5 | 5 - 5 | 5 - 7 | - 9 | - 11 | - 13 | + 12 | 15 | - 17 | - 19 | - | + 20 | (41 rows) select r.a, s.c from orca.r left outer join orca.s on(r.a=s.c and r.a=r.b and s.c=s.d) order by r.a,s.c; @@ -3311,125 +3318,125 @@ select r.a, s.c from orca.r right outer join orca.s on(r.a=s.c); a | c ---+--- 1 | 1 - 3 | 3 - 5 | 5 + | 0 1 | 1 - 3 | 3 - 5 | 5 + | 0 1 | 1 - 3 | 3 - 5 | 5 + | 0 1 | 1 - 3 | 3 - 5 | 5 + | 0 1 | 1 2 | 2 + 3 | 3 4 | 4 - 6 | 6 - | 0 2 | 2 + 3 | 3 4 | 4 - 6 | 6 - | 0 2 | 2 + 3 | 3 4 | 4 - 6 | 6 - | 0 2 | 2 + 3 | 3 4 | 4 - 6 | 6 - | 0 2 | 2 + 5 | 5 + 6 | 6 + 5 | 5 + 6 | 6 + 5 | 5 + 6 | 6 + 5 | 5 + 6 | 6 (30 rows) select * from orca.r where exists (select * from orca.s where s.c=r.a + 2); a | b ---+--- 2 | 2 - 4 | 1 1 | 1 3 | 0 + 4 | 1 (4 rows) select * from orca.r where exists (select * from orca.s where s.c=r.b); a | b ----+--- + 1 | 1 + 12 | 0 15 | 0 + 6 | 0 9 | 0 - 3 | 0 - 17 | 2 - 11 | 2 - 5 | 2 - | 1 - 19 | 1 + 10 | 1 13 | 1 + 3 | 0 + 4 | 1 7 | 1 - 1 | 1 16 | 1 - 10 | 1 - 4 | 1 18 | 0 - 12 | 0 - 6 | 0 + 19 | 1 + | 1 + 2 | 2 + 8 | 2 20 | 2 + 5 | 2 + 11 | 2 14 | 2 - 8 | 2 - 2 | 2 + 17 | 2 (21 rows) select * from orca.m where m.a not in (select a from orca.m1 where a=5); a | b ----+--- - 0 | 1 1 | 0 - 2 | 1 3 | 0 - 4 | 1 - 6 | 1 7 | 0 - 8 | 1 9 | 0 - 10 | 1 11 | 0 12 | 1 13 | 0 - 14 | 1 - 15 | 0 - 16 | 1 - 17 | 0 - 18 | 1 - 19 | 0 20 | 1 - 21 | 0 22 | 1 - 23 | 0 - 24 | 1 25 | 0 - 26 | 1 27 | 0 - 28 | 1 29 | 0 - 30 | 1 31 | 0 + 0 | 1 + 4 | 1 + 8 | 1 + 14 | 1 + 19 | 0 + 21 | 0 + 24 | 1 + 26 | 1 + 28 | 1 32 | 1 33 | 0 34 | 1 + 2 | 1 + 6 | 1 + 10 | 1 + 15 | 0 + 16 | 1 + 17 | 0 + 18 | 1 + 23 | 0 + 30 | 1 (34 rows) select * from orca.m where m.a not in (select a from orca.m1); a | b ----+--- 24 | 1 - 25 | 0 26 | 1 - 27 | 0 28 | 1 - 29 | 0 - 30 | 1 - 31 | 0 32 | 1 33 | 0 34 | 1 + 25 | 0 + 27 | 0 + 29 | 0 + 31 | 0 + 30 | 1 (11 rows) select * from orca.m where m.a in (select a from orca.m1 where m1.a-1 = m.b); @@ -3465,24 +3472,24 @@ select 1 from orca.m, orca.m1 where m.a = m1.a and m.b!=m1.b; select * from orca.r left outer join orca.s on (r.a=s.c and r.b Seq Scan on s (cost=0.00..431.00 rows=10 width=8) -> Hash (cost=431.00..431.00 rows=7 width=8) -> Seq Scan on r (cost=0.00..431.00 rows=7 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) -- explain Hash Join with equality join condition @@ -3642,41 +3649,41 @@ insert into orca.m values (1,-1), (1,2), (1,1); select a,a,a+b from orca.m; a | a | ?column? ----+----+---------- - 0 | 0 | 1 1 | 1 | 1 - 2 | 2 | 3 3 | 3 | 3 - 4 | 4 | 5 5 | 5 | 5 - 6 | 6 | 7 7 | 7 | 7 - 8 | 8 | 9 9 | 9 | 9 - 10 | 10 | 11 11 | 11 | 11 12 | 12 | 13 13 | 13 | 13 - 14 | 14 | 15 - 15 | 15 | 15 - 16 | 16 | 17 - 17 | 17 | 17 - 18 | 18 | 19 - 19 | 19 | 19 20 | 20 | 21 - 21 | 21 | 21 22 | 22 | 23 - 23 | 23 | 23 - 24 | 24 | 25 25 | 25 | 25 - 26 | 26 | 27 27 | 27 | 27 - 28 | 28 | 29 29 | 29 | 29 - 30 | 30 | 31 31 | 31 | 31 + 0 | 0 | 1 + 4 | 4 | 5 + 8 | 8 | 9 + 14 | 14 | 15 + 19 | 19 | 19 + 21 | 21 | 21 + 24 | 24 | 25 + 26 | 26 | 27 + 28 | 28 | 29 32 | 32 | 33 33 | 33 | 33 34 | 34 | 35 + 2 | 2 | 3 + 6 | 6 | 7 + 10 | 10 | 11 + 15 | 15 | 15 + 16 | 16 | 17 + 17 | 17 | 17 + 18 | 18 | 19 + 23 | 23 | 23 + 30 | 30 | 31 1 | 1 | 0 1 | 1 | 3 1 | 1 | 2 @@ -3686,40 +3693,40 @@ select a,a+b,a+b from orca.m; a | ?column? | ?column? ----+----------+---------- 0 | 1 | 1 + 4 | 5 | 5 + 8 | 9 | 9 + 14 | 15 | 15 + 19 | 19 | 19 + 21 | 21 | 21 + 24 | 25 | 25 + 26 | 27 | 27 + 28 | 29 | 29 + 32 | 33 | 33 + 33 | 33 | 33 + 34 | 35 | 35 1 | 1 | 1 - 2 | 3 | 3 3 | 3 | 3 - 4 | 5 | 5 5 | 5 | 5 - 6 | 7 | 7 7 | 7 | 7 - 8 | 9 | 9 9 | 9 | 9 - 10 | 11 | 11 11 | 11 | 11 12 | 13 | 13 13 | 13 | 13 - 14 | 15 | 15 - 15 | 15 | 15 - 16 | 17 | 17 - 17 | 17 | 17 - 18 | 19 | 19 - 19 | 19 | 19 20 | 21 | 21 - 21 | 21 | 21 22 | 23 | 23 - 23 | 23 | 23 - 24 | 25 | 25 25 | 25 | 25 - 26 | 27 | 27 27 | 27 | 27 - 28 | 29 | 29 29 | 29 | 29 - 30 | 31 | 31 31 | 31 | 31 - 32 | 33 | 33 - 33 | 33 | 33 - 34 | 35 | 35 + 2 | 3 | 3 + 6 | 7 | 7 + 10 | 11 | 11 + 15 | 15 | 15 + 16 | 17 | 17 + 17 | 17 | 17 + 18 | 19 | 19 + 23 | 23 | 23 + 30 | 31 | 31 1 | 0 | 0 1 | 3 | 3 1 | 2 | 2 @@ -3737,124 +3744,96 @@ select * from orca.m where a=abs(b); select a,b,count(*) from orca.m group by grouping sets ((a), (a,b)); a | b | count ----+----+------- - 0 | 1 | 1 - 1 | -1 | 1 - 1 | 0 | 1 - 1 | 1 | 1 - 1 | 2 | 1 - 2 | 1 | 1 3 | 0 | 1 - 4 | 1 | 1 5 | 0 | 1 - 6 | 1 | 1 - 7 | 0 | 1 - 8 | 1 | 1 9 | 0 | 1 - 10 | 1 | 1 11 | 0 | 1 - 12 | 1 | 1 - 13 | 0 | 1 14 | 1 | 1 15 | 0 | 1 - 16 | 1 | 1 17 | 0 | 1 + 21 | 0 | 1 + 26 | 1 | 1 + 28 | 1 | 1 + 30 | 1 | 1 + 5 | | 1 + 6 | | 1 + 9 | | 1 + 10 | | 1 + 11 | | 1 + 13 | | 1 + 14 | | 1 + 17 | | 1 + 21 | | 1 + 25 | | 1 + 28 | | 1 + 32 | | 1 + 33 | | 1 + 0 | 1 | 1 + 1 | 0 | 1 + 2 | 1 | 1 + 4 | 1 | 1 + 6 | 1 | 1 + 8 | 1 | 1 + 13 | 0 | 1 18 | 1 | 1 19 | 0 | 1 - 20 | 1 | 1 - 21 | 0 | 1 22 | 1 | 1 23 | 0 | 1 - 24 | 1 | 1 25 | 0 | 1 - 26 | 1 | 1 - 27 | 0 | 1 - 28 | 1 | 1 29 | 0 | 1 - 30 | 1 | 1 - 31 | 0 | 1 32 | 1 | 1 33 | 0 | 1 - 34 | 1 | 1 - 0 | | 1 - 1 | | 4 2 | | 1 3 | | 1 4 | | 1 - 5 | | 1 - 6 | | 1 7 | | 1 8 | | 1 - 9 | | 1 - 10 | | 1 - 11 | | 1 - 12 | | 1 - 13 | | 1 - 14 | | 1 - 15 | | 1 16 | | 1 - 17 | | 1 18 | | 1 19 | | 1 - 20 | | 1 - 21 | | 1 22 | | 1 - 23 | | 1 24 | | 1 - 25 | | 1 - 26 | | 1 27 | | 1 - 28 | | 1 29 | | 1 + 34 | | 1 + 1 | -1 | 1 + 1 | 1 | 1 + 1 | 2 | 1 + 7 | 0 | 1 + 10 | 1 | 1 + 12 | 1 | 1 + 16 | 1 | 1 + 20 | 1 | 1 + 24 | 1 | 1 + 27 | 0 | 1 + 31 | 0 | 1 + 34 | 1 | 1 + 0 | | 1 + 1 | | 4 + 12 | | 1 + 15 | | 1 + 20 | | 1 + 23 | | 1 + 26 | | 1 30 | | 1 31 | | 1 - 32 | | 1 - 33 | | 1 - 34 | | 1 (73 rows) select b,count(*) from orca.m group by grouping sets ((a), (a,b)); b | count ----+------- - 1 | 1 - -1 | 1 - 0 | 1 - 1 | 1 - 2 | 1 - 1 | 1 - 0 | 1 - 1 | 1 - 0 | 1 - 1 | 1 - 0 | 1 - 1 | 1 - 0 | 1 - 1 | 1 - 0 | 1 - 1 | 1 - 0 | 1 - 1 | 1 - 0 | 1 - 1 | 1 0 | 1 - 1 | 1 0 | 1 - 1 | 1 0 | 1 - 1 | 1 0 | 1 1 | 1 0 | 1 - 1 | 1 0 | 1 - 1 | 1 0 | 1 1 | 1 - 0 | 1 1 | 1 - 0 | 1 1 | 1 | 1 - | 4 | 1 | 1 | 1 @@ -3867,7 +3846,20 @@ select b,count(*) from orca.m group by grouping sets ((a), (a,b)); | 1 | 1 | 1 + -1 | 1 + 1 | 1 + 2 | 1 + 0 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 0 | 1 + 0 | 1 + 1 | 1 | 1 + | 4 | 1 | 1 | 1 @@ -3875,6 +3867,21 @@ select b,count(*) from orca.m group by grouping sets ((a), (a,b)); | 1 | 1 | 1 + 1 | 1 + 0 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 0 | 1 + 1 | 1 + 0 | 1 + 1 | 1 + 0 | 1 + 0 | 1 + 0 | 1 + 1 | 1 + 0 | 1 | 1 | 1 | 1 @@ -3895,199 +3902,199 @@ select a,count(*) from orca.m group by grouping sets ((a), (a,b)); ----+------- 0 | 1 1 | 1 - 1 | 1 - 1 | 1 - 1 | 1 2 | 1 - 3 | 1 4 | 1 - 5 | 1 6 | 1 - 7 | 1 8 | 1 - 9 | 1 - 10 | 1 - 11 | 1 - 12 | 1 13 | 1 - 14 | 1 - 15 | 1 - 16 | 1 - 17 | 1 18 | 1 19 | 1 - 20 | 1 - 21 | 1 22 | 1 23 | 1 - 24 | 1 25 | 1 - 26 | 1 - 27 | 1 - 28 | 1 29 | 1 - 30 | 1 - 31 | 1 32 | 1 33 | 1 - 34 | 1 - 0 | 1 - 1 | 4 2 | 1 3 | 1 4 | 1 - 5 | 1 - 6 | 1 7 | 1 8 | 1 - 9 | 1 - 10 | 1 - 11 | 1 - 12 | 1 - 13 | 1 - 14 | 1 - 15 | 1 16 | 1 - 17 | 1 18 | 1 19 | 1 - 20 | 1 - 21 | 1 22 | 1 - 23 | 1 24 | 1 - 25 | 1 - 26 | 1 27 | 1 - 28 | 1 29 | 1 - 30 | 1 - 31 | 1 - 32 | 1 - 33 | 1 34 | 1 -(73 rows) - -select a,count(*) from orca.m group by grouping sets ((a), (b)); - a | count -----+------- - | 1 - | 17 - | 19 - | 1 - 0 | 1 - 1 | 4 - 2 | 1 3 | 1 - 4 | 1 + 5 | 1 + 9 | 1 + 11 | 1 + 14 | 1 + 15 | 1 + 17 | 1 + 21 | 1 + 26 | 1 + 28 | 1 + 30 | 1 5 | 1 6 | 1 - 7 | 1 - 8 | 1 9 | 1 10 | 1 11 | 1 - 12 | 1 13 | 1 14 | 1 + 17 | 1 + 21 | 1 + 25 | 1 + 28 | 1 + 32 | 1 + 33 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 7 | 1 + 10 | 1 + 12 | 1 + 16 | 1 + 20 | 1 + 24 | 1 + 27 | 1 + 31 | 1 + 34 | 1 + 0 | 1 + 1 | 4 + 12 | 1 15 | 1 + 20 | 1 + 23 | 1 + 26 | 1 + 30 | 1 + 31 | 1 +(73 rows) + +select a,count(*) from orca.m group by grouping sets ((a), (b)); + a | count +----+------- + | 1 + 2 | 1 + 3 | 1 + 4 | 1 + 7 | 1 + 8 | 1 16 | 1 - 17 | 1 18 | 1 19 | 1 - 20 | 1 - 21 | 1 22 | 1 - 23 | 1 24 | 1 - 25 | 1 - 26 | 1 27 | 1 - 28 | 1 29 | 1 + 34 | 1 + | 17 + | 19 + 0 | 1 + 1 | 4 + 12 | 1 + 15 | 1 + 20 | 1 + 23 | 1 + 26 | 1 30 | 1 31 | 1 + | 1 + 5 | 1 + 6 | 1 + 9 | 1 + 10 | 1 + 11 | 1 + 13 | 1 + 14 | 1 + 17 | 1 + 21 | 1 + 25 | 1 + 28 | 1 32 | 1 33 | 1 - 34 | 1 (39 rows) select a,b,count(*) from orca.m group by rollup(a, b); a | b | count ----+----+------- - 0 | 1 | 1 - 1 | -1 | 1 - 1 | 0 | 1 - 1 | 1 | 1 - 1 | 2 | 1 - 2 | 1 | 1 3 | 0 | 1 - 4 | 1 | 1 5 | 0 | 1 - 6 | 1 | 1 - 7 | 0 | 1 - 8 | 1 | 1 9 | 0 | 1 - 10 | 1 | 1 11 | 0 | 1 - 12 | 1 | 1 - 13 | 0 | 1 14 | 1 | 1 15 | 0 | 1 - 16 | 1 | 1 17 | 0 | 1 + 21 | 0 | 1 + 26 | 1 | 1 + 28 | 1 | 1 + 30 | 1 | 1 + 5 | | 1 + 6 | | 1 + 9 | | 1 + 10 | | 1 + 11 | | 1 + 13 | | 1 + 14 | | 1 + 17 | | 1 + 21 | | 1 + 25 | | 1 + 28 | | 1 + 32 | | 1 + 33 | | 1 + 0 | 1 | 1 + 1 | 0 | 1 + 2 | 1 | 1 + 4 | 1 | 1 + 6 | 1 | 1 + 8 | 1 | 1 + 13 | 0 | 1 18 | 1 | 1 19 | 0 | 1 - 20 | 1 | 1 - 21 | 0 | 1 22 | 1 | 1 23 | 0 | 1 - 24 | 1 | 1 25 | 0 | 1 - 26 | 1 | 1 - 27 | 0 | 1 - 28 | 1 | 1 29 | 0 | 1 - 30 | 1 | 1 - 31 | 0 | 1 32 | 1 | 1 33 | 0 | 1 - 34 | 1 | 1 - 0 | | 1 - 1 | | 4 2 | | 1 3 | | 1 4 | | 1 - 5 | | 1 - 6 | | 1 7 | | 1 8 | | 1 - 9 | | 1 - 10 | | 1 - 11 | | 1 - 12 | | 1 - 13 | | 1 - 14 | | 1 - 15 | | 1 16 | | 1 - 17 | | 1 18 | | 1 19 | | 1 - 20 | | 1 - 21 | | 1 22 | | 1 - 23 | | 1 24 | | 1 - 25 | | 1 - 26 | | 1 27 | | 1 - 28 | | 1 29 | | 1 + 34 | | 1 + 1 | -1 | 1 + 1 | 1 | 1 + 1 | 2 | 1 + 7 | 0 | 1 + 10 | 1 | 1 + 12 | 1 | 1 + 16 | 1 | 1 + 20 | 1 | 1 + 24 | 1 | 1 + 27 | 0 | 1 + 31 | 0 | 1 + 34 | 1 | 1 + 0 | | 1 + 1 | | 4 + 12 | | 1 + 15 | | 1 + 20 | | 1 + 23 | | 1 + 26 | | 1 30 | | 1 31 | | 1 - 32 | | 1 - 33 | | 1 - 34 | | 1 | | 38 (74 rows) @@ -4179,54 +4186,54 @@ select count(*) from orca.m group by (); select a, count(*) from orca.r group by (), a; a | count ----+------- - 1 | 1 - 3 | 1 5 | 1 - 7 | 1 + 6 | 1 9 | 1 + 10 | 1 11 | 1 13 | 1 - 15 | 1 + 14 | 1 17 | 1 - 19 | 1 - | 1 2 | 1 + 3 | 1 4 | 1 - 6 | 1 + 7 | 1 8 | 1 - 10 | 1 - 12 | 1 - 14 | 1 16 | 1 18 | 1 + 19 | 1 + | 1 + 1 | 1 + 12 | 1 + 15 | 1 20 | 1 (21 rows) select a, count(*) from orca.r group by grouping sets ((),(a)); a | count ----+------- - 2 | 1 - 4 | 1 - 6 | 1 - 8 | 1 - 10 | 1 - 12 | 1 - 14 | 1 - 16 | 1 - 18 | 1 - 20 | 1 - | 21 - 1 | 1 - 3 | 1 5 | 1 - 7 | 1 + 6 | 1 9 | 1 + 10 | 1 11 | 1 13 | 1 - 15 | 1 + 14 | 1 17 | 1 + 2 | 1 + 3 | 1 + 4 | 1 + 7 | 1 + 8 | 1 + 16 | 1 + 18 | 1 19 | 1 | 1 + 1 | 1 + 12 | 1 + 15 | 1 + 20 | 1 + | 21 (22 rows) select a, b, count(*) c from orca.r group by grouping sets ((),(a), (a,b)) order by b,a,c; @@ -4334,61 +4341,61 @@ select 1 from orca.r group by (); select a,1 from orca.r group by rollup(a); a | ?column? ----+---------- - 1 | 1 - 3 | 1 5 | 1 - 7 | 1 + 6 | 1 9 | 1 + 10 | 1 11 | 1 13 | 1 - 15 | 1 + 14 | 1 17 | 1 - 19 | 1 - | 1 - | 1 + 1 | 1 + 12 | 1 + 15 | 1 + 20 | 1 2 | 1 + 3 | 1 4 | 1 - 6 | 1 + 7 | 1 8 | 1 - 10 | 1 - 12 | 1 - 14 | 1 16 | 1 18 | 1 - 20 | 1 + 19 | 1 + | 1 + | 1 (22 rows) select distinct grouping(a) + grouping(b) from orca.m group by rollup(a,b); ?column? ---------- + 2 0 1 - 2 (3 rows) -- arrays select array[array[a,b]], array[b] from orca.r; array | array ------------+------- - {{2,2}} | {2} - {{4,1}} | {1} - {{6,0}} | {0} - {{8,2}} | {2} - {{10,1}} | {1} + {{1,1}} | {1} {{12,0}} | {0} - {{14,2}} | {2} - {{16,1}} | {1} - {{18,0}} | {0} + {{15,0}} | {0} {{20,2}} | {2} - {{1,1}} | {1} - {{3,0}} | {0} {{5,2}} | {2} - {{7,1}} | {1} + {{6,0}} | {0} {{9,0}} | {0} + {{10,1}} | {1} {{11,2}} | {2} {{13,1}} | {1} - {{15,0}} | {0} + {{14,2}} | {2} {{17,2}} | {2} + {{2,2}} | {2} + {{3,0}} | {0} + {{4,1}} | {1} + {{7,1}} | {1} + {{8,2}} | {2} + {{16,1}} | {1} + {{18,0}} | {0} {{19,1}} | {1} {{NULL,1}} | {1} (21 rows) @@ -4397,178 +4404,178 @@ select array[array[a,b]], array[b] from orca.r; select a, b from orca.m union select b,a from orca.m; a | b ----+---- - 0 | 1 - 0 | 3 0 | 5 - 0 | 7 0 | 9 - 0 | 11 - 0 | 13 - 0 | 15 - 0 | 17 - 0 | 19 0 | 21 - 0 | 23 0 | 25 - 0 | 27 - 0 | 29 - 0 | 31 - 0 | 33 - 1 | 0 + 1 | -1 1 | 1 1 | 2 - 1 | 4 1 | 6 - 1 | 8 - 1 | -1 1 | 10 1 | 12 + 1 | 20 + 1 | 30 + 7 | 0 + 10 | 1 + 12 | 1 + 16 | 1 + 20 | 1 + 24 | 1 + 27 | 0 + 31 | 0 + 34 | 1 + -1 | 1 + 0 | 1 + 0 | 13 + 0 | 19 + 0 | 27 + 0 | 29 + 0 | 31 + 1 | 0 1 | 14 1 | 16 1 | 18 - 1 | 20 1 | 22 - 1 | 24 1 | 26 - 1 | 28 - 1 | 30 1 | 32 1 | 34 2 | 1 - 3 | 0 4 | 1 - 5 | 0 6 | 1 - 7 | 0 8 | 1 - 9 | 0 - -1 | 1 - 10 | 1 - 11 | 0 - 12 | 1 13 | 0 - 14 | 1 - 15 | 0 - 16 | 1 - 17 | 0 18 | 1 19 | 0 - 20 | 1 - 21 | 0 22 | 1 23 | 0 - 24 | 1 25 | 0 - 26 | 1 - 27 | 0 - 28 | 1 29 | 0 - 30 | 1 - 31 | 0 32 | 1 33 | 0 - 34 | 1 + 0 | 3 + 0 | 7 + 0 | 11 + 0 | 15 + 0 | 17 + 0 | 23 + 0 | 33 + 1 | 4 + 1 | 8 + 1 | 24 + 1 | 28 + 3 | 0 + 5 | 0 + 9 | 0 + 11 | 0 + 14 | 1 + 15 | 0 + 17 | 0 + 21 | 0 + 26 | 1 + 28 | 1 + 30 | 1 (71 rows) SELECT a from orca.m UNION ALL select b from orca.m UNION ALL select a+b from orca.m group by 1; a ---- 0 + 4 + 8 + 14 + 19 + 21 + 24 + 26 + 28 + 32 + 33 + 34 + 1 + 1 + 1 + 1 0 0 + 1 + 1 + 1 + 1 0 + 1 0 + 1 + 15 + 23 + 31 + 35 + 1 + 3 + 5 + 7 + 9 + 11 + 12 + 13 + 20 + 22 + 25 + 27 + 29 + 31 0 0 0 0 0 0 + 1 0 + 1 + 1 0 0 0 0 - 0 - 0 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 + 5 + 9 + 11 + 13 + 17 + 21 + 25 + 33 + 2 + 6 + 10 + 15 + 16 + 17 + 18 + 23 + 30 1 1 1 1 1 1 + 0 1 + 0 1 + 0 1 + -1 2 - 2 + 1 2 3 - 3 - 4 - 5 - 5 - 6 - 7 7 - 8 - 9 - 9 - -1 - 10 - 11 - 11 - 12 - 13 - 13 - 14 - 15 - 15 - 16 - 17 - 17 - 18 - 19 19 - 20 - 21 - 21 - 22 - 23 - 23 - 24 - 25 - 25 - 26 27 - 27 - 28 29 - 29 - 30 - 31 - 31 - 32 - 33 - 33 - 34 - 35 (96 rows) drop table if exists orca.foo; @@ -4586,69 +4593,69 @@ insert into orca.bar select i, i%3, i%2 from generate_series(1,30)i; SELECT distinct a, b from orca.foo; a | b ----+--- - 2 | 0 - 4 | 0 - 6 | 0 - 8 | 0 - 10 | 0 + 1 | 1 12 | 0 - 14 | 0 - 16 | 0 - 18 | 0 + 15 | 1 20 | 0 - 22 | 0 - 24 | 0 + 23 | 1 26 | 0 - 28 | 0 30 | 0 - 32 | 0 - 34 | 0 + 31 | 1 + 35 | 1 36 | 0 38 | 0 40 | 0 - 1 | 1 + 2 | 0 3 | 1 - 5 | 1 + 4 | 0 7 | 1 - 9 | 1 + 8 | 0 + 16 | 0 + 18 | 0 + 19 | 1 + 22 | 0 + 24 | 0 + 27 | 1 + 29 | 1 + 34 | 0 + 37 | 1 + 39 | 1 + 5 | 1 + 6 | 0 + 9 | 1 + 10 | 0 11 | 1 13 | 1 - 15 | 1 + 14 | 0 17 | 1 - 19 | 1 21 | 1 - 23 | 1 25 | 1 - 27 | 1 - 29 | 1 - 31 | 1 + 28 | 0 + 32 | 0 33 | 1 - 35 | 1 - 37 | 1 - 39 | 1 (40 rows) SELECT distinct foo.a, bar.b from orca.foo, orca.bar where foo.b = bar.a; a | b ----+--- - 1 | 1 3 | 1 - 5 | 1 - 7 | 1 9 | 1 11 | 1 - 13 | 1 + 23 | 1 + 31 | 1 + 33 | 1 + 5 | 1 + 7 | 1 15 | 1 - 17 | 1 19 | 1 21 | 1 - 23 | 1 - 25 | 1 27 | 1 - 29 | 1 - 31 | 1 - 33 | 1 35 | 1 + 1 | 1 + 13 | 1 + 17 | 1 + 25 | 1 + 29 | 1 37 | 1 39 | 1 (20 rows) @@ -4656,43 +4663,43 @@ SELECT distinct foo.a, bar.b from orca.foo, orca.bar where foo.b = bar.a; SELECT distinct a, b from orca.foo; a | b ----+--- - 1 | 1 - 3 | 1 5 | 1 - 7 | 1 + 6 | 0 9 | 1 + 10 | 0 11 | 1 13 | 1 - 15 | 1 + 14 | 0 17 | 1 - 19 | 1 21 | 1 - 23 | 1 25 | 1 - 27 | 1 - 29 | 1 - 31 | 1 + 28 | 0 + 32 | 0 33 | 1 - 35 | 1 - 37 | 1 - 39 | 1 2 | 0 + 3 | 1 4 | 0 - 6 | 0 + 7 | 1 8 | 0 - 10 | 0 - 12 | 0 - 14 | 0 16 | 0 18 | 0 - 20 | 0 + 19 | 1 22 | 0 24 | 0 + 27 | 1 + 29 | 1 + 34 | 0 + 37 | 1 + 39 | 1 + 1 | 1 + 12 | 0 + 15 | 1 + 20 | 0 + 23 | 1 26 | 0 - 28 | 0 30 | 0 - 32 | 0 - 34 | 0 + 31 | 1 + 35 | 1 36 | 0 38 | 0 40 | 0 @@ -4701,69 +4708,69 @@ SELECT distinct a, b from orca.foo; SELECT distinct a, count(*) from orca.foo group by a; a | count ----+------- - 1 | 1 2 | 1 3 | 1 4 | 1 - 5 | 1 - 6 | 1 7 | 1 8 | 1 - 9 | 1 - 10 | 1 - 11 | 1 - 12 | 1 - 13 | 1 - 14 | 1 - 15 | 1 16 | 1 - 17 | 1 18 | 1 19 | 1 - 20 | 1 - 21 | 1 22 | 1 - 23 | 1 24 | 1 - 25 | 1 - 26 | 1 27 | 1 - 28 | 1 29 | 1 + 34 | 1 + 37 | 1 + 39 | 1 + 1 | 1 + 12 | 1 + 15 | 1 + 20 | 1 + 23 | 1 + 26 | 1 30 | 1 31 | 1 - 32 | 1 - 33 | 1 - 34 | 1 35 | 1 36 | 1 - 37 | 1 38 | 1 - 39 | 1 40 | 1 + 5 | 1 + 6 | 1 + 9 | 1 + 10 | 1 + 11 | 1 + 13 | 1 + 14 | 1 + 17 | 1 + 21 | 1 + 25 | 1 + 28 | 1 + 32 | 1 + 33 | 1 (40 rows) SELECT distinct foo.a, bar.b, sum(bar.c+foo.c) from orca.foo, orca.bar where foo.b = bar.a group by foo.a, bar.b; a | b | sum ----+---+----- - 1 | 1 | 2 - 3 | 1 | 4 5 | 1 | 2 7 | 1 | 4 - 9 | 1 | 2 - 11 | 1 | 4 - 13 | 1 | 2 15 | 1 | 4 - 17 | 1 | 2 19 | 1 | 4 21 | 1 | 2 - 23 | 1 | 4 - 25 | 1 | 2 27 | 1 | 4 - 29 | 1 | 2 + 35 | 1 | 4 + 3 | 1 | 4 + 9 | 1 | 2 + 11 | 1 | 4 + 23 | 1 | 4 31 | 1 | 4 33 | 1 | 2 - 35 | 1 | 4 + 1 | 1 | 2 + 13 | 1 | 2 + 17 | 1 | 2 + 25 | 1 | 2 + 29 | 1 | 2 37 | 1 | 2 39 | 1 | 4 (20 rows) @@ -4771,69 +4778,69 @@ SELECT distinct foo.a, bar.b, sum(bar.c+foo.c) from orca.foo, orca.bar where foo SELECT distinct a, count(*) from orca.foo group by a; a | count ----+------- - 1 | 1 2 | 1 3 | 1 4 | 1 - 5 | 1 - 6 | 1 7 | 1 8 | 1 - 9 | 1 - 10 | 1 - 11 | 1 - 12 | 1 - 13 | 1 - 14 | 1 - 15 | 1 16 | 1 - 17 | 1 18 | 1 19 | 1 - 20 | 1 - 21 | 1 22 | 1 - 23 | 1 24 | 1 - 25 | 1 - 26 | 1 27 | 1 - 28 | 1 29 | 1 + 34 | 1 + 37 | 1 + 39 | 1 + 1 | 1 + 12 | 1 + 15 | 1 + 20 | 1 + 23 | 1 + 26 | 1 30 | 1 31 | 1 - 32 | 1 - 33 | 1 - 34 | 1 35 | 1 36 | 1 - 37 | 1 38 | 1 - 39 | 1 40 | 1 + 5 | 1 + 6 | 1 + 9 | 1 + 10 | 1 + 11 | 1 + 13 | 1 + 14 | 1 + 17 | 1 + 21 | 1 + 25 | 1 + 28 | 1 + 32 | 1 + 33 | 1 (40 rows) SELECT distinct foo.a, bar.b from orca.foo, orca.bar where foo.b = bar.a; a | b ----+--- - 1 | 1 - 3 | 1 5 | 1 7 | 1 - 9 | 1 - 11 | 1 - 13 | 1 15 | 1 - 17 | 1 19 | 1 21 | 1 - 23 | 1 - 25 | 1 27 | 1 - 29 | 1 + 35 | 1 + 3 | 1 + 9 | 1 + 11 | 1 + 23 | 1 31 | 1 33 | 1 - 35 | 1 + 1 | 1 + 13 | 1 + 17 | 1 + 25 | 1 + 29 | 1 37 | 1 39 | 1 (20 rows) @@ -4842,165 +4849,165 @@ SELECT distinct foo.a, bar.b, sum(bar.c+foo.c) from orca.foo, orca.bar where foo a | b | sum ----+---+----- 1 | 1 | 2 + 13 | 1 | 2 + 17 | 1 | 2 + 25 | 1 | 2 + 29 | 1 | 2 + 37 | 1 | 2 + 39 | 1 | 4 3 | 1 | 4 - 5 | 1 | 2 - 7 | 1 | 4 9 | 1 | 2 11 | 1 | 4 - 13 | 1 | 2 + 23 | 1 | 4 + 31 | 1 | 4 + 33 | 1 | 2 + 5 | 1 | 2 + 7 | 1 | 4 15 | 1 | 4 - 17 | 1 | 2 19 | 1 | 4 21 | 1 | 2 - 23 | 1 | 4 - 25 | 1 | 2 27 | 1 | 4 - 29 | 1 | 2 - 31 | 1 | 4 - 33 | 1 | 2 35 | 1 | 4 - 37 | 1 | 2 - 39 | 1 | 4 (20 rows) SELECT distinct a, b from orca.foo; a | b ----+--- - 2 | 0 - 4 | 0 + 5 | 1 6 | 0 - 8 | 0 + 9 | 1 10 | 0 - 12 | 0 + 11 | 1 + 13 | 1 14 | 0 - 16 | 0 - 18 | 0 - 20 | 0 - 22 | 0 - 24 | 0 - 26 | 0 + 17 | 1 + 21 | 1 + 25 | 1 28 | 0 - 30 | 0 32 | 0 - 34 | 0 - 36 | 0 - 38 | 0 - 40 | 0 - 1 | 1 + 33 | 1 + 2 | 0 3 | 1 - 5 | 1 + 4 | 0 7 | 1 - 9 | 1 - 11 | 1 - 13 | 1 - 15 | 1 - 17 | 1 + 8 | 0 + 16 | 0 + 18 | 0 19 | 1 - 21 | 1 - 23 | 1 - 25 | 1 + 22 | 0 + 24 | 0 27 | 1 29 | 1 - 31 | 1 - 33 | 1 - 35 | 1 + 34 | 0 37 | 1 39 | 1 + 1 | 1 + 12 | 0 + 15 | 1 + 20 | 0 + 23 | 1 + 26 | 0 + 30 | 0 + 31 | 1 + 35 | 1 + 36 | 0 + 38 | 0 + 40 | 0 (40 rows) SELECT distinct a, count(*) from orca.foo group by a; a | count ----+------- - 1 | 1 - 2 | 1 - 3 | 1 - 4 | 1 5 | 1 6 | 1 - 7 | 1 - 8 | 1 9 | 1 10 | 1 11 | 1 - 12 | 1 13 | 1 14 | 1 + 17 | 1 + 21 | 1 + 25 | 1 + 28 | 1 + 32 | 1 + 33 | 1 + 1 | 1 + 12 | 1 15 | 1 + 20 | 1 + 23 | 1 + 26 | 1 + 30 | 1 + 31 | 1 + 35 | 1 + 36 | 1 + 38 | 1 + 40 | 1 + 2 | 1 + 3 | 1 + 4 | 1 + 7 | 1 + 8 | 1 16 | 1 - 17 | 1 18 | 1 19 | 1 - 20 | 1 - 21 | 1 22 | 1 - 23 | 1 24 | 1 - 25 | 1 - 26 | 1 27 | 1 - 28 | 1 29 | 1 - 30 | 1 - 31 | 1 - 32 | 1 - 33 | 1 34 | 1 - 35 | 1 - 36 | 1 37 | 1 - 38 | 1 39 | 1 - 40 | 1 (40 rows) SELECT distinct foo.a, bar.b from orca.foo, orca.bar where foo.b = bar.a; a | b ----+--- 1 | 1 - 3 | 1 + 13 | 1 + 17 | 1 + 25 | 1 + 29 | 1 + 37 | 1 + 39 | 1 5 | 1 7 | 1 - 9 | 1 - 11 | 1 - 13 | 1 15 | 1 - 17 | 1 19 | 1 21 | 1 - 23 | 1 - 25 | 1 27 | 1 - 29 | 1 + 35 | 1 + 3 | 1 + 9 | 1 + 11 | 1 + 23 | 1 31 | 1 33 | 1 - 35 | 1 - 37 | 1 - 39 | 1 (20 rows) SELECT distinct foo.a, bar.b, sum(bar.c+foo.c) from orca.foo, orca.bar where foo.b = bar.a group by foo.a, bar.b; a | b | sum ----+---+----- 1 | 1 | 2 - 3 | 1 | 4 + 13 | 1 | 2 + 17 | 1 | 2 + 25 | 1 | 2 + 29 | 1 | 2 + 37 | 1 | 2 + 39 | 1 | 4 5 | 1 | 2 7 | 1 | 4 - 9 | 1 | 2 - 11 | 1 | 4 - 13 | 1 | 2 15 | 1 | 4 - 17 | 1 | 2 19 | 1 | 4 21 | 1 | 2 - 23 | 1 | 4 - 25 | 1 | 2 27 | 1 | 4 - 29 | 1 | 2 + 35 | 1 | 4 + 3 | 1 | 4 + 9 | 1 | 2 + 11 | 1 | 4 + 23 | 1 | 4 31 | 1 | 4 33 | 1 | 2 - 35 | 1 | 4 - 37 | 1 | 2 - 39 | 1 | 4 (20 rows) -- window operations @@ -6600,12 +6607,12 @@ select (select rank() over() from orca_w3 where a = orca_w1.a) as one, row_numbe | 1 | 2 | 3 - | 1 - | 2 - | 3 1 | 1 1 | 2 1 | 3 + | 1 + | 2 + | 3 (9 rows) -- window function in IN clause @@ -6643,9 +6650,9 @@ select (select a+1 from (select a from orca_w2 where orca_w1.a=orca_w2.a) sq(a)) select (select a+1 from (select a from orca_w2 where sq2.a=orca_w2.a) sq1(a)) as one, row_number() over(partition by sq2.a) as two from (select 1,1,1,a from orca_w1) sq2(x,y,z,a); one | two -----+----- - | 1 3 | 1 4 | 1 + | 1 (3 rows) -- cte in scalar subquery @@ -6723,46 +6730,46 @@ select rank() over(partition by a, case when b = 0 then a+b end order by b asc) select foo.d from orca.foo full join orca.bar on (foo.d = bar.a) group by d; d ---- - 1 + 2 3 - 5 + 4 7 - 9 - 11 - 13 - 15 - 17 + 8 + 16 + 18 19 - 21 - 23 - 25 + 22 + 24 27 29 - 31 - 33 - 35 + 34 37 39 0 - 2 - 4 - 6 - 8 - 10 + 1 12 - 14 - 16 - 18 + 15 20 - 22 - 24 + 23 26 - 28 30 - 32 - 34 + 31 + 35 36 38 + 5 + 6 + 9 + 10 + 11 + 13 + 14 + 17 + 21 + 25 + 28 + 32 + 33 (40 rows) select 1 as v from orca.foo full join orca.bar on (foo.d = bar.a) group by d; @@ -6850,119 +6857,119 @@ insert into orca.rcte select i, i%2, i%3 from generate_series(1,40)i; with x as (select * from orca.rcte where a < 10) select * from x x1, x x2; a | b | c | a | b | c ---+---+---+---+---+--- + 1 | 1 | 1 | 1 | 1 | 1 + 1 | 1 | 1 | 2 | 0 | 2 + 1 | 1 | 1 | 3 | 1 | 0 + 1 | 1 | 1 | 4 | 0 | 1 + 1 | 1 | 1 | 7 | 1 | 1 + 1 | 1 | 1 | 8 | 0 | 2 + 1 | 1 | 1 | 5 | 1 | 2 + 1 | 1 | 1 | 6 | 0 | 0 + 1 | 1 | 1 | 9 | 1 | 0 2 | 0 | 2 | 1 | 1 | 1 - 4 | 0 | 1 | 1 | 1 | 1 - 6 | 0 | 0 | 1 | 1 | 1 - 8 | 0 | 2 | 1 | 1 | 1 + 2 | 0 | 2 | 2 | 0 | 2 2 | 0 | 2 | 3 | 1 | 0 - 4 | 0 | 1 | 3 | 1 | 0 - 6 | 0 | 0 | 3 | 1 | 0 - 8 | 0 | 2 | 3 | 1 | 0 - 2 | 0 | 2 | 5 | 1 | 2 - 4 | 0 | 1 | 5 | 1 | 2 - 6 | 0 | 0 | 5 | 1 | 2 - 8 | 0 | 2 | 5 | 1 | 2 + 2 | 0 | 2 | 4 | 0 | 1 2 | 0 | 2 | 7 | 1 | 1 - 4 | 0 | 1 | 7 | 1 | 1 - 6 | 0 | 0 | 7 | 1 | 1 - 8 | 0 | 2 | 7 | 1 | 1 + 2 | 0 | 2 | 8 | 0 | 2 + 2 | 0 | 2 | 5 | 1 | 2 + 2 | 0 | 2 | 6 | 0 | 0 2 | 0 | 2 | 9 | 1 | 0 - 4 | 0 | 1 | 9 | 1 | 0 - 6 | 0 | 0 | 9 | 1 | 0 - 8 | 0 | 2 | 9 | 1 | 0 - 2 | 0 | 2 | 2 | 0 | 2 + 3 | 1 | 0 | 1 | 1 | 1 + 3 | 1 | 0 | 2 | 0 | 2 + 3 | 1 | 0 | 3 | 1 | 0 + 3 | 1 | 0 | 4 | 0 | 1 + 3 | 1 | 0 | 7 | 1 | 1 + 3 | 1 | 0 | 8 | 0 | 2 + 3 | 1 | 0 | 5 | 1 | 2 + 3 | 1 | 0 | 6 | 0 | 0 + 3 | 1 | 0 | 9 | 1 | 0 + 4 | 0 | 1 | 1 | 1 | 1 4 | 0 | 1 | 2 | 0 | 2 - 6 | 0 | 0 | 2 | 0 | 2 - 8 | 0 | 2 | 2 | 0 | 2 - 2 | 0 | 2 | 4 | 0 | 1 + 4 | 0 | 1 | 3 | 1 | 0 4 | 0 | 1 | 4 | 0 | 1 - 6 | 0 | 0 | 4 | 0 | 1 - 8 | 0 | 2 | 4 | 0 | 1 - 2 | 0 | 2 | 6 | 0 | 0 - 4 | 0 | 1 | 6 | 0 | 0 - 6 | 0 | 0 | 6 | 0 | 0 - 8 | 0 | 2 | 6 | 0 | 0 - 2 | 0 | 2 | 8 | 0 | 2 + 4 | 0 | 1 | 7 | 1 | 1 4 | 0 | 1 | 8 | 0 | 2 - 6 | 0 | 0 | 8 | 0 | 2 - 8 | 0 | 2 | 8 | 0 | 2 - 1 | 1 | 1 | 1 | 1 | 1 - 3 | 1 | 0 | 1 | 1 | 1 - 5 | 1 | 2 | 1 | 1 | 1 + 4 | 0 | 1 | 5 | 1 | 2 + 4 | 0 | 1 | 6 | 0 | 0 + 4 | 0 | 1 | 9 | 1 | 0 7 | 1 | 1 | 1 | 1 | 1 - 9 | 1 | 0 | 1 | 1 | 1 - 1 | 1 | 1 | 3 | 1 | 0 - 3 | 1 | 0 | 3 | 1 | 0 - 5 | 1 | 2 | 3 | 1 | 0 + 7 | 1 | 1 | 2 | 0 | 2 7 | 1 | 1 | 3 | 1 | 0 - 9 | 1 | 0 | 3 | 1 | 0 - 1 | 1 | 1 | 5 | 1 | 2 - 3 | 1 | 0 | 5 | 1 | 2 - 5 | 1 | 2 | 5 | 1 | 2 - 7 | 1 | 1 | 5 | 1 | 2 - 9 | 1 | 0 | 5 | 1 | 2 - 1 | 1 | 1 | 7 | 1 | 1 - 3 | 1 | 0 | 7 | 1 | 1 - 5 | 1 | 2 | 7 | 1 | 1 + 7 | 1 | 1 | 4 | 0 | 1 7 | 1 | 1 | 7 | 1 | 1 - 9 | 1 | 0 | 7 | 1 | 1 - 1 | 1 | 1 | 9 | 1 | 0 - 3 | 1 | 0 | 9 | 1 | 0 - 5 | 1 | 2 | 9 | 1 | 0 + 7 | 1 | 1 | 8 | 0 | 2 + 7 | 1 | 1 | 5 | 1 | 2 + 7 | 1 | 1 | 6 | 0 | 0 7 | 1 | 1 | 9 | 1 | 0 - 9 | 1 | 0 | 9 | 1 | 0 - 1 | 1 | 1 | 2 | 0 | 2 - 3 | 1 | 0 | 2 | 0 | 2 + 8 | 0 | 2 | 1 | 1 | 1 + 8 | 0 | 2 | 2 | 0 | 2 + 8 | 0 | 2 | 3 | 1 | 0 + 8 | 0 | 2 | 4 | 0 | 1 + 8 | 0 | 2 | 7 | 1 | 1 + 8 | 0 | 2 | 8 | 0 | 2 + 8 | 0 | 2 | 5 | 1 | 2 + 8 | 0 | 2 | 6 | 0 | 0 + 8 | 0 | 2 | 9 | 1 | 0 + 5 | 1 | 2 | 1 | 1 | 1 5 | 1 | 2 | 2 | 0 | 2 - 7 | 1 | 1 | 2 | 0 | 2 - 9 | 1 | 0 | 2 | 0 | 2 - 1 | 1 | 1 | 4 | 0 | 1 - 3 | 1 | 0 | 4 | 0 | 1 + 5 | 1 | 2 | 3 | 1 | 0 5 | 1 | 2 | 4 | 0 | 1 - 7 | 1 | 1 | 4 | 0 | 1 - 9 | 1 | 0 | 4 | 0 | 1 - 1 | 1 | 1 | 6 | 0 | 0 - 3 | 1 | 0 | 6 | 0 | 0 - 5 | 1 | 2 | 6 | 0 | 0 - 7 | 1 | 1 | 6 | 0 | 0 - 9 | 1 | 0 | 6 | 0 | 0 - 1 | 1 | 1 | 8 | 0 | 2 - 3 | 1 | 0 | 8 | 0 | 2 + 5 | 1 | 2 | 7 | 1 | 1 5 | 1 | 2 | 8 | 0 | 2 - 7 | 1 | 1 | 8 | 0 | 2 + 5 | 1 | 2 | 5 | 1 | 2 + 5 | 1 | 2 | 6 | 0 | 0 + 5 | 1 | 2 | 9 | 1 | 0 + 6 | 0 | 0 | 1 | 1 | 1 + 6 | 0 | 0 | 2 | 0 | 2 + 6 | 0 | 0 | 3 | 1 | 0 + 6 | 0 | 0 | 4 | 0 | 1 + 6 | 0 | 0 | 7 | 1 | 1 + 6 | 0 | 0 | 8 | 0 | 2 + 6 | 0 | 0 | 5 | 1 | 2 + 6 | 0 | 0 | 6 | 0 | 0 + 6 | 0 | 0 | 9 | 1 | 0 + 9 | 1 | 0 | 1 | 1 | 1 + 9 | 1 | 0 | 2 | 0 | 2 + 9 | 1 | 0 | 3 | 1 | 0 + 9 | 1 | 0 | 4 | 0 | 1 + 9 | 1 | 0 | 7 | 1 | 1 9 | 1 | 0 | 8 | 0 | 2 + 9 | 1 | 0 | 5 | 1 | 2 + 9 | 1 | 0 | 6 | 0 | 0 + 9 | 1 | 0 | 9 | 1 | 0 (81 rows) with x as (select * from orca.rcte where a < 10) select * from x x1, x x2 where x2.a = x1.b; a | b | c | a | b | c ---+---+---+---+---+--- 1 | 1 | 1 | 1 | 1 | 1 - 3 | 1 | 0 | 1 | 1 | 1 5 | 1 | 2 | 1 | 1 | 1 - 7 | 1 | 1 | 1 | 1 | 1 9 | 1 | 0 | 1 | 1 | 1 + 3 | 1 | 0 | 1 | 1 | 1 + 7 | 1 | 1 | 1 | 1 | 1 (5 rows) with x as (select * from orca.rcte where a < 10) select a from x union all select b from x; a --- 2 + 3 4 - 6 + 7 8 0 + 1 0 - 0 + 1 0 1 - 3 + 1 5 - 7 + 6 9 1 - 1 - 1 - 1 + 0 1 (18 rows) @@ -6971,8 +6978,8 @@ with x as (select * from orca.rcte where a < 10) select * from x x1 where x1.b = ---+---+--- 1 | 1 | 1 3 | 1 | 0 - 5 | 1 | 2 7 | 1 | 1 + 5 | 1 | 2 9 | 1 | 0 (5 rows) @@ -6984,31 +6991,31 @@ with x as (select * from orca.rcte where a < 10) select * from x x1 where x1.b = with x as (select * from orca.rcte where a < 10) select * from x x1, x x2, x x3 where x2.a = x1.b and x3.b = x2.b ; a | b | c | a | b | c | a | b | c ---+---+---+---+---+---+---+---+--- - 1 | 1 | 1 | 1 | 1 | 1 | 9 | 1 | 0 - 1 | 1 | 1 | 1 | 1 | 1 | 7 | 1 | 1 - 1 | 1 | 1 | 1 | 1 | 1 | 5 | 1 | 2 - 1 | 1 | 1 | 1 | 1 | 1 | 3 | 1 | 0 - 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 - 3 | 1 | 0 | 1 | 1 | 1 | 9 | 1 | 0 3 | 1 | 0 | 1 | 1 | 1 | 7 | 1 | 1 - 3 | 1 | 0 | 1 | 1 | 1 | 5 | 1 | 2 3 | 1 | 0 | 1 | 1 | 1 | 3 | 1 | 0 3 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 - 5 | 1 | 2 | 1 | 1 | 1 | 9 | 1 | 0 - 5 | 1 | 2 | 1 | 1 | 1 | 7 | 1 | 1 - 5 | 1 | 2 | 1 | 1 | 1 | 5 | 1 | 2 - 5 | 1 | 2 | 1 | 1 | 1 | 3 | 1 | 0 - 5 | 1 | 2 | 1 | 1 | 1 | 1 | 1 | 1 - 7 | 1 | 1 | 1 | 1 | 1 | 9 | 1 | 0 + 3 | 1 | 0 | 1 | 1 | 1 | 9 | 1 | 0 + 3 | 1 | 0 | 1 | 1 | 1 | 5 | 1 | 2 7 | 1 | 1 | 1 | 1 | 1 | 7 | 1 | 1 - 7 | 1 | 1 | 1 | 1 | 1 | 5 | 1 | 2 7 | 1 | 1 | 1 | 1 | 1 | 3 | 1 | 0 7 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 - 9 | 1 | 0 | 1 | 1 | 1 | 9 | 1 | 0 + 7 | 1 | 1 | 1 | 1 | 1 | 9 | 1 | 0 + 7 | 1 | 1 | 1 | 1 | 1 | 5 | 1 | 2 + 1 | 1 | 1 | 1 | 1 | 1 | 7 | 1 | 1 + 1 | 1 | 1 | 1 | 1 | 1 | 3 | 1 | 0 + 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 + 1 | 1 | 1 | 1 | 1 | 1 | 9 | 1 | 0 + 1 | 1 | 1 | 1 | 1 | 1 | 5 | 1 | 2 + 5 | 1 | 2 | 1 | 1 | 1 | 7 | 1 | 1 + 5 | 1 | 2 | 1 | 1 | 1 | 3 | 1 | 0 + 5 | 1 | 2 | 1 | 1 | 1 | 1 | 1 | 1 + 5 | 1 | 2 | 1 | 1 | 1 | 9 | 1 | 0 + 5 | 1 | 2 | 1 | 1 | 1 | 5 | 1 | 2 9 | 1 | 0 | 1 | 1 | 1 | 7 | 1 | 1 - 9 | 1 | 0 | 1 | 1 | 1 | 5 | 1 | 2 9 | 1 | 0 | 1 | 1 | 1 | 3 | 1 | 0 9 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 + 9 | 1 | 0 | 1 | 1 | 1 | 9 | 1 | 0 + 9 | 1 | 0 | 1 | 1 | 1 | 5 | 1 | 2 (25 rows) with x as (select * from orca.rcte where a < 10) select * from x x2 where x2.b < (select avg(b) from x x1); @@ -7016,8 +7023,8 @@ with x as (select * from orca.rcte where a < 10) select * from x x2 where x2.b < ---+---+--- 2 | 0 | 2 4 | 0 | 1 - 6 | 0 | 0 8 | 0 | 2 + 6 | 0 | 0 (4 rows) with x as (select r.a from orca.r, orca.s where r.a < 10 and s.d < 10 and r.a = s.d) select * from x x1, x x2; @@ -7254,694 +7261,694 @@ with x as (select r.a from orca.r, orca.s where r.a < 10 and s.c < 10 and r.a = a | a ---+--- 1 | 1 - 3 | 1 - 5 | 1 1 | 1 - 3 | 1 - 5 | 1 1 | 1 - 3 | 1 - 5 | 1 1 | 1 - 3 | 1 - 5 | 1 1 | 1 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 1 | 1 - 3 | 1 - 5 | 1 1 | 1 - 3 | 1 - 5 | 1 1 | 1 - 3 | 1 - 5 | 1 1 | 1 - 3 | 1 - 5 | 1 1 | 1 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 1 | 1 - 3 | 1 - 5 | 1 1 | 1 - 3 | 1 - 5 | 1 1 | 1 - 3 | 1 - 5 | 1 1 | 1 - 3 | 1 - 5 | 1 1 | 1 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 1 | 1 - 3 | 1 - 5 | 1 1 | 1 - 3 | 1 - 5 | 1 1 | 1 - 3 | 1 - 5 | 1 1 | 1 - 3 | 1 - 5 | 1 1 | 1 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 1 | 1 - 3 | 1 - 5 | 1 1 | 1 - 3 | 1 - 5 | 1 1 | 1 - 3 | 1 - 5 | 1 1 | 1 + 1 | 1 + 2 | 1 + 2 | 1 + 2 | 1 + 2 | 1 + 2 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 4 | 1 + 4 | 1 + 4 | 1 + 4 | 1 + 4 | 1 + 2 | 1 + 2 | 1 + 2 | 1 + 2 | 1 + 2 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 4 | 1 + 4 | 1 + 4 | 1 + 4 | 1 + 4 | 1 + 2 | 1 + 2 | 1 + 2 | 1 + 2 | 1 + 2 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 4 | 1 + 4 | 1 + 4 | 1 + 4 | 1 + 4 | 1 + 2 | 1 + 2 | 1 + 2 | 1 + 2 | 1 + 2 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 3 | 1 3 | 1 + 4 | 1 + 4 | 1 + 4 | 1 + 4 | 1 + 4 | 1 + 2 | 1 + 2 | 1 + 2 | 1 + 2 | 1 + 2 | 1 5 | 1 - 1 | 1 - 1 | 2 - 3 | 2 - 5 | 2 + 5 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 6 | 1 1 | 2 - 3 | 2 - 5 | 2 + 1 | 3 + 1 | 4 1 | 2 - 3 | 2 - 5 | 2 + 1 | 3 + 1 | 4 1 | 2 - 3 | 2 - 5 | 2 + 1 | 3 + 1 | 4 1 | 2 + 1 | 3 1 | 4 - 3 | 4 - 5 | 4 + 1 | 2 + 1 | 2 + 1 | 3 1 | 4 - 3 | 4 - 5 | 4 + 1 | 2 + 1 | 3 1 | 4 - 3 | 4 - 5 | 4 + 1 | 2 + 1 | 3 1 | 4 - 3 | 4 - 5 | 4 + 1 | 2 + 1 | 3 1 | 4 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 1 | 2 - 3 | 2 - 5 | 2 1 | 2 - 3 | 2 - 5 | 2 + 1 | 3 + 1 | 4 1 | 2 - 3 | 2 - 5 | 2 + 1 | 3 + 1 | 4 1 | 2 - 3 | 2 - 5 | 2 + 1 | 3 + 1 | 4 1 | 2 + 1 | 3 1 | 4 - 3 | 4 - 5 | 4 + 1 | 2 + 1 | 2 + 1 | 3 1 | 4 - 3 | 4 - 5 | 4 + 1 | 2 + 1 | 3 1 | 4 - 3 | 4 - 5 | 4 + 1 | 2 + 1 | 3 1 | 4 - 3 | 4 - 5 | 4 + 1 | 2 + 1 | 3 1 | 4 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 1 | 2 - 3 | 2 - 5 | 2 1 | 2 - 3 | 2 - 5 | 2 + 1 | 3 + 1 | 4 1 | 2 - 3 | 2 - 5 | 2 + 1 | 3 + 1 | 4 1 | 2 - 3 | 2 - 5 | 2 + 1 | 3 + 1 | 4 1 | 2 + 1 | 3 1 | 4 + 1 | 2 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 3 | 2 + 3 | 3 3 | 4 - 5 | 4 - 1 | 4 + 3 | 2 + 3 | 3 3 | 4 - 5 | 4 - 1 | 4 + 3 | 2 + 3 | 3 3 | 4 - 5 | 4 - 1 | 4 + 3 | 2 + 3 | 3 3 | 4 - 5 | 4 - 1 | 4 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 1 | 2 3 | 2 - 5 | 2 - 1 | 2 - 3 | 2 - 5 | 2 - 1 | 2 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 3 | 2 - 5 | 2 - 1 | 2 + 3 | 3 + 3 | 4 3 | 2 - 5 | 2 - 1 | 2 - 1 | 4 + 3 | 3 3 | 4 - 5 | 4 - 1 | 4 + 3 | 2 + 3 | 3 3 | 4 - 5 | 4 - 1 | 4 + 3 | 2 + 3 | 3 3 | 4 - 5 | 4 - 1 | 4 + 3 | 2 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 3 | 2 + 3 | 3 3 | 4 - 5 | 4 - 1 | 4 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 1 | 2 3 | 2 - 5 | 2 - 1 | 2 + 3 | 3 + 3 | 4 3 | 2 - 5 | 2 - 1 | 2 + 3 | 3 + 3 | 4 3 | 2 - 5 | 2 - 1 | 2 + 3 | 3 + 3 | 4 3 | 2 - 5 | 2 - 1 | 2 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 2 | 3 + 4 | 2 4 | 3 - 6 | 3 - 2 | 3 + 4 | 4 + 4 | 2 4 | 3 - 6 | 3 - 2 | 3 + 4 | 4 + 4 | 2 4 | 3 - 6 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 3 | 2 + 3 | 3 + 3 | 4 + 3 | 2 + 3 | 3 + 3 | 4 + 3 | 2 + 3 | 3 + 3 | 4 + 3 | 2 + 3 | 3 + 3 | 4 + 3 | 2 + 4 | 2 4 | 3 - 6 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 2 | 3 + 2 | 4 + 2 | 2 + 5 | 2 + 5 | 3 + 5 | 4 + 5 | 2 + 5 | 3 + 5 | 4 + 5 | 2 + 5 | 3 + 5 | 4 + 5 | 2 + 5 | 3 + 5 | 4 + 5 | 2 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 5 | 2 + 5 | 3 + 5 | 4 + 5 | 2 + 5 | 3 + 5 | 4 + 5 | 2 + 5 | 3 + 5 | 4 + 5 | 2 + 5 | 3 + 5 | 4 + 5 | 2 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 5 | 2 + 5 | 3 + 5 | 4 + 5 | 2 + 5 | 3 + 5 | 4 + 5 | 2 + 5 | 3 + 5 | 4 + 5 | 2 + 5 | 3 + 5 | 4 + 5 | 2 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 5 | 2 + 5 | 3 + 5 | 4 + 5 | 2 + 5 | 3 + 5 | 4 + 5 | 2 + 5 | 3 + 5 | 4 + 5 | 2 + 5 | 3 + 5 | 4 + 5 | 2 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 2 | 5 + 2 | 6 + 2 | 5 + 2 | 6 + 2 | 5 + 2 | 6 + 2 | 5 + 2 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 4 | 5 - 6 | 5 - 2 | 5 + 4 | 6 4 | 5 - 6 | 5 - 2 | 5 + 4 | 6 4 | 5 - 6 | 5 - 2 | 5 + 4 | 6 4 | 5 - 6 | 5 + 4 | 6 2 | 5 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 + 2 | 6 2 | 5 - 4 | 5 - 6 | 5 + 2 | 6 2 | 5 - 4 | 5 - 6 | 5 + 2 | 6 2 | 5 + 2 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 4 | 5 - 6 | 5 - 2 | 5 + 4 | 6 4 | 5 - 6 | 5 - 2 | 5 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 2 | 5 + 4 | 6 4 | 5 - 6 | 5 - 2 | 5 + 4 | 6 4 | 5 - 6 | 5 + 4 | 6 2 | 5 - 4 | 5 - 6 | 5 + 2 | 6 2 | 5 - 4 | 5 - 6 | 5 + 2 | 6 2 | 5 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 + 2 | 6 2 | 5 + 2 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 4 | 5 - 6 | 5 - 2 | 5 + 4 | 6 4 | 5 - 6 | 5 - 2 | 5 + 4 | 6 4 | 5 - 6 | 5 - 2 | 5 + 4 | 6 4 | 5 - 6 | 5 + 4 | 6 2 | 5 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 2 | 6 - 4 | 6 - 6 | 6 + 2 | 5 2 | 6 - 4 | 6 - 6 | 6 + 2 | 5 2 | 6 - 4 | 6 - 6 | 6 + 2 | 5 2 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 + 4 | 5 4 | 6 - 6 | 6 + 4 | 5 + 4 | 6 + 4 | 5 + 4 | 6 + 4 | 5 + 4 | 6 + 2 | 5 2 | 6 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 + 2 | 5 2 | 6 - 4 | 6 + 2 | 5 + 2 | 6 + 2 | 5 + 2 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 6 | 5 + 6 | 6 + 6 | 5 + 6 | 6 + 6 | 5 6 | 6 - 2 | 6 - 4 | 6 + 6 | 5 6 | 6 - 2 | 6 - 4 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 6 | 5 6 | 6 - 2 | 6 - 4 | 6 + 6 | 5 6 | 6 - 2 | 6 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 2 | 6 - 4 | 6 + 6 | 5 6 | 6 - 2 | 6 - 4 | 6 + 6 | 5 6 | 6 - 2 | 6 - 4 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 6 | 5 6 | 6 - 2 | 6 - 4 | 6 + 6 | 5 6 | 6 - 2 | 6 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 2 | 6 - 4 | 6 + 6 | 5 6 | 6 - 2 | 6 - 4 | 6 + 6 | 5 6 | 6 - 2 | 6 - 4 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 6 | 5 6 | 6 - 2 | 6 - 4 | 6 + 6 | 5 + 6 | 6 + 6 | 5 + 6 | 6 + 6 | 5 6 | 6 - 2 | 6 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 (676 rows) with x as (select * from orca.rcte where a < 10) (select a from x x2) union all (select max(a) from x x1); a --- + 1 2 + 3 4 - 6 + 7 8 - 1 - 3 5 - 7 + 6 9 9 (10 rows) @@ -7981,7 +7988,7 @@ select (select generate_series(1,5)); ERROR: one or more assertions failed DETAIL: Expected no more than one row to be returned by expression select (select a from orca.foo inner1 where inner1.a=outer1.a union select b from orca.foo inner2 where inner2.b=outer1.b) from orca.foo outer1; -ERROR: more than one row returned by a subquery used as an expression +ERROR: more than one row returned by a subquery used as an expression (seg1 slice1 172.18.0.2:7003 pid=60470) select (select generate_series(1,1)) as series; series -------- @@ -8143,11 +8150,11 @@ group by ten having exists (select 1 from orca.onek b where sum(distinct a.four) = b.four); ten | sum -----+----- + 9 | 3 0 | 2 1 | 3 3 | 3 4 | 2 - 9 | 3 (5 rows) -- indexes on partitioned tables @@ -8166,6 +8173,8 @@ insert into orca.t select i, i::char(2), i, i, case when i%2 = 0 then 'a' else 'b' end, i from generate_series(1,100) i; select * from orca.t order by 1, 2, 3, 4, 5, 6 limit 4; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b | to_be_drop | c | d | e ---+----+------------+---+----+--- 1 | 1 | 1 | 1 | b | 1 @@ -8176,6 +8185,8 @@ select * from orca.t order by 1, 2, 3, 4, 5, 6 limit 4; alter table orca.t drop column to_be_drop; select * from orca.t order by 1, 2, 3, 4, 5 limit 4; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b | c | d | e ---+----+---+----+--- 1 | 1 | 1 | b | 1 @@ -8187,6 +8198,8 @@ select * from orca.t order by 1, 2, 3, 4, 5 limit 4; insert into orca.t (d, a) values('a', 0); insert into orca.t (a, d) values(0, 'b'); select * from orca.t order by 1, 2, 3, 4, 5 limit 4; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b | c | d | e ---+----+---+----+--- 0 | | | a | @@ -8215,8 +8228,8 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Multi-level partitioned tables a | b -----+----- - 1 | 1 100 | 200 + 1 | 1 (2 rows) -- test appendonly @@ -8228,6 +8241,8 @@ insert into orca.t select i, i::char(2), i, i, case when i%2 = 0 then 'a' else 'b' end, i from generate_series(1,100) i; select * from orca.t order by 1, 2, 3, 4, 5, 6 limit 4; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b | to_be_drop | c | d | e ---+----+------------+---+----+--- 1 | 1 | 1 | 1 | b | 1 @@ -8238,6 +8253,8 @@ select * from orca.t order by 1, 2, 3, 4, 5, 6 limit 4; alter table orca.t drop column to_be_drop; select * from orca.t order by 1, 2, 3, 4, 5 limit 4; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b | c | d | e ---+----+---+----+--- 1 | 1 | 1 | b | 1 @@ -8250,6 +8267,8 @@ insert into orca.t select i, i::char(2), i, case when i%2 = 0 then 'a' else 'b' end, i from generate_series(1,100) i; select * from orca.t order by 1, 2, 3, 4, 5 limit 4; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b | c | d | e ---+----+---+----+--- 1 | 1 | 1 | b | 1 @@ -8276,6 +8295,8 @@ insert into orca.t values('201207',1,'tag1','tag2'); insert into orca.t values('201208',2,'tag1','tag2'); -- test projections select * from orca.t order by 1,2; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. timest | user_id | tag1 | tag2 --------+---------+-------+------- 201203 | 0 | tag1 | tag2 @@ -8289,6 +8310,8 @@ select * from orca.t order by 1,2; -- test EXPLAIN support of partition selection nodes, while we're at it. explain select * from orca.t order by 1,2; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN ------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=24) @@ -8297,10 +8320,12 @@ explain select * from orca.t order by 1,2; Sort Key: timest, user_id -> Dynamic Seq Scan on t (cost=0.00..431.00 rows=1 width=24) Number of partitions to scan: 6 (out of 6) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) select tag2, tag1 from orca.t order by 1, 2;; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. tag2 | tag1 -------+------- tag2 | tag1 @@ -8313,6 +8338,8 @@ select tag2, tag1 from orca.t order by 1, 2;; (7 rows) select tag1, user_id from orca.t order by 1, 2; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. tag1 | user_id -------+--------- tag1 | 0 @@ -8326,6 +8353,8 @@ select tag1, user_id from orca.t order by 1, 2; insert into orca.t(user_id, timest, tag2) values(3, '201208','tag2'); select * from orca.t order by 1, 2; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. timest | user_id | tag1 | tag2 --------+---------+-------+------- 201203 | 0 | tag1 | tag2 @@ -8365,6 +8394,9 @@ insert into orca.t_date values('01-03-2012'::date,8,'tag1','tag2'); insert into orca.t_date values('01-03-2012'::date,9,'tag1','tag2'); set optimizer_enable_space_pruning=off; set optimizer_enable_constant_expression_evaluation=on; +-- start_ignore +analyze orca.t_date; +-- end_ignore explain select * from orca.t_date where user_id=9; QUERY PLAN ------------------------------------------------------------------------------- @@ -8372,7 +8404,7 @@ explain select * from orca.t_date where user_id=9; -> Dynamic Seq Scan on t_date (cost=0.00..431.00 rows=1 width=20) Number of partitions to scan: 6 (out of 6) Filter: (user_id = '9'::numeric) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) select * from orca.t_date where user_id=9; @@ -8408,6 +8440,9 @@ insert into orca.t_text values('01-03-2012'::date,8,'bad','tag2'); insert into orca.t_text values('01-03-2012'::date,9,'ugly','tag2'); set optimizer_enable_space_pruning=off; set optimizer_enable_constant_expression_evaluation=on; +-- start_ignore +analyze orca.t_text; +-- end_ignore explain select * from orca.t_text where user_id=9; QUERY PLAN ------------------------------------------------------------------------------- @@ -8415,7 +8450,7 @@ explain select * from orca.t_text where user_id=9; -> Dynamic Seq Scan on t_text (cost=0.00..431.00 rows=1 width=20) Number of partitions to scan: 3 (out of 3) Filter: (user_id = '9'::numeric) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) select * from orca.t_text where user_id=9; @@ -8443,6 +8478,9 @@ insert into orca.t_ceeval_ints values(5, 102, 'tag1', 'tag2'); set optimizer_enable_space_pruning=off; set optimizer_enable_constant_expression_evaluation=on; set optimizer_use_external_constant_expression_evaluation_for_ints = on; +-- start_ignore +analyze orca.t_ceeval_ints; +-- end_ignore explain select * from orca.t_ceeval_ints where user_id=4; QUERY PLAN ------------------------------------------------------------------------------- @@ -8450,7 +8488,7 @@ explain select * from orca.t_ceeval_ints where user_id=4; -> Dynamic Seq Scan on t_ceeval_ints (cost=0.00..431.00 rows=1 width=21) Number of partitions to scan: 3 (out of 3) Filter: (user_id = '4'::numeric) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) select * from orca.t_ceeval_ints where user_id=4; @@ -8513,9 +8551,9 @@ insert into orca.fooh2 select i%3, i%2, i from generate_series(1,20) i; select sum(f1.b) from orca.fooh1 f1 group by f1.a; sum ----- + 5 4 6 - 5 6 (4 rows) @@ -8625,27 +8663,27 @@ select sum(f1.a+1)+1 from orca.fooh1 f1 group by f1.a+1; ?column? ---------- 11 + 16 21 6 - 16 (4 rows) select sum(f1.a+1)+sum(f1.a+1) from orca.fooh1 f1 group by f1.a+1; ?column? ---------- - 20 - 40 10 + 20 30 + 40 (4 rows) select sum(f1.a+1)+avg(f1.a+1), sum(f1.a), sum(f1.a+1) from orca.fooh1 f1 group by f1.a+1; ?column? | sum | sum ------------------------+-----+----- - 12.0000000000000000 | 5 | 10 - 24.0000000000000000 | 15 | 20 6.00000000000000000000 | 0 | 5 + 12.0000000000000000 | 5 | 10 18.0000000000000000 | 10 | 15 + 24.0000000000000000 | 15 | 20 (4 rows) -- @@ -8676,45 +8714,45 @@ select a, (select sum(e) from bar where foo.b = bar.f), b, count(*) from foo, ja select foo.a, (select (foo.a + foo.b) * count(bar.e) from bar), b, count(*) from foo group by foo.a, foo.b, foo.a + foo.b; a | ?column? | b | count ---+----------+---+------- - 3 | 18 | 3 | 1 1 | 6 | 1 | 1 2 | 12 | 2 | 1 + 3 | 18 | 3 | 1 (3 rows) -- aggfunc over an outer reference in a subquery select (select sum(foo.a + bar.d) from bar) from foo group by a, b; sum ----- - 9 12 15 + 9 (3 rows) -- complex expression of aggfunc over an outer reference in a subquery select (select sum(foo.a + bar.d) + 1 from bar) from foo group by a, b; ?column? ---------- - 10 13 16 + 10 (3 rows) -- aggrefs with multiple agglevelsup select (select (select sum(foo.a + bar.d) from jazz) from bar) from foo group by a, b; sum ----- + 9 12 15 - 9 (3 rows) -- aggrefs with multiple agglevelsup in an expression select (select (select sum(foo.a + bar.d) * 2 from jazz) from bar) from foo group by a, b; ?column? ---------- - 18 24 30 + 18 (3 rows) -- nested group by @@ -8739,26 +8777,26 @@ select a, count(*), (with cte as (select min(d) dd from bar group by e) select m select a, count(*), (with cte as (select e, min(d) as dd from bar group by e) select max(a) * sum(dd) from cte) from foo group by a; a | count | ?column? ---+-------+---------- - 3 | 1 | 18 1 | 1 | 6 2 | 1 | 12 + 3 | 1 | 18 (3 rows) -- subquery in group by select max(a) from foo group by (select e from bar where bar.e = foo.a); max ----- + 2 3 1 - 2 (3 rows) -- nested subquery in group by select max(a) from foo group by (select g from jazz where foo.a = (select max(a) from foo where c = 1 group by b)); max ----- - 3 1 + 3 (2 rows) -- group by inside groupby inside group by @@ -8773,9 +8811,9 @@ select max(a) from foo group by (select min(g) from jazz where foo.a = (select m select max(a) from foo group by b, (with cte as (select min(g) from jazz group by h) select a from cte); max ----- - 3 1 2 + 3 (3 rows) -- group by subquery in order by @@ -8800,18 +8838,18 @@ select max(b), (select foo.a * count(bar.e) from bar), (with cte as (select e, m select b + (a+1) from foo group by b, a+1; ?column? ---------- - 3 5 7 + 3 (3 rows) -- subselects inside aggs SELECT foo.b+1, avg (( SELECT bar.f FROM bar WHERE bar.d = foo.b)) AS t FROM foo GROUP BY foo.b; ?column? | t ----------+------------------------ - 2 | 1.00000000000000000000 3 | 2.0000000000000000 4 | 3.0000000000000000 + 2 | 1.00000000000000000000 (3 rows) SELECT foo.b+1, sum( 1 + (SELECT bar.f FROM bar WHERE bar.d = ANY (SELECT jazz.g FROM jazz WHERE jazz.h = foo.b))) AS t FROM foo GROUP BY foo.b; @@ -8825,18 +8863,18 @@ SELECT foo.b+1, sum( 1 + (SELECT bar.f FROM bar WHERE bar.d = ANY (SELECT jazz.g select foo.b+1, sum((with cte as (select * from jazz) select 1 from cte where cte.h = foo.b)) as t FROM foo GROUP BY foo.b; ?column? | t ----------+--- - 2 | 3 | 1 4 | + 2 | (3 rows) -- ctes inside aggs select foo.b+1, sum((with cte as (select * from jazz) select 1 from cte cte1, cte cte2 where cte1.h = foo.b)) as t FROM foo GROUP BY foo.b; ?column? | t ----------+--- + 2 | 3 | 1 4 | - 2 | (3 rows) drop table foo, bar, jazz; @@ -8851,8 +8889,8 @@ SELECT to_char(AVG( char_length(DT466.C952) ), '9999999.9999999'), MAX( char_len to_char | max ------------------+----- 5.0000000 | 5 - 4.0000000 | 4 6.0000000 | 6 + 4.0000000 | 4 (3 rows) create table orca.prod9 (sale integer, prodnm varchar,price integer); @@ -8865,8 +8903,8 @@ insert into orca.prod9 values (300, 't-shirts', 300); select prodnm, price from orca.prod9 GROUP BY prodnm, price HAVING price !=300; prodnm | price --------+------- - shirts | 500 pants | 800 + shirts | 500 (2 rows) -- analyze on tables with dropped attributes @@ -8875,7 +8913,7 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into orca.toanalyze values (1,1), (2,2), (3,3); alter table orca.toanalyze drop column a; -NOTICE: dropping a column that is part of the distribution policy forces a random distribution policy +NOTICE: dropping a column that is part of the distribution policy forces a NULL distribution policy analyze orca.toanalyze; -- union create table orca.ur (a int, b int); @@ -8998,14 +9036,14 @@ select * from orca.tab1 where 0 < (select count(*) from generate_series(1,i)) or select * from orca.tab1 where i > (select b from orca.tab2); i | j ----+--- - 4 | 0 - 6 | 0 - 8 | 0 - 10 | 0 3 | 1 + 4 | 0 5 | 1 - 7 | 1 9 | 1 + 10 | 0 + 6 | 0 + 7 | 1 + 8 | 0 (8 rows) -- subqueries @@ -9121,6 +9159,8 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into mpp22791 values (1, 1), (2, 2), (3, 3); select * from mpp22791 where b > 1; +NOTICE: One or more columns in the following table(s) do not have statistics: mpp22791 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b ---+--- 2 | 2 @@ -9128,11 +9168,13 @@ select * from mpp22791 where b > 1; (2 rows) select * from mpp22791 where b <= 3; +NOTICE: One or more columns in the following table(s) do not have statistics: mpp22791 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b ---+--- - 1 | 1 - 3 | 3 2 | 2 + 3 | 3 + 1 | 1 (3 rows) -- MPP-20713, MPP-20714, MPP-20738: Const table get with a filter @@ -9147,6 +9189,8 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into orca.p1 select * from generate_series(2,15); select count(*) from (select gp_segment_id,ctid,tableoid from orca.p1 group by gp_segment_id,ctid,tableoid) as foo; +NOTICE: One or more columns in the following table(s) do not have statistics: p1 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. count ------- 14 @@ -9908,7 +9952,7 @@ where c.cid = s.cid and s.date_sk = d.date_sk and -> Hash (cost=431.00..431.00 rows=1 width=12) -> Seq Scan on datedim d (cost=0.00..431.00 rows=1 width=12) Filter: ((year = 2001) OR (moy = 4)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (18 rows) -- Bitmap indexes @@ -9963,6 +10007,9 @@ alter table orca.bm_dyn_test drop column to_be_dropped; alter table orca.bm_dyn_test add partition part5 values(5); insert into orca.bm_dyn_test values(2, 5, '2'); set optimizer_enable_dynamicbitmapscan=on; +-- start_ignore +analyze orca.bm_dyn_test; +-- end_ignore -- gather on 1 segment because of direct dispatch explain select * from orca.bm_dyn_test where i=2 and t='2'; QUERY PLAN @@ -9974,7 +10021,7 @@ explain select * from orca.bm_dyn_test where i=2 and t='2'; Filter: ((i = 2) AND (t = '2'::text)) -> Dynamic Bitmap Index Scan on bm_dyn_test_idx (cost=0.00..0.00 rows=0 width=0) Index Cond: (i = 2) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) select * from orca.bm_dyn_test where i=2 and t='2'; @@ -10017,7 +10064,7 @@ analyze orca.bm_dyn_test_onepart; explain select * from orca.bm_dyn_test_onepart where i=2 and t='2'; INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because no plan has been computed for required properties in GPORCA - QUERY PLAN + QUERY PLAN ------------------------------------------------------------------------------------------------------------------ Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..6.85 rows=22 width=10) -> Append (cost=0.00..6.55 rows=7 width=10) @@ -10393,8 +10440,8 @@ select id, comment from idxscan_outer as o join idxscan_inner as i on o.id = i.p where ordernum between 10 and 20; id | comment ----+--------- - 1 | xxxx 3 | zzzz + 1 | xxxx (2 rows) reset optimizer_enable_hashjoin; @@ -10510,7 +10557,7 @@ show optimizer; update can_set_tag_target set y = y + 1; INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner -DETAIL: DXL-to-PlStmt Translation: Attribute number 12 not found in project list +DETAIL: DXL-to-PlStmt Translation: Attribute number 8 not found in project list select count(1) from can_set_tag_audit; count ------- @@ -10525,6 +10572,7 @@ drop table can_set_tag_target; drop table can_set_tag_audit; -- start_ignore create language plpython3u; +ERROR: extension "plpython3u" already exists -- end_ignore -- Checking if ORCA uses parser's canSetTag for CREATE TABLE AS SELECT create or replace function canSetTag_Func(x int) returns int as $$ @@ -10556,6 +10604,12 @@ select disable_xform('CXformSelect2IndexGet'); CXformSelect2IndexGet is disabled (1 row) +select disable_xform('CXformSelect2IndexOnlyGet'); + disable_xform +--------------------------------------- + CXformSelect2IndexOnlyGet is disabled +(1 row) + -- end_ignore EXPLAIN SELECT * FROM btree_test WHERE a in (1, 47); QUERY PLAN @@ -10618,7 +10672,7 @@ EXPLAIN SELECT * FROM btree_test WHERE a in (1, 2, 47) AND b > 1; Recheck Cond: ((a = ANY ('{1,2,47}'::integer[])) AND (b > 1)) -> Bitmap Index Scan on btree_test_index_ab (cost=0.00..0.00 rows=0 width=0) Index Cond: ((a = ANY ('{1,2,47}'::integer[])) AND (b > 1)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (6 rows) SELECT * FROM btree_test WHERE a in (1, 2, 47) AND b > 1; @@ -10635,6 +10689,12 @@ select enable_xform('CXformSelect2IndexGet'); CXformSelect2IndexGet is enabled (1 row) +select enable_xform('CXformSelect2IndexOnlyGet'); + enable_xform +-------------------------------------- + CXformSelect2IndexOnlyGet is enabled +(1 row) + -- end_ignore reset optimizer_enable_tablescan; -- Test Bitmap index scan with in list @@ -10699,7 +10759,6 @@ EXPLAIN SELECT * FROM bitmap_test WHERE a in ('1', '2', 47); -- Test Logging for unsupported features in ORCA -- start_ignore drop table if exists foo; -NOTICE: table "foo" does not exist, skipping -- end_ignore create table foo(a int, b int) distributed by (a); -- The amount of log messages you get depends on a lot of options, but any @@ -10863,7 +10922,7 @@ set log_statement='none'; set log_min_duration_statement=-1; set client_min_messages='log'; create table foo_ctas(a) as (select generate_series(1,10)) distributed by (a); -"Falling back to Postgres-based planner because GPORCA does not support the following feature: CTAS. Set optimizer_enable_ctas to on to enable CTAS with GPORCA", +LOG: 2026-06-21 19:55:05:352569 PDT,THD000,NOTICE,"Falling back to Postgres-based planner because GPORCA does not support the following feature: CTAS. Set optimizer_enable_ctas to on to enable CTAS with GPORCA", INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: CTAS. Set optimizer_enable_ctas to on to enable CTAS with GPORCA reset client_min_messages; @@ -10991,14 +11050,14 @@ set optimizer_enable_streaming_material = on; select c1 from t_outer where not c1 =all (select c2 from t_inner); c1 ---- - 1 2 3 4 - 5 - 6 7 8 + 1 + 5 + 6 9 10 (10 rows) @@ -11007,16 +11066,16 @@ set optimizer_enable_streaming_material = off; select c1 from t_outer where not c1 =all (select c2 from t_inner); c1 ---- - 8 - 9 - 10 - 1 2 3 4 + 7 + 8 + 1 5 6 - 7 + 9 + 10 (10 rows) reset optimizer_enable_streaming_material; @@ -11226,8 +11285,8 @@ EXPLAIN SELECT a FROM csq_cast_param_outer WHERE b in (SELECT CASE WHEN a > 1 TH SELECT a FROM csq_cast_param_outer WHERE b in (SELECT CASE WHEN a > 1 THEN d ELSE '42' END FROM csq_cast_param_inner); a --- - 1 2 + 1 (2 rows) SELECT a FROM ggg WHERE a IN (NULL, 'x'); @@ -11317,12 +11376,12 @@ EXPLAIN (COSTS OFF) WITH abc AS (SELECT onetimefilter1.a, onetimefilter1.b FROM WITH abc AS (SELECT onetimefilter1.a, onetimefilter1.b FROM onetimefilter1, onetimefilter2 WHERE onetimefilter1.a=onetimefilter2.a) SELECT (SELECT 1 FROM abc WHERE f1.b = f2.b LIMIT 1), COALESCE((SELECT 2 FROM abc WHERE f1.a=random() AND f1.a=2), 0), (SELECT b FROM abc WHERE b=f1.b) FROM onetimefilter1 f1, onetimefilter2 f2 WHERE f1.b = f2.b; ?column? | coalesce | b ----------+----------+---- - 1 | 0 | 1 + 1 | 0 | 2 1 | 0 | 3 1 | 0 | 4 1 | 0 | 7 1 | 0 | 8 - 1 | 0 | 2 + 1 | 0 | 1 1 | 0 | 5 1 | 0 | 6 1 | 0 | 9 @@ -11338,9 +11397,9 @@ CREATE TABLE fbar (c, d) AS (VALUES (1, 42), (2, 43), (4, 45), (5, 46)) DISTRIBU SELECT d FROM ffoo FULL OUTER JOIN fbar ON a = c WHERE b BETWEEN 5 and 9; d ---- + 45 46 - 45 (3 rows) -- test index left outer joins on bitmap and btree indexes on partitioned tables with and without select clause @@ -11358,16 +11417,16 @@ CREATE INDEX tinnerbtree_ix ON tinnerbtree USING btree(a); SELECT * FROM touter LEFT JOIN tinnerbitmap ON touter.a = tinnerbitmap.a; a | b | a | b ----+---+----+--- - 1 | 1 | 1 | 1 - 6 | 0 | 6 | 0 5 | 5 | 5 | 5 + 6 | 0 | 6 | 0 9 | 3 | 9 | 3 10 | 4 | 10 | 4 + 1 | 1 | 1 | 1 2 | 2 | 2 | 2 - 7 | 1 | 7 | 1 - 8 | 2 | 8 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 + 7 | 1 | 7 | 1 + 8 | 2 | 8 | 2 (10 rows) SELECT * FROM touter LEFT JOIN tinnerbitmap ON touter.a = tinnerbitmap.a AND tinnerbitmap.b=10; @@ -11388,31 +11447,31 @@ SELECT * FROM touter LEFT JOIN tinnerbitmap ON touter.a = tinnerbitmap.a AND tin SELECT * FROM touter LEFT JOIN tinnerbtree ON touter.a = tinnerbtree.a; a | b | a | b ----+---+----+--- - 1 | 1 | 1 | 1 - 6 | 0 | 6 | 0 5 | 5 | 5 | 5 + 6 | 0 | 6 | 0 9 | 3 | 9 | 3 10 | 4 | 10 | 4 2 | 2 | 2 | 2 - 7 | 1 | 7 | 1 - 8 | 2 | 8 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 + 7 | 1 | 7 | 1 + 8 | 2 | 8 | 2 + 1 | 1 | 1 | 1 (10 rows) SELECT * FROM touter LEFT JOIN tinnerbtree ON touter.a = tinnerbtree.a AND tinnerbtree.b=10; a | b | a | b ----+---+---+--- - 1 | 1 | | - 5 | 5 | | - 6 | 0 | | - 9 | 3 | | - 10 | 4 | | 2 | 2 | | 3 | 3 | | 4 | 4 | | 7 | 1 | | 8 | 2 | | + 1 | 1 | | + 5 | 5 | | + 6 | 0 | | + 9 | 3 | | + 10 | 4 | | (10 rows) -- test subplan in a qual under dynamic scan @@ -11440,36 +11499,36 @@ SELECT * FROM ds_part, non_part2 WHERE ds_part.c = non_part2.e AND non_part2.f = explain analyze SELECT * FROM ds_part, non_part2 WHERE ds_part.c = non_part2.e AND non_part2.f = 10 AND a IN ( SELECT b + 1 FROM non_part1); QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324480.95 rows=1 width=20) (actual time=4.000..4.000 rows=0 loops=1) - -> Hash Join (cost=0.00..1324480.95 rows=1 width=20) (actual time=4.000..4.000 rows=0 loops=1) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324480.95 rows=1 width=20) (actual time=3.446..3.450 rows=0 loops=1) + -> Hash Join (cost=0.00..1324480.95 rows=1 width=20) (actual time=3.294..3.297 rows=0 loops=1) Hash Cond: (ds_part.c = non_part2.e) - -> Dynamic Seq Scan on ds_part (cost=0.00..1324049.89 rows=334 width=12) (actual time=0.000..0.000 rows=0 loops=1) + -> Dynamic Seq Scan on ds_part (cost=0.00..1324049.89 rows=334 width=12) (actual time=0.145..0.145 rows=0 loops=1) Number of partitions to scan: 6 (out of 6) Filter: ((a = (b + 1)) AND (SubPlan 1)) Partitions scanned: Avg 1.0 x 3 workers. Max 1 parts (seg0). SubPlan 1 -> Materialize (cost=0.00..431.00 rows=1 width=4) (never executed) -> Broadcast Motion 1:3 (slice2) (cost=0.00..431.00 rows=1 width=4) (never executed) - -> Limit (cost=0.00..431.00 rows=1 width=4) (actual time=4.000..4.000 rows=1 loops=1) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=4) (actual time=4.000..4.000 rows=1 loops=1) - -> Limit (cost=0.00..431.00 rows=1 width=4) (actual time=0.000..0.000 rows=1 loops=1) - -> Seq Scan on non_part1 (cost=0.00..431.00 rows=34 width=4) (actual time=0.000..0.000 rows=1 loops=1) - -> Hash (cost=431.00..431.00 rows=1 width=8) (actual time=4.000..4.000 rows=1 loops=1) + -> Limit (cost=0.00..431.00 rows=1 width=4) (actual time=0.003..0.005 rows=1 loops=1) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=4) (actual time=0.002..0.002 rows=1 loops=1) + -> Limit (cost=0.00..431.00 rows=1 width=4) (actual time=0.094..0.095 rows=1 loops=1) + -> Seq Scan on non_part1 (cost=0.00..431.00 rows=34 width=4) (actual time=0.093..0.094 rows=1 loops=1) + -> Hash (cost=431.00..431.00 rows=1 width=8) (actual time=2.608..2.609 rows=1 loops=1) Buckets: 262144 Batches: 1 Memory Usage: 2049kB - -> Partition Selector (selector id: $0) (cost=0.00..431.00 rows=1 width=8) (actual time=4.000..4.000 rows=1 loops=1) - -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..431.00 rows=1 width=8) (actual time=4.000..4.000 rows=1 loops=1) - -> Seq Scan on non_part2 (cost=0.00..431.00 rows=1 width=8) (actual time=0.000..0.000 rows=1 loops=1) + -> Partition Selector (selector id: $0) (cost=0.00..431.00 rows=1 width=8) (actual time=0.006..2.606 rows=1 loops=1) + -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..431.00 rows=1 width=8) (actual time=0.003..2.602 rows=1 loops=1) + -> Seq Scan on non_part2 (cost=0.00..431.00 rows=1 width=8) (actual time=0.149..0.157 rows=1 loops=1) Filter: (f = 10) Rows Removed by Filter: 24 - Planning Time: 24.393 ms - (slice0) Executor memory: 81K bytes. - (slice1) Executor memory: 2231K bytes avg x 3x(0) workers, 2231K bytes max (seg0). Work_mem: 2049K bytes max. - (slice2) Executor memory: 20K bytes (entry db). - (slice3) Executor memory: 118K bytes avg x 3x(0) workers, 118K bytes max (seg0). - (slice4) Executor memory: 115K bytes avg x 3x(0) workers, 115K bytes max (seg0). + Planning Time: 20.469 ms + (slice0) Executor memory: 69K bytes. + (slice1) Executor memory: 2223K bytes avg x 3x(0) workers, 2223K bytes max (seg0). Work_mem: 2049K bytes max. + (slice2) Executor memory: 18K bytes (entry db). + (slice3) Executor memory: 116K bytes avg x 3x(0) workers, 116K bytes max (seg0). + (slice4) Executor memory: 114K bytes avg x 3x(0) workers, 114K bytes max (seg0). Memory used: 128000kB Optimizer: GPORCA - Execution Time: 2.262 ms + Execution Time: 5.374 ms (30 rows) SELECT *, a IN ( SELECT b + 1 FROM non_part1) FROM ds_part, non_part2 WHERE ds_part.c = non_part2.e AND non_part2.f = 10 AND a IN ( SELECT b FROM non_part1); @@ -11493,8 +11552,8 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO varchar_sc_array_cmp VALUES ('a'), ('b'), ('c'), ('d'); EXPLAIN SELECT * FROM varchar_sc_array_cmp t1, varchar_sc_array_cmp t2 where t1.a = t2.a and t1.a in ('b', 'c'); - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=1 width=16) -> Hash Join (cost=0.00..862.00 rows=1 width=16) Hash Cond: ((t1.a)::text = (t2.a)::text) @@ -11503,7 +11562,7 @@ EXPLAIN SELECT * FROM varchar_sc_array_cmp t1, varchar_sc_array_cmp t2 where t1. -> Hash (cost=431.00..431.00 rows=1 width=8) -> Seq Scan on varchar_sc_array_cmp t2 (cost=0.00..431.00 rows=1 width=8) Filter: (a = ANY ('{b,c}'::character varying[])) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) SELECT * FROM varchar_sc_array_cmp t1, varchar_sc_array_cmp t2 where t1.a = t2.a and t1.a in ('b', 'c'); @@ -11525,15 +11584,15 @@ EXPLAIN SELECT * FROM varchar_sc_array_cmp t1, varchar_sc_array_cmp t2 where t1. -> Hash (cost=431.00..431.00 rows=1 width=8) -> Seq Scan on varchar_sc_array_cmp t2 (cost=0.00..431.00 rows=1 width=8) Filter: (a = ANY ('{a,b,c}'::character varying[])) - Optimizer: Pivotal Optimizer (GPORCA) version 3.65.2 + Optimizer: GPORCA (9 rows) SELECT * FROM varchar_sc_array_cmp t1, varchar_sc_array_cmp t2 where t1.a = t2.a and (t1.a in ('b', 'c') OR t1.a = 'a'); a | a ---+--- + b | b a | a c | c - b | b (3 rows) DROP TABLE varchar_sc_array_cmp; @@ -11612,10 +11671,10 @@ insert into tt values (1, 'b'), (1, 'B'); select * from tc, tt where c = v; a | c | b | v ---+---+---+--- - 1 | a | 1 | a - 1 | A | 1 | A 1 | B | 1 | B 1 | b | 1 | b + 1 | a | 1 | a + 1 | A | 1 | A (4 rows) -- bitmap scan on bitmap index @@ -11635,7 +11694,7 @@ explain select * from tc where c='a'; Recheck Cond: (c = 'a'::citext) -> Bitmap Index Scan on tc_idx (cost=0.00..0.00 rows=0 width=0) Index Cond: (c = 'a'::citext) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (6 rows) -- test gpexpand phase 1 @@ -11697,7 +11756,7 @@ DETAIL: Unknown error: Partially Distributed Data explain select count(*) from noexp_hash n join gpexp_hash x on n.a=x.a; INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Unknown error: Partially Distributed Data - QUERY PLAN + QUERY PLAN ----------------------------------------------------------------------------------------------------------- Finalize Aggregate (cost=3.60..3.61 rows=1 width=8) -> Gather Motion 2:1 (slice1; segments: 2) (cost=3.55..3.59 rows=2 width=8) @@ -11755,7 +11814,7 @@ DETAIL: Unknown error: Partially Distributed Data explain update gpexp_rand set b=(select b from gpexp_hash where gpexp_rand.a = gpexp_hash.a); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Unknown error: Partially Distributed Data - QUERY PLAN + QUERY PLAN ---------------------------------------------------------------------------------------------------------- Update on gpexp_rand (cost=0.00..70.00 rows=0 width=0) -> Seq Scan on gpexp_rand (cost=0.00..70.00 rows=25 width=46) @@ -11796,7 +11855,7 @@ DETAIL: Unknown error: Partially Distributed Data explain insert into gpexp_repl values (20, 20); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Unknown error: Partially Distributed Data - QUERY PLAN + QUERY PLAN -------------------------------------------------------- Insert on gpexp_repl (cost=0.00..0.01 rows=0 width=0) -> Result (cost=0.00..0.01 rows=1 width=8) @@ -11809,7 +11868,7 @@ DETAIL: Unknown error: Partially Distributed Data explain select count(*) from gpexp_hash h join gpexp_repl r on h.a=r.a; INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Unknown error: Partially Distributed Data - QUERY PLAN + QUERY PLAN ------------------------------------------------------------------------------------------- Finalize Aggregate (cost=3.61..3.62 rows=1 width=8) -> Gather Motion 2:1 (slice1; segments: 2) (cost=3.56..3.60 rows=2 width=8) @@ -11833,7 +11892,7 @@ DETAIL: Unknown error: Partially Distributed Data explain select count(*) as expect_20 from noexp_hash h join gpexp_repl r on h.a=r.a; INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Unknown error: Partially Distributed Data - QUERY PLAN + QUERY PLAN ----------------------------------------------------------------------------------------------------------- Finalize Aggregate (cost=3.87..3.88 rows=1 width=8) -> Gather Motion 3:1 (slice1; segments: 3) (cost=3.81..3.86 rows=3 width=8) @@ -11892,6 +11951,19 @@ explain select * from part1, part2 where part1.b = part2.b limit 5; (13 rows) -- test opfamily handling in ORCA +-- start_ignore +DROP FUNCTION abseq(int, int) CASCADE; +NOTICE: drop cascades to 4 other objects +DETAIL: drop cascades to operator |=|(integer,integer) +drop cascades to operator class abs_int_btree_ops for access method btree +drop cascades to operator class abs_int_hash_ops for access method hash +drop cascades to table abs_opclass_test +DROP FUNCTION abslt(int, int) CASCADE; +NOTICE: drop cascades to operator |<|(integer,integer) +DROP FUNCTION absgt(int, int) CASCADE; +NOTICE: drop cascades to operator |>|(integer,integer) +DROP FUNCTION abscmp(int, int) CASCADE; +-- end_ignore CREATE FUNCTION abseq(int, int) RETURNS BOOL AS $$ begin return abs($1) = abs($2); end; @@ -11954,10 +12026,10 @@ SELECT a, b FROM atab_old_hash INNER JOIN btab_old_hash ON a |=| b; a | b ----+---- 0 | 0 - -1 | 1 1 | 1 - -1 | -1 + -1 | 1 1 | -1 + -1 | -1 (5 rows) CREATE OPERATOR CLASS abs_int_hash_ops FOR TYPE int4 @@ -11984,7 +12056,7 @@ EXPLAIN SELECT a, b FROM atab_old_hash INNER JOIN btab_old_hash ON a |=| b; -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=4) Hash Key: atab_old_hash.a -> Seq Scan on atab_old_hash (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) SELECT a, b FROM atab_old_hash INNER JOIN btab_old_hash ON a |=| b; @@ -12010,18 +12082,18 @@ EXPLAIN SELECT a, b FROM btab_old_hash LEFT OUTER JOIN atab_old_hash ON a |=| b; -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=4) Hash Key: atab_old_hash.a -> Seq Scan on atab_old_hash (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) SELECT a, b FROM btab_old_hash LEFT OUTER JOIN atab_old_hash ON a |=| b; a | b ----+---- | 2 + 1 | -1 + -1 | -1 0 | 0 - -1 | 1 1 | 1 - -1 | -1 - 1 | -1 + -1 | 1 (6 rows) set optimizer_expand_fulljoin = on; @@ -12052,15 +12124,15 @@ EXPLAIN SELECT a, b FROM atab_old_hash FULL JOIN btab_old_hash ON a |=| b; -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=4) Hash Key: share3_ref2.a -> Shared Scan (share slice:id 3:3) (cost=0.00..431.00 rows=1 width=4) - -> Hash Anti Join (cost=0.00..862.00 rows=1 width=4) + -> Hash Right Anti Join (cost=0.00..862.00 rows=1 width=4) Hash Cond: (share3_ref3.a |=| share2_ref3.b) - -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..431.00 rows=1 width=4) - Hash Key: share3_ref3.a - -> Shared Scan (share slice:id 4:3) (cost=0.00..431.00 rows=1 width=4) - -> Hash (cost=431.00..431.00 rows=2 width=4) - -> Redistribute Motion 3:3 (slice5; segments: 3) (cost=0.00..431.00 rows=2 width=4) - Hash Key: share2_ref3.b - -> Shared Scan (share slice:id 5:2) (cost=0.00..431.00 rows=2 width=4) + -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..431.00 rows=2 width=4) + Hash Key: share2_ref3.b + -> Shared Scan (share slice:id 4:2) (cost=0.00..431.00 rows=2 width=4) + -> Hash (cost=431.00..431.00 rows=1 width=4) + -> Redistribute Motion 3:3 (slice5; segments: 3) (cost=0.00..431.00 rows=1 width=4) + Hash Key: share3_ref3.a + -> Shared Scan (share slice:id 5:3) (cost=0.00..431.00 rows=1 width=4) Optimizer: GPORCA (28 rows) @@ -12069,10 +12141,10 @@ SELECT a, b FROM atab_old_hash FULL JOIN btab_old_hash ON a |=| b; ----+---- | 2 0 | 0 - 1 | -1 1 | 1 - -1 | -1 -1 | 1 + 1 | -1 + -1 | -1 (6 rows) reset optimizer_expand_fulljoin; @@ -12177,8 +12249,8 @@ SELECT DISTINCT L1.c, L1.lid FROM t55 L1 CROSS JOIN META WHERE L1.lid = int4in(textout(meta.load_id)); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause. Creating a NULL policy entry. - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Result (cost=0.00..431.09 rows=1 width=8) Output: c, lid -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..431.07 rows=1 width=8) @@ -12198,7 +12270,7 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause. Creating a NULL policy entr Output: ('2020-01-01'::text), ('99'::text) -> Result (cost=0.00..0.00 rows=1 width=1) Output: '2020-01-01'::text, '99'::text - Settings: enable_incremental_sort = 'on', optimizer = 'on', optimizer_enable_dynamicbitmapscan = 'on', optimizer_join_order = 'query' + Settings: optimizer = 'on', gp_use_streaming_hashagg = 'off', enable_incremental_sort = 'on', optimizer_segments = '3', optimizer_enable_dynamicbitmapscan = 'on', optimizer_join_order = 'query' Optimizer: GPORCA (21 rows) @@ -12219,10 +12291,6 @@ SELECT * from tp; create table lossycastrangepart(a float, b float) partition by range(b) (start(0) end(40) every(10)); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. -NOTICE: CREATE TABLE will create partition "lossycastrangepart_1_prt_1" for table "lossycastrangepart" -NOTICE: CREATE TABLE will create partition "lossycastrangepart_1_prt_2" for table "lossycastrangepart" -NOTICE: CREATE TABLE will create partition "lossycastrangepart_1_prt_3" for table "lossycastrangepart" -NOTICE: CREATE TABLE will create partition "lossycastrangepart_1_prt_4" for table "lossycastrangepart" insert into lossycastrangepart (values (5.1,5.1), (9.9,9.9), (10.1,10.1), (9.1,9.1), (10.9,10.9), (11.1,11.1), (21.0,21.0)); explain select * from lossycastrangepart where b::int = 10; QUERY PLAN @@ -12237,8 +12305,8 @@ explain select * from lossycastrangepart where b::int = 10; select * from lossycastrangepart where b::int = 10; a | b ------+------ - 10.1 | 10.1 9.9 | 9.9 + 10.1 | 10.1 (2 rows) explain select * from lossycastrangepart where b::int = 11; @@ -12271,8 +12339,8 @@ explain select * from lossycastrangepart where b::int < 10; select * from lossycastrangepart where b::int < 10; a | b -----+----- - 9.1 | 9.1 5.1 | 5.1 + 9.1 | 9.1 (2 rows) explain select * from lossycastrangepart where b::int < 11; @@ -12281,25 +12349,22 @@ explain select * from lossycastrangepart where b::int < 11; Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=16) -> Dynamic Seq Scan on lossycastrangepart (cost=0.00..431.00 rows=1 width=16) Number of partitions to scan: 4 (out of 4) - Filter: (int4(b) < 11) - Optimizer: Pivotal Optimizer (GPORCA) + Filter: ((b)::integer < 11) + Optimizer: GPORCA (5 rows) select * from lossycastrangepart where b::int < 11; a | b ------+------ - 9.1 | 9.1 - 10.1 | 10.1 5.1 | 5.1 + 10.1 | 10.1 9.9 | 9.9 + 9.1 | 9.1 (4 rows) create table lossycastlistpart( a int, b float) partition by list(b) (partition l1 values(1.7, 2.1), partition l2 values(1.3, 2.7), partition l3 values(1.8, 2.8)); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. -NOTICE: CREATE TABLE will create partition "lossycastlistpart_1_prt_l1" for table "lossycastlistpart" -NOTICE: CREATE TABLE will create partition "lossycastlistpart_1_prt_l2" for table "lossycastlistpart" -NOTICE: CREATE TABLE will create partition "lossycastlistpart_1_prt_l3" for table "lossycastlistpart" insert into lossycastlistpart (values (1.0,2.1), (1.0,1.3), (10.1,2.1), (9.1,2.7), (10.9,1.8), (11.1,2.8), (21.0,1.7)); explain select * from lossycastlistpart where b::int < 2; QUERY PLAN @@ -12307,8 +12372,8 @@ explain select * from lossycastlistpart where b::int < 2; Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=12) -> Dynamic Seq Scan on lossycastlistpart (cost=0.00..431.00 rows=1 width=12) Number of partitions to scan: 3 (out of 3) - Filter: (int4(b) < 2) - Optimizer: Pivotal Optimizer (GPORCA) + Filter: ((b)::integer < 2) + Optimizer: GPORCA (5 rows) select * from lossycastlistpart where b::int < 2; @@ -12323,17 +12388,17 @@ explain select * from lossycastlistpart where b::int = 2; Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=12) -> Dynamic Seq Scan on lossycastlistpart (cost=0.00..431.00 rows=1 width=12) Number of partitions to scan: 3 (out of 3) - Filter: (int4(b) = 2) - Optimizer: Pivotal Optimizer (GPORCA) + Filter: ((b)::integer = 2) + Optimizer: GPORCA (5 rows) select * from lossycastlistpart where b::int = 2; a | b ----+----- - 11 | 1.8 + 1 | 2.1 10 | 2.1 21 | 1.7 - 1 | 2.1 + 11 | 1.8 (4 rows) --Test lossy casted NEQ on range partitioned table @@ -12343,39 +12408,6 @@ partition by range(sales_ts) (start (timestamp '2010-01-01 00:00:00') end(timest every (interval '1 day')); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. -NOTICE: CREATE TABLE will create partition "sales_1_prt_1" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_2" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_3" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_4" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_5" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_6" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_7" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_8" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_9" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_10" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_11" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_12" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_13" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_14" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_15" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_16" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_17" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_18" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_19" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_20" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_21" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_22" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_23" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_24" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_25" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_26" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_27" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_28" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_29" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_30" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_31" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_32" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_33" for table "sales" insert into sales select i, i%100, i%1000, timestamp '2010-01-01 00:00:00' + i * interval '1 day' from generate_series(1,20) i; select * from sales where sales_ts::date != '2010-01-05' order by sales_ts; id | prod_id | cust_id | sales_ts @@ -12448,7 +12480,7 @@ where out.b in (select coalesce(tcorr2.a, 99) -> Materialize (cost=0.00..431.00 rows=1 width=4) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on tcorr2 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (14 rows) -- expect 1 row @@ -12480,7 +12512,7 @@ where out.b in (select max(tcorr2.b + out.b - 1) -> Materialize (cost=0.00..431.00 rows=1 width=8) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on tcorr2 (cost=0.00..431.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) -- expect 1 row @@ -12604,7 +12636,7 @@ where out.b in (select max(tcorr2.b + out.b - 1) -> Materialize (cost=0.00..431.00 rows=1 width=8) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on tcorr2 (cost=0.00..431.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) -- expect 1 row @@ -12784,17 +12816,17 @@ select * from foo join tbitmap on foo.a=tbitmap.a; select * from foo join tbitmap on foo.a=tbitmap.a; a | b | c | a | b | c -------+-------+-------+-------+-------+------- - 5000 | 5000 | 5000 | 5000 | 5000 | 5000 - 3000 | 3000 | 3000 | 3000 | 3000 | 3000 - 4000 | 4000 | 4000 | 4000 | 4000 | 4000 - 9000 | 9000 | 9000 | 9000 | 9000 | 9000 - 10000 | 10000 | 10000 | 10000 | 10000 | 10000 1000 | 1000 | 1000 | 1000 | 1000 | 1000 2000 | 2000 | 2000 | 2000 | 2000 | 2000 2000 | 2000 | 2000 | 2000 | -1 | -1 6000 | 6000 | 6000 | 6000 | 6000 | 6000 7000 | 7000 | 7000 | 7000 | 7000 | 7000 8000 | 8000 | 8000 | 8000 | 8000 | 8000 + 3000 | 3000 | 3000 | 3000 | 3000 | 3000 + 4000 | 4000 | 4000 | 4000 | 4000 | 4000 + 9000 | 9000 | 9000 | 9000 | 9000 | 9000 + 10000 | 10000 | 10000 | 10000 | 10000 | 10000 + 5000 | 5000 | 5000 | 5000 | 5000 | 5000 (11 rows) -- 3 btree with select pred @@ -12845,8 +12877,8 @@ select * from foo join tbitmap on foo.a=tbitmap.a where tbitmap.a < 5000; a | b | c | a | b | c ------+------+------+------+------+------ 1000 | 1000 | 1000 | 1000 | 1000 | 1000 - 2000 | 2000 | 2000 | 2000 | -1 | -1 2000 | 2000 | 2000 | 2000 | 2000 | 2000 + 2000 | 2000 | 2000 | 2000 | -1 | -1 3000 | 3000 | 3000 | 3000 | 3000 | 3000 4000 | 4000 | 4000 | 4000 | 4000 | 4000 (5 rows) @@ -12870,7 +12902,6 @@ select * from foo join (select a, b+c as bc from tbtree) proj on foo.a=proj.a; select * from foo join (select a, b+c as bc from tbtree) proj on foo.a=proj.a; a | b | c | a | bc -------+-------+-------+-------+------- - 5000 | 5000 | 5000 | 5000 | 10000 3000 | 3000 | 3000 | 3000 | 6000 4000 | 4000 | 4000 | 4000 | 8000 9000 | 9000 | 9000 | 9000 | 18000 @@ -12881,6 +12912,7 @@ select * from foo join (select a, b+c as bc from tbtree) proj on foo.a=proj.a; 6000 | 6000 | 6000 | 6000 | 12000 7000 | 7000 | 7000 | 7000 | 14000 8000 | 8000 | 8000 | 8000 | 16000 + 5000 | 5000 | 5000 | 5000 | 10000 (11 rows) -- 6 bitmap with project @@ -12896,23 +12928,23 @@ select * from foo join (select a, b+c as bc from tbitmap) proj on foo.a=proj.a; Recheck Cond: (a = foo.a) -> Bitmap Index Scan on tbitmapxa Index Cond: (a = foo.a) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) select * from foo join (select a, b+c as bc from tbitmap) proj on foo.a=proj.a; a | b | c | a | bc -------+-------+-------+-------+------- 5000 | 5000 | 5000 | 5000 | 10000 - 3000 | 3000 | 3000 | 3000 | 6000 - 4000 | 4000 | 4000 | 4000 | 8000 - 9000 | 9000 | 9000 | 9000 | 18000 - 10000 | 10000 | 10000 | 10000 | 20000 1000 | 1000 | 1000 | 1000 | 2000 2000 | 2000 | 2000 | 2000 | 4000 2000 | 2000 | 2000 | 2000 | -2 6000 | 6000 | 6000 | 6000 | 12000 7000 | 7000 | 7000 | 7000 | 14000 8000 | 8000 | 8000 | 8000 | 16000 + 3000 | 3000 | 3000 | 3000 | 6000 + 4000 | 4000 | 4000 | 4000 | 8000 + 9000 | 9000 | 9000 | 9000 | 18000 + 10000 | 10000 | 10000 | 10000 | 20000 (11 rows) -- 7 btree with grby @@ -12937,16 +12969,16 @@ select * from foo join (select a, count(*) as cnt from tbtree group by a,b) grby a | b | c | a | cnt -------+-------+-------+-------+----- 5000 | 5000 | 5000 | 5000 | 1 - 3000 | 3000 | 3000 | 3000 | 1 - 4000 | 4000 | 4000 | 4000 | 1 - 9000 | 9000 | 9000 | 9000 | 1 - 10000 | 10000 | 10000 | 10000 | 1 1000 | 1000 | 1000 | 1000 | 1 2000 | 2000 | 2000 | 2000 | 1 2000 | 2000 | 2000 | 2000 | 1 6000 | 6000 | 6000 | 6000 | 1 7000 | 7000 | 7000 | 7000 | 1 8000 | 8000 | 8000 | 8000 | 1 + 3000 | 3000 | 3000 | 3000 | 1 + 4000 | 4000 | 4000 | 4000 | 1 + 9000 | 9000 | 9000 | 9000 | 1 + 10000 | 10000 | 10000 | 10000 | 1 (11 rows) -- 8 bitmap with grby @@ -12964,18 +12996,18 @@ select * from foo join (select a, count(*) as cnt from tbitmap group by a) grby Recheck Cond: (a = foo.a) -> Bitmap Index Scan on tbitmapxa Index Cond: (a = foo.a) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) select * from foo join (select a, count(*) as cnt from tbitmap group by a) grby on foo.a=grby.a; a | b | c | a | cnt -------+-------+-------+-------+----- - 5000 | 5000 | 5000 | 5000 | 1 1000 | 1000 | 1000 | 1000 | 1 2000 | 2000 | 2000 | 2000 | 2 6000 | 6000 | 6000 | 6000 | 1 7000 | 7000 | 7000 | 7000 | 1 8000 | 8000 | 8000 | 8000 | 1 + 5000 | 5000 | 5000 | 5000 | 1 3000 | 3000 | 3000 | 3000 | 1 4000 | 4000 | 4000 | 4000 | 1 9000 | 9000 | 9000 | 9000 | 1 @@ -13055,22 +13087,22 @@ select * from foo join (select a, count(*) as cnt from (select distinct a, b fro Recheck Cond: (a = foo.a) -> Bitmap Index Scan on tbitmapxa Index Cond: (a = foo.a) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) select * from foo join (select a, count(*) as cnt from (select distinct a, b from tbitmap) grby1 group by a) grby2 on foo.a=grby2.a; a | b | c | a | cnt -------+-------+-------+-------+----- 5000 | 5000 | 5000 | 5000 | 1 - 3000 | 3000 | 3000 | 3000 | 1 - 4000 | 4000 | 4000 | 4000 | 1 - 9000 | 9000 | 9000 | 9000 | 1 - 10000 | 10000 | 10000 | 10000 | 1 1000 | 1000 | 1000 | 1000 | 1 2000 | 2000 | 2000 | 2000 | 2 6000 | 6000 | 6000 | 6000 | 1 7000 | 7000 | 7000 | 7000 | 1 8000 | 8000 | 8000 | 8000 | 1 + 3000 | 3000 | 3000 | 3000 | 1 + 4000 | 4000 | 4000 | 4000 | 1 + 9000 | 9000 | 9000 | 9000 | 1 + 10000 | 10000 | 10000 | 10000 | 1 (10 rows) -- 12 btree with proj select 2*grby select @@ -13118,14 +13150,14 @@ select * from foo join (select a, a::bigint*a::bigint as aa from tbtree) proj on -> Seq Scan on foo -> Materialize -> Seq Scan on tbtree - Optimizer: Pivotal Optimizer (GPORCA) -(6 rows) + Optimizer: GPORCA +(7 rows) -- 14 join pred accesses a projected column - no index scan explain (costs off) select * from foo join (select a, count(*) as cnt from tbitmap group by a) grby on foo.a=grby.a and foo.b=grby.cnt; - QUERY PLAN --------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: ((foo.a = tbitmap.a) AND (foo.b = (count(*)))) @@ -13133,7 +13165,7 @@ select * from foo join (select a, count(*) as cnt from tbitmap group by a) grby -> HashAggregate Group Key: tbitmap.a -> Seq Scan on tbitmap - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) -- 15 the potential index join itself contains outer refs - no index scan @@ -13162,7 +13194,7 @@ from foo l1 where b in (select ab -> Materialize -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on tbtree - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (17 rows) -- 16 group by columns are not a superset of the distribution columns - no index scan @@ -13181,7 +13213,7 @@ select * from foo join (select b, count(*) as cnt from tbtree group by b) grby o -> Redistribute Motion 3:3 (slice2; segments: 3) Hash Key: tbtree.b -> Seq Scan on tbtree - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) -- 17 group by columns don't intersect - no index scan @@ -13205,7 +13237,7 @@ select * from foo join (select min_a, count(*) as cnt from (select min(a) as min -> Redistribute Motion 3:3 (slice3; segments: 3) Hash Key: tbitmap.b -> Seq Scan on tbitmap - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (17 rows) reset optimizer_join_order; @@ -13244,7 +13276,7 @@ explain (costs off) select count(*), t2.c from roj1 t1 left join roj2 t2 on t1.a -> Hash -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on roj1 t1 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) -- check that ROJ can be disabled via GUC @@ -13303,8 +13335,8 @@ select * from tpart_ao_btree where a = 3 and b = 3; (1 row) explain (costs off) select * from tpart_dim d join t_ao_btree f on d.a=f.a where d.b=1; - QUERY PLAN ---------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -13312,12 +13344,12 @@ explain (costs off) select * from tpart_dim d join t_ao_btree f on d.a=f.a where Filter: (b = 1) -> Index Only Scan using t_ao_btree_ix on t_ao_btree f Index Cond: (a = d.a) - Optimizer: Pivotal Optimizer (GPORCA) -(9 rows) + Optimizer: GPORCA +(8 rows) explain (costs off) select * from tpart_dim d join tpart_ao_btree f on d.a=f.a where d.b=1; - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -13326,7 +13358,7 @@ explain (costs off) select * from tpart_dim d join tpart_ao_btree f on d.a=f.a w -> Dynamic Index Only Scan on tpart_ao_btree_ix on tpart_ao_btree f Index Cond: (a = d.a) Number of partitions to scan: 2 (out of 2) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) -- negative test, make sure we don't use a btree scan on an AO table @@ -13360,7 +13392,7 @@ explain (costs off) select * from t_ao_btree where a = 3 and b = 3; Gather Motion 1:1 (slice1; segments: 1) -> Index Only Scan using t_ao_btree_ix on t_ao_btree Index Cond: ((a = 3) AND (b = 3)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) explain (costs off) select * from tpart_ao_btree where a = 3 and b = 3; @@ -13370,7 +13402,7 @@ explain (costs off) select * from tpart_ao_btree where a = 3 and b = 3; -> Dynamic Index Only Scan on tpart_ao_btree_ix on tpart_ao_btree Index Cond: ((a = 3) AND (b = 3)) Number of partitions to scan: 1 (out of 2) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) select * from tpart_dim d join t_ao_btree f on d.a=f.a where d.b=1; @@ -13461,7 +13493,7 @@ group by asset_records.uid, asset_records.hostname, asset_records.asset_type, as -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on coverage Filter: (NOT (vendor_sla IS NULL)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (17 rows) -- IndexApply-PartResolverExpand.mdp @@ -13521,7 +13553,7 @@ explain (costs off) select * from infer_part_vc inner join infer_txt on (infer_p -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on infer_txt Filter: (a = 'M'::text) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) -- NewBtreeIndexScanCost.mdp @@ -13567,7 +13599,7 @@ explain (costs off) select * from oip oip join ria a on ip=cidr and oip.oid=19 Hash Key: oip.cidr -> Seq Scan on oip Filter: (oid = 194073) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) -- PartTbl-ArrayCoerce.mdp @@ -13585,7 +13617,7 @@ explain (costs off) select * from pt where gender in ( 'F', 'FM'); -> Dynamic Seq Scan on pt Number of partitions to scan: 2 (out of 3) Filter: ((gender)::text = ANY ('{F,FM}'::text[])) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) -- PartTbl-List-DPE-Varchar-Predicates.mdp @@ -13612,7 +13644,7 @@ select * from pt where gender is null; -> Dynamic Seq Scan on pt pt_3 Number of partitions to scan: 1 (out of 3) Filter: (gender IS NULL) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (15 rows) -- PartTbl-RangeJoinPred.mdp @@ -13643,8 +13675,8 @@ where d.msisdn=f.subscriberaddress and f.sessioncreationtimestamp >= d.start_dtm and f.sessioncreationtimestamp Hash Join Hash Cond: ((d.msisdn)::text = (stg_xdr_crce_cdr.subscriberaddress)::text) @@ -13655,7 +13687,7 @@ where d.msisdn=f.subscriberaddress and -> Broadcast Motion 3:3 (slice2; segments: 3) -> Dynamic Seq Scan on stg_xdr_crce_cdr Number of partitions to scan: 2 (out of 2) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) -- PartTbl-Relabel-Equality.mdp @@ -13671,13 +13703,13 @@ explain (costs off) select month_id, cust_group_acc, mobile_no from ds_4 where month_id::text = 'Apr'; - QUERY PLAN --------------------------------------------------- + QUERY PLAN +---------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Dynamic Seq Scan on ds_4 Number of partitions to scan: 1 (out of 2) Filter: ((month_id)::text = 'Apr'::text) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) -- PartTbl-Relabel-Range.mdp @@ -13694,7 +13726,7 @@ where month_id::text >= 'Feb' and month_id::text < 'Mar'; -> Dynamic Seq Scan on ds_4 Number of partitions to scan: 2 (out of 2) Filter: (((month_id)::text >= 'Feb'::text) AND ((month_id)::text < 'Mar'::text)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) -- retail_28.mdp @@ -13719,8 +13751,8 @@ GROUP BY to_char(order_datetime,'YYYY-Q') ORDER BY to_char(order_datetime,'YYYY-Q') , item_shipment_status_code ; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Merge Key: (to_char(order_datetime, 'YYYY-Q'::text)), item_shipment_status_code -> GroupAggregate @@ -13732,7 +13764,7 @@ ORDER BY to_char(order_datetime,'YYYY-Q') -> Dynamic Seq Scan on order_lineitems Number of partitions to scan: 3 (out of 12) Filter: ((order_datetime >= 'Thu Apr 01 00:00:00 2010'::timestamp without time zone) AND (order_datetime <= '06-30-2010'::date)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) -- test partioned table with no partitions @@ -13844,15 +13876,15 @@ explain select r.a, r.b, r.c, l.c from left_outer_index_nl_foo r left outer join -> Materialize (cost=0.00..431.00 rows=5 width=8) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=5 width=8) -> Seq Scan on left_outer_index_nl_bar l (cost=0.00..431.00 rows=2 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) select r.a, r.b, r.c, l.c from left_outer_index_nl_foo r left outer join left_outer_index_nl_bar l on r.b=l.b; a | b | c | c ---+---+---+--- + 2 | 2 | 2 | 2 4 | 4 | 4 | 4 1 | 1 | 1 | - 2 | 2 | 2 | 2 3 | 3 | 3 | 3 (4 rows) @@ -13878,7 +13910,7 @@ explain select r.a, r.b, r.c, l.c from left_outer_index_nl_foo_hash r left outer -> Materialize (cost=0.00..431.00 rows=5 width=8) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=5 width=8) -> Seq Scan on left_outer_index_nl_bar l (cost=0.00..431.00 rows=2 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) select r.a, r.b, r.c, l.c from left_outer_index_nl_foo_hash r left outer join left_outer_index_nl_bar l on r.b=l.b; @@ -13901,16 +13933,16 @@ explain select r.a, r.b, r.c, l.c from left_outer_index_nl_foo_hash r left outer -> Materialize (cost=0.00..431.00 rows=5 width=6) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=5 width=6) -> Seq Scan on left_outer_index_nl_bar_hash l (cost=0.00..431.00 rows=2 width=6) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) select r.a, r.b, r.c, l.c from left_outer_index_nl_foo_hash r left outer join left_outer_index_nl_bar_hash l on r.b=l.b; a | b | c | c ---+---+---+--- - 1 | 1 | 1 | 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 + 1 | 1 | 1 | (4 rows) create table left_outer_index_nl_foo_repl (a integer, b integer, c integer) distributed replicated; @@ -13952,7 +13984,7 @@ explain select r.a, r.b, r.c, l.c from left_outer_index_nl_foo_repl r left outer -> Materialize (cost=0.00..431.00 rows=15 width=6) -> Broadcast Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=15 width=6) -> Seq Scan on left_outer_index_nl_bar_hash l (cost=0.00..431.00 rows=2 width=6) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) select r.a, r.b, r.c, l.c from left_outer_index_nl_foo_repl r left outer join left_outer_index_nl_bar_hash l on r.b=l.b; @@ -13989,7 +14021,7 @@ EXPLAIN SELECT b FROM tt1 WHERE NOT EXISTS (SELECT * FROM tt2 WHERE (tt2.d = tt1 -> Materialize (cost=0.00..431.00 rows=4 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=4 width=4) -> Seq Scan on tt2 (cost=0.00..431.00 rows=2 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) SELECT b FROM tt1 WHERE NOT EXISTS (SELECT * FROM tt2 WHERE (tt2.d = tt1.b) IS DISTINCT FROM false); @@ -14007,7 +14039,7 @@ EXPLAIN SELECT b FROM tt1 WHERE NOT EXISTS (SELECT * FROM tt2 WHERE (tt2.d = tt1 -> Materialize (cost=0.00..431.00 rows=4 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=4 width=4) -> Seq Scan on tt2 (cost=0.00..431.00 rows=2 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) SELECT b FROM tt1 WHERE NOT EXISTS (SELECT * FROM tt2 WHERE (tt2.d = tt1.b) IS DISTINCT FROM true); @@ -14025,7 +14057,7 @@ EXPLAIN SELECT b FROM tt1 WHERE NOT EXISTS (SELECT * FROM tt2 WHERE (tt1.b = tt2 -> Materialize (cost=0.00..431.00 rows=4 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=4 width=4) -> Seq Scan on tt2 (cost=0.00..431.00 rows=2 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) SELECT b FROM tt1 WHERE NOT EXISTS (SELECT * FROM tt2 WHERE (tt1.b = tt2.d) IS DISTINCT FROM NULL); @@ -14137,22 +14169,22 @@ EXPLAIN (COSTS OFF) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.a Join Filter: (t1.a = t2.a) -> Seq Scan on tone t1 -> Seq Scan on tone t2 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (6 rows) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.a; a | b | c | a | b | c ----+----+----+----+----+---- - 1 | 1 | 1 | 1 | 1 | 1 - 5 | 5 | 5 | 5 | 5 | 5 - 6 | 6 | 6 | 6 | 6 | 6 - 9 | 9 | 9 | 9 | 9 | 9 - 10 | 10 | 10 | 10 | 10 | 10 2 | 2 | 2 | 2 | 2 | 2 3 | 3 | 3 | 3 | 3 | 3 4 | 4 | 4 | 4 | 4 | 4 7 | 7 | 7 | 7 | 7 | 7 8 | 8 | 8 | 8 | 8 | 8 + 1 | 1 | 1 | 1 | 1 | 1 + 5 | 5 | 5 | 5 | 5 | 5 + 6 | 6 | 6 | 6 | 6 | 6 + 9 | 9 | 9 | 9 | 9 | 9 + 10 | 10 | 10 | 10 | 10 | 10 (10 rows) --- if the inner child is not distributed on the join column, orca should @@ -14168,7 +14200,7 @@ EXPLAIN (COSTS OFF) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.b -> Redistribute Motion 3:3 (slice2; segments: 3) Hash Key: t2.b -> Seq Scan on tone t2 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.b; @@ -14197,22 +14229,22 @@ EXPLAIN (COSTS OFF) SELECT * FROM tone t1 LEFT OUTER JOIN (SELECT 1+t2.b as b fr -> Redistribute Motion 3:3 (slice2; segments: 3) Hash Key: ((1 + t2.b)) -> Seq Scan on tone t2 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) SELECT * FROM tone t1 LEFT OUTER JOIN (SELECT 1+t2.b as b from tone t2) t2 ON t1.a = t2.b; a | b | c | b ----+----+----+---- - 5 | 5 | 5 | 5 - 6 | 6 | 6 | 6 - 9 | 9 | 9 | 9 - 10 | 10 | 10 | 10 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 7 | 7 | 7 | 7 8 | 8 | 8 | 8 1 | 1 | 1 | + 5 | 5 | 5 | 5 + 6 | 6 | 6 | 6 + 9 | 9 | 9 | 9 + 10 | 10 | 10 | 10 (10 rows) --- if the join condition does not involve a simple scalar ident, orca must @@ -14227,7 +14259,7 @@ EXPLAIN (COSTS OFF) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.b -> Materialize -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on tone t2 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.b-t1.a; @@ -14257,22 +14289,22 @@ EXPLAIN (COSTS OFF) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.b -> Materialize -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on tone t2 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.b; a | b | c | a | b | c ----+----+----+----+----+---- - 1 | 1 | 1 | 1 | 1 | 1 - 5 | 5 | 5 | 5 | 5 | 5 - 6 | 6 | 6 | 6 | 6 | 6 - 9 | 9 | 9 | 9 | 9 | 9 - 10 | 10 | 10 | 10 | 10 | 10 2 | 2 | 2 | 2 | 2 | 2 3 | 3 | 3 | 3 | 3 | 3 4 | 4 | 4 | 4 | 4 | 4 7 | 7 | 7 | 7 | 7 | 7 8 | 8 | 8 | 8 | 8 | 8 + 5 | 5 | 5 | 5 | 5 | 5 + 6 | 6 | 6 | 6 | 6 | 6 + 9 | 9 | 9 | 9 | 9 | 9 + 10 | 10 | 10 | 10 | 10 | 10 + 1 | 1 | 1 | 1 | 1 | 1 (10 rows) EXPLAIN (COSTS OFF) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.a; @@ -14285,21 +14317,21 @@ EXPLAIN (COSTS OFF) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.a -> Materialize -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on tone t2 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.a; a | b | c | a | b | c ----+----+----+----+----+---- - 5 | 5 | 5 | 5 | 5 | 5 - 6 | 6 | 6 | 6 | 6 | 6 - 9 | 9 | 9 | 9 | 9 | 9 - 10 | 10 | 10 | 10 | 10 | 10 2 | 2 | 2 | 2 | 2 | 2 3 | 3 | 3 | 3 | 3 | 3 4 | 4 | 4 | 4 | 4 | 4 7 | 7 | 7 | 7 | 7 | 7 8 | 8 | 8 | 8 | 8 | 8 + 5 | 5 | 5 | 5 | 5 | 5 + 6 | 6 | 6 | 6 | 6 | 6 + 9 | 9 | 9 | 9 | 9 | 9 + 10 | 10 | 10 | 10 | 10 | 10 1 | 1 | 1 | 1 | 1 | 1 (10 rows) @@ -14449,7 +14481,11 @@ DROP TABLE t_clientinstrumentind2, t_clientproductind2; -- eval_const_expressions() call for subplan. ORCA has only one call to -- fold_constants() at the very beginning and doesn't perform folding later. CREATE TABLE join_null_rej1(i int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TABLE join_null_rej2(i int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO join_null_rej1(i) VALUES (1), (2), (3); INSERT INTO join_null_rej2 SELECT i FROM join_null_rej1; CREATE OR REPLACE FUNCTION join_null_rej_func() RETURNS int AS $$ @@ -14463,8 +14499,8 @@ EXPLAIN (COSTS OFF) SELECT ( LEFT JOIN join_null_rej2 t2 ON t1.i = t2.i WHERE t2.i < join_null_rej_func() ); - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------- Nested Loop Left Join Join Filter: true -> Result @@ -14477,7 +14513,7 @@ EXPLAIN (COSTS OFF) SELECT ( -> Hash -> Seq Scan on join_null_rej2 t2 Filter: (i < join_null_rej_func()) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) -- Optional, but let's check we get same result for both, folded and @@ -14505,7 +14541,7 @@ set i = tt.i from (select (min(i) over (order by j)) as i, j from window_agg_test) tt where t.j = tt.j; INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner -DETAIL: DXL-to-PlStmt Translation: Attribute number 21 not found in project list +DETAIL: DXL-to-PlStmt Translation: Attribute number 13 not found in project list QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- Update on window_agg_test t (cost=3699.81..185385.16 rows=0 width=0) @@ -14537,31 +14573,31 @@ create type complex_t as (r float8, i float8); create type quad as (c1 complex_t, c2 complex_t); create function quad_func_cast() returns quad immutable as $$ select ((1.1,null),(2.2,null))::quad $$ language sql; explain select c1 from quad_func_cast(); - QUERY PLAN + QUERY PLAN ------------------------------------------------------------------- Function Scan on quad_func_cast (cost=0.00..0.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (2 rows) explain select c2 from quad_func_cast(); - QUERY PLAN + QUERY PLAN ------------------------------------------------------------------- Function Scan on quad_func_cast (cost=0.00..0.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (2 rows) explain select (c1).r from quad_func_cast(); QUERY PLAN ------------------------------------------------------------------- Function Scan on quad_func_cast (cost=0.00..0.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (2 rows) explain select (c2).i from quad_func_cast(); QUERY PLAN ------------------------------------------------------------------- Function Scan on quad_func_cast (cost=0.00..0.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (2 rows) select c1 from quad_func_cast(); @@ -14591,24 +14627,24 @@ select (c2).i from quad_func_cast(); create type mix_type as (a text, b integer, c bool); create function mix_func_cast() returns mix_type immutable as $$ select ('column1', 1, true)::mix_type $$ language sql; explain select a from mix_func_cast(); - QUERY PLAN + QUERY PLAN ------------------------------------------------------------------ Function Scan on mix_func_cast (cost=0.00..0.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (2 rows) explain select b from mix_func_cast(); - QUERY PLAN + QUERY PLAN ------------------------------------------------------------------ Function Scan on mix_func_cast (cost=0.00..0.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (2 rows) explain select c from mix_func_cast(); - QUERY PLAN + QUERY PLAN ------------------------------------------------------------------ Function Scan on mix_func_cast (cost=0.00..0.00 rows=1 width=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (2 rows) select a from mix_func_cast(); @@ -14713,11 +14749,11 @@ explain (costs off) select * from comp_table where (item).c>(item).d ; select (x.item).a from comp_table x join comp_table y on (x.item).c=(y.item).c; a ---- + VM DB DB GP GP - VM (5 rows) explain (costs off) select (x.item).a from comp_table x join comp_table y on (x.item).c=(y.item).c; @@ -14799,11 +14835,11 @@ explain (costs off) select (item).a from comp_table where (item).c=10 and (item) select (x.item).a from comp_part x join comp_part y on (X.item).c=(Y.item).c; a ---- - GP - GP VM DB DB + GP + GP (5 rows) explain (costs off) select (x.item).a from comp_part x join comp_part y on (X.item).c=(Y.item).c; @@ -14860,7 +14896,7 @@ explain select * from ts_tbl where ts = to_timestamp('99991231'::text, 'YYYYMMDD Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..6.01 rows=1 width=8) -> Index Only Scan using ts_tbl_idx on ts_tbl (cost=0.00..6.01 rows=1 width=8) Index Cond: (ts = 'Fri Dec 31 00:00:00 9999 PST'::timestamp with time zone) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) -- Test ORCA support for implicit array coerce cast @@ -14878,11 +14914,11 @@ explain insert into array_coerce_foo select * from array_coerce_bar; ------------------------------------------------------------------------- Insert on array_coerce_foo (cost=0.00..431.02 rows=1 width=12) -> Seq Scan on array_coerce_bar (cost=0.00..431.00 rows=1 width=12) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) insert into array_coerce_foo select * from array_coerce_bar; -ERROR: value too long for type character varying(2) (seg1 127.0.0.1:7003 pid=51460) +ERROR: value too long for type character varying(2) (seg1 172.18.0.2:7003 pid=60470) WITH conf AS ( SELECT setting FROM pg_catalog.pg_config @@ -14908,7 +14944,7 @@ baz.b = 11 OR baz.b = 12 OR baz.b = 13 OR baz.b = 14 OR baz.b = 15 OR baz.b = 16 Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on baz (cost=0.00..431.00 rows=1 width=8) Filter: ((a = 1) OR (b = 1) OR (b = 2) OR (b = 3) OR (b = 4) OR (b = 5) OR (b = 6) OR (b = 7) OR (b = 8) OR (b = 9) OR (b = 10) OR (b = 11) OR (b = 12) OR (b = 13) OR (b = 14) OR (b = 15) OR (b = 16) OR (b = 17) OR (b = 18) OR (b = 19) OR (b = 20)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) drop table baz; @@ -14921,7 +14957,7 @@ explain select * from baz where baz.a::bpchar='b' or baz.a='c'; Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on baz (cost=0.00..431.00 rows=1 width=8) Filter: (((a)::bpchar = 'b'::bpchar) OR ((a)::text = 'c'::text)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) drop table baz; @@ -14941,13 +14977,14 @@ explain (analyze, costs off, summary off, timing off) with cte as (select * from -> Append (actual rows=10 loops=1) -> Shared Scan (share slice:id 1:0) (actual rows=5 loops=1) -> Shared Scan (share slice:id 1:0) (actual rows=5 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) -- While retrieving the columns width in partitioned tables, inherited stats i.e. -- stats that cover all the child tables should be used -- start_ignore create language plpython3u; +ERROR: extension "plpython3u" already exists -- end_ignore create or replace function check_col_width(query text, operator text, width text) returns int as $$ @@ -15019,26 +15056,27 @@ SELECT CAST(a AS TEXT[]) FROM array_coerceviaio; --------------------------------------------------------------------------------- DROP TABLE IF EXISTS schema_test_table; +NOTICE: table "schema_test_table" does not exist, skipping CREATE TABLE schema_test_table(a numeric, b numeric(5,2), c char(10) NOT NULL) distributed by (a); -- In 7x, redundant Result nodes in planned_stmt are being removed by ORCA, -- which caused the loss of typmod info of column type in plan. -- Below query is used by external libraries to fetch schema of table. -- Test that the typmod of column type is correct in explain plan. EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM schema_test_table WHERE 1=0; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Result Output: NULL::numeric, NULL::numeric(5,2), NULL::character(10) One-Time Filter: false + Settings: optimizer = 'on', gp_use_streaming_hashagg = 'off', enable_incremental_sort = 'on', optimizer_segments = '3', optimizer_enable_dynamicbitmapscan = 'on', optimizer_enable_dynamicindexscan = 'on' Optimizer: GPORCA - Settings: optimizer_enable_coordinator_only_queries = 'on', optimizer_enable_master_only_queries = 'on', optimizer_segments = '3' (5 rows) --------------------------------------------------------------------------------- -- Test ALL NULL scalar array compare create table DatumSortedSet_core (a int, b character varying NOT NULL) distributed by (a); explain select * from DatumSortedSet_core where b in (NULL, NULL); - QUERY PLAN + QUERY PLAN ------------------------------------------- Result (cost=0.00..0.00 rows=0 width=12) One-Time Filter: false @@ -15085,3 +15123,108 @@ explain (costs off) select max(s1) from foo inner join bar on j1 = j2 group by g drop table foo; drop table bar; reset optimizer_enable_eageragg; +-- start_ignore +DROP SCHEMA orca CASCADE; +NOTICE: drop cascades to 190 other objects +DETAIL: drop cascades to table bar1 +drop cascades to table bar2 +drop cascades to table r +drop cascades to table s +drop cascades to table m +drop cascades to table m1 +drop cascades to table orca_w1 +drop cascades to table orca_w2 +drop cascades to table orca_w3 +drop cascades to table rcte +drop cascades to table onek +drop cascades to table pp +drop cascades to table multilevel_p +drop cascades to table t +drop cascades to table t_date +drop cascades to table t_text +drop cascades to table t_ceeval_ints +drop cascades to function csq_f(integer) +drop cascades to table csq_r +drop cascades to table fooh1 +drop cascades to table fooh2 +drop cascades to table t77 +drop cascades to table prod9 +drop cascades to table toanalyze +drop cascades to table ur +drop cascades to table us +drop cascades to table ut +drop cascades to table uu +drop cascades to table twf1 +drop cascades to table twf2 +drop cascades to table tab1 +drop cascades to table tab2 +drop cascades to function sum_sfunc(anyelement,anyelement) +drop cascades to function sum_combinefunc(anyelement,anyelement) +drop cascades to function myagg1(anyelement) +drop cascades to function sum_sfunc2(anyelement,anyelement,anyelement) +drop cascades to function myagg2(anyelement,anyelement) +drop cascades to function gptfp(anyarray,anyelement) +drop cascades to function gpffp(anyarray) +drop cascades to function myagg3(anyelement) +drop cascades to table array_table +drop cascades to table mpp22453 +drop cascades to table mpp22791 +drop cascades to table p1 +drop cascades to table tmp_verd_s_pp_provtabs_agt_0015_extract1 +drop cascades to table arrtest +drop cascades to table foo_missing_stats +drop cascades to table bar_missing_stats +drop cascades to table table_with_small_statistic_precision_diff +drop cascades to table cust +drop cascades to table datedim +drop cascades to function plusone(integer) +drop cascades to table bm_test +drop cascades to table bm_dyn_test +drop cascades to table bm_dyn_test_onepart +drop cascades to table bm_dyn_test_multilvl_part +drop cascades to table my_tt_agg_opt +drop cascades to table my_tq_agg_opt_part +drop cascades to function plusone(numeric) +drop cascades to table ggg +drop cascades to table t3 +drop cascades to table index_test +drop cascades to table btree_test +drop cascades to table bitmap_test +drop cascades to type rainbow +drop cascades to table foo_ctas +drop cascades to table input_tab1 +drop cascades to table input_tab2 +drop cascades to table tab_1 +drop cascades to table tab_2 +drop cascades to table tab_3 +drop cascades to table t_outer +drop cascades to table t_inner +drop cascades to table wst0 +drop cascades to table wst1 +drop cascades to table wst2 +drop cascades to table test1 +drop cascades to table t_new +drop cascades to table x_tab +drop cascades to table y_tab +drop cascades to table z_tab +drop cascades to function test_func_pg_stats() +drop cascades to function myintin(cstring) +drop cascades to type myint +drop cascades to function myintout(myint) +drop cascades to function myint_int8(myint) +drop cascades to table csq_cast_param_outer +drop cascades to table csq_cast_param_inner +drop cascades to function myint_numeric(myint) +drop cascades to cast from myint to numeric +drop cascades to table onetimefilter1 +drop cascades to table onetimefilter2 +drop cascades to table ffoo +drop cascades to table fbar +drop cascades to table touter +drop cascades to table tinnerbitmap +drop cascades to table tinnerbtree +drop cascades to table ds_part +drop cascades to table non_part1 +drop cascades to table non_part2 +and 90 other objects (see server log for list) +-- end_ignore diff --git a/contrib/pax_storage/src/test/regress/expected/join.out b/contrib/pax_storage/src/test/regress/expected/join.out index 2174c5989c6..2d76160817a 100644 --- a/contrib/pax_storage/src/test/regress/expected/join.out +++ b/contrib/pax_storage/src/test/regress/expected/join.out @@ -7,10 +7,14 @@ CREATE TABLE J1_TBL ( j integer, t text ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TABLE J2_TBL ( i integer, k integer ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO J1_TBL VALUES (1, 4, 'one'); INSERT INTO J1_TBL VALUES (2, 3, 'two'); INSERT INTO J1_TBL VALUES (3, 2, 'three'); @@ -33,6 +37,7 @@ INSERT INTO J2_TBL VALUES (NULL, NULL); INSERT INTO J2_TBL VALUES (NULL, 0); -- useful in some tests below create temp table onerow(); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause, and no column type is suitable for a distribution key. Creating a NULL policy entry. insert into onerow default values; analyze onerow; -- @@ -44,15 +49,15 @@ SELECT * FROM J1_TBL AS tx; i | j | t ---+---+------- + 5 | 0 | five + 6 | 6 | six 1 | 4 | one + 0 | | zero 2 | 3 | two 3 | 2 | three 4 | 1 | four - 5 | 0 | five - 6 | 6 | six 7 | 7 | seven 8 | 8 | eight - 0 | | zero | | null | 0 | zero (11 rows) @@ -61,32 +66,32 @@ SELECT * FROM J1_TBL tx; i | j | t ---+---+------- - 1 | 4 | one 2 | 3 | two 3 | 2 | three 4 | 1 | four - 5 | 0 | five - 6 | 6 | six 7 | 7 | seven 8 | 8 | eight - 0 | | zero | | null | 0 | zero + 5 | 0 | five + 6 | 6 | six + 1 | 4 | one + 0 | | zero (11 rows) SELECT * FROM J1_TBL AS t1 (a, b, c); a | b | c ---+---+------- + 5 | 0 | five + 6 | 6 | six 1 | 4 | one + 0 | | zero 2 | 3 | two 3 | 2 | three 4 | 1 | four - 5 | 0 | five - 6 | 6 | six 7 | 7 | seven 8 | 8 | eight - 0 | | zero | | null | 0 | zero (11 rows) @@ -95,15 +100,15 @@ SELECT * FROM J1_TBL t1 (a, b, c); a | b | c ---+---+------- + 5 | 0 | five + 6 | 6 | six 1 | 4 | one + 0 | | zero 2 | 3 | two 3 | 2 | three 4 | 1 | four - 5 | 0 | five - 6 | 6 | six 7 | 7 | seven 8 | 8 | eight - 0 | | zero | | null | 0 | zero (11 rows) @@ -112,105 +117,105 @@ SELECT * FROM J1_TBL t1 (a, b, c), J2_TBL t2 (d, e); a | b | c | d | e ---+---+-------+---+---- - 1 | 4 | one | 1 | -1 2 | 3 | two | 1 | -1 3 | 2 | three | 1 | -1 4 | 1 | four | 1 | -1 - 5 | 0 | five | 1 | -1 - 6 | 6 | six | 1 | -1 7 | 7 | seven | 1 | -1 8 | 8 | eight | 1 | -1 - 0 | | zero | 1 | -1 | | null | 1 | -1 | 0 | zero | 1 | -1 - 1 | 4 | one | 2 | 2 + 2 | 3 | two | 0 | + 3 | 2 | three | 0 | + 4 | 1 | four | 0 | + 7 | 7 | seven | 0 | + 8 | 8 | eight | 0 | + | | null | 0 | + | 0 | zero | 0 | + 2 | 3 | two | 5 | -5 + 3 | 2 | three | 5 | -5 + 4 | 1 | four | 5 | -5 + 7 | 7 | seven | 5 | -5 + 8 | 8 | eight | 5 | -5 + | | null | 5 | -5 + | 0 | zero | 5 | -5 + 2 | 3 | two | 5 | -5 + 3 | 2 | three | 5 | -5 + 4 | 1 | four | 5 | -5 + 7 | 7 | seven | 5 | -5 + 8 | 8 | eight | 5 | -5 + | | null | 5 | -5 + | 0 | zero | 5 | -5 2 | 3 | two | 2 | 2 3 | 2 | three | 2 | 2 4 | 1 | four | 2 | 2 - 5 | 0 | five | 2 | 2 - 6 | 6 | six | 2 | 2 7 | 7 | seven | 2 | 2 8 | 8 | eight | 2 | 2 - 0 | | zero | 2 | 2 | | null | 2 | 2 | 0 | zero | 2 | 2 - 1 | 4 | one | 3 | -3 2 | 3 | two | 3 | -3 3 | 2 | three | 3 | -3 4 | 1 | four | 3 | -3 - 5 | 0 | five | 3 | -3 - 6 | 6 | six | 3 | -3 7 | 7 | seven | 3 | -3 8 | 8 | eight | 3 | -3 - 0 | | zero | 3 | -3 | | null | 3 | -3 | 0 | zero | 3 | -3 - 1 | 4 | one | 2 | 4 2 | 3 | two | 2 | 4 3 | 2 | three | 2 | 4 4 | 1 | four | 2 | 4 - 5 | 0 | five | 2 | 4 - 6 | 6 | six | 2 | 4 7 | 7 | seven | 2 | 4 8 | 8 | eight | 2 | 4 - 0 | | zero | 2 | 4 | | null | 2 | 4 | 0 | zero | 2 | 4 - 1 | 4 | one | 5 | -5 - 2 | 3 | two | 5 | -5 - 3 | 2 | three | 5 | -5 - 4 | 1 | four | 5 | -5 - 5 | 0 | five | 5 | -5 - 6 | 6 | six | 5 | -5 - 7 | 7 | seven | 5 | -5 - 8 | 8 | eight | 5 | -5 - 0 | | zero | 5 | -5 - | | null | 5 | -5 - | 0 | zero | 5 | -5 - 1 | 4 | one | 5 | -5 - 2 | 3 | two | 5 | -5 - 3 | 2 | three | 5 | -5 - 4 | 1 | four | 5 | -5 - 5 | 0 | five | 5 | -5 - 6 | 6 | six | 5 | -5 - 7 | 7 | seven | 5 | -5 - 8 | 8 | eight | 5 | -5 - 0 | | zero | 5 | -5 - | | null | 5 | -5 - | 0 | zero | 5 | -5 - 1 | 4 | one | 0 | - 2 | 3 | two | 0 | - 3 | 2 | three | 0 | - 4 | 1 | four | 0 | - 5 | 0 | five | 0 | - 6 | 6 | six | 0 | - 7 | 7 | seven | 0 | - 8 | 8 | eight | 0 | - 0 | | zero | 0 | - | | null | 0 | - | 0 | zero | 0 | - 1 | 4 | one | | 2 | 3 | two | | 3 | 2 | three | | 4 | 1 | four | | - 5 | 0 | five | | - 6 | 6 | six | | 7 | 7 | seven | | 8 | 8 | eight | | - 0 | | zero | | | | null | | | 0 | zero | | - 1 | 4 | one | | 0 2 | 3 | two | | 0 3 | 2 | three | | 0 4 | 1 | four | | 0 - 5 | 0 | five | | 0 - 6 | 6 | six | | 0 7 | 7 | seven | | 0 8 | 8 | eight | | 0 - 0 | | zero | | 0 | | null | | 0 | 0 | zero | | 0 + 1 | 4 | one | 5 | -5 + 0 | | zero | 5 | -5 + 1 | 4 | one | 5 | -5 + 0 | | zero | 5 | -5 + 1 | 4 | one | 1 | -1 + 0 | | zero | 1 | -1 + 1 | 4 | one | 0 | + 0 | | zero | 0 | + 1 | 4 | one | 2 | 2 + 0 | | zero | 2 | 2 + 1 | 4 | one | 3 | -3 + 0 | | zero | 3 | -3 + 1 | 4 | one | 2 | 4 + 0 | | zero | 2 | 4 + 1 | 4 | one | | + 0 | | zero | | + 1 | 4 | one | | 0 + 0 | | zero | | 0 + 5 | 0 | five | 5 | -5 + 6 | 6 | six | 5 | -5 + 5 | 0 | five | 5 | -5 + 6 | 6 | six | 5 | -5 + 5 | 0 | five | 1 | -1 + 6 | 6 | six | 1 | -1 + 5 | 0 | five | 0 | + 6 | 6 | six | 0 | + 5 | 0 | five | 2 | 2 + 6 | 6 | six | 2 | 2 + 5 | 0 | five | 3 | -3 + 6 | 6 | six | 3 | -3 + 5 | 0 | five | 2 | 4 + 6 | 6 | six | 2 | 4 + 5 | 0 | five | | + 6 | 6 | six | | + 5 | 0 | five | | 0 + 6 | 6 | six | | 0 (99 rows) SELECT t1.a, t2.e @@ -218,13 +223,13 @@ SELECT t1.a, t2.e WHERE t1.a = t2.d; a | e ---+---- - 0 | 1 | -1 - 2 | 2 - 2 | 4 - 3 | -3 + 0 | 5 | -5 5 | -5 + 2 | 2 + 3 | -3 + 2 | 4 (7 rows) -- @@ -236,105 +241,105 @@ SELECT * FROM J1_TBL CROSS JOIN J2_TBL; i | j | t | i | k ---+---+-------+---+---- - 1 | 4 | one | 1 | -1 - 2 | 3 | two | 1 | -1 - 3 | 2 | three | 1 | -1 - 4 | 1 | four | 1 | -1 + 5 | 0 | five | 5 | -5 + 6 | 6 | six | 5 | -5 + 5 | 0 | five | 5 | -5 + 6 | 6 | six | 5 | -5 + 5 | 0 | five | 2 | 2 + 6 | 6 | six | 2 | 2 + 5 | 0 | five | 3 | -3 + 6 | 6 | six | 3 | -3 + 5 | 0 | five | 2 | 4 + 6 | 6 | six | 2 | 4 + 5 | 0 | five | | + 6 | 6 | six | | + 5 | 0 | five | | 0 + 6 | 6 | six | | 0 5 | 0 | five | 1 | -1 6 | 6 | six | 1 | -1 - 7 | 7 | seven | 1 | -1 - 8 | 8 | eight | 1 | -1 - 0 | | zero | 1 | -1 - | | null | 1 | -1 - | 0 | zero | 1 | -1 + 5 | 0 | five | 0 | + 6 | 6 | six | 0 | + 1 | 4 | one | 5 | -5 + 0 | | zero | 5 | -5 + 1 | 4 | one | 5 | -5 + 0 | | zero | 5 | -5 1 | 4 | one | 2 | 2 + 0 | | zero | 2 | 2 + 1 | 4 | one | 3 | -3 + 0 | | zero | 3 | -3 + 1 | 4 | one | 2 | 4 + 0 | | zero | 2 | 4 + 1 | 4 | one | | + 0 | | zero | | + 1 | 4 | one | | 0 + 0 | | zero | | 0 + 1 | 4 | one | 1 | -1 + 0 | | zero | 1 | -1 + 1 | 4 | one | 0 | + 0 | | zero | 0 | + 2 | 3 | two | 5 | -5 + 3 | 2 | three | 5 | -5 + 4 | 1 | four | 5 | -5 + 7 | 7 | seven | 5 | -5 + 8 | 8 | eight | 5 | -5 + | | null | 5 | -5 + | 0 | zero | 5 | -5 + 2 | 3 | two | 5 | -5 + 3 | 2 | three | 5 | -5 + 4 | 1 | four | 5 | -5 + 7 | 7 | seven | 5 | -5 + 8 | 8 | eight | 5 | -5 + | | null | 5 | -5 + | 0 | zero | 5 | -5 2 | 3 | two | 2 | 2 3 | 2 | three | 2 | 2 4 | 1 | four | 2 | 2 - 5 | 0 | five | 2 | 2 - 6 | 6 | six | 2 | 2 7 | 7 | seven | 2 | 2 8 | 8 | eight | 2 | 2 - 0 | | zero | 2 | 2 | | null | 2 | 2 | 0 | zero | 2 | 2 - 1 | 4 | one | 3 | -3 2 | 3 | two | 3 | -3 3 | 2 | three | 3 | -3 4 | 1 | four | 3 | -3 - 5 | 0 | five | 3 | -3 - 6 | 6 | six | 3 | -3 7 | 7 | seven | 3 | -3 8 | 8 | eight | 3 | -3 - 0 | | zero | 3 | -3 | | null | 3 | -3 | 0 | zero | 3 | -3 - 1 | 4 | one | 2 | 4 2 | 3 | two | 2 | 4 3 | 2 | three | 2 | 4 4 | 1 | four | 2 | 4 - 5 | 0 | five | 2 | 4 - 6 | 6 | six | 2 | 4 7 | 7 | seven | 2 | 4 8 | 8 | eight | 2 | 4 - 0 | | zero | 2 | 4 | | null | 2 | 4 | 0 | zero | 2 | 4 - 1 | 4 | one | 5 | -5 - 2 | 3 | two | 5 | -5 - 3 | 2 | three | 5 | -5 - 4 | 1 | four | 5 | -5 - 5 | 0 | five | 5 | -5 - 6 | 6 | six | 5 | -5 - 7 | 7 | seven | 5 | -5 - 8 | 8 | eight | 5 | -5 - 0 | | zero | 5 | -5 - | | null | 5 | -5 - | 0 | zero | 5 | -5 - 1 | 4 | one | 5 | -5 - 2 | 3 | two | 5 | -5 - 3 | 2 | three | 5 | -5 - 4 | 1 | four | 5 | -5 - 5 | 0 | five | 5 | -5 - 6 | 6 | six | 5 | -5 - 7 | 7 | seven | 5 | -5 - 8 | 8 | eight | 5 | -5 - 0 | | zero | 5 | -5 - | | null | 5 | -5 - | 0 | zero | 5 | -5 - 1 | 4 | one | 0 | - 2 | 3 | two | 0 | - 3 | 2 | three | 0 | - 4 | 1 | four | 0 | - 5 | 0 | five | 0 | - 6 | 6 | six | 0 | - 7 | 7 | seven | 0 | - 8 | 8 | eight | 0 | - 0 | | zero | 0 | - | | null | 0 | - | 0 | zero | 0 | - 1 | 4 | one | | 2 | 3 | two | | 3 | 2 | three | | 4 | 1 | four | | - 5 | 0 | five | | - 6 | 6 | six | | 7 | 7 | seven | | 8 | 8 | eight | | - 0 | | zero | | | | null | | | 0 | zero | | - 1 | 4 | one | | 0 2 | 3 | two | | 0 3 | 2 | three | | 0 4 | 1 | four | | 0 - 5 | 0 | five | | 0 - 6 | 6 | six | | 0 7 | 7 | seven | | 0 8 | 8 | eight | | 0 - 0 | | zero | | 0 | | null | | 0 | 0 | zero | | 0 + 2 | 3 | two | 1 | -1 + 3 | 2 | three | 1 | -1 + 4 | 1 | four | 1 | -1 + 7 | 7 | seven | 1 | -1 + 8 | 8 | eight | 1 | -1 + | | null | 1 | -1 + | 0 | zero | 1 | -1 + 2 | 3 | two | 0 | + 3 | 2 | three | 0 | + 4 | 1 | four | 0 | + 7 | 7 | seven | 0 | + 8 | 8 | eight | 0 | + | | null | 0 | + | 0 | zero | 0 | (99 rows) -- ambiguous column @@ -349,102 +354,102 @@ SELECT t1.i, k, t i | k | t ---+----+------- 1 | -1 | one + 0 | -1 | zero + 1 | | one + 0 | | zero + 1 | -5 | one + 0 | -5 | zero + 1 | -5 | one + 0 | -5 | zero + 1 | 2 | one + 0 | 2 | zero + 1 | -3 | one + 0 | -3 | zero + 1 | 4 | one + 0 | 4 | zero + 1 | | one + 0 | | zero + 1 | 0 | one + 0 | 0 | zero + 5 | -1 | five + 6 | -1 | six + 5 | | five + 6 | | six + 5 | -5 | five + 6 | -5 | six + 5 | -5 | five + 6 | -5 | six + 5 | 2 | five + 6 | 2 | six + 5 | -3 | five + 6 | -3 | six + 5 | 4 | five + 6 | 4 | six + 5 | | five + 6 | | six + 5 | 0 | five + 6 | 0 | six 2 | -1 | two 3 | -1 | three 4 | -1 | four - 5 | -1 | five - 6 | -1 | six 7 | -1 | seven 8 | -1 | eight - 0 | -1 | zero | -1 | null | -1 | zero - 1 | 2 | one + 2 | | two + 3 | | three + 4 | | four + 7 | | seven + 8 | | eight + | | null + | | zero + 2 | -5 | two + 3 | -5 | three + 4 | -5 | four + 7 | -5 | seven + 8 | -5 | eight + | -5 | null + | -5 | zero + 2 | -5 | two + 3 | -5 | three + 4 | -5 | four + 7 | -5 | seven + 8 | -5 | eight + | -5 | null + | -5 | zero 2 | 2 | two 3 | 2 | three 4 | 2 | four - 5 | 2 | five - 6 | 2 | six 7 | 2 | seven 8 | 2 | eight - 0 | 2 | zero | 2 | null | 2 | zero - 1 | -3 | one 2 | -3 | two 3 | -3 | three 4 | -3 | four - 5 | -3 | five - 6 | -3 | six 7 | -3 | seven 8 | -3 | eight - 0 | -3 | zero | -3 | null | -3 | zero - 1 | 4 | one 2 | 4 | two 3 | 4 | three 4 | 4 | four - 5 | 4 | five - 6 | 4 | six 7 | 4 | seven 8 | 4 | eight - 0 | 4 | zero | 4 | null | 4 | zero - 1 | -5 | one - 2 | -5 | two - 3 | -5 | three - 4 | -5 | four - 5 | -5 | five - 6 | -5 | six - 7 | -5 | seven - 8 | -5 | eight - 0 | -5 | zero - | -5 | null - | -5 | zero - 1 | -5 | one - 2 | -5 | two - 3 | -5 | three - 4 | -5 | four - 5 | -5 | five - 6 | -5 | six - 7 | -5 | seven - 8 | -5 | eight - 0 | -5 | zero - | -5 | null - | -5 | zero - 1 | | one - 2 | | two - 3 | | three - 4 | | four - 5 | | five - 6 | | six - 7 | | seven - 8 | | eight - 0 | | zero - | | null - | | zero - 1 | | one 2 | | two 3 | | three 4 | | four - 5 | | five - 6 | | six 7 | | seven 8 | | eight - 0 | | zero | | null | | zero - 1 | 0 | one 2 | 0 | two 3 | 0 | three 4 | 0 | four - 5 | 0 | five - 6 | 0 | six 7 | 0 | seven 8 | 0 | eight - 0 | 0 | zero | 0 | null | 0 | zero (99 rows) @@ -454,103 +459,103 @@ SELECT ii, tt, kk AS tx (ii, jj, tt, ii2, kk); ii | tt | kk ----+-------+---- + 5 | five | -1 + 6 | six | -1 + 5 | five | + 6 | six | + 5 | five | -5 + 6 | six | -5 + 5 | five | -5 + 6 | six | -5 + 5 | five | 2 + 6 | six | 2 + 5 | five | -3 + 6 | six | -3 + 5 | five | 4 + 6 | six | 4 + 5 | five | + 6 | six | + 5 | five | 0 + 6 | six | 0 1 | one | -1 + 0 | zero | -1 + 1 | one | + 0 | zero | + 1 | one | -5 + 0 | zero | -5 + 1 | one | -5 + 0 | zero | -5 + 1 | one | 2 + 0 | zero | 2 + 1 | one | -3 + 0 | zero | -3 + 1 | one | 4 + 0 | zero | 4 + 1 | one | + 0 | zero | + 1 | one | 0 + 0 | zero | 0 2 | two | -1 3 | three | -1 4 | four | -1 - 5 | five | -1 - 6 | six | -1 7 | seven | -1 8 | eight | -1 - 0 | zero | -1 | null | -1 | zero | -1 - 1 | one | 2 + 2 | two | + 3 | three | + 4 | four | + 7 | seven | + 8 | eight | + | null | + | zero | + 2 | two | -5 + 3 | three | -5 + 4 | four | -5 + 7 | seven | -5 + 8 | eight | -5 + | null | -5 + | zero | -5 + 2 | two | -5 + 3 | three | -5 + 4 | four | -5 + 7 | seven | -5 + 8 | eight | -5 + | null | -5 + | zero | -5 2 | two | 2 3 | three | 2 4 | four | 2 - 5 | five | 2 - 6 | six | 2 7 | seven | 2 8 | eight | 2 - 0 | zero | 2 | null | 2 | zero | 2 - 1 | one | -3 2 | two | -3 3 | three | -3 4 | four | -3 - 5 | five | -3 - 6 | six | -3 7 | seven | -3 8 | eight | -3 - 0 | zero | -3 | null | -3 | zero | -3 - 1 | one | 4 2 | two | 4 3 | three | 4 4 | four | 4 - 5 | five | 4 - 6 | six | 4 7 | seven | 4 8 | eight | 4 - 0 | zero | 4 | null | 4 | zero | 4 - 1 | one | -5 - 2 | two | -5 - 3 | three | -5 - 4 | four | -5 - 5 | five | -5 - 6 | six | -5 - 7 | seven | -5 - 8 | eight | -5 - 0 | zero | -5 - | null | -5 - | zero | -5 - 1 | one | -5 - 2 | two | -5 - 3 | three | -5 - 4 | four | -5 - 5 | five | -5 - 6 | six | -5 - 7 | seven | -5 - 8 | eight | -5 - 0 | zero | -5 - | null | -5 - | zero | -5 - 1 | one | - 2 | two | - 3 | three | - 4 | four | - 5 | five | - 6 | six | - 7 | seven | - 8 | eight | - 0 | zero | - | null | - | zero | - 1 | one | 2 | two | 3 | three | 4 | four | - 5 | five | - 6 | six | 7 | seven | 8 | eight | - 0 | zero | | null | | zero | - 1 | one | 0 2 | two | 0 3 | three | 0 4 | four | 0 - 5 | five | 0 - 6 | six | 0 7 | seven | 0 8 | eight | 0 - 0 | zero | 0 | null | 0 | zero | 0 (99 rows) @@ -560,1000 +565,1000 @@ SELECT tx.ii, tx.jj, tx.kk AS tx (ii, jj, tt, ii2, kk); ii | jj | kk ----+----+---- - 1 | 4 | -1 - 2 | 3 | -1 - 3 | 2 | -1 - 4 | 1 | -1 - 5 | 0 | -1 - 6 | 6 | -1 - 7 | 7 | -1 - 8 | 8 | -1 - 0 | | -1 - | | -1 - | 0 | -1 - 1 | 4 | 2 - 2 | 3 | 2 - 3 | 2 | 2 - 4 | 1 | 2 - 5 | 0 | 2 - 6 | 6 | 2 - 7 | 7 | 2 + 2 | 3 | -5 + 3 | 2 | -5 + 4 | 1 | -5 + 7 | 7 | -5 + 8 | 8 | -5 + | | -5 + | 0 | -5 + 2 | 3 | -5 + 3 | 2 | -5 + 4 | 1 | -5 + 7 | 7 | -5 + 8 | 8 | -5 + | | -5 + | 0 | -5 + 2 | 3 | 2 + 3 | 2 | 2 + 4 | 1 | 2 + 7 | 7 | 2 8 | 8 | 2 - 0 | | 2 | | 2 | 0 | 2 - 1 | 4 | -3 2 | 3 | -3 3 | 2 | -3 4 | 1 | -3 - 5 | 0 | -3 - 6 | 6 | -3 7 | 7 | -3 8 | 8 | -3 - 0 | | -3 | | -3 | 0 | -3 - 1 | 4 | 4 2 | 3 | 4 3 | 2 | 4 4 | 1 | 4 - 5 | 0 | 4 - 6 | 6 | 4 7 | 7 | 4 8 | 8 | 4 - 0 | | 4 | | 4 | 0 | 4 - 1 | 4 | -5 - 2 | 3 | -5 - 3 | 2 | -5 - 4 | 1 | -5 - 5 | 0 | -5 - 6 | 6 | -5 - 7 | 7 | -5 - 8 | 8 | -5 - 0 | | -5 - | | -5 - | 0 | -5 - 1 | 4 | -5 - 2 | 3 | -5 - 3 | 2 | -5 - 4 | 1 | -5 - 5 | 0 | -5 - 6 | 6 | -5 - 7 | 7 | -5 - 8 | 8 | -5 - 0 | | -5 - | | -5 - | 0 | -5 - 1 | 4 | 2 | 3 | 3 | 2 | 4 | 1 | - 5 | 0 | - 6 | 6 | 7 | 7 | 8 | 8 | - 0 | | | | | 0 | - 1 | 4 | + 2 | 3 | 0 + 3 | 2 | 0 + 4 | 1 | 0 + 7 | 7 | 0 + 8 | 8 | 0 + | | 0 + | 0 | 0 + 2 | 3 | -1 + 3 | 2 | -1 + 4 | 1 | -1 + 7 | 7 | -1 + 8 | 8 | -1 + | | -1 + | 0 | -1 2 | 3 | 3 | 2 | 4 | 1 | - 5 | 0 | - 6 | 6 | 7 | 7 | 8 | 8 | - 0 | | | | | 0 | + 1 | 4 | -5 + 0 | | -5 + 1 | 4 | -5 + 0 | | -5 + 1 | 4 | -1 + 0 | | -1 + 1 | 4 | + 0 | | + 1 | 4 | 2 + 0 | | 2 + 1 | 4 | -3 + 0 | | -3 + 1 | 4 | 4 + 0 | | 4 + 1 | 4 | + 0 | | 1 | 4 | 0 - 2 | 3 | 0 - 3 | 2 | 0 - 4 | 1 | 0 + 0 | | 0 + 5 | 0 | -5 + 6 | 6 | -5 + 5 | 0 | -5 + 6 | 6 | -5 + 5 | 0 | 2 + 6 | 6 | 2 + 5 | 0 | -3 + 6 | 6 | -3 + 5 | 0 | 4 + 6 | 6 | 4 + 5 | 0 | + 6 | 6 | 5 | 0 | 0 6 | 6 | 0 - 7 | 7 | 0 - 8 | 8 | 0 - 0 | | 0 - | | 0 - | 0 | 0 + 5 | 0 | -1 + 6 | 6 | -1 + 5 | 0 | + 6 | 6 | (99 rows) SELECT * FROM J1_TBL CROSS JOIN J2_TBL a CROSS JOIN J2_TBL b; i | j | t | i | k | i | k ---+---+-------+---+----+---+---- - 1 | 4 | one | 1 | -1 | 1 | -1 - 1 | 4 | one | 1 | -1 | 2 | 2 - 1 | 4 | one | 1 | -1 | 3 | -3 - 1 | 4 | one | 1 | -1 | 2 | 4 - 1 | 4 | one | 1 | -1 | 5 | -5 - 1 | 4 | one | 1 | -1 | 5 | -5 - 1 | 4 | one | 1 | -1 | 0 | - 1 | 4 | one | 1 | -1 | | - 1 | 4 | one | 1 | -1 | | 0 - 2 | 3 | two | 1 | -1 | 1 | -1 - 2 | 3 | two | 1 | -1 | 2 | 2 - 2 | 3 | two | 1 | -1 | 3 | -3 - 2 | 3 | two | 1 | -1 | 2 | 4 - 2 | 3 | two | 1 | -1 | 5 | -5 - 2 | 3 | two | 1 | -1 | 5 | -5 - 2 | 3 | two | 1 | -1 | 0 | - 2 | 3 | two | 1 | -1 | | - 2 | 3 | two | 1 | -1 | | 0 - 3 | 2 | three | 1 | -1 | 1 | -1 - 3 | 2 | three | 1 | -1 | 2 | 2 - 3 | 2 | three | 1 | -1 | 3 | -3 - 3 | 2 | three | 1 | -1 | 2 | 4 - 3 | 2 | three | 1 | -1 | 5 | -5 - 3 | 2 | three | 1 | -1 | 5 | -5 - 3 | 2 | three | 1 | -1 | 0 | - 3 | 2 | three | 1 | -1 | | - 3 | 2 | three | 1 | -1 | | 0 - 4 | 1 | four | 1 | -1 | 1 | -1 - 4 | 1 | four | 1 | -1 | 2 | 2 - 4 | 1 | four | 1 | -1 | 3 | -3 - 4 | 1 | four | 1 | -1 | 2 | 4 - 4 | 1 | four | 1 | -1 | 5 | -5 - 4 | 1 | four | 1 | -1 | 5 | -5 - 4 | 1 | four | 1 | -1 | 0 | - 4 | 1 | four | 1 | -1 | | - 4 | 1 | four | 1 | -1 | | 0 - 5 | 0 | five | 1 | -1 | 1 | -1 - 5 | 0 | five | 1 | -1 | 2 | 2 - 5 | 0 | five | 1 | -1 | 3 | -3 - 5 | 0 | five | 1 | -1 | 2 | 4 - 5 | 0 | five | 1 | -1 | 5 | -5 - 5 | 0 | five | 1 | -1 | 5 | -5 - 5 | 0 | five | 1 | -1 | 0 | - 5 | 0 | five | 1 | -1 | | - 5 | 0 | five | 1 | -1 | | 0 - 6 | 6 | six | 1 | -1 | 1 | -1 - 6 | 6 | six | 1 | -1 | 2 | 2 - 6 | 6 | six | 1 | -1 | 3 | -3 - 6 | 6 | six | 1 | -1 | 2 | 4 - 6 | 6 | six | 1 | -1 | 5 | -5 - 6 | 6 | six | 1 | -1 | 5 | -5 - 6 | 6 | six | 1 | -1 | 0 | - 6 | 6 | six | 1 | -1 | | - 6 | 6 | six | 1 | -1 | | 0 - 7 | 7 | seven | 1 | -1 | 1 | -1 - 7 | 7 | seven | 1 | -1 | 2 | 2 - 7 | 7 | seven | 1 | -1 | 3 | -3 - 7 | 7 | seven | 1 | -1 | 2 | 4 - 7 | 7 | seven | 1 | -1 | 5 | -5 - 7 | 7 | seven | 1 | -1 | 5 | -5 - 7 | 7 | seven | 1 | -1 | 0 | - 7 | 7 | seven | 1 | -1 | | - 7 | 7 | seven | 1 | -1 | | 0 - 8 | 8 | eight | 1 | -1 | 1 | -1 - 8 | 8 | eight | 1 | -1 | 2 | 2 - 8 | 8 | eight | 1 | -1 | 3 | -3 - 8 | 8 | eight | 1 | -1 | 2 | 4 - 8 | 8 | eight | 1 | -1 | 5 | -5 - 8 | 8 | eight | 1 | -1 | 5 | -5 - 8 | 8 | eight | 1 | -1 | 0 | - 8 | 8 | eight | 1 | -1 | | - 8 | 8 | eight | 1 | -1 | | 0 - 0 | | zero | 1 | -1 | 1 | -1 - 0 | | zero | 1 | -1 | 2 | 2 - 0 | | zero | 1 | -1 | 3 | -3 - 0 | | zero | 1 | -1 | 2 | 4 - 0 | | zero | 1 | -1 | 5 | -5 - 0 | | zero | 1 | -1 | 5 | -5 - 0 | | zero | 1 | -1 | 0 | - 0 | | zero | 1 | -1 | | - 0 | | zero | 1 | -1 | | 0 - | | null | 1 | -1 | 1 | -1 - | | null | 1 | -1 | 2 | 2 - | | null | 1 | -1 | 3 | -3 - | | null | 1 | -1 | 2 | 4 - | | null | 1 | -1 | 5 | -5 - | | null | 1 | -1 | 5 | -5 - | | null | 1 | -1 | 0 | - | | null | 1 | -1 | | - | | null | 1 | -1 | | 0 - | 0 | zero | 1 | -1 | 1 | -1 - | 0 | zero | 1 | -1 | 2 | 2 - | 0 | zero | 1 | -1 | 3 | -3 - | 0 | zero | 1 | -1 | 2 | 4 - | 0 | zero | 1 | -1 | 5 | -5 - | 0 | zero | 1 | -1 | 5 | -5 - | 0 | zero | 1 | -1 | 0 | - | 0 | zero | 1 | -1 | | - | 0 | zero | 1 | -1 | | 0 - 1 | 4 | one | 2 | 2 | 1 | -1 - 1 | 4 | one | 2 | 2 | 2 | 2 - 1 | 4 | one | 2 | 2 | 3 | -3 - 1 | 4 | one | 2 | 2 | 2 | 4 - 1 | 4 | one | 2 | 2 | 5 | -5 - 1 | 4 | one | 2 | 2 | 5 | -5 - 1 | 4 | one | 2 | 2 | 0 | - 1 | 4 | one | 2 | 2 | | - 1 | 4 | one | 2 | 2 | | 0 - 2 | 3 | two | 2 | 2 | 1 | -1 - 2 | 3 | two | 2 | 2 | 2 | 2 - 2 | 3 | two | 2 | 2 | 3 | -3 - 2 | 3 | two | 2 | 2 | 2 | 4 - 2 | 3 | two | 2 | 2 | 5 | -5 - 2 | 3 | two | 2 | 2 | 5 | -5 - 2 | 3 | two | 2 | 2 | 0 | - 2 | 3 | two | 2 | 2 | | - 2 | 3 | two | 2 | 2 | | 0 - 3 | 2 | three | 2 | 2 | 1 | -1 - 3 | 2 | three | 2 | 2 | 2 | 2 - 3 | 2 | three | 2 | 2 | 3 | -3 - 3 | 2 | three | 2 | 2 | 2 | 4 - 3 | 2 | three | 2 | 2 | 5 | -5 - 3 | 2 | three | 2 | 2 | 5 | -5 - 3 | 2 | three | 2 | 2 | 0 | - 3 | 2 | three | 2 | 2 | | - 3 | 2 | three | 2 | 2 | | 0 - 4 | 1 | four | 2 | 2 | 1 | -1 - 4 | 1 | four | 2 | 2 | 2 | 2 - 4 | 1 | four | 2 | 2 | 3 | -3 - 4 | 1 | four | 2 | 2 | 2 | 4 - 4 | 1 | four | 2 | 2 | 5 | -5 - 4 | 1 | four | 2 | 2 | 5 | -5 - 4 | 1 | four | 2 | 2 | 0 | - 4 | 1 | four | 2 | 2 | | - 4 | 1 | four | 2 | 2 | | 0 5 | 0 | five | 2 | 2 | 1 | -1 + 5 | 0 | five | 2 | 2 | 0 | + 5 | 0 | five | 2 | 2 | 5 | -5 + 5 | 0 | five | 2 | 2 | 5 | -5 5 | 0 | five | 2 | 2 | 2 | 2 5 | 0 | five | 2 | 2 | 3 | -3 5 | 0 | five | 2 | 2 | 2 | 4 - 5 | 0 | five | 2 | 2 | 5 | -5 - 5 | 0 | five | 2 | 2 | 5 | -5 - 5 | 0 | five | 2 | 2 | 0 | 5 | 0 | five | 2 | 2 | | 5 | 0 | five | 2 | 2 | | 0 - 6 | 6 | six | 2 | 2 | 1 | -1 - 6 | 6 | six | 2 | 2 | 2 | 2 - 6 | 6 | six | 2 | 2 | 3 | -3 - 6 | 6 | six | 2 | 2 | 2 | 4 - 6 | 6 | six | 2 | 2 | 5 | -5 - 6 | 6 | six | 2 | 2 | 5 | -5 - 6 | 6 | six | 2 | 2 | 0 | - 6 | 6 | six | 2 | 2 | | - 6 | 6 | six | 2 | 2 | | 0 - 7 | 7 | seven | 2 | 2 | 1 | -1 - 7 | 7 | seven | 2 | 2 | 2 | 2 - 7 | 7 | seven | 2 | 2 | 3 | -3 - 7 | 7 | seven | 2 | 2 | 2 | 4 - 7 | 7 | seven | 2 | 2 | 5 | -5 - 7 | 7 | seven | 2 | 2 | 5 | -5 - 7 | 7 | seven | 2 | 2 | 0 | - 7 | 7 | seven | 2 | 2 | | - 7 | 7 | seven | 2 | 2 | | 0 - 8 | 8 | eight | 2 | 2 | 1 | -1 - 8 | 8 | eight | 2 | 2 | 2 | 2 - 8 | 8 | eight | 2 | 2 | 3 | -3 - 8 | 8 | eight | 2 | 2 | 2 | 4 - 8 | 8 | eight | 2 | 2 | 5 | -5 - 8 | 8 | eight | 2 | 2 | 5 | -5 - 8 | 8 | eight | 2 | 2 | 0 | - 8 | 8 | eight | 2 | 2 | | - 8 | 8 | eight | 2 | 2 | | 0 - 0 | | zero | 2 | 2 | 1 | -1 - 0 | | zero | 2 | 2 | 2 | 2 - 0 | | zero | 2 | 2 | 3 | -3 - 0 | | zero | 2 | 2 | 2 | 4 - 0 | | zero | 2 | 2 | 5 | -5 - 0 | | zero | 2 | 2 | 5 | -5 - 0 | | zero | 2 | 2 | 0 | - 0 | | zero | 2 | 2 | | - 0 | | zero | 2 | 2 | | 0 - | | null | 2 | 2 | 1 | -1 - | | null | 2 | 2 | 2 | 2 - | | null | 2 | 2 | 3 | -3 - | | null | 2 | 2 | 2 | 4 - | | null | 2 | 2 | 5 | -5 - | | null | 2 | 2 | 5 | -5 - | | null | 2 | 2 | 0 | - | | null | 2 | 2 | | - | | null | 2 | 2 | | 0 - | 0 | zero | 2 | 2 | 1 | -1 - | 0 | zero | 2 | 2 | 2 | 2 - | 0 | zero | 2 | 2 | 3 | -3 - | 0 | zero | 2 | 2 | 2 | 4 - | 0 | zero | 2 | 2 | 5 | -5 - | 0 | zero | 2 | 2 | 5 | -5 - | 0 | zero | 2 | 2 | 0 | - | 0 | zero | 2 | 2 | | - | 0 | zero | 2 | 2 | | 0 - 1 | 4 | one | 3 | -3 | 1 | -1 - 1 | 4 | one | 3 | -3 | 2 | 2 - 1 | 4 | one | 3 | -3 | 3 | -3 - 1 | 4 | one | 3 | -3 | 2 | 4 - 1 | 4 | one | 3 | -3 | 5 | -5 - 1 | 4 | one | 3 | -3 | 5 | -5 - 1 | 4 | one | 3 | -3 | 0 | - 1 | 4 | one | 3 | -3 | | - 1 | 4 | one | 3 | -3 | | 0 - 2 | 3 | two | 3 | -3 | 1 | -1 - 2 | 3 | two | 3 | -3 | 2 | 2 - 2 | 3 | two | 3 | -3 | 3 | -3 - 2 | 3 | two | 3 | -3 | 2 | 4 - 2 | 3 | two | 3 | -3 | 5 | -5 - 2 | 3 | two | 3 | -3 | 5 | -5 - 2 | 3 | two | 3 | -3 | 0 | - 2 | 3 | two | 3 | -3 | | - 2 | 3 | two | 3 | -3 | | 0 - 3 | 2 | three | 3 | -3 | 1 | -1 - 3 | 2 | three | 3 | -3 | 2 | 2 - 3 | 2 | three | 3 | -3 | 3 | -3 - 3 | 2 | three | 3 | -3 | 2 | 4 - 3 | 2 | three | 3 | -3 | 5 | -5 - 3 | 2 | three | 3 | -3 | 5 | -5 - 3 | 2 | three | 3 | -3 | 0 | - 3 | 2 | three | 3 | -3 | | - 3 | 2 | three | 3 | -3 | | 0 - 4 | 1 | four | 3 | -3 | 1 | -1 - 4 | 1 | four | 3 | -3 | 2 | 2 - 4 | 1 | four | 3 | -3 | 3 | -3 - 4 | 1 | four | 3 | -3 | 2 | 4 - 4 | 1 | four | 3 | -3 | 5 | -5 - 4 | 1 | four | 3 | -3 | 5 | -5 - 4 | 1 | four | 3 | -3 | 0 | - 4 | 1 | four | 3 | -3 | | - 4 | 1 | four | 3 | -3 | | 0 5 | 0 | five | 3 | -3 | 1 | -1 + 5 | 0 | five | 3 | -3 | 0 | + 5 | 0 | five | 3 | -3 | 5 | -5 + 5 | 0 | five | 3 | -3 | 5 | -5 5 | 0 | five | 3 | -3 | 2 | 2 5 | 0 | five | 3 | -3 | 3 | -3 5 | 0 | five | 3 | -3 | 2 | 4 - 5 | 0 | five | 3 | -3 | 5 | -5 - 5 | 0 | five | 3 | -3 | 5 | -5 - 5 | 0 | five | 3 | -3 | 0 | 5 | 0 | five | 3 | -3 | | 5 | 0 | five | 3 | -3 | | 0 - 6 | 6 | six | 3 | -3 | 1 | -1 - 6 | 6 | six | 3 | -3 | 2 | 2 - 6 | 6 | six | 3 | -3 | 3 | -3 - 6 | 6 | six | 3 | -3 | 2 | 4 - 6 | 6 | six | 3 | -3 | 5 | -5 - 6 | 6 | six | 3 | -3 | 5 | -5 - 6 | 6 | six | 3 | -3 | 0 | - 6 | 6 | six | 3 | -3 | | - 6 | 6 | six | 3 | -3 | | 0 - 7 | 7 | seven | 3 | -3 | 1 | -1 - 7 | 7 | seven | 3 | -3 | 2 | 2 - 7 | 7 | seven | 3 | -3 | 3 | -3 - 7 | 7 | seven | 3 | -3 | 2 | 4 - 7 | 7 | seven | 3 | -3 | 5 | -5 - 7 | 7 | seven | 3 | -3 | 5 | -5 - 7 | 7 | seven | 3 | -3 | 0 | - 7 | 7 | seven | 3 | -3 | | - 7 | 7 | seven | 3 | -3 | | 0 - 8 | 8 | eight | 3 | -3 | 1 | -1 - 8 | 8 | eight | 3 | -3 | 2 | 2 - 8 | 8 | eight | 3 | -3 | 3 | -3 - 8 | 8 | eight | 3 | -3 | 2 | 4 - 8 | 8 | eight | 3 | -3 | 5 | -5 - 8 | 8 | eight | 3 | -3 | 5 | -5 - 8 | 8 | eight | 3 | -3 | 0 | - 8 | 8 | eight | 3 | -3 | | - 8 | 8 | eight | 3 | -3 | | 0 - 0 | | zero | 3 | -3 | 1 | -1 - 0 | | zero | 3 | -3 | 2 | 2 - 0 | | zero | 3 | -3 | 3 | -3 - 0 | | zero | 3 | -3 | 2 | 4 - 0 | | zero | 3 | -3 | 5 | -5 - 0 | | zero | 3 | -3 | 5 | -5 - 0 | | zero | 3 | -3 | 0 | - 0 | | zero | 3 | -3 | | - 0 | | zero | 3 | -3 | | 0 - | | null | 3 | -3 | 1 | -1 - | | null | 3 | -3 | 2 | 2 - | | null | 3 | -3 | 3 | -3 - | | null | 3 | -3 | 2 | 4 - | | null | 3 | -3 | 5 | -5 - | | null | 3 | -3 | 5 | -5 - | | null | 3 | -3 | 0 | - | | null | 3 | -3 | | - | | null | 3 | -3 | | 0 - | 0 | zero | 3 | -3 | 1 | -1 - | 0 | zero | 3 | -3 | 2 | 2 - | 0 | zero | 3 | -3 | 3 | -3 - | 0 | zero | 3 | -3 | 2 | 4 - | 0 | zero | 3 | -3 | 5 | -5 - | 0 | zero | 3 | -3 | 5 | -5 - | 0 | zero | 3 | -3 | 0 | - | 0 | zero | 3 | -3 | | - | 0 | zero | 3 | -3 | | 0 - 1 | 4 | one | 2 | 4 | 1 | -1 - 1 | 4 | one | 2 | 4 | 2 | 2 - 1 | 4 | one | 2 | 4 | 3 | -3 - 1 | 4 | one | 2 | 4 | 2 | 4 - 1 | 4 | one | 2 | 4 | 5 | -5 - 1 | 4 | one | 2 | 4 | 5 | -5 - 1 | 4 | one | 2 | 4 | 0 | - 1 | 4 | one | 2 | 4 | | - 1 | 4 | one | 2 | 4 | | 0 - 2 | 3 | two | 2 | 4 | 1 | -1 - 2 | 3 | two | 2 | 4 | 2 | 2 - 2 | 3 | two | 2 | 4 | 3 | -3 - 2 | 3 | two | 2 | 4 | 2 | 4 - 2 | 3 | two | 2 | 4 | 5 | -5 - 2 | 3 | two | 2 | 4 | 5 | -5 - 2 | 3 | two | 2 | 4 | 0 | - 2 | 3 | two | 2 | 4 | | - 2 | 3 | two | 2 | 4 | | 0 - 3 | 2 | three | 2 | 4 | 1 | -1 - 3 | 2 | three | 2 | 4 | 2 | 2 - 3 | 2 | three | 2 | 4 | 3 | -3 - 3 | 2 | three | 2 | 4 | 2 | 4 - 3 | 2 | three | 2 | 4 | 5 | -5 - 3 | 2 | three | 2 | 4 | 5 | -5 - 3 | 2 | three | 2 | 4 | 0 | - 3 | 2 | three | 2 | 4 | | - 3 | 2 | three | 2 | 4 | | 0 - 4 | 1 | four | 2 | 4 | 1 | -1 - 4 | 1 | four | 2 | 4 | 2 | 2 - 4 | 1 | four | 2 | 4 | 3 | -3 - 4 | 1 | four | 2 | 4 | 2 | 4 - 4 | 1 | four | 2 | 4 | 5 | -5 - 4 | 1 | four | 2 | 4 | 5 | -5 - 4 | 1 | four | 2 | 4 | 0 | - 4 | 1 | four | 2 | 4 | | - 4 | 1 | four | 2 | 4 | | 0 5 | 0 | five | 2 | 4 | 1 | -1 + 5 | 0 | five | 2 | 4 | 0 | + 5 | 0 | five | 2 | 4 | 5 | -5 + 5 | 0 | five | 2 | 4 | 5 | -5 5 | 0 | five | 2 | 4 | 2 | 2 5 | 0 | five | 2 | 4 | 3 | -3 5 | 0 | five | 2 | 4 | 2 | 4 - 5 | 0 | five | 2 | 4 | 5 | -5 - 5 | 0 | five | 2 | 4 | 5 | -5 - 5 | 0 | five | 2 | 4 | 0 | 5 | 0 | five | 2 | 4 | | 5 | 0 | five | 2 | 4 | | 0 + 5 | 0 | five | | | 1 | -1 + 5 | 0 | five | | | 0 | + 5 | 0 | five | | | 5 | -5 + 5 | 0 | five | | | 5 | -5 + 5 | 0 | five | | | 2 | 2 + 5 | 0 | five | | | 3 | -3 + 5 | 0 | five | | | 2 | 4 + 5 | 0 | five | | | | + 5 | 0 | five | | | | 0 + 5 | 0 | five | | 0 | 1 | -1 + 5 | 0 | five | | 0 | 0 | + 5 | 0 | five | | 0 | 5 | -5 + 5 | 0 | five | | 0 | 5 | -5 + 5 | 0 | five | | 0 | 2 | 2 + 5 | 0 | five | | 0 | 3 | -3 + 5 | 0 | five | | 0 | 2 | 4 + 5 | 0 | five | | 0 | | + 5 | 0 | five | | 0 | | 0 + 6 | 6 | six | 2 | 2 | 1 | -1 + 6 | 6 | six | 2 | 2 | 0 | + 6 | 6 | six | 2 | 2 | 5 | -5 + 6 | 6 | six | 2 | 2 | 5 | -5 + 6 | 6 | six | 2 | 2 | 2 | 2 + 6 | 6 | six | 2 | 2 | 3 | -3 + 6 | 6 | six | 2 | 2 | 2 | 4 + 6 | 6 | six | 2 | 2 | | + 6 | 6 | six | 2 | 2 | | 0 + 6 | 6 | six | 3 | -3 | 1 | -1 + 6 | 6 | six | 3 | -3 | 0 | + 6 | 6 | six | 3 | -3 | 5 | -5 + 6 | 6 | six | 3 | -3 | 5 | -5 + 6 | 6 | six | 3 | -3 | 2 | 2 + 6 | 6 | six | 3 | -3 | 3 | -3 + 6 | 6 | six | 3 | -3 | 2 | 4 + 6 | 6 | six | 3 | -3 | | + 6 | 6 | six | 3 | -3 | | 0 6 | 6 | six | 2 | 4 | 1 | -1 + 6 | 6 | six | 2 | 4 | 0 | + 6 | 6 | six | 2 | 4 | 5 | -5 + 6 | 6 | six | 2 | 4 | 5 | -5 6 | 6 | six | 2 | 4 | 2 | 2 6 | 6 | six | 2 | 4 | 3 | -3 6 | 6 | six | 2 | 4 | 2 | 4 - 6 | 6 | six | 2 | 4 | 5 | -5 - 6 | 6 | six | 2 | 4 | 5 | -5 - 6 | 6 | six | 2 | 4 | 0 | 6 | 6 | six | 2 | 4 | | 6 | 6 | six | 2 | 4 | | 0 - 7 | 7 | seven | 2 | 4 | 1 | -1 - 7 | 7 | seven | 2 | 4 | 2 | 2 - 7 | 7 | seven | 2 | 4 | 3 | -3 - 7 | 7 | seven | 2 | 4 | 2 | 4 - 7 | 7 | seven | 2 | 4 | 5 | -5 - 7 | 7 | seven | 2 | 4 | 5 | -5 - 7 | 7 | seven | 2 | 4 | 0 | - 7 | 7 | seven | 2 | 4 | | - 7 | 7 | seven | 2 | 4 | | 0 - 8 | 8 | eight | 2 | 4 | 1 | -1 - 8 | 8 | eight | 2 | 4 | 2 | 2 - 8 | 8 | eight | 2 | 4 | 3 | -3 - 8 | 8 | eight | 2 | 4 | 2 | 4 - 8 | 8 | eight | 2 | 4 | 5 | -5 - 8 | 8 | eight | 2 | 4 | 5 | -5 - 8 | 8 | eight | 2 | 4 | 0 | - 8 | 8 | eight | 2 | 4 | | - 8 | 8 | eight | 2 | 4 | | 0 - 0 | | zero | 2 | 4 | 1 | -1 - 0 | | zero | 2 | 4 | 2 | 2 - 0 | | zero | 2 | 4 | 3 | -3 - 0 | | zero | 2 | 4 | 2 | 4 - 0 | | zero | 2 | 4 | 5 | -5 - 0 | | zero | 2 | 4 | 5 | -5 - 0 | | zero | 2 | 4 | 0 | + 6 | 6 | six | | | 1 | -1 + 6 | 6 | six | | | 0 | + 6 | 6 | six | | | 5 | -5 + 6 | 6 | six | | | 5 | -5 + 6 | 6 | six | | | 2 | 2 + 6 | 6 | six | | | 3 | -3 + 6 | 6 | six | | | 2 | 4 + 6 | 6 | six | | | | + 6 | 6 | six | | | | 0 + 6 | 6 | six | | 0 | 1 | -1 + 6 | 6 | six | | 0 | 0 | + 6 | 6 | six | | 0 | 5 | -5 + 6 | 6 | six | | 0 | 5 | -5 + 6 | 6 | six | | 0 | 2 | 2 + 6 | 6 | six | | 0 | 3 | -3 + 6 | 6 | six | | 0 | 2 | 4 + 6 | 6 | six | | 0 | | + 6 | 6 | six | | 0 | | 0 + 1 | 4 | one | 2 | 2 | 1 | -1 + 1 | 4 | one | 2 | 2 | 0 | + 1 | 4 | one | 2 | 2 | 5 | -5 + 1 | 4 | one | 2 | 2 | 5 | -5 + 1 | 4 | one | 2 | 2 | 2 | 2 + 1 | 4 | one | 2 | 2 | 3 | -3 + 1 | 4 | one | 2 | 2 | 2 | 4 + 1 | 4 | one | 2 | 2 | | + 1 | 4 | one | 2 | 2 | | 0 + 1 | 4 | one | 3 | -3 | 1 | -1 + 1 | 4 | one | 3 | -3 | 0 | + 1 | 4 | one | 3 | -3 | 5 | -5 + 1 | 4 | one | 3 | -3 | 5 | -5 + 1 | 4 | one | 3 | -3 | 2 | 2 + 1 | 4 | one | 3 | -3 | 3 | -3 + 1 | 4 | one | 3 | -3 | 2 | 4 + 1 | 4 | one | 3 | -3 | | + 1 | 4 | one | 3 | -3 | | 0 + 1 | 4 | one | 2 | 4 | 1 | -1 + 1 | 4 | one | 2 | 4 | 0 | + 1 | 4 | one | 2 | 4 | 5 | -5 + 1 | 4 | one | 2 | 4 | 5 | -5 + 1 | 4 | one | 2 | 4 | 2 | 2 + 1 | 4 | one | 2 | 4 | 3 | -3 + 1 | 4 | one | 2 | 4 | 2 | 4 + 1 | 4 | one | 2 | 4 | | + 1 | 4 | one | 2 | 4 | | 0 + 1 | 4 | one | | | 1 | -1 + 1 | 4 | one | | | 0 | + 1 | 4 | one | | | 5 | -5 + 1 | 4 | one | | | 5 | -5 + 1 | 4 | one | | | 2 | 2 + 1 | 4 | one | | | 3 | -3 + 1 | 4 | one | | | 2 | 4 + 1 | 4 | one | | | | + 1 | 4 | one | | | | 0 + 1 | 4 | one | | 0 | 1 | -1 + 1 | 4 | one | | 0 | 0 | + 1 | 4 | one | | 0 | 5 | -5 + 1 | 4 | one | | 0 | 5 | -5 + 1 | 4 | one | | 0 | 2 | 2 + 1 | 4 | one | | 0 | 3 | -3 + 1 | 4 | one | | 0 | 2 | 4 + 1 | 4 | one | | 0 | | + 1 | 4 | one | | 0 | | 0 + 0 | | zero | 2 | 2 | 1 | -1 + 0 | | zero | 2 | 2 | 0 | + 0 | | zero | 2 | 2 | 5 | -5 + 0 | | zero | 2 | 2 | 5 | -5 + 0 | | zero | 2 | 2 | 2 | 2 + 0 | | zero | 2 | 2 | 3 | -3 + 0 | | zero | 2 | 2 | 2 | 4 + 0 | | zero | 2 | 2 | | + 0 | | zero | 2 | 2 | | 0 + 0 | | zero | 3 | -3 | 1 | -1 + 0 | | zero | 3 | -3 | 0 | + 0 | | zero | 3 | -3 | 5 | -5 + 0 | | zero | 3 | -3 | 5 | -5 + 0 | | zero | 3 | -3 | 2 | 2 + 0 | | zero | 3 | -3 | 3 | -3 + 0 | | zero | 3 | -3 | 2 | 4 + 0 | | zero | 3 | -3 | | + 0 | | zero | 3 | -3 | | 0 + 0 | | zero | 2 | 4 | 1 | -1 + 0 | | zero | 2 | 4 | 0 | + 0 | | zero | 2 | 4 | 5 | -5 + 0 | | zero | 2 | 4 | 5 | -5 + 0 | | zero | 2 | 4 | 2 | 2 + 0 | | zero | 2 | 4 | 3 | -3 + 0 | | zero | 2 | 4 | 2 | 4 0 | | zero | 2 | 4 | | 0 | | zero | 2 | 4 | | 0 - | | null | 2 | 4 | 1 | -1 - | | null | 2 | 4 | 2 | 2 - | | null | 2 | 4 | 3 | -3 - | | null | 2 | 4 | 2 | 4 - | | null | 2 | 4 | 5 | -5 - | | null | 2 | 4 | 5 | -5 - | | null | 2 | 4 | 0 | - | | null | 2 | 4 | | - | | null | 2 | 4 | | 0 - | 0 | zero | 2 | 4 | 1 | -1 - | 0 | zero | 2 | 4 | 2 | 2 - | 0 | zero | 2 | 4 | 3 | -3 - | 0 | zero | 2 | 4 | 2 | 4 - | 0 | zero | 2 | 4 | 5 | -5 - | 0 | zero | 2 | 4 | 5 | -5 - | 0 | zero | 2 | 4 | 0 | - | 0 | zero | 2 | 4 | | - | 0 | zero | 2 | 4 | | 0 - 1 | 4 | one | 5 | -5 | 1 | -1 - 1 | 4 | one | 5 | -5 | 2 | 2 - 1 | 4 | one | 5 | -5 | 3 | -3 - 1 | 4 | one | 5 | -5 | 2 | 4 - 1 | 4 | one | 5 | -5 | 5 | -5 - 1 | 4 | one | 5 | -5 | 5 | -5 - 1 | 4 | one | 5 | -5 | 0 | - 1 | 4 | one | 5 | -5 | | - 1 | 4 | one | 5 | -5 | | 0 - 2 | 3 | two | 5 | -5 | 1 | -1 - 2 | 3 | two | 5 | -5 | 2 | 2 - 2 | 3 | two | 5 | -5 | 3 | -3 - 2 | 3 | two | 5 | -5 | 2 | 4 - 2 | 3 | two | 5 | -5 | 5 | -5 - 2 | 3 | two | 5 | -5 | 5 | -5 - 2 | 3 | two | 5 | -5 | 0 | - 2 | 3 | two | 5 | -5 | | - 2 | 3 | two | 5 | -5 | | 0 - 3 | 2 | three | 5 | -5 | 1 | -1 - 3 | 2 | three | 5 | -5 | 2 | 2 - 3 | 2 | three | 5 | -5 | 3 | -3 - 3 | 2 | three | 5 | -5 | 2 | 4 - 3 | 2 | three | 5 | -5 | 5 | -5 - 3 | 2 | three | 5 | -5 | 5 | -5 - 3 | 2 | three | 5 | -5 | 0 | - 3 | 2 | three | 5 | -5 | | - 3 | 2 | three | 5 | -5 | | 0 - 4 | 1 | four | 5 | -5 | 1 | -1 - 4 | 1 | four | 5 | -5 | 2 | 2 - 4 | 1 | four | 5 | -5 | 3 | -3 - 4 | 1 | four | 5 | -5 | 2 | 4 - 4 | 1 | four | 5 | -5 | 5 | -5 - 4 | 1 | four | 5 | -5 | 5 | -5 - 4 | 1 | four | 5 | -5 | 0 | - 4 | 1 | four | 5 | -5 | | - 4 | 1 | four | 5 | -5 | | 0 - 5 | 0 | five | 5 | -5 | 1 | -1 - 5 | 0 | five | 5 | -5 | 2 | 2 - 5 | 0 | five | 5 | -5 | 3 | -3 - 5 | 0 | five | 5 | -5 | 2 | 4 - 5 | 0 | five | 5 | -5 | 5 | -5 - 5 | 0 | five | 5 | -5 | 5 | -5 - 5 | 0 | five | 5 | -5 | 0 | - 5 | 0 | five | 5 | -5 | | - 5 | 0 | five | 5 | -5 | | 0 - 6 | 6 | six | 5 | -5 | 1 | -1 - 6 | 6 | six | 5 | -5 | 2 | 2 - 6 | 6 | six | 5 | -5 | 3 | -3 - 6 | 6 | six | 5 | -5 | 2 | 4 - 6 | 6 | six | 5 | -5 | 5 | -5 - 6 | 6 | six | 5 | -5 | 5 | -5 - 6 | 6 | six | 5 | -5 | 0 | - 6 | 6 | six | 5 | -5 | | - 6 | 6 | six | 5 | -5 | | 0 - 7 | 7 | seven | 5 | -5 | 1 | -1 - 7 | 7 | seven | 5 | -5 | 2 | 2 - 7 | 7 | seven | 5 | -5 | 3 | -3 - 7 | 7 | seven | 5 | -5 | 2 | 4 - 7 | 7 | seven | 5 | -5 | 5 | -5 - 7 | 7 | seven | 5 | -5 | 5 | -5 - 7 | 7 | seven | 5 | -5 | 0 | - 7 | 7 | seven | 5 | -5 | | - 7 | 7 | seven | 5 | -5 | | 0 - 8 | 8 | eight | 5 | -5 | 1 | -1 - 8 | 8 | eight | 5 | -5 | 2 | 2 - 8 | 8 | eight | 5 | -5 | 3 | -3 - 8 | 8 | eight | 5 | -5 | 2 | 4 - 8 | 8 | eight | 5 | -5 | 5 | -5 - 8 | 8 | eight | 5 | -5 | 5 | -5 - 8 | 8 | eight | 5 | -5 | 0 | - 8 | 8 | eight | 5 | -5 | | - 8 | 8 | eight | 5 | -5 | | 0 - 0 | | zero | 5 | -5 | 1 | -1 - 0 | | zero | 5 | -5 | 2 | 2 - 0 | | zero | 5 | -5 | 3 | -3 - 0 | | zero | 5 | -5 | 2 | 4 - 0 | | zero | 5 | -5 | 5 | -5 - 0 | | zero | 5 | -5 | 5 | -5 - 0 | | zero | 5 | -5 | 0 | - 0 | | zero | 5 | -5 | | - 0 | | zero | 5 | -5 | | 0 - | | null | 5 | -5 | 1 | -1 - | | null | 5 | -5 | 2 | 2 - | | null | 5 | -5 | 3 | -3 - | | null | 5 | -5 | 2 | 4 - | | null | 5 | -5 | 5 | -5 - | | null | 5 | -5 | 5 | -5 - | | null | 5 | -5 | 0 | - | | null | 5 | -5 | | - | | null | 5 | -5 | | 0 - | 0 | zero | 5 | -5 | 1 | -1 - | 0 | zero | 5 | -5 | 2 | 2 - | 0 | zero | 5 | -5 | 3 | -3 - | 0 | zero | 5 | -5 | 2 | 4 - | 0 | zero | 5 | -5 | 5 | -5 - | 0 | zero | 5 | -5 | 5 | -5 - | 0 | zero | 5 | -5 | 0 | - | 0 | zero | 5 | -5 | | - | 0 | zero | 5 | -5 | | 0 - 1 | 4 | one | 5 | -5 | 1 | -1 - 1 | 4 | one | 5 | -5 | 2 | 2 - 1 | 4 | one | 5 | -5 | 3 | -3 - 1 | 4 | one | 5 | -5 | 2 | 4 - 1 | 4 | one | 5 | -5 | 5 | -5 - 1 | 4 | one | 5 | -5 | 5 | -5 - 1 | 4 | one | 5 | -5 | 0 | - 1 | 4 | one | 5 | -5 | | - 1 | 4 | one | 5 | -5 | | 0 - 2 | 3 | two | 5 | -5 | 1 | -1 - 2 | 3 | two | 5 | -5 | 2 | 2 - 2 | 3 | two | 5 | -5 | 3 | -3 - 2 | 3 | two | 5 | -5 | 2 | 4 - 2 | 3 | two | 5 | -5 | 5 | -5 - 2 | 3 | two | 5 | -5 | 5 | -5 - 2 | 3 | two | 5 | -5 | 0 | - 2 | 3 | two | 5 | -5 | | - 2 | 3 | two | 5 | -5 | | 0 - 3 | 2 | three | 5 | -5 | 1 | -1 - 3 | 2 | three | 5 | -5 | 2 | 2 - 3 | 2 | three | 5 | -5 | 3 | -3 - 3 | 2 | three | 5 | -5 | 2 | 4 - 3 | 2 | three | 5 | -5 | 5 | -5 - 3 | 2 | three | 5 | -5 | 5 | -5 - 3 | 2 | three | 5 | -5 | 0 | - 3 | 2 | three | 5 | -5 | | - 3 | 2 | three | 5 | -5 | | 0 - 4 | 1 | four | 5 | -5 | 1 | -1 - 4 | 1 | four | 5 | -5 | 2 | 2 - 4 | 1 | four | 5 | -5 | 3 | -3 - 4 | 1 | four | 5 | -5 | 2 | 4 - 4 | 1 | four | 5 | -5 | 5 | -5 - 4 | 1 | four | 5 | -5 | 5 | -5 - 4 | 1 | four | 5 | -5 | 0 | - 4 | 1 | four | 5 | -5 | | - 4 | 1 | four | 5 | -5 | | 0 - 5 | 0 | five | 5 | -5 | 1 | -1 - 5 | 0 | five | 5 | -5 | 2 | 2 - 5 | 0 | five | 5 | -5 | 3 | -3 - 5 | 0 | five | 5 | -5 | 2 | 4 - 5 | 0 | five | 5 | -5 | 5 | -5 - 5 | 0 | five | 5 | -5 | 5 | -5 - 5 | 0 | five | 5 | -5 | 0 | - 5 | 0 | five | 5 | -5 | | - 5 | 0 | five | 5 | -5 | | 0 - 6 | 6 | six | 5 | -5 | 1 | -1 - 6 | 6 | six | 5 | -5 | 2 | 2 - 6 | 6 | six | 5 | -5 | 3 | -3 - 6 | 6 | six | 5 | -5 | 2 | 4 - 6 | 6 | six | 5 | -5 | 5 | -5 - 6 | 6 | six | 5 | -5 | 5 | -5 - 6 | 6 | six | 5 | -5 | 0 | - 6 | 6 | six | 5 | -5 | | - 6 | 6 | six | 5 | -5 | | 0 - 7 | 7 | seven | 5 | -5 | 1 | -1 - 7 | 7 | seven | 5 | -5 | 2 | 2 - 7 | 7 | seven | 5 | -5 | 3 | -3 - 7 | 7 | seven | 5 | -5 | 2 | 4 - 7 | 7 | seven | 5 | -5 | 5 | -5 - 7 | 7 | seven | 5 | -5 | 5 | -5 - 7 | 7 | seven | 5 | -5 | 0 | - 7 | 7 | seven | 5 | -5 | | - 7 | 7 | seven | 5 | -5 | | 0 - 8 | 8 | eight | 5 | -5 | 1 | -1 - 8 | 8 | eight | 5 | -5 | 2 | 2 - 8 | 8 | eight | 5 | -5 | 3 | -3 - 8 | 8 | eight | 5 | -5 | 2 | 4 - 8 | 8 | eight | 5 | -5 | 5 | -5 - 8 | 8 | eight | 5 | -5 | 5 | -5 - 8 | 8 | eight | 5 | -5 | 0 | - 8 | 8 | eight | 5 | -5 | | - 8 | 8 | eight | 5 | -5 | | 0 - 0 | | zero | 5 | -5 | 1 | -1 - 0 | | zero | 5 | -5 | 2 | 2 - 0 | | zero | 5 | -5 | 3 | -3 - 0 | | zero | 5 | -5 | 2 | 4 - 0 | | zero | 5 | -5 | 5 | -5 - 0 | | zero | 5 | -5 | 5 | -5 - 0 | | zero | 5 | -5 | 0 | - 0 | | zero | 5 | -5 | | - 0 | | zero | 5 | -5 | | 0 - | | null | 5 | -5 | 1 | -1 - | | null | 5 | -5 | 2 | 2 - | | null | 5 | -5 | 3 | -3 - | | null | 5 | -5 | 2 | 4 - | | null | 5 | -5 | 5 | -5 - | | null | 5 | -5 | 5 | -5 - | | null | 5 | -5 | 0 | - | | null | 5 | -5 | | - | | null | 5 | -5 | | 0 - | 0 | zero | 5 | -5 | 1 | -1 - | 0 | zero | 5 | -5 | 2 | 2 - | 0 | zero | 5 | -5 | 3 | -3 - | 0 | zero | 5 | -5 | 2 | 4 - | 0 | zero | 5 | -5 | 5 | -5 - | 0 | zero | 5 | -5 | 5 | -5 - | 0 | zero | 5 | -5 | 0 | - | 0 | zero | 5 | -5 | | - | 0 | zero | 5 | -5 | | 0 - 1 | 4 | one | 0 | | 1 | -1 + 0 | | zero | | | 1 | -1 + 0 | | zero | | | 0 | + 0 | | zero | | | 5 | -5 + 0 | | zero | | | 5 | -5 + 0 | | zero | | | 2 | 2 + 0 | | zero | | | 3 | -3 + 0 | | zero | | | 2 | 4 + 0 | | zero | | | | + 0 | | zero | | | | 0 + 0 | | zero | | 0 | 1 | -1 + 0 | | zero | | 0 | 0 | + 0 | | zero | | 0 | 5 | -5 + 0 | | zero | | 0 | 5 | -5 + 0 | | zero | | 0 | 2 | 2 + 0 | | zero | | 0 | 3 | -3 + 0 | | zero | | 0 | 2 | 4 + 0 | | zero | | 0 | | + 0 | | zero | | 0 | | 0 + 2 | 3 | two | 2 | 2 | 1 | -1 + 2 | 3 | two | 2 | 2 | 0 | + 2 | 3 | two | 2 | 2 | 5 | -5 + 2 | 3 | two | 2 | 2 | 5 | -5 + 2 | 3 | two | 2 | 2 | 2 | 2 + 2 | 3 | two | 2 | 2 | 3 | -3 + 2 | 3 | two | 2 | 2 | 2 | 4 + 2 | 3 | two | 2 | 2 | | + 2 | 3 | two | 2 | 2 | | 0 + 2 | 3 | two | 3 | -3 | 1 | -1 + 2 | 3 | two | 3 | -3 | 0 | + 2 | 3 | two | 3 | -3 | 5 | -5 + 2 | 3 | two | 3 | -3 | 5 | -5 + 2 | 3 | two | 3 | -3 | 2 | 2 + 2 | 3 | two | 3 | -3 | 3 | -3 + 2 | 3 | two | 3 | -3 | 2 | 4 + 2 | 3 | two | 3 | -3 | | + 2 | 3 | two | 3 | -3 | | 0 + 2 | 3 | two | 2 | 4 | 1 | -1 + 2 | 3 | two | 2 | 4 | 0 | + 2 | 3 | two | 2 | 4 | 5 | -5 + 2 | 3 | two | 2 | 4 | 5 | -5 + 2 | 3 | two | 2 | 4 | 2 | 2 + 2 | 3 | two | 2 | 4 | 3 | -3 + 2 | 3 | two | 2 | 4 | 2 | 4 + 2 | 3 | two | 2 | 4 | | + 2 | 3 | two | 2 | 4 | | 0 + 2 | 3 | two | | | 1 | -1 + 1 | 4 | one | 1 | -1 | 2 | 2 + 1 | 4 | one | 1 | -1 | 3 | -3 + 1 | 4 | one | 1 | -1 | 2 | 4 + 1 | 4 | one | 1 | -1 | | + 1 | 4 | one | 1 | -1 | | 0 + 1 | 4 | one | 1 | -1 | 1 | -1 + 1 | 4 | one | 1 | -1 | 0 | + 1 | 4 | one | 1 | -1 | 5 | -5 + 1 | 4 | one | 1 | -1 | 5 | -5 1 | 4 | one | 0 | | 2 | 2 1 | 4 | one | 0 | | 3 | -3 1 | 4 | one | 0 | | 2 | 4 - 1 | 4 | one | 0 | | 5 | -5 - 1 | 4 | one | 0 | | 5 | -5 - 1 | 4 | one | 0 | | 0 | 1 | 4 | one | 0 | | | 1 | 4 | one | 0 | | | 0 - 2 | 3 | two | 0 | | 1 | -1 + 1 | 4 | one | 0 | | 1 | -1 + 1 | 4 | one | 0 | | 0 | + 1 | 4 | one | 0 | | 5 | -5 + 1 | 4 | one | 0 | | 5 | -5 + 0 | | zero | 1 | -1 | 2 | 2 + 0 | | zero | 1 | -1 | 3 | -3 + 0 | | zero | 1 | -1 | 2 | 4 + 0 | | zero | 1 | -1 | | + 0 | | zero | 1 | -1 | | 0 + 0 | | zero | 1 | -1 | 1 | -1 + 0 | | zero | 1 | -1 | 0 | + 0 | | zero | 1 | -1 | 5 | -5 + 0 | | zero | 1 | -1 | 5 | -5 + 0 | | zero | 0 | | 2 | 2 + 0 | | zero | 0 | | 3 | -3 + 0 | | zero | 0 | | 2 | 4 + 0 | | zero | 0 | | | + 0 | | zero | 0 | | | 0 + 0 | | zero | 0 | | 1 | -1 + 0 | | zero | 0 | | 0 | + 0 | | zero | 0 | | 5 | -5 + 0 | | zero | 0 | | 5 | -5 + 5 | 0 | five | 1 | -1 | 2 | 2 + 5 | 0 | five | 1 | -1 | 3 | -3 + 5 | 0 | five | 1 | -1 | 2 | 4 + 5 | 0 | five | 1 | -1 | | + 5 | 0 | five | 1 | -1 | | 0 + 5 | 0 | five | 1 | -1 | 1 | -1 + 5 | 0 | five | 1 | -1 | 0 | + 5 | 0 | five | 1 | -1 | 5 | -5 + 5 | 0 | five | 1 | -1 | 5 | -5 + 5 | 0 | five | 0 | | 2 | 2 + 5 | 0 | five | 0 | | 3 | -3 + 5 | 0 | five | 0 | | 2 | 4 + 5 | 0 | five | 0 | | | + 5 | 0 | five | 0 | | | 0 + 5 | 0 | five | 0 | | 1 | -1 + 5 | 0 | five | 0 | | 0 | + 5 | 0 | five | 0 | | 5 | -5 + 5 | 0 | five | 0 | | 5 | -5 + 6 | 6 | six | 1 | -1 | 2 | 2 + 6 | 6 | six | 1 | -1 | 3 | -3 + 6 | 6 | six | 1 | -1 | 2 | 4 + 6 | 6 | six | 1 | -1 | | + 6 | 6 | six | 1 | -1 | | 0 + 6 | 6 | six | 1 | -1 | 1 | -1 + 6 | 6 | six | 1 | -1 | 0 | + 6 | 6 | six | 1 | -1 | 5 | -5 + 6 | 6 | six | 1 | -1 | 5 | -5 + 6 | 6 | six | 0 | | 2 | 2 + 6 | 6 | six | 0 | | 3 | -3 + 6 | 6 | six | 0 | | 2 | 4 + 6 | 6 | six | 0 | | | + 6 | 6 | six | 0 | | | 0 + 6 | 6 | six | 0 | | 1 | -1 + 6 | 6 | six | 0 | | 0 | + 6 | 6 | six | 0 | | 5 | -5 + 6 | 6 | six | 0 | | 5 | -5 + 2 | 3 | two | 1 | -1 | 2 | 2 + 2 | 3 | two | 1 | -1 | 3 | -3 + 2 | 3 | two | 1 | -1 | 2 | 4 + 2 | 3 | two | 1 | -1 | | + 2 | 3 | two | 1 | -1 | | 0 + 2 | 3 | two | 1 | -1 | 1 | -1 + 2 | 3 | two | 1 | -1 | 0 | + 2 | 3 | two | 1 | -1 | 5 | -5 + 2 | 3 | two | 1 | -1 | 5 | -5 2 | 3 | two | 0 | | 2 | 2 2 | 3 | two | 0 | | 3 | -3 2 | 3 | two | 0 | | 2 | 4 - 2 | 3 | two | 0 | | 5 | -5 - 2 | 3 | two | 0 | | 5 | -5 - 2 | 3 | two | 0 | | 0 | 2 | 3 | two | 0 | | | 2 | 3 | two | 0 | | | 0 - 3 | 2 | three | 0 | | 1 | -1 + 2 | 3 | two | 0 | | 1 | -1 + 2 | 3 | two | 0 | | 0 | + 2 | 3 | two | 0 | | 5 | -5 + 2 | 3 | two | 0 | | 5 | -5 + 3 | 2 | three | 1 | -1 | 2 | 2 + 3 | 2 | three | 1 | -1 | 3 | -3 + 3 | 2 | three | 1 | -1 | 2 | 4 + 3 | 2 | three | 1 | -1 | | + 3 | 2 | three | 1 | -1 | | 0 + 3 | 2 | three | 1 | -1 | 1 | -1 + 3 | 2 | three | 1 | -1 | 0 | + 3 | 2 | three | 1 | -1 | 5 | -5 + 3 | 2 | three | 1 | -1 | 5 | -5 3 | 2 | three | 0 | | 2 | 2 3 | 2 | three | 0 | | 3 | -3 3 | 2 | three | 0 | | 2 | 4 - 3 | 2 | three | 0 | | 5 | -5 - 3 | 2 | three | 0 | | 5 | -5 - 3 | 2 | three | 0 | | 0 | 3 | 2 | three | 0 | | | 3 | 2 | three | 0 | | | 0 - 4 | 1 | four | 0 | | 1 | -1 + 3 | 2 | three | 0 | | 1 | -1 + 3 | 2 | three | 0 | | 0 | + 3 | 2 | three | 0 | | 5 | -5 + 3 | 2 | three | 0 | | 5 | -5 + 4 | 1 | four | 1 | -1 | 2 | 2 + 4 | 1 | four | 1 | -1 | 3 | -3 + 4 | 1 | four | 1 | -1 | 2 | 4 + 4 | 1 | four | 1 | -1 | | + 4 | 1 | four | 1 | -1 | | 0 + 4 | 1 | four | 1 | -1 | 1 | -1 + 4 | 1 | four | 1 | -1 | 0 | + 4 | 1 | four | 1 | -1 | 5 | -5 + 4 | 1 | four | 1 | -1 | 5 | -5 4 | 1 | four | 0 | | 2 | 2 4 | 1 | four | 0 | | 3 | -3 4 | 1 | four | 0 | | 2 | 4 - 4 | 1 | four | 0 | | 5 | -5 - 4 | 1 | four | 0 | | 5 | -5 - 4 | 1 | four | 0 | | 0 | 4 | 1 | four | 0 | | | 4 | 1 | four | 0 | | | 0 - 5 | 0 | five | 0 | | 1 | -1 - 5 | 0 | five | 0 | | 2 | 2 - 5 | 0 | five | 0 | | 3 | -3 - 5 | 0 | five | 0 | | 2 | 4 - 5 | 0 | five | 0 | | 5 | -5 - 5 | 0 | five | 0 | | 5 | -5 - 5 | 0 | five | 0 | | 0 | - 5 | 0 | five | 0 | | | - 5 | 0 | five | 0 | | | 0 - 6 | 6 | six | 0 | | 1 | -1 - 6 | 6 | six | 0 | | 2 | 2 - 6 | 6 | six | 0 | | 3 | -3 - 6 | 6 | six | 0 | | 2 | 4 - 6 | 6 | six | 0 | | 5 | -5 - 6 | 6 | six | 0 | | 5 | -5 - 6 | 6 | six | 0 | | 0 | - 6 | 6 | six | 0 | | | - 6 | 6 | six | 0 | | | 0 - 7 | 7 | seven | 0 | | 1 | -1 + 4 | 1 | four | 0 | | 1 | -1 + 4 | 1 | four | 0 | | 0 | + 4 | 1 | four | 0 | | 5 | -5 + 4 | 1 | four | 0 | | 5 | -5 + 7 | 7 | seven | 1 | -1 | 2 | 2 + 7 | 7 | seven | 1 | -1 | 3 | -3 + 7 | 7 | seven | 1 | -1 | 2 | 4 + 7 | 7 | seven | 1 | -1 | | + 7 | 7 | seven | 1 | -1 | | 0 + 7 | 7 | seven | 1 | -1 | 1 | -1 + 7 | 7 | seven | 1 | -1 | 0 | + 7 | 7 | seven | 1 | -1 | 5 | -5 + 7 | 7 | seven | 1 | -1 | 5 | -5 7 | 7 | seven | 0 | | 2 | 2 7 | 7 | seven | 0 | | 3 | -3 7 | 7 | seven | 0 | | 2 | 4 - 7 | 7 | seven | 0 | | 5 | -5 - 7 | 7 | seven | 0 | | 5 | -5 - 7 | 7 | seven | 0 | | 0 | 7 | 7 | seven | 0 | | | 7 | 7 | seven | 0 | | | 0 - 8 | 8 | eight | 0 | | 1 | -1 + 7 | 7 | seven | 0 | | 1 | -1 + 7 | 7 | seven | 0 | | 0 | + 7 | 7 | seven | 0 | | 5 | -5 + 7 | 7 | seven | 0 | | 5 | -5 + 8 | 8 | eight | 1 | -1 | 2 | 2 + 8 | 8 | eight | 1 | -1 | 3 | -3 + 8 | 8 | eight | 1 | -1 | 2 | 4 + 8 | 8 | eight | 1 | -1 | | + 8 | 8 | eight | 1 | -1 | | 0 + 8 | 8 | eight | 1 | -1 | 1 | -1 + 8 | 8 | eight | 1 | -1 | 0 | + 8 | 8 | eight | 1 | -1 | 5 | -5 + 8 | 8 | eight | 1 | -1 | 5 | -5 8 | 8 | eight | 0 | | 2 | 2 8 | 8 | eight | 0 | | 3 | -3 8 | 8 | eight | 0 | | 2 | 4 - 8 | 8 | eight | 0 | | 5 | -5 - 8 | 8 | eight | 0 | | 5 | -5 - 8 | 8 | eight | 0 | | 0 | 8 | 8 | eight | 0 | | | 8 | 8 | eight | 0 | | | 0 - 0 | | zero | 0 | | 1 | -1 - 0 | | zero | 0 | | 2 | 2 - 0 | | zero | 0 | | 3 | -3 - 0 | | zero | 0 | | 2 | 4 - 0 | | zero | 0 | | 5 | -5 - 0 | | zero | 0 | | 5 | -5 - 0 | | zero | 0 | | 0 | - 0 | | zero | 0 | | | - 0 | | zero | 0 | | | 0 - | | null | 0 | | 1 | -1 + 8 | 8 | eight | 0 | | 1 | -1 + 8 | 8 | eight | 0 | | 0 | + 8 | 8 | eight | 0 | | 5 | -5 + 8 | 8 | eight | 0 | | 5 | -5 + | | null | 1 | -1 | 2 | 2 + | | null | 1 | -1 | 3 | -3 + | | null | 1 | -1 | 2 | 4 + | | null | 1 | -1 | | + | | null | 1 | -1 | | 0 + | | null | 1 | -1 | 1 | -1 + | | null | 1 | -1 | 0 | + | | null | 1 | -1 | 5 | -5 + | | null | 1 | -1 | 5 | -5 | | null | 0 | | 2 | 2 | | null | 0 | | 3 | -3 | | null | 0 | | 2 | 4 - | | null | 0 | | 5 | -5 - | | null | 0 | | 5 | -5 - | | null | 0 | | 0 | | | null | 0 | | | | | null | 0 | | | 0 - | 0 | zero | 0 | | 1 | -1 + | | null | 0 | | 1 | -1 + | | null | 0 | | 0 | + | | null | 0 | | 5 | -5 + | | null | 0 | | 5 | -5 + | 0 | zero | 1 | -1 | 2 | 2 + | 0 | zero | 1 | -1 | 3 | -3 + | 0 | zero | 1 | -1 | 2 | 4 + | 0 | zero | 1 | -1 | | + | 0 | zero | 1 | -1 | | 0 + | 0 | zero | 1 | -1 | 1 | -1 + | 0 | zero | 1 | -1 | 0 | + | 0 | zero | 1 | -1 | 5 | -5 + | 0 | zero | 1 | -1 | 5 | -5 | 0 | zero | 0 | | 2 | 2 | 0 | zero | 0 | | 3 | -3 | 0 | zero | 0 | | 2 | 4 - | 0 | zero | 0 | | 5 | -5 - | 0 | zero | 0 | | 5 | -5 - | 0 | zero | 0 | | 0 | | 0 | zero | 0 | | | | 0 | zero | 0 | | | 0 - 1 | 4 | one | | | 1 | -1 - 1 | 4 | one | | | 2 | 2 - 1 | 4 | one | | | 3 | -3 - 1 | 4 | one | | | 2 | 4 - 1 | 4 | one | | | 5 | -5 - 1 | 4 | one | | | 5 | -5 - 1 | 4 | one | | | 0 | - 1 | 4 | one | | | | - 1 | 4 | one | | | | 0 - 2 | 3 | two | | | 1 | -1 + | 0 | zero | 0 | | 1 | -1 + | 0 | zero | 0 | | 0 | + | 0 | zero | 0 | | 5 | -5 + | 0 | zero | 0 | | 5 | -5 + 1 | 4 | one | 5 | -5 | 2 | 2 + 1 | 4 | one | 5 | -5 | 3 | -3 + 1 | 4 | one | 5 | -5 | 2 | 4 + 1 | 4 | one | 5 | -5 | | + 1 | 4 | one | 5 | -5 | | 0 + 1 | 4 | one | 5 | -5 | 1 | -1 + 1 | 4 | one | 5 | -5 | 0 | + 1 | 4 | one | 5 | -5 | 5 | -5 + 1 | 4 | one | 5 | -5 | 5 | -5 + 1 | 4 | one | 5 | -5 | 2 | 2 + 1 | 4 | one | 5 | -5 | 3 | -3 + 1 | 4 | one | 5 | -5 | 2 | 4 + 1 | 4 | one | 5 | -5 | | + 1 | 4 | one | 5 | -5 | | 0 + 1 | 4 | one | 5 | -5 | 1 | -1 + 1 | 4 | one | 5 | -5 | 0 | + 1 | 4 | one | 5 | -5 | 5 | -5 + 1 | 4 | one | 5 | -5 | 5 | -5 + 0 | | zero | 5 | -5 | 2 | 2 + 0 | | zero | 5 | -5 | 3 | -3 + 0 | | zero | 5 | -5 | 2 | 4 + 0 | | zero | 5 | -5 | | + 0 | | zero | 5 | -5 | | 0 + 0 | | zero | 5 | -5 | 1 | -1 + 0 | | zero | 5 | -5 | 0 | + 0 | | zero | 5 | -5 | 5 | -5 + 0 | | zero | 5 | -5 | 5 | -5 + 0 | | zero | 5 | -5 | 2 | 2 + 0 | | zero | 5 | -5 | 3 | -3 + 0 | | zero | 5 | -5 | 2 | 4 + 0 | | zero | 5 | -5 | | + 0 | | zero | 5 | -5 | | 0 + 0 | | zero | 5 | -5 | 1 | -1 + 0 | | zero | 5 | -5 | 0 | + 0 | | zero | 5 | -5 | 5 | -5 + 0 | | zero | 5 | -5 | 5 | -5 + 5 | 0 | five | 5 | -5 | 2 | 2 + 5 | 0 | five | 5 | -5 | 3 | -3 + 5 | 0 | five | 5 | -5 | 2 | 4 + 5 | 0 | five | 5 | -5 | | + 5 | 0 | five | 5 | -5 | | 0 + 5 | 0 | five | 5 | -5 | 1 | -1 + 5 | 0 | five | 5 | -5 | 0 | + 5 | 0 | five | 5 | -5 | 5 | -5 + 5 | 0 | five | 5 | -5 | 5 | -5 + 5 | 0 | five | 5 | -5 | 2 | 2 + 5 | 0 | five | 5 | -5 | 3 | -3 + 5 | 0 | five | 5 | -5 | 2 | 4 + 5 | 0 | five | 5 | -5 | | + 5 | 0 | five | 5 | -5 | | 0 + 5 | 0 | five | 5 | -5 | 1 | -1 + 5 | 0 | five | 5 | -5 | 0 | + 5 | 0 | five | 5 | -5 | 5 | -5 + 5 | 0 | five | 5 | -5 | 5 | -5 + 6 | 6 | six | 5 | -5 | 2 | 2 + 6 | 6 | six | 5 | -5 | 3 | -3 + 6 | 6 | six | 5 | -5 | 2 | 4 + 6 | 6 | six | 5 | -5 | | + 6 | 6 | six | 5 | -5 | | 0 + 6 | 6 | six | 5 | -5 | 1 | -1 + 6 | 6 | six | 5 | -5 | 0 | + 6 | 6 | six | 5 | -5 | 5 | -5 + 6 | 6 | six | 5 | -5 | 5 | -5 + 6 | 6 | six | 5 | -5 | 2 | 2 + 6 | 6 | six | 5 | -5 | 3 | -3 + 6 | 6 | six | 5 | -5 | 2 | 4 + 6 | 6 | six | 5 | -5 | | + 6 | 6 | six | 5 | -5 | | 0 + 6 | 6 | six | 5 | -5 | 1 | -1 + 6 | 6 | six | 5 | -5 | 0 | + 6 | 6 | six | 5 | -5 | 5 | -5 + 6 | 6 | six | 5 | -5 | 5 | -5 + 2 | 3 | two | 5 | -5 | 2 | 2 + 2 | 3 | two | 5 | -5 | 3 | -3 + 2 | 3 | two | 5 | -5 | 2 | 4 + 2 | 3 | two | 5 | -5 | | + 2 | 3 | two | 5 | -5 | | 0 + 2 | 3 | two | 5 | -5 | 1 | -1 + 2 | 3 | two | 5 | -5 | 0 | + 2 | 3 | two | 5 | -5 | 5 | -5 + 2 | 3 | two | 5 | -5 | 5 | -5 + 2 | 3 | two | 5 | -5 | 2 | 2 + 2 | 3 | two | 5 | -5 | 3 | -3 + 2 | 3 | two | 5 | -5 | 2 | 4 + 2 | 3 | two | 5 | -5 | | + 2 | 3 | two | 5 | -5 | | 0 + 2 | 3 | two | 5 | -5 | 1 | -1 + 2 | 3 | two | 5 | -5 | 0 | + 2 | 3 | two | 5 | -5 | 5 | -5 + 2 | 3 | two | 5 | -5 | 5 | -5 + 3 | 2 | three | 5 | -5 | 2 | 2 + 3 | 2 | three | 5 | -5 | 3 | -3 + 3 | 2 | three | 5 | -5 | 2 | 4 + 3 | 2 | three | 5 | -5 | | + 3 | 2 | three | 5 | -5 | | 0 + 3 | 2 | three | 5 | -5 | 1 | -1 + 3 | 2 | three | 5 | -5 | 0 | + 3 | 2 | three | 5 | -5 | 5 | -5 + 3 | 2 | three | 5 | -5 | 5 | -5 + 3 | 2 | three | 5 | -5 | 2 | 2 + 3 | 2 | three | 5 | -5 | 3 | -3 + 3 | 2 | three | 5 | -5 | 2 | 4 + 3 | 2 | three | 5 | -5 | | + 3 | 2 | three | 5 | -5 | | 0 + 3 | 2 | three | 5 | -5 | 1 | -1 + 3 | 2 | three | 5 | -5 | 0 | + 3 | 2 | three | 5 | -5 | 5 | -5 + 3 | 2 | three | 5 | -5 | 5 | -5 + 4 | 1 | four | 5 | -5 | 2 | 2 + 4 | 1 | four | 5 | -5 | 3 | -3 + 4 | 1 | four | 5 | -5 | 2 | 4 + 4 | 1 | four | 5 | -5 | | + 4 | 1 | four | 5 | -5 | | 0 + 4 | 1 | four | 5 | -5 | 1 | -1 + 4 | 1 | four | 5 | -5 | 0 | + 4 | 1 | four | 5 | -5 | 5 | -5 + 4 | 1 | four | 5 | -5 | 5 | -5 + 4 | 1 | four | 5 | -5 | 2 | 2 + 4 | 1 | four | 5 | -5 | 3 | -3 + 4 | 1 | four | 5 | -5 | 2 | 4 + 4 | 1 | four | 5 | -5 | | + 4 | 1 | four | 5 | -5 | | 0 + 4 | 1 | four | 5 | -5 | 1 | -1 + 4 | 1 | four | 5 | -5 | 0 | + 4 | 1 | four | 5 | -5 | 5 | -5 + 4 | 1 | four | 5 | -5 | 5 | -5 + 7 | 7 | seven | 5 | -5 | 2 | 2 + 7 | 7 | seven | 5 | -5 | 3 | -3 + 7 | 7 | seven | 5 | -5 | 2 | 4 + 7 | 7 | seven | 5 | -5 | | + 7 | 7 | seven | 5 | -5 | | 0 + 7 | 7 | seven | 5 | -5 | 1 | -1 + 7 | 7 | seven | 5 | -5 | 0 | + 7 | 7 | seven | 5 | -5 | 5 | -5 + 7 | 7 | seven | 5 | -5 | 5 | -5 + 7 | 7 | seven | 5 | -5 | 2 | 2 + 7 | 7 | seven | 5 | -5 | 3 | -3 + 7 | 7 | seven | 5 | -5 | 2 | 4 + 7 | 7 | seven | 5 | -5 | | + 7 | 7 | seven | 5 | -5 | | 0 + 7 | 7 | seven | 5 | -5 | 1 | -1 + 7 | 7 | seven | 5 | -5 | 0 | + 7 | 7 | seven | 5 | -5 | 5 | -5 + 7 | 7 | seven | 5 | -5 | 5 | -5 + 8 | 8 | eight | 5 | -5 | 2 | 2 + 8 | 8 | eight | 5 | -5 | 3 | -3 + 8 | 8 | eight | 5 | -5 | 2 | 4 + 8 | 8 | eight | 5 | -5 | | + 8 | 8 | eight | 5 | -5 | | 0 + 8 | 8 | eight | 5 | -5 | 1 | -1 + 8 | 8 | eight | 5 | -5 | 0 | + 8 | 8 | eight | 5 | -5 | 5 | -5 + 8 | 8 | eight | 5 | -5 | 5 | -5 + 8 | 8 | eight | 5 | -5 | 2 | 2 + 8 | 8 | eight | 5 | -5 | 3 | -3 + 8 | 8 | eight | 5 | -5 | 2 | 4 + 8 | 8 | eight | 5 | -5 | | + 8 | 8 | eight | 5 | -5 | | 0 + 8 | 8 | eight | 5 | -5 | 1 | -1 + 8 | 8 | eight | 5 | -5 | 0 | + 8 | 8 | eight | 5 | -5 | 5 | -5 + 8 | 8 | eight | 5 | -5 | 5 | -5 + | | null | 5 | -5 | 2 | 2 + | | null | 5 | -5 | 3 | -3 + | | null | 5 | -5 | 2 | 4 + | | null | 5 | -5 | | + | | null | 5 | -5 | | 0 + | | null | 5 | -5 | 1 | -1 + | | null | 5 | -5 | 0 | + | | null | 5 | -5 | 5 | -5 + | | null | 5 | -5 | 5 | -5 + | | null | 5 | -5 | 2 | 2 + | | null | 5 | -5 | 3 | -3 + | | null | 5 | -5 | 2 | 4 + | | null | 5 | -5 | | + | | null | 5 | -5 | | 0 + | | null | 5 | -5 | 1 | -1 + | | null | 5 | -5 | 0 | + | | null | 5 | -5 | 5 | -5 + | | null | 5 | -5 | 5 | -5 + | 0 | zero | 5 | -5 | 2 | 2 + | 0 | zero | 5 | -5 | 3 | -3 + | 0 | zero | 5 | -5 | 2 | 4 + | 0 | zero | 5 | -5 | | + | 0 | zero | 5 | -5 | | 0 + | 0 | zero | 5 | -5 | 1 | -1 + | 0 | zero | 5 | -5 | 0 | + | 0 | zero | 5 | -5 | 5 | -5 + | 0 | zero | 5 | -5 | 5 | -5 + | 0 | zero | 5 | -5 | 2 | 2 + | 0 | zero | 5 | -5 | 3 | -3 + | 0 | zero | 5 | -5 | 2 | 4 + | 0 | zero | 5 | -5 | | + | 0 | zero | 5 | -5 | | 0 + | 0 | zero | 5 | -5 | 1 | -1 + | 0 | zero | 5 | -5 | 0 | + | 0 | zero | 5 | -5 | 5 | -5 + | 0 | zero | 5 | -5 | 5 | -5 + 2 | 3 | two | | | 0 | + 2 | 3 | two | | | 5 | -5 + 2 | 3 | two | | | 5 | -5 2 | 3 | two | | | 2 | 2 2 | 3 | two | | | 3 | -3 2 | 3 | two | | | 2 | 4 - 2 | 3 | two | | | 5 | -5 - 2 | 3 | two | | | 5 | -5 - 2 | 3 | two | | | 0 | 2 | 3 | two | | | | 2 | 3 | two | | | | 0 - 3 | 2 | three | | | 1 | -1 - 3 | 2 | three | | | 2 | 2 - 3 | 2 | three | | | 3 | -3 - 3 | 2 | three | | | 2 | 4 - 3 | 2 | three | | | 5 | -5 - 3 | 2 | three | | | 5 | -5 - 3 | 2 | three | | | 0 | - 3 | 2 | three | | | | - 3 | 2 | three | | | | 0 - 4 | 1 | four | | | 1 | -1 - 4 | 1 | four | | | 2 | 2 - 4 | 1 | four | | | 3 | -3 - 4 | 1 | four | | | 2 | 4 - 4 | 1 | four | | | 5 | -5 - 4 | 1 | four | | | 5 | -5 - 4 | 1 | four | | | 0 | - 4 | 1 | four | | | | - 4 | 1 | four | | | | 0 - 5 | 0 | five | | | 1 | -1 - 5 | 0 | five | | | 2 | 2 - 5 | 0 | five | | | 3 | -3 - 5 | 0 | five | | | 2 | 4 - 5 | 0 | five | | | 5 | -5 - 5 | 0 | five | | | 5 | -5 - 5 | 0 | five | | | 0 | - 5 | 0 | five | | | | - 5 | 0 | five | | | | 0 - 6 | 6 | six | | | 1 | -1 - 6 | 6 | six | | | 2 | 2 - 6 | 6 | six | | | 3 | -3 - 6 | 6 | six | | | 2 | 4 - 6 | 6 | six | | | 5 | -5 - 6 | 6 | six | | | 5 | -5 - 6 | 6 | six | | | 0 | - 6 | 6 | six | | | | - 6 | 6 | six | | | | 0 - 7 | 7 | seven | | | 1 | -1 - 7 | 7 | seven | | | 2 | 2 - 7 | 7 | seven | | | 3 | -3 - 7 | 7 | seven | | | 2 | 4 - 7 | 7 | seven | | | 5 | -5 - 7 | 7 | seven | | | 5 | -5 - 7 | 7 | seven | | | 0 | - 7 | 7 | seven | | | | - 7 | 7 | seven | | | | 0 - 8 | 8 | eight | | | 1 | -1 - 8 | 8 | eight | | | 2 | 2 - 8 | 8 | eight | | | 3 | -3 - 8 | 8 | eight | | | 2 | 4 - 8 | 8 | eight | | | 5 | -5 - 8 | 8 | eight | | | 5 | -5 - 8 | 8 | eight | | | 0 | - 8 | 8 | eight | | | | - 8 | 8 | eight | | | | 0 - 0 | | zero | | | 1 | -1 - 0 | | zero | | | 2 | 2 - 0 | | zero | | | 3 | -3 - 0 | | zero | | | 2 | 4 - 0 | | zero | | | 5 | -5 - 0 | | zero | | | 5 | -5 - 0 | | zero | | | 0 | - 0 | | zero | | | | - 0 | | zero | | | | 0 - | | null | | | 1 | -1 - | | null | | | 2 | 2 - | | null | | | 3 | -3 - | | null | | | 2 | 4 - | | null | | | 5 | -5 - | | null | | | 5 | -5 - | | null | | | 0 | - | | null | | | | - | | null | | | | 0 - | 0 | zero | | | 1 | -1 - | 0 | zero | | | 2 | 2 - | 0 | zero | | | 3 | -3 - | 0 | zero | | | 2 | 4 - | 0 | zero | | | 5 | -5 - | 0 | zero | | | 5 | -5 - | 0 | zero | | | 0 | - | 0 | zero | | | | - | 0 | zero | | | | 0 - 1 | 4 | one | | 0 | 1 | -1 - 1 | 4 | one | | 0 | 2 | 2 - 1 | 4 | one | | 0 | 3 | -3 - 1 | 4 | one | | 0 | 2 | 4 - 1 | 4 | one | | 0 | 5 | -5 - 1 | 4 | one | | 0 | 5 | -5 - 1 | 4 | one | | 0 | 0 | - 1 | 4 | one | | 0 | | - 1 | 4 | one | | 0 | | 0 2 | 3 | two | | 0 | 1 | -1 + 2 | 3 | two | | 0 | 0 | + 2 | 3 | two | | 0 | 5 | -5 + 2 | 3 | two | | 0 | 5 | -5 2 | 3 | two | | 0 | 2 | 2 2 | 3 | two | | 0 | 3 | -3 2 | 3 | two | | 0 | 2 | 4 - 2 | 3 | two | | 0 | 5 | -5 - 2 | 3 | two | | 0 | 5 | -5 - 2 | 3 | two | | 0 | 0 | 2 | 3 | two | | 0 | | 2 | 3 | two | | 0 | | 0 + 3 | 2 | three | 2 | 2 | 1 | -1 + 3 | 2 | three | 2 | 2 | 0 | + 3 | 2 | three | 2 | 2 | 5 | -5 + 3 | 2 | three | 2 | 2 | 5 | -5 + 3 | 2 | three | 2 | 2 | 2 | 2 + 3 | 2 | three | 2 | 2 | 3 | -3 + 3 | 2 | three | 2 | 2 | 2 | 4 + 3 | 2 | three | 2 | 2 | | + 3 | 2 | three | 2 | 2 | | 0 + 3 | 2 | three | 3 | -3 | 1 | -1 + 3 | 2 | three | 3 | -3 | 0 | + 3 | 2 | three | 3 | -3 | 5 | -5 + 3 | 2 | three | 3 | -3 | 5 | -5 + 3 | 2 | three | 3 | -3 | 2 | 2 + 3 | 2 | three | 3 | -3 | 3 | -3 + 3 | 2 | three | 3 | -3 | 2 | 4 + 3 | 2 | three | 3 | -3 | | + 3 | 2 | three | 3 | -3 | | 0 + 3 | 2 | three | 2 | 4 | 1 | -1 + 3 | 2 | three | 2 | 4 | 0 | + 3 | 2 | three | 2 | 4 | 5 | -5 + 3 | 2 | three | 2 | 4 | 5 | -5 + 3 | 2 | three | 2 | 4 | 2 | 2 + 3 | 2 | three | 2 | 4 | 3 | -3 + 3 | 2 | three | 2 | 4 | 2 | 4 + 3 | 2 | three | 2 | 4 | | + 3 | 2 | three | 2 | 4 | | 0 + 3 | 2 | three | | | 1 | -1 + 3 | 2 | three | | | 0 | + 3 | 2 | three | | | 5 | -5 + 3 | 2 | three | | | 5 | -5 + 3 | 2 | three | | | 2 | 2 + 3 | 2 | three | | | 3 | -3 + 3 | 2 | three | | | 2 | 4 + 3 | 2 | three | | | | + 3 | 2 | three | | | | 0 3 | 2 | three | | 0 | 1 | -1 + 3 | 2 | three | | 0 | 0 | + 3 | 2 | three | | 0 | 5 | -5 + 3 | 2 | three | | 0 | 5 | -5 3 | 2 | three | | 0 | 2 | 2 3 | 2 | three | | 0 | 3 | -3 3 | 2 | three | | 0 | 2 | 4 - 3 | 2 | three | | 0 | 5 | -5 - 3 | 2 | three | | 0 | 5 | -5 - 3 | 2 | three | | 0 | 0 | 3 | 2 | three | | 0 | | 3 | 2 | three | | 0 | | 0 + 4 | 1 | four | 2 | 2 | 1 | -1 + 4 | 1 | four | 2 | 2 | 0 | + 4 | 1 | four | 2 | 2 | 5 | -5 + 4 | 1 | four | 2 | 2 | 5 | -5 + 4 | 1 | four | 2 | 2 | 2 | 2 + 4 | 1 | four | 2 | 2 | 3 | -3 + 4 | 1 | four | 2 | 2 | 2 | 4 + 4 | 1 | four | 2 | 2 | | + 4 | 1 | four | 2 | 2 | | 0 + 4 | 1 | four | 3 | -3 | 1 | -1 + 4 | 1 | four | 3 | -3 | 0 | + 4 | 1 | four | 3 | -3 | 5 | -5 + 4 | 1 | four | 3 | -3 | 5 | -5 + 4 | 1 | four | 3 | -3 | 2 | 2 + 4 | 1 | four | 3 | -3 | 3 | -3 + 4 | 1 | four | 3 | -3 | 2 | 4 + 4 | 1 | four | 3 | -3 | | + 4 | 1 | four | 3 | -3 | | 0 + 4 | 1 | four | 2 | 4 | 1 | -1 + 4 | 1 | four | 2 | 4 | 0 | + 4 | 1 | four | 2 | 4 | 5 | -5 + 4 | 1 | four | 2 | 4 | 5 | -5 + 4 | 1 | four | 2 | 4 | 2 | 2 + 4 | 1 | four | 2 | 4 | 3 | -3 + 4 | 1 | four | 2 | 4 | 2 | 4 + 4 | 1 | four | 2 | 4 | | + 4 | 1 | four | 2 | 4 | | 0 + 4 | 1 | four | | | 1 | -1 + 4 | 1 | four | | | 0 | + 4 | 1 | four | | | 5 | -5 + 4 | 1 | four | | | 5 | -5 + 4 | 1 | four | | | 2 | 2 + 4 | 1 | four | | | 3 | -3 + 4 | 1 | four | | | 2 | 4 + 4 | 1 | four | | | | + 4 | 1 | four | | | | 0 4 | 1 | four | | 0 | 1 | -1 + 4 | 1 | four | | 0 | 0 | + 4 | 1 | four | | 0 | 5 | -5 + 4 | 1 | four | | 0 | 5 | -5 4 | 1 | four | | 0 | 2 | 2 4 | 1 | four | | 0 | 3 | -3 4 | 1 | four | | 0 | 2 | 4 - 4 | 1 | four | | 0 | 5 | -5 - 4 | 1 | four | | 0 | 5 | -5 - 4 | 1 | four | | 0 | 0 | 4 | 1 | four | | 0 | | 4 | 1 | four | | 0 | | 0 - 5 | 0 | five | | 0 | 1 | -1 - 5 | 0 | five | | 0 | 2 | 2 - 5 | 0 | five | | 0 | 3 | -3 - 5 | 0 | five | | 0 | 2 | 4 - 5 | 0 | five | | 0 | 5 | -5 - 5 | 0 | five | | 0 | 5 | -5 - 5 | 0 | five | | 0 | 0 | - 5 | 0 | five | | 0 | | - 5 | 0 | five | | 0 | | 0 - 6 | 6 | six | | 0 | 1 | -1 - 6 | 6 | six | | 0 | 2 | 2 - 6 | 6 | six | | 0 | 3 | -3 - 6 | 6 | six | | 0 | 2 | 4 - 6 | 6 | six | | 0 | 5 | -5 - 6 | 6 | six | | 0 | 5 | -5 - 6 | 6 | six | | 0 | 0 | - 6 | 6 | six | | 0 | | - 6 | 6 | six | | 0 | | 0 + 7 | 7 | seven | 2 | 2 | 1 | -1 + 7 | 7 | seven | 2 | 2 | 0 | + 7 | 7 | seven | 2 | 2 | 5 | -5 + 7 | 7 | seven | 2 | 2 | 5 | -5 + 7 | 7 | seven | 2 | 2 | 2 | 2 + 7 | 7 | seven | 2 | 2 | 3 | -3 + 7 | 7 | seven | 2 | 2 | 2 | 4 + 7 | 7 | seven | 2 | 2 | | + 7 | 7 | seven | 2 | 2 | | 0 + 7 | 7 | seven | 3 | -3 | 1 | -1 + 7 | 7 | seven | 3 | -3 | 0 | + 7 | 7 | seven | 3 | -3 | 5 | -5 + 7 | 7 | seven | 3 | -3 | 5 | -5 + 7 | 7 | seven | 3 | -3 | 2 | 2 + 7 | 7 | seven | 3 | -3 | 3 | -3 + 7 | 7 | seven | 3 | -3 | 2 | 4 + 7 | 7 | seven | 3 | -3 | | + 7 | 7 | seven | 3 | -3 | | 0 + 7 | 7 | seven | 2 | 4 | 1 | -1 + 7 | 7 | seven | 2 | 4 | 0 | + 7 | 7 | seven | 2 | 4 | 5 | -5 + 7 | 7 | seven | 2 | 4 | 5 | -5 + 7 | 7 | seven | 2 | 4 | 2 | 2 + 7 | 7 | seven | 2 | 4 | 3 | -3 + 7 | 7 | seven | 2 | 4 | 2 | 4 + 7 | 7 | seven | 2 | 4 | | + 7 | 7 | seven | 2 | 4 | | 0 + 7 | 7 | seven | | | 1 | -1 + 7 | 7 | seven | | | 0 | + 7 | 7 | seven | | | 5 | -5 + 7 | 7 | seven | | | 5 | -5 + 7 | 7 | seven | | | 2 | 2 + 7 | 7 | seven | | | 3 | -3 + 7 | 7 | seven | | | 2 | 4 + 7 | 7 | seven | | | | + 7 | 7 | seven | | | | 0 7 | 7 | seven | | 0 | 1 | -1 + 7 | 7 | seven | | 0 | 0 | + 7 | 7 | seven | | 0 | 5 | -5 + 7 | 7 | seven | | 0 | 5 | -5 7 | 7 | seven | | 0 | 2 | 2 7 | 7 | seven | | 0 | 3 | -3 7 | 7 | seven | | 0 | 2 | 4 - 7 | 7 | seven | | 0 | 5 | -5 - 7 | 7 | seven | | 0 | 5 | -5 - 7 | 7 | seven | | 0 | 0 | 7 | 7 | seven | | 0 | | 7 | 7 | seven | | 0 | | 0 + 8 | 8 | eight | 2 | 2 | 1 | -1 + 8 | 8 | eight | 2 | 2 | 0 | + 8 | 8 | eight | 2 | 2 | 5 | -5 + 8 | 8 | eight | 2 | 2 | 5 | -5 + 8 | 8 | eight | 2 | 2 | 2 | 2 + 8 | 8 | eight | 2 | 2 | 3 | -3 + 8 | 8 | eight | 2 | 2 | 2 | 4 + 8 | 8 | eight | 2 | 2 | | + 8 | 8 | eight | 2 | 2 | | 0 + 8 | 8 | eight | 3 | -3 | 1 | -1 + 8 | 8 | eight | 3 | -3 | 0 | + 8 | 8 | eight | 3 | -3 | 5 | -5 + 8 | 8 | eight | 3 | -3 | 5 | -5 + 8 | 8 | eight | 3 | -3 | 2 | 2 + 8 | 8 | eight | 3 | -3 | 3 | -3 + 8 | 8 | eight | 3 | -3 | 2 | 4 + 8 | 8 | eight | 3 | -3 | | + 8 | 8 | eight | 3 | -3 | | 0 + 8 | 8 | eight | 2 | 4 | 1 | -1 + 8 | 8 | eight | 2 | 4 | 0 | + 8 | 8 | eight | 2 | 4 | 5 | -5 + 8 | 8 | eight | 2 | 4 | 5 | -5 + 8 | 8 | eight | 2 | 4 | 2 | 2 + 8 | 8 | eight | 2 | 4 | 3 | -3 + 8 | 8 | eight | 2 | 4 | 2 | 4 + 8 | 8 | eight | 2 | 4 | | + 8 | 8 | eight | 2 | 4 | | 0 + 8 | 8 | eight | | | 1 | -1 + 8 | 8 | eight | | | 0 | + 8 | 8 | eight | | | 5 | -5 + 8 | 8 | eight | | | 5 | -5 + 8 | 8 | eight | | | 2 | 2 + 8 | 8 | eight | | | 3 | -3 + 8 | 8 | eight | | | 2 | 4 + 8 | 8 | eight | | | | + 8 | 8 | eight | | | | 0 8 | 8 | eight | | 0 | 1 | -1 + 8 | 8 | eight | | 0 | 0 | + 8 | 8 | eight | | 0 | 5 | -5 + 8 | 8 | eight | | 0 | 5 | -5 8 | 8 | eight | | 0 | 2 | 2 8 | 8 | eight | | 0 | 3 | -3 8 | 8 | eight | | 0 | 2 | 4 - 8 | 8 | eight | | 0 | 5 | -5 - 8 | 8 | eight | | 0 | 5 | -5 - 8 | 8 | eight | | 0 | 0 | 8 | 8 | eight | | 0 | | 8 | 8 | eight | | 0 | | 0 - 0 | | zero | | 0 | 1 | -1 - 0 | | zero | | 0 | 2 | 2 - 0 | | zero | | 0 | 3 | -3 - 0 | | zero | | 0 | 2 | 4 - 0 | | zero | | 0 | 5 | -5 - 0 | | zero | | 0 | 5 | -5 - 0 | | zero | | 0 | 0 | - 0 | | zero | | 0 | | - 0 | | zero | | 0 | | 0 + | | null | 2 | 2 | 1 | -1 + | | null | 2 | 2 | 0 | + | | null | 2 | 2 | 5 | -5 + | | null | 2 | 2 | 5 | -5 + | | null | 2 | 2 | 2 | 2 + | | null | 2 | 2 | 3 | -3 + | | null | 2 | 2 | 2 | 4 + | | null | 2 | 2 | | + | | null | 2 | 2 | | 0 + | | null | 3 | -3 | 1 | -1 + | | null | 3 | -3 | 0 | + | | null | 3 | -3 | 5 | -5 + | | null | 3 | -3 | 5 | -5 + | | null | 3 | -3 | 2 | 2 + | | null | 3 | -3 | 3 | -3 + | | null | 3 | -3 | 2 | 4 + | | null | 3 | -3 | | + | | null | 3 | -3 | | 0 + | | null | 2 | 4 | 1 | -1 + | | null | 2 | 4 | 0 | + | | null | 2 | 4 | 5 | -5 + | | null | 2 | 4 | 5 | -5 + | | null | 2 | 4 | 2 | 2 + | | null | 2 | 4 | 3 | -3 + | | null | 2 | 4 | 2 | 4 + | | null | 2 | 4 | | + | | null | 2 | 4 | | 0 + | | null | | | 1 | -1 + | | null | | | 0 | + | | null | | | 5 | -5 + | | null | | | 5 | -5 + | | null | | | 2 | 2 + | | null | | | 3 | -3 + | | null | | | 2 | 4 + | | null | | | | + | | null | | | | 0 | | null | | 0 | 1 | -1 + | | null | | 0 | 0 | + | | null | | 0 | 5 | -5 + | | null | | 0 | 5 | -5 | | null | | 0 | 2 | 2 | | null | | 0 | 3 | -3 | | null | | 0 | 2 | 4 - | | null | | 0 | 5 | -5 - | | null | | 0 | 5 | -5 - | | null | | 0 | 0 | | | null | | 0 | | | | null | | 0 | | 0 + | 0 | zero | 2 | 2 | 1 | -1 + | 0 | zero | 2 | 2 | 0 | + | 0 | zero | 2 | 2 | 5 | -5 + | 0 | zero | 2 | 2 | 5 | -5 + | 0 | zero | 2 | 2 | 2 | 2 + | 0 | zero | 2 | 2 | 3 | -3 + | 0 | zero | 2 | 2 | 2 | 4 + | 0 | zero | 2 | 2 | | + | 0 | zero | 2 | 2 | | 0 + | 0 | zero | 3 | -3 | 1 | -1 + | 0 | zero | 3 | -3 | 0 | + | 0 | zero | 3 | -3 | 5 | -5 + | 0 | zero | 3 | -3 | 5 | -5 + | 0 | zero | 3 | -3 | 2 | 2 + | 0 | zero | 3 | -3 | 3 | -3 + | 0 | zero | 3 | -3 | 2 | 4 + | 0 | zero | 3 | -3 | | + | 0 | zero | 3 | -3 | | 0 + | 0 | zero | 2 | 4 | 1 | -1 + | 0 | zero | 2 | 4 | 0 | + | 0 | zero | 2 | 4 | 5 | -5 + | 0 | zero | 2 | 4 | 5 | -5 + | 0 | zero | 2 | 4 | 2 | 2 + | 0 | zero | 2 | 4 | 3 | -3 + | 0 | zero | 2 | 4 | 2 | 4 + | 0 | zero | 2 | 4 | | + | 0 | zero | 2 | 4 | | 0 + | 0 | zero | | | 1 | -1 + | 0 | zero | | | 0 | + | 0 | zero | | | 5 | -5 + | 0 | zero | | | 5 | -5 + | 0 | zero | | | 2 | 2 + | 0 | zero | | | 3 | -3 + | 0 | zero | | | 2 | 4 + | 0 | zero | | | | + | 0 | zero | | | | 0 | 0 | zero | | 0 | 1 | -1 + | 0 | zero | | 0 | 0 | + | 0 | zero | | 0 | 5 | -5 + | 0 | zero | | 0 | 5 | -5 | 0 | zero | | 0 | 2 | 2 | 0 | zero | | 0 | 3 | -3 | 0 | zero | | 0 | 2 | 4 - | 0 | zero | | 0 | 5 | -5 - | 0 | zero | | 0 | 5 | -5 - | 0 | zero | | 0 | 0 | | 0 | zero | | 0 | | | 0 | zero | | 0 | | 0 (891 rows) @@ -1573,13 +1578,13 @@ SELECT * FROM J1_TBL INNER JOIN J2_TBL USING (i); i | j | t | k ---+---+-------+---- - 0 | | zero | + 5 | 0 | five | -5 + 5 | 0 | five | -5 1 | 4 | one | -1 + 0 | | zero | 2 | 3 | two | 2 - 2 | 3 | two | 4 3 | 2 | three | -3 - 5 | 0 | five | -5 - 5 | 0 | five | -5 + 2 | 3 | two | 4 (7 rows) -- Same as above, slightly different syntax @@ -1587,13 +1592,13 @@ SELECT * FROM J1_TBL JOIN J2_TBL USING (i); i | j | t | k ---+---+-------+---- - 0 | | zero | - 1 | 4 | one | -1 2 | 3 | two | 2 - 2 | 3 | two | 4 3 | 2 | three | -3 + 2 | 3 | two | 4 5 | 0 | five | -5 5 | 0 | five | -5 + 1 | 4 | one | -1 + 0 | | zero | (7 rows) SELECT * @@ -1681,35 +1686,35 @@ SELECT * FROM J1_TBL NATURAL JOIN J2_TBL; i | j | t | k ---+---+-------+---- - 0 | | zero | 1 | 4 | one | -1 - 2 | 3 | two | 2 - 2 | 3 | two | 4 - 3 | 2 | three | -3 + 0 | | zero | 5 | 0 | five | -5 5 | 0 | five | -5 + 2 | 3 | two | 2 + 3 | 2 | three | -3 + 2 | 3 | two | 4 (7 rows) SELECT * FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (a, d); a | b | c | d ---+---+-------+---- - 0 | | zero | - 1 | 4 | one | -1 - 2 | 3 | two | 2 - 2 | 3 | two | 4 - 3 | 2 | three | -3 5 | 0 | five | -5 5 | 0 | five | -5 + 2 | 3 | two | 2 + 3 | 2 | three | -3 + 2 | 3 | two | 4 + 1 | 4 | one | -1 + 0 | | zero | (7 rows) SELECT * FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a); a | b | c | d ---+---+------+--- - 0 | | zero | 2 | 3 | two | 2 4 | 1 | four | 2 + 0 | | zero | (3 rows) -- mismatch number of columns @@ -1718,13 +1723,13 @@ SELECT * FROM J1_TBL t1 (a, b) NATURAL JOIN J2_TBL t2 (a); a | b | t | k ---+---+-------+---- - 0 | | zero | 1 | 4 | one | -1 - 2 | 3 | two | 2 - 2 | 3 | two | 4 - 3 | 2 | three | -3 + 0 | | zero | 5 | 0 | five | -5 5 | 0 | five | -5 + 2 | 3 | two | 2 + 3 | 2 | three | -3 + 2 | 3 | two | 4 (7 rows) -- @@ -1734,11 +1739,11 @@ SELECT * FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.i); i | j | t | i | k ---+---+-------+---+---- - 0 | | zero | 0 | 1 | 4 | one | 1 | -1 + 0 | | zero | 0 | 2 | 3 | two | 2 | 2 - 2 | 3 | two | 2 | 4 3 | 2 | three | 3 | -3 + 2 | 3 | two | 2 | 4 5 | 0 | five | 5 | -5 5 | 0 | five | 5 | -5 (7 rows) @@ -1760,14 +1765,14 @@ SELECT * i | j | t | i | k ---+---+-------+---+--- 1 | 4 | one | 2 | 2 - 2 | 3 | two | 2 | 2 0 | | zero | 2 | 2 1 | 4 | one | 2 | 4 + 0 | | zero | 2 | 4 + 0 | | zero | | 0 + 2 | 3 | two | 2 | 2 2 | 3 | two | 2 | 4 3 | 2 | three | 2 | 4 4 | 1 | four | 2 | 4 - 0 | | zero | 2 | 4 - 0 | | zero | | 0 (9 rows) -- @@ -1818,13 +1823,13 @@ SELECT * FROM J1_TBL RIGHT OUTER JOIN J2_TBL USING (i); i | j | t | k ---+---+-------+---- - 0 | | zero | 1 | 4 | one | -1 - 2 | 3 | two | 2 - 2 | 3 | two | 4 - 3 | 2 | three | -3 + 0 | | zero | 5 | 0 | five | -5 5 | 0 | five | -5 + 2 | 3 | two | 2 + 3 | 2 | three | -3 + 2 | 3 | two | 4 | | | | | | 0 (9 rows) @@ -1833,13 +1838,13 @@ SELECT * FROM J1_TBL RIGHT JOIN J2_TBL USING (i); i | j | t | k ---+---+-------+---- - 0 | | zero | + 5 | 0 | five | -5 + 5 | 0 | five | -5 1 | 4 | one | -1 + 0 | | zero | 2 | 3 | two | 2 - 2 | 3 | two | 4 3 | 2 | three | -3 - 5 | 0 | five | -5 - 5 | 0 | five | -5 + 2 | 3 | two | 4 | | | | | | 0 (9 rows) @@ -1909,21 +1914,21 @@ select * from int4_tbl i4, tenk1 a where exists(select * from tenk1 b where a.twothousand = b.twothousand and a.fivethous <> b.fivethous) and i4.f1 = a.tenthous; - QUERY PLAN ---------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Join Hash Cond: (i4.f1 = a.tenthous) -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on int4_tbl i4 -> Hash - -> Hash Semi Join - Hash Cond: (a.twothousand = b.twothousand) + -> Hash Right Semi Join + Hash Cond: (b.twothousand = a.twothousand) Join Filter: (a.fivethous <> b.fivethous) - -> Seq Scan on tenk1 a + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Seq Scan on tenk1 b -> Hash - -> Broadcast Motion 3:3 (slice3; segments: 3) - -> Seq Scan on tenk1 b + -> Seq Scan on tenk1 a Optimizer: Postgres query optimizer (14 rows) @@ -1934,8 +1939,14 @@ where exists(select * from tenk1 b -- Multiway full join -- CREATE TABLE t1 (name TEXT, n INTEGER); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'name' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TABLE t2 (name TEXT, n INTEGER); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'name' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TABLE t3 (name TEXT, n INTEGER); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'name' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO t1 VALUES ( 'bb', 11 ); INSERT INTO t2 VALUES ( 'bb', 12 ); INSERT INTO t2 VALUES ( 'cc', 22 ); @@ -1947,8 +1958,8 @@ SELECT * FROM t1 FULL JOIN t2 USING (name) FULL JOIN t3 USING (name); name | n | n | n ------+----+----+---- bb | 11 | 12 | 13 - cc | | 22 | 23 dd | | | 33 + cc | | 22 | 23 ee | | 42 | (4 rows) @@ -1975,8 +1986,8 @@ USING (name); name | n | n ------+----+---- bb | 12 | 13 - cc | 22 | 23 ee | 42 | + cc | 22 | 23 (3 rows) SELECT * FROM @@ -1986,8 +1997,8 @@ FULL JOIN USING (name); name | n | n ------+----+---- - bb | 12 | 13 cc | 22 | 23 + bb | 12 | 13 dd | | 33 ee | 42 | (4 rows) @@ -2000,8 +2011,8 @@ NATURAL INNER JOIN (SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; name | s2_n | s2_2 | s3_n | s3_2 ------+------+------+------+------ - bb | 12 | 2 | 13 | 3 cc | 22 | 2 | 23 | 3 + bb | 12 | 2 | 13 | 3 (2 rows) SELECT * FROM @@ -2011,8 +2022,8 @@ NATURAL LEFT JOIN name | s2_n | s2_2 | s3_n | s3_2 ------+------+------+------+------ bb | 12 | 2 | 13 | 3 - cc | 22 | 2 | 23 | 3 ee | 42 | 2 | | + cc | 22 | 2 | 23 | 3 (3 rows) SELECT * FROM @@ -2022,8 +2033,8 @@ NATURAL FULL JOIN name | s2_n | s2_2 | s3_n | s3_2 ------+------+------+------+------ bb | 12 | 2 | 13 | 3 - cc | 22 | 2 | 23 | 3 dd | | | 33 | 3 + cc | 22 | 2 | 23 | 3 ee | 42 | 2 | | (4 rows) @@ -2047,9 +2058,9 @@ NATURAL FULL JOIN name | s1_n | s1_1 | s2_n | s2_2 | s3_n | s3_2 ------+------+------+------+------+------+------ bb | 11 | 1 | 12 | 2 | 13 | 3 - cc | | | 22 | 2 | 23 | 3 dd | | | | | 33 | 3 ee | | | 42 | 2 | | + cc | | | 22 | 2 | 23 | 3 (4 rows) SELECT * FROM @@ -2062,10 +2073,10 @@ NATURAL FULL JOIN ) ss2; name | s1_n | s2_n | s3_n ------+------+------+------ - bb | 11 | 12 | 13 + ee | | 42 | cc | | 22 | 23 + bb | 11 | 12 | 13 dd | | | 33 - ee | | 42 | (4 rows) SELECT * FROM @@ -2079,9 +2090,9 @@ NATURAL FULL JOIN name | s1_n | s2_n | s2_2 | s3_n ------+------+------+------+------ bb | 11 | 12 | 2 | 13 - cc | | 22 | 2 | 23 dd | | | | 33 ee | | 42 | 2 | + cc | | 22 | 2 | 23 (4 rows) -- Constants as join keys can also be problematic @@ -2093,19 +2104,23 @@ ON (s1_n = s2_n); name | s1_n | name | s2_n ------+------+------+------ | | bb | 2 - | | cc | 2 | | ee | 2 + | | cc | 2 bb | 11 | | (4 rows) -- Test for propagation of nullability constraints into sub-joins create temp table x (x1 int, x2 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'x1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into x values (1,11); insert into x values (2,22); insert into x values (3,null); insert into x values (4,44); insert into x values (5,null); create temp table y (y1 int, y2 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'y1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into y values (1,111); insert into y values (2,222); insert into y values (3,333); @@ -2114,28 +2129,28 @@ select * from x; x1 | x2 ----+---- 1 | 11 + 5 | 2 | 22 3 | 4 | 44 - 5 | (5 rows) select * from y; y1 | y2 ----+----- - 1 | 111 2 | 222 3 | 333 4 | + 1 | 111 (4 rows) select * from x left join y on (x1 = y1 and x2 is not null); x1 | x2 | y1 | y2 ----+----+----+----- - 1 | 11 | 1 | 111 2 | 22 | 2 | 222 3 | | | 4 | 44 | 4 | + 1 | 11 | 1 | 111 5 | | | (5 rows) @@ -2143,20 +2158,20 @@ select * from x left join y on (x1 = y1 and y2 is not null); x1 | x2 | y1 | y2 ----+----+----+----- 1 | 11 | 1 | 111 + 5 | | | 2 | 22 | 2 | 222 3 | | 3 | 333 4 | 44 | | - 5 | | | (5 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | 3 | 4 | 44 | 4 | | 4 | 44 + 1 | 11 | 1 | 111 | 1 | 11 5 | | | | 5 | (5 rows) @@ -2164,22 +2179,22 @@ select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1 and x2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | | 4 | 44 | 4 | | 4 | 44 5 | | | | | + 1 | 11 | 1 | 111 | 1 | 11 (5 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1 and y2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | 3 | 4 | 44 | 4 | | | 5 | | | | | + 1 | 11 | 1 | 111 | 1 | 11 (5 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) @@ -2187,10 +2202,10 @@ on (x1 = xx1 and xx2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- 1 | 11 | 1 | 111 | 1 | 11 + 5 | | | | | 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | | 4 | 44 | 4 | | 4 | 44 - 5 | | | | | (5 rows) -- these should NOT give the same answers as above @@ -2198,9 +2213,9 @@ select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1) where (x2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 4 | 44 | 4 | | 4 | 44 + 1 | 11 | 1 | 111 | 1 | 11 (3 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) @@ -2269,11 +2284,12 @@ explain (costs off) select aa, bb, unique1, unique1 from tenk1 right join b_star on aa = unique1 where bb < bb and bb is null; - QUERY PLAN --------------------------- + QUERY PLAN +------------------------------------- Result One-Time Filter: false -(2 rows) + Optimizer: Postgres query optimizer +(3 rows) select aa, bb, unique1, unique1 from tenk1 right join b_star on aa = unique1 @@ -2809,16 +2825,16 @@ select * from on j1_tbl.i = j2_tbl.i and j1_tbl.i = j2_tbl.k; --order none i | j | t | i | k ---+---+-------+---+---- + 6 | 6 | six | | + | | | 5 | -5 + | | | 5 | -5 + 5 | 0 | five | | | | | | 0 | | | | | 0 | zero | | | | null | | 8 | 8 | eight | | 7 | 7 | seven | | - 6 | 6 | six | | - | | | 5 | -5 - | | | 5 | -5 - 5 | 0 | five | | 4 | 1 | four | | | | | 3 | -3 3 | 2 | three | | @@ -2927,9 +2943,17 @@ DROP TABLE J2_TBL; -- Both DELETE and UPDATE allow the specification of additional tables -- to "join" against to determine which rows should be modified. CREATE TEMP TABLE t1 (a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TEMP TABLE t2 (a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TEMP TABLE t3 (x int, y int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'x' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TEMP TABLE t4 (x int, y int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'x' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO t1 VALUES (5, 10); INSERT INTO t1 VALUES (15, 20); INSERT INTO t1 VALUES (100, 100); @@ -2966,15 +2990,16 @@ SELECT * FROM t3; -- Test join against inheritance tree create temp table t2a () inherits (t2); +NOTICE: table has parent, setting distribution columns to match parent table insert into t2a values (200, 2001); select * from t1 left join t2 on (t1.a = t2.a); a | b | a | b -----+------+-----+------ - 5 | 10 | | 15 | 20 | | - 100 | 100 | | 200 | 1000 | 200 | 2000 200 | 1000 | 200 | 2001 + 100 | 100 | | + 5 | 10 | | (5 rows) -- Test matching of column name with wrong alias @@ -3020,9 +3045,13 @@ LINE 3: for update of bar; -- regression test for 8.1 merge right join bug -- CREATE TEMP TABLE tt1 ( tt1_id int4, joincol int4 ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'tt1_id' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO tt1 VALUES (1, 11); INSERT INTO tt1 VALUES (2, NULL); CREATE TEMP TABLE tt2 ( tt2_id int4, joincol int4 ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'tt2_id' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO tt2 VALUES (21, 11); INSERT INTO tt2 VALUES (22, 11); set enable_hashjoin to off; @@ -3039,8 +3068,8 @@ select tt1.*, tt2.* from tt1 left join tt2 on tt1.joincol = tt2.joincol; select tt1.*, tt2.* from tt2 right join tt1 on tt1.joincol = tt2.joincol; tt1_id | joincol | tt2_id | joincol --------+---------+--------+--------- - 1 | 11 | 21 | 11 1 | 11 | 22 | 11 + 1 | 11 | 21 | 11 2 | | | (3 rows) @@ -3081,25 +3110,25 @@ select * from tbl_ra t1 where not exists (select 1 from tbl_ra t2 where t2.b = t1.a) and t1.b < 2; a | b ------+--- - 100 | 0 101 | 1 - 200 | 0 - 201 | 1 - 300 | 0 301 | 1 - 400 | 0 - 401 | 1 500 | 0 501 | 1 - 600 | 0 - 601 | 1 700 | 0 - 701 | 1 800 | 0 801 | 1 + 1000 | 0 + 201 | 1 + 300 | 0 + 400 | 0 + 401 | 1 900 | 0 + 100 | 0 + 200 | 0 + 600 | 0 + 601 | 1 + 701 | 1 901 | 1 - 1000 | 0 (19 rows) reset enable_hashjoin; @@ -3107,10 +3136,6 @@ reset enable_nestloop; -- -- regression test for bug #13908 (hash join with skew tuples & nbatch increase) -- --- start_ignore --- GPDB_96_MERGE_FIXME: does the plan exercise the nbatch increase in GPDB --- like it does on PostgreSQL? --- end_ignore set work_mem to '64kB'; set enable_mergejoin to off; set enable_memoize to off; @@ -3146,9 +3171,13 @@ reset enable_memoize; -- regression test for 8.2 bug with improper re-ordering of left joins -- create temp table tt3(f1 int, f2 text); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into tt3 select x, repeat('xyzzy', 100) from generate_series(1,10000) x; analyze tt3; create temp table tt4(f1 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into tt4 values (0),(1),(9999); analyze tt4; set enable_nestloop to off; @@ -3205,16 +3234,16 @@ reset enable_nestloop; explain (costs off) select a.* from tenk1 a where unique1 in (select unique2 from tenk1 b); - QUERY PLAN ------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join - Hash Cond: (a.unique1 = b.unique2) - -> Seq Scan on tenk1 a + -> Hash Right Semi Join + Hash Cond: (b.unique2 = a.unique1) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: b.unique2 + -> Seq Scan on tenk1 b -> Hash - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: b.unique2 - -> Seq Scan on tenk1 b + -> Seq Scan on tenk1 a Optimizer: Postgres query optimizer (9 rows) @@ -3237,16 +3266,16 @@ where unique1 not in (select unique2 from tenk1 b); explain (costs off) select a.* from tenk1 a where exists (select 1 from tenk1 b where a.unique1 = b.unique2); - QUERY PLAN ------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join - Hash Cond: (a.unique1 = b.unique2) - -> Seq Scan on tenk1 a + -> Hash Right Semi Join + Hash Cond: (b.unique2 = a.unique1) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: b.unique2 + -> Seq Scan on tenk1 b -> Hash - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: b.unique2 - -> Seq Scan on tenk1 b + -> Seq Scan on tenk1 a Optimizer: Postgres query optimizer (9 rows) @@ -3286,6 +3315,8 @@ where b.unique2 is null; -- regression test for proper handling of outer joins within antijoins -- create temp table tt4x(c1 int, c2 int, c3 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. explain (costs off) select * from tt4x t1 where not exists ( @@ -3331,7 +3362,11 @@ where not exists ( -- regression test for problems of the sort depicted in bug #3494 -- create temp table tt5(f1 int, f2 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp table tt6(f1 int, f2 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into tt5 values(1, 10); insert into tt5 values(1, 11); insert into tt6 values(1, 9); @@ -3347,7 +3382,11 @@ select * from tt5,tt6 where tt5.f1 = tt6.f1 and tt5.f1 = tt5.f2 - tt6.f2; -- regression test for problems of the sort depicted in bug #3588 -- create temp table xx (pkxx int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'pkxx' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp table yy (pkyy int, pkxx int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'pkyy' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into xx values (1); insert into xx values (2); insert into xx values (3); @@ -3363,8 +3402,8 @@ from yy yy_pkyy | yy_pkxx | yya_pkyy | xxa_pkxx | xxb_pkxx ---------+---------+----------+----------+---------- 101 | 1 | 101 | 1 | 1 - 201 | 2 | | | 1 301 | | | | 1 + 201 | 2 | | | 1 (3 rows) -- @@ -3434,7 +3473,11 @@ set enable_mergejoin = 1; set enable_hashjoin = 0; set enable_nestloop = 0; create temp table a (i integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp table b (x integer, y integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'x' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. select * from a left join b on i = x and i = y and x = i; i | x | y ---+---+--- @@ -3447,6 +3490,8 @@ rollback; begin; create type mycomptype as (id int, v bigint); create temp table tidv (idv mycomptype); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'idv' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create index on tidv (idv); analyze tidv; explain (costs off) @@ -3654,9 +3699,9 @@ SELECT qq, unique1 INNER JOIN tenk1 c ON qq = unique2; qq | unique1 -----+--------- + 456 | 7318 123 | 4596 123 | 4596 - 456 | 7318 (3 rows) -- @@ -3674,12 +3719,14 @@ create temp table nt2 ( b2 boolean, foreign key (nt1_id) references nt1(id) ); +WARNING: referential integrity (FOREIGN KEY) constraints are not supported in Apache Cloudberry, will not be enforced create temp table nt3 ( id int primary key, nt2_id int, c1 boolean, foreign key (nt2_id) references nt2(id) ); +WARNING: referential integrity (FOREIGN KEY) constraints are not supported in Apache Cloudberry, will not be enforced insert into nt1 values (1,true,true); ANALYZE nt1; insert into nt1 values (2,true,false); @@ -3860,14 +3907,14 @@ select * from int4_tbl a full join int4_tbl b on true order by 1, 2; select * from int4_tbl a full join int4_tbl b on false; --order none f1 | f1 -------------+------------- - | 0 | 123456 | -123456 + | 0 | 2147483647 | -2147483647 - 0 | 123456 | -123456 | + 0 | 2147483647 | -2147483647 | (10 rows) @@ -3876,7 +3923,11 @@ select * from int4_tbl a full join int4_tbl b on false; --order none -- test for ability to use a cartesian join when necessary -- create temp table q1 as select 1 as q1; +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'q1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp table q2 as select 0 as q2; +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'q2' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. analyze q1; analyze q2; explain (costs off) @@ -4110,8 +4161,8 @@ explain (verbose, costs off) select * from (select 1 as x) ss1 left join (select 2 as y) ss2 on (true), lateral (select ss2.y as z limit 1) ss3; - QUERY PLAN ---------------------------- + QUERY PLAN +------------------------------------- Nested Loop Output: 1, (2), ((2)) -> Result @@ -4122,8 +4173,9 @@ select * from Output: ((2)) -> Result Output: (2) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(11 rows) +(12 rows) select * from (select 1 as x) ss1 left join (select 2 as y) ss2 on (true), @@ -4152,7 +4204,8 @@ where b; -> Result -> Result One-Time Filter: (true) -(6 rows) + Optimizer: Postgres query optimizer +(7 rows) select * from (select 0 as z) as t1 @@ -4191,8 +4244,9 @@ where f1 in ( select c3.f1 from ctetable c2 full join ctetable c3 on true ); Output: (1) -> Result Output: 1 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(16 rows) +(17 rows) with ctetable as not materialized ( select 1 as f1 ) select * from ctetable c1 @@ -4214,7 +4268,9 @@ from int4_tbl t1 Result Output: 'regression'::information_schema.sql_identifier, (c.relname)::information_schema.sql_identifier One-Time Filter: false -(3 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(5 rows) -- Test handling of qual pushdown to appendrel members with non-Var outputs explain (verbose, costs off) @@ -4238,8 +4294,9 @@ where ss.x is null; Output: 'foo'::text -> Result Output: 'bar'::text + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(15 rows) +(16 rows) -- -- test inlining of immutable functions @@ -4264,8 +4321,8 @@ explain (verbose, costs off) select unique1, x.* from tenk1, (select *, random() from f_immutable_int4(1) x) x where x = unique1; - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +----------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: tenk1.unique1, (1), (random()) -> Nested Loop @@ -4278,8 +4335,8 @@ where x = unique1; -> Index Only Scan using tenk1_unique1 on public.tenk1 Output: tenk1.unique1 Index Cond: (tenk1.unique1 = (1)) + Settings: optimizer = 'off', enable_nestloop = 'on' Optimizer: Postgres query optimizer - Settings: enable_nestloop = 'on' (14 rows) explain (costs off) @@ -4350,8 +4407,8 @@ select unique1, x from tenk1 right join f_immutable_int4(1) x on unique1 = x; explain (costs off) select unique1, x from tenk1 full join f_immutable_int4(1) x on unique1 = x; - QUERY PLAN ----------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Hash Full Join Hash Cond: (tenk1.unique1 = (1)) @@ -4366,8 +4423,8 @@ select unique1, x from tenk1 full join f_immutable_int4(1) x on unique1 = x; -- check that pullup of a const function allows further const-folding explain (costs off) select unique1 from tenk1, f_immutable_int4(1) x where x = 42; - QUERY PLAN --------------------------- + QUERY PLAN +------------------------------------- Result One-Time Filter: false Optimizer: Postgres query optimizer @@ -4387,8 +4444,8 @@ from nt3 as nt3 ) as ss2 on ss2.id = nt3.nt2_id where nt3.id = 1 and ss2.b3; - QUERY PLAN ----------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Hash Right Join Hash Cond: (nt2.id = nt3.nt2_id) @@ -4403,7 +4460,7 @@ where nt3.id = 1 and ss2.b3; -> Seq Scan on nt3 Filter: (id = 1) Optimizer: Postgres query optimizer -(15 rows) +(14 rows) drop function f_immutable_int4(int); -- test inlining when function returns composite @@ -4413,8 +4470,8 @@ create function mki4(int) returns int4_tbl as $$select row($1)::int4_tbl$$ language sql; explain (verbose, costs off) select * from mki8(1,2); - QUERY PLAN ------------------------------------- + QUERY PLAN +-------------------------------------------------- Subquery Scan on sirvf_sq Output: (sirvf_sq.mki8).q1, (sirvf_sq.mki8).q2 -> Result @@ -4422,8 +4479,9 @@ select * from mki8(1,2); InitPlan 1 (returns $0) -> Result Output: '(1,2)'::int8_tbl + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(8 rows) +(9 rows) select * from mki8(1,2); q1 | q2 @@ -4433,8 +4491,8 @@ select * from mki8(1,2); explain (verbose, costs off) select * from mki4(42); - QUERY PLAN ------------------------------------ + QUERY PLAN +------------------------------------------ Subquery Scan on sirvf_sq Output: (sirvf_sq.mki4).f1 -> Result @@ -4442,8 +4500,9 @@ select * from mki4(42); InitPlan 1 (returns $0) -> Result Output: '(42)'::int4_tbl + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(8 rows) +(9 rows) select * from mki4(42); f1 @@ -4479,8 +4538,9 @@ select (t2.*).unique1, f_field_select(t2) from tenk1 t1 -> Materialize -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on public.int8_tbl t3 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(17 rows) +(18 rows) drop function f_field_select(t onek); -- @@ -4729,8 +4789,8 @@ select * from ) ss where fault = 122 order by fault; - QUERY PLAN ------------------------------------------------------------------------ + QUERY PLAN +-------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Right Join Hash Cond: (tenk1.unique2 = int8_tbl.q2) @@ -4899,16 +4959,16 @@ select * from int8_tbl t1 left join int8_tbl t2 on t1.q2 = t2.q1, lateral (select * from int8_tbl t3 where t2.q1 = t2.q2) ss; q1 | q2 | q1 | q2 | q1 | q2 ------------------+------------------+------------------+------------------+------------------+------------------- - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 456 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 456 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 456 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 456 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 (10 rows) -- @@ -4953,8 +5013,9 @@ using (join_key); Hash Key: "*VALUES*".column1 -> Values Scan on "*VALUES*" Output: "*VALUES*".column1 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(25 rows) +(26 rows) select foo1.join_key as foo1_id, foo3.join_key AS foo3_id, bug_field from (values (0),(1)) foo1(join_key) @@ -5013,8 +5074,9 @@ order by i0.f1, x; Output: i0.f1 -> Seq Scan on public.int4_tbl i0 Output: i0.f1 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(25 rows) +(26 rows) select * from int4_tbl i0 left join @@ -5092,8 +5154,9 @@ select t1.* from Hash Key: i8b1.q2 -> Seq Scan on public.int8_tbl i8b1 Output: i8b1.q2 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(43 rows) +(44 rows) select t1.* from text_tbl t1 @@ -5122,8 +5185,8 @@ select t1.* from on (t1.f1 = b1.d1) left join int4_tbl i4 on (i8.q2 = i4.f1); - QUERY PLAN ---------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: t1.f1 -> Hash Left Join @@ -5172,9 +5235,9 @@ select t1.* from Output: i4.f1 -> Seq Scan on public.int4_tbl i4 Output: i4.f1 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off -(49 rows) +(50 rows) select t1.* from text_tbl t1 @@ -5255,8 +5318,9 @@ select t1.* from Hash Key: i8b1.q2 -> Seq Scan on public.int8_tbl i8b1 Output: i8b1.q2 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(50 rows) +(51 rows) select t1.* from text_tbl t1 @@ -5316,8 +5380,9 @@ select * from -> Seq Scan on public.text_tbl t1 Output: t1.f1 Filter: (t1.f1 = 'doh!'::text) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(31 rows) +(32 rows) select * from text_tbl t1 @@ -5342,14 +5407,15 @@ left join from pg_class c left join pg_namespace n on n.oid = c.relnamespace where c.relkind = 'r' ) ss2 on false; - QUERY PLAN --------------------------------- + QUERY PLAN +------------------------------------- Nested Loop Left Join Join Filter: false -> Result -> Result One-Time Filter: false -(5 rows) + Optimizer: Postgres query optimizer +(6 rows) -- check handling of apparently-commutable outer joins with non-commutable -- joins between them @@ -5361,8 +5427,8 @@ select 1 from join int4_tbl i42 on ss1.a is null or i8.q1 <> i8.q2 right join (select 2 as b) ss2 on ss2.b < i4.f1; - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------------------------------------------- Nested Loop Left Join -> Result -> Materialize @@ -5390,6 +5456,10 @@ select 1 from -- test for appropriate join order in the presence of lateral references -- -- start_ignore +-- GPDB_94_STABLE_MERGE_FIXME: Currently LATERAL is not fully supported in GPDB +-- and the queries below are failing at the moment (The first one fails with +-- error and the other two fail with panic). Comment them off temporarily. +/* explain (verbose, costs off) select * from text_tbl t1 @@ -5397,82 +5467,22 @@ select * from 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) - -> Memoize - Output: (i8.q1), t2.f1 - Cache Key: i8.q1 - Cache Mode: binary - -> Limit - Output: (i8.q1), t2.f1 - -> Seq Scan on public.text_tbl t2 - Output: i8.q1, t2.f1 -(20 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) - -> Memoize - Output: (i8.q1), t2.f1 - Cache Key: i8.q1 - Cache Mode: binary - -> Limit - Output: (i8.q1), t2.f1 - -> Seq Scan on public.text_tbl t2 - Output: i8.q1, t2.f1 - -> Memoize - Output: ((i8.q1)), (t2.f1) - Cache Key: (i8.q1), t2.f1 - Cache Mode: binary - -> Limit - Output: ((i8.q1)), (t2.f1) - -> Seq Scan on public.text_tbl t3 - Output: (i8.q1), t2.f1 -(30 rows) +where t1.f1 = ss.f1; + +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; select * from text_tbl t1 @@ -5481,10 +5491,6 @@ select * from 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 @@ -5494,41 +5500,6 @@ select 1 from 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 - -> 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) - -> Memoize - Output: ss1.c0 - Cache Key: tt4.f1 - Cache Mode: binary - -> 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 -(33 rows) select 1 from text_tbl as tt1 @@ -5537,10 +5508,7 @@ select 1 from 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) - +*/ --end_ignore explain (verbose, costs off) select 1 from @@ -5550,12 +5518,14 @@ select 1 from right join (select 1 as z) as ss2 on true) on false, lateral (select i4.f1, ss1.n from int8_tbl as i8 limit 1) as ss3; - QUERY PLAN --------------------------- + QUERY PLAN +------------------------------------- Result Output: 1 One-Time Filter: false -(3 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(5 rows) select 1 from int4_tbl as i4 @@ -5584,11 +5554,12 @@ select 1 from t t1 on false where t3.a = coalesce(t5.a,1)) as s2 on true; - QUERY PLAN --------------------------- + QUERY PLAN +------------------------------------- Result One-Time Filter: false -(2 rows) + Optimizer: Postgres query optimizer +(3 rows) rollback; -- @@ -5652,8 +5623,9 @@ where ss1.c2 = 0; -> Materialize -> Gather Motion 3:1 (slice4; segments: 3) -> Seq Scan on public.text_tbl + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(43 rows) +(44 rows) --end_ignore select ss2.* from @@ -5751,8 +5723,8 @@ explain (verbose, costs off) select a.q2, b.q1 from int8_tbl a left join int8_tbl b on a.q2 = coalesce(b.q1, 1) where coalesce(b.q1, 1) > 0; - QUERY PLAN -------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: a.q2, b.q1 -> Merge Left Join @@ -5777,8 +5749,8 @@ explain (verbose, costs off) Hash Key: COALESCE(b.q1, '1'::bigint) -> Seq Scan on public.int8_tbl b Output: b.q1 + Settings: optimizer = 'off', enable_hashjoin = 'off', enable_nestloop = 'off', enable_mergejoin = 'on' Optimizer: Postgres query optimizer - Settings: enable_hashjoin=off, enable_mergejoin=on, enable_nestloop=off (26 rows) select a.q2, b.q1 @@ -5787,8 +5759,6 @@ select a.q2, b.q1 q2 | q1 -------------------+------------------ -4567890123456789 | - 123 | 123 - 123 | 123 456 | 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 @@ -5796,6 +5766,8 @@ select a.q2, b.q1 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 + 123 | 123 + 123 | 123 (10 rows) reset enable_hashjoin; @@ -5955,6 +5927,8 @@ CREATE TEMP TABLE a (id int PRIMARY KEY, b_id int); CREATE TEMP TABLE b (id int PRIMARY KEY, c_id int); CREATE TEMP TABLE c (id int PRIMARY KEY); CREATE TEMP TABLE d (a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO a VALUES (0, 0), (1, NULL); INSERT INTO b VALUES (0, 0), (1, NULL); INSERT INTO c VALUES (0), (1); @@ -6374,6 +6348,7 @@ select c.id, ss.a from c CREATE TEMP TABLE parted_b (id int PRIMARY KEY) partition by range(id); CREATE TEMP TABLE parted_b1 partition of parted_b for values from (0) to (10); +NOTICE: table has parent, setting distribution columns to match parent table -- test join removals on a partitioned table explain (costs off) select a.* from a left join parted_b pb on a.b_id = pb.id; @@ -6400,9 +6375,9 @@ insert into child values (1, 100), (4, 400); select p.* from parent p left join child c on (p.k = c.k); k | pd ---+---- - 1 | 10 2 | 20 3 | 30 + 1 | 10 (3 rows) explain (costs off) @@ -6470,8 +6445,8 @@ explain (costs off) select p.* from (parent p left join child c on (p.k = c.k)) join parent x on p.k = x.k where p.k = 1 and p.k = 2; - QUERY PLAN ------------------------------------ + QUERY PLAN +------------------------------------- Result One-Time Filter: false Optimizer: Postgres query optimizer @@ -6508,11 +6483,11 @@ SELECT * FROM ON true; x | q1 | q2 | y ---+------------------+-------------------+------------------ - 1 | 123 | 456 | 123 - 1 | 123 | 4567890123456789 | 123 1 | 4567890123456789 | 123 | 42 1 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 1 | 123 | 4567890123456789 | 123 1 | 4567890123456789 | -4567890123456789 | 4567890123456789 + 1 | 123 | 456 | 123 (5 rows) -- join removal bug #17769: can't remove if there's a pushed-down reference @@ -6554,8 +6529,9 @@ SELECT q2 FROM -> Result Output: q2, 'constant'::text One-Time Filter: false + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(11 rows) +(12 rows) -- join removal bug #17786: check that OR conditions are cleaned up EXPLAIN (COSTS OFF) @@ -6778,8 +6754,9 @@ where q2 = 456; -> Seq Scan on public.int4_tbl i4 Output: i4.f1 Filter: (i4.f1 = 1) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(24 rows) +(25 rows) select i8.*, ss.v, t.unique2 from int8_tbl i8 @@ -6796,6 +6773,7 @@ where q2 = 456; -- a PHV that's been translated to a child rel create temp table parttbl (a integer primary key) partition by range (a); create temp table parttbl1 partition of parttbl for values from (1) to (100); +NOTICE: table has parent, setting distribution columns to match parent table insert into parttbl values (11), (12); set optimizer_enable_dynamicindexonlyscan=off; explain (costs off) @@ -6889,12 +6867,14 @@ explain (verbose, costs off) select 1 from (select * from int8_tbl where q1 <> (select 42) offset 0) ss where false; - QUERY PLAN --------------------------- + QUERY PLAN +------------------------------------- Result Output: 1 One-Time Filter: false -(3 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(5 rows) -- -- Test LATERAL @@ -6960,10 +6940,10 @@ from int4_tbl x left join lateral (select unique1, unique2 from tenk1 where f1 = unique2 | f1 ---------+------------- 9998 | 0 - | 123456 - | -123456 | 2147483647 | -2147483647 + | 123456 + | -123456 (5 rows) explain (costs off) @@ -6985,21 +6965,21 @@ explain (costs off) select *, (select r from (select q1 as q2) x, (select q2 as r) y) from int8_tbl; q1 | q2 | r ------------------+-------------------+------------------- - 123 | 456 | 456 - 123 | 4567890123456789 | 4567890123456789 4567890123456789 | 123 | 123 4567890123456789 | 4567890123456789 | 4567890123456789 4567890123456789 | -4567890123456789 | -4567890123456789 + 123 | 456 | 456 + 123 | 4567890123456789 | 4567890123456789 (5 rows) select *, (select r from (select q1 as q2) x, lateral (select q2 as r) y) from int8_tbl; q1 | q2 | r ------------------+-------------------+------------------ - 123 | 456 | 123 - 123 | 4567890123456789 | 123 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 4567890123456789 | -4567890123456789 | 4567890123456789 + 123 | 456 | 123 + 123 | 4567890123456789 | 123 (5 rows) -- lateral with function in FROM @@ -7059,11 +7039,6 @@ explain (costs off) (10 rows) -- lateral with UNION ALL subselect --- start_ignore --- GPDB_96_MERGE_FIXME: we used to get a better plan here, with --- the Nested Loop join being done on segments, and just a single --- Gather Motion at the top. Can we improve? --- end_ignore explain (costs off) select * from generate_series(100,200) g, lateral (select * from int8_tbl a where g = q1 union all @@ -7160,6 +7135,7 @@ select count(*) from tenk1 a, -- these will get fixed once we catch up to those. Or if not, at least it will be -- nicer to work on the code, knowing that there aren't going to be a dozen commits -- coming up, touching the same area. +-- FAIL with ERROR: could not devise a query plan for the given query (pathnode.c:416) explain (costs off) select * from int8_tbl a, int8_tbl x left join lateral (select a.q1 from int4_tbl y) ss(z) @@ -7185,10 +7161,10 @@ select * from (select f1 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1, x | f1 | y -------------+-------------+------------- 0 | 0 | 0 - 123456 | 123456 | 123456 - -123456 | -123456 | -123456 2147483647 | 2147483647 | 2147483647 -2147483647 | -2147483647 | -2147483647 + 123456 | 123456 | 123456 + -123456 | -123456 | -123456 (5 rows) select * from ((select f1/2 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1) j, @@ -7213,16 +7189,6 @@ select * from (select f1/1000000000 from int4_tbl) x(lb), lateral generate_series(lb,4) x4; lb | x4 ----+---- - 0 | 0 - 0 | 1 - 0 | 2 - 0 | 3 - 0 | 4 - 0 | 0 - 0 | 1 - 0 | 2 - 0 | 3 - 0 | 4 0 | 0 0 | 1 0 | 2 @@ -7238,6 +7204,16 @@ select * from (select f1/1000000000 from int4_tbl) x(lb), -2 | 2 -2 | 3 -2 | 4 + 0 | 0 + 0 | 1 + 0 | 2 + 0 | 3 + 0 | 4 + 0 | 0 + 0 | 1 + 0 | 2 + 0 | 3 + 0 | 4 (25 rows) select * from (values(1)) x(lb), @@ -7263,16 +7239,16 @@ select * from lateral (values(x.q1,y.q1,y.q2)) v(xq1,yq1,yq2); q1 | q2 | q1 | q2 | xq1 | yq1 | yq2 ------------------+-------------------+------------------+-------------------+------------------+------------------+------------------- - 123 | 456 | | | 123 | | - 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | -4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 123 | 123 | 4567890123456789 | 123 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 123 | 123 | 456 | 4567890123456789 | 123 | 456 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 123 4567890123456789 | -4567890123456789 | | | 4567890123456789 | | + 123 | 456 | | | 123 | | + 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | -4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 123 | 123 | 4567890123456789 | 123 (10 rows) select * from @@ -7280,16 +7256,16 @@ select * from lateral (select x.q1,y.q1,y.q2) v(xq1,yq1,yq2); q1 | q2 | q1 | q2 | xq1 | yq1 | yq2 ------------------+-------------------+------------------+-------------------+------------------+------------------+------------------- + 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 123 + 4567890123456789 | -4567890123456789 | | | 4567890123456789 | | 123 | 456 | | | 123 | | 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | -4567890123456789 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 123 | 4567890123456789 | 4567890123456789 | 123 | 123 | 4567890123456789 | 123 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 123 | 123 | 456 | 4567890123456789 | 123 | 456 - 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 123 - 4567890123456789 | -4567890123456789 | | | 4567890123456789 | | (10 rows) select x.* from @@ -7297,16 +7273,16 @@ select x.* from lateral (select x.q1,y.q1,y.q2) v(xq1,yq1,yq2); q1 | q2 ------------------+------------------- + 4567890123456789 | 4567890123456789 + 4567890123456789 | 4567890123456789 + 4567890123456789 | 4567890123456789 + 4567890123456789 | -4567890123456789 123 | 456 123 | 4567890123456789 123 | 4567890123456789 123 | 4567890123456789 4567890123456789 | 123 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 (10 rows) select v.* from @@ -7315,26 +7291,26 @@ select v.* from lateral (select x.q1,y.q1 union all select x.q2,y.q2) v(vx,vy); vx | vy -------------------+------------------- - 123 | - 456 | - 123 | 4567890123456789 - 4567890123456789 | -4567890123456789 - 123 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 - 4567890123456789 | 123 + 123 | 456 4567890123456789 | 123 123 | 4567890123456789 4567890123456789 | 123 - 123 | 456 + -4567890123456789 | + 4567890123456789 | + 456 | + 123 | + 4567890123456789 | 123 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 + 4567890123456789 | -4567890123456789 4567890123456789 | 4567890123456789 4567890123456789 | 123 - 4567890123456789 | - -4567890123456789 | + 123 | 4567890123456789 + 4567890123456789 | 4567890123456789 + 123 | 4567890123456789 + 4567890123456789 | -4567890123456789 + 123 | 4567890123456789 (20 rows) select v.* from @@ -7343,26 +7319,26 @@ select v.* from lateral (select x.q1,y.q1 union all select x.q2,y.q2) v(vx,vy); vx | vy -------------------+------------------- + -4567890123456789 | + 4567890123456789 | + 456 | + 123 | 4567890123456789 | 123 - 123 | 456 - 4567890123456789 | 123 - 123 | 4567890123456789 4567890123456789 | 4567890123456789 - 4567890123456789 | 123 - 123 | 4567890123456789 - 4567890123456789 | 123 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 + 4567890123456789 | -4567890123456789 4567890123456789 | 4567890123456789 + 4567890123456789 | 123 + 123 | 4567890123456789 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 123 | 4567890123456789 4567890123456789 | -4567890123456789 - 123 | - 456 | - 4567890123456789 | - -4567890123456789 | + 123 | 4567890123456789 + 123 | 456 + 4567890123456789 | 123 + 123 | 4567890123456789 + 4567890123456789 | 123 (20 rows) select v.* from @@ -7371,26 +7347,26 @@ select v.* from lateral (select x.q1,y.q1 from onerow union all select x.q2,y.q2 from onerow) v(vx,vy); vx | vy -------------------+------------------- - 4567890123456789 | 123 - 123 | 456 + -4567890123456789 | + 4567890123456789 | + 456 | + 123 | 4567890123456789 | 123 123 | 4567890123456789 4567890123456789 | 4567890123456789 - 4567890123456789 | 123 + 123 | 4567890123456789 + 4567890123456789 | -4567890123456789 123 | 4567890123456789 4567890123456789 | 123 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 4567890123456789 | -4567890123456789 + 4567890123456789 | 4567890123456789 + 123 | 456 + 4567890123456789 | 123 123 | 4567890123456789 - 4567890123456789 | -4567890123456789 - 123 | - 456 | - 4567890123456789 | - -4567890123456789 | + 4567890123456789 | 123 (20 rows) explain (verbose, costs off) @@ -7411,8 +7387,8 @@ select * from -> Seq Scan on public.int8_tbl b Output: b.q1, b.q2, a.q2 Filter: (a.q2 = b.q1) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (14 rows) select * from @@ -7424,20 +7400,20 @@ select * from 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 - 4567890123456789 | 123 | 123 | 456 | 123 - 4567890123456789 | 123 | 123 | 4567890123456789 | 123 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 4567890123456789 | -4567890123456789 | | | + 4567890123456789 | 123 | 123 | 456 | 123 + 4567890123456789 | 123 | 123 | 4567890123456789 | 123 (10 rows) explain (verbose, costs off) select * from int8_tbl a left join lateral (select *, coalesce(a.q2, 42) as x from int8_tbl b) ss on a.q2 = ss.q1; - QUERY PLAN ----------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Output: a.q1, a.q2, b.q1, b.q2, (COALESCE(a.q2, '42'::bigint)) -> Nested Loop Left Join @@ -7450,8 +7426,8 @@ select * from -> Seq Scan on public.int8_tbl b Output: b.q1, b.q2, COALESCE(a.q2, '42'::bigint) Filter: (a.q2 = b.q1) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (14 rows) select * from @@ -7459,16 +7435,16 @@ select * from lateral (select *, coalesce(a.q2, 42) as x from int8_tbl b) ss on a.q2 = ss.q1; q1 | q2 | q1 | q2 | x ------------------+-------------------+------------------+-------------------+------------------ - 123 | 456 | | | - 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 4567890123456789 | 123 | 123 | 456 | 123 4567890123456789 | 123 | 123 | 4567890123456789 | 123 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 4567890123456789 | -4567890123456789 | | | + 123 | 456 | | | + 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 (10 rows) -- lateral can result in join conditions appearing below their @@ -7489,19 +7465,19 @@ select * from int4_tbl i left join Output: i.f1 -> Seq Scan on public.int4_tbl i Output: i.f1 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (13 rows) select * from int4_tbl i left join lateral (select * from int2_tbl j where i.f1 = j.f1) k on true; f1 | f1 -------------+---- - 0 | 0 123456 | -123456 | - 2147483647 | + 0 | 0 -2147483647 | + 2147483647 | (5 rows) explain (verbose, costs off) @@ -7518,17 +7494,17 @@ select * from int4_tbl i left join -> Seq Scan on public.int2_tbl j Output: j.f1, COALESCE(i.*) Filter: (i.f1 = j.f1) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (11 rows) select * from int4_tbl i left join lateral (select coalesce(i) from int2_tbl j where i.f1 = j.f1) k on true; f1 | coalesce -------------+---------- - 0 | (0) 123456 | -123456 | + 0 | (0) 2147483647 | -2147483647 | (5 rows) @@ -7568,8 +7544,9 @@ select * from int4_tbl a, Output: c.q1, c.q2 -> Seq Scan on public.int8_tbl c Output: c.q1, c.q2 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(29 rows) +(30 rows) select * from int4_tbl a, lateral ( @@ -7578,30 +7555,30 @@ select * from int4_tbl a, f1 | f1 | q1 | q2 -------------+-------------+----+---- 0 | 0 | | - 0 | 123456 | | - 0 | -123456 | | 0 | 2147483647 | | 0 | -2147483647 | | - 123456 | 0 | | - 123456 | 123456 | | - 123456 | -123456 | | - 123456 | 2147483647 | | - 123456 | -2147483647 | | - -123456 | 0 | | - -123456 | 123456 | | - -123456 | -123456 | | - -123456 | 2147483647 | | - -123456 | -2147483647 | | + 0 | 123456 | | + 0 | -123456 | | 2147483647 | 0 | | - 2147483647 | 123456 | | - 2147483647 | -123456 | | 2147483647 | 2147483647 | | 2147483647 | -2147483647 | | + 2147483647 | 123456 | | + 2147483647 | -123456 | | -2147483647 | 0 | | - -2147483647 | 123456 | | - -2147483647 | -123456 | | -2147483647 | 2147483647 | | -2147483647 | -2147483647 | | + -2147483647 | 123456 | | + -2147483647 | -123456 | | + 123456 | 0 | | + 123456 | 2147483647 | | + 123456 | -2147483647 | | + 123456 | 123456 | | + 123456 | -123456 | | + -123456 | 0 | | + -123456 | 2147483647 | | + -123456 | -2147483647 | | + -123456 | 123456 | | + -123456 | -123456 | | (25 rows) -- lateral reference in a PlaceHolderVar evaluated at join level @@ -7669,8 +7646,8 @@ select * from Output: ((COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2))) -> Result Output: (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (38 rows) -- another case requiring nested PlaceHolderVars @@ -7679,8 +7656,8 @@ select * from (select 0 as val0) as ss0 left join (select 1 as val) as ss1 on true left join lateral (select ss1.val as val_filtered where false) as ss2 on true; - QUERY PLAN --------------------------------- + QUERY PLAN +------------------------------------- Nested Loop Left Join Output: 0, (1), ((1)) Join Filter: false @@ -7689,7 +7666,9 @@ select * from -> Result Output: (1) One-Time Filter: false -(8 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(10 rows) select * from (select 0 as val0) as ss0 @@ -7765,8 +7744,9 @@ select c.*,a.*,ss1.q1,ss2.q1,ss3.* from Hash Key: c.q2 -> Seq Scan on public.int8_tbl c Output: c.q1, c.q2 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(52 rows) +(53 rows) -- check processing of postponed quals (bug #9041) explain (verbose, costs off) @@ -7792,8 +7772,8 @@ select * from Output: (3) -> Result Output: 3 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (17 rows) -- a new postponed-quals issue (bug #17768) @@ -7841,9 +7821,9 @@ select * from int8_tbl i8 left join lateral -> Result Output: f1, i8.q2 One-Time Filter: false + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off -(11 rows) +(12 rows) explain (verbose, costs off) select * from int8_tbl i8 left join lateral @@ -7859,8 +7839,8 @@ select * from int8_tbl i8 left join lateral -> Result Output: f1, f1, i8.q2 One-Time Filter: false + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (11 rows) -- check handling of nested appendrels inside LATERAL @@ -7913,8 +7893,8 @@ select * from Output: tenk1.unique1, tenk1.unique2 -> Seq Scan on public.tenk1 Output: tenk1.unique1, tenk1.unique2 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (21 rows) select * from @@ -7997,6 +7977,8 @@ LINE 1: select 1 from tenk1 a, lateral (select max(a.unique1) from i... ^ -- check behavior of LATERAL in UPDATE/DELETE create temp table xx1 as select f1 as x1, -f1 as x2 from int4_tbl; +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'x1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. -- error, can't do this: update xx1 set x2 = f1 from (select * from int4_tbl where f1 = x1) ss; ERROR: column "x1" does not exist @@ -8038,11 +8020,18 @@ HINT: There is an entry for table "xx1", but it cannot be referenced from this -- produced for a multi-level partitioned table hierarchy. -- create table join_pt1 (a int, b int, c varchar) partition by range(a); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create table join_pt1p1 partition of join_pt1 for values from (0) to (100) partition by range(b); +NOTICE: table has parent, setting distribution columns to match parent table create table join_pt1p2 partition of join_pt1 for values from (100) to (200); +NOTICE: table has parent, setting distribution columns to match parent table create table join_pt1p1p1 partition of join_pt1p1 for values from (0) to (100); +NOTICE: table has parent, setting distribution columns to match parent table insert into join_pt1 values (1, 1, 'x'), (101, 101, 'y'); create table join_ut1 (a int, b int, c varchar); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into join_ut1 values (101, 101, 'y'), (2, 2, 'z'); -- GPDB_12_MERGE_FIXME: The query fails. This test query is new with v12, -- but a corresponding query fails on GPDB master, too. I think this is @@ -8069,6 +8058,8 @@ drop table join_ut1; -- begin; create table fkest (x integer, x10 integer, x10b integer, x100 integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'x' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into fkest select x, x/10, x/10, x/100 from generate_series(1,1000) x; create unique index on fkest(x, x10, x100); analyze fkest; @@ -8077,8 +8068,8 @@ select * from fkest f1 join fkest f2 on (f1.x = f2.x and f1.x10 = f2.x10b and f1.x100 = f2.x100) join fkest f3 on f1.x = f3.x where f1.x100 = 2; - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +----------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Join Hash Cond: (f3.x = f1.x) @@ -8096,13 +8087,14 @@ select * from fkest f1 alter table fkest add constraint fk foreign key (x, x10b, x100) references fkest (x, x10, x100); +WARNING: referential integrity (FOREIGN KEY) constraints are not supported in Apache Cloudberry, will not be enforced explain (costs off) select * from fkest f1 join fkest f2 on (f1.x = f2.x and f1.x10 = f2.x10b and f1.x100 = f2.x100) join fkest f3 on f1.x = f3.x where f1.x100 = 2; - QUERY PLAN ------------------------------------------------------ + QUERY PLAN +----------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Join Hash Cond: ((f1.x = f2.x) AND (f1.x10 = f2.x10b)) @@ -8138,6 +8130,7 @@ insert into fkest select x/10, x%10, x from generate_series(1,1000*10) x; insert into fkest1 select x/10, x%10 from generate_series(1,1000*10) x; alter table fkest1 add constraint fkest1_a_b_fkey foreign key (a,b) references fkest; +WARNING: referential integrity (FOREIGN KEY) constraints are not supported in Apache Cloudberry, will not be enforced analyze fkest; analyze fkest1; explain (costs off) @@ -8168,7 +8161,7 @@ where f.c = 1; -> Index Only Scan using fkest1_pkey on fkest1 f3 Index Cond: ((a = f.a) AND (b = f.b)) Optimizer: Postgres query optimizer -(13 rows) +(19 rows) rollback; -- @@ -8177,6 +8170,8 @@ rollback; create table j1 (id int primary key); create table j2 (id int primary key); create table j3 (id int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into j1 values(1),(2),(3); insert into j2 values(1),(2),(3); insert into j3 values(1),(1); @@ -8210,8 +8205,8 @@ select * from j1 inner join j2 on j1.id = j2.id; Output: j2.id -> Seq Scan on public.j2 Output: j2.id + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (14 rows) -- ensure join is not unique when not an equi-join @@ -8230,8 +8225,8 @@ select * from j1 inner join j2 on j1.id > j2.id; -> Index Only Scan using j2_pkey on public.j2 Output: j2.id Index Cond: (j2.id < j1.id) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (13 rows) -- ensure non-unique rel is not chosen as inner @@ -8251,8 +8246,8 @@ select * from j1 inner join j3 on j1.id = j3.id; Output: j1.id -> Seq Scan on public.j1 Output: j1.id + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (14 rows) -- ensure left join is marked as unique @@ -8272,8 +8267,8 @@ select * from j1 left join j2 on j1.id = j2.id; Output: j2.id -> Seq Scan on public.j2 Output: j2.id + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (14 rows) -- ensure right join is marked as unique @@ -8293,8 +8288,8 @@ select * from j1 right join j2 on j1.id = j2.id; Output: j1.id -> Seq Scan on public.j1 Output: j1.id + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (14 rows) -- ensure full join is marked as unique @@ -8314,8 +8309,8 @@ select * from j1 full join j2 on j1.id = j2.id; Output: j2.id -> Seq Scan on public.j2 Output: j2.id + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (14 rows) -- a clauseless (cross) join can't be unique @@ -8335,8 +8330,8 @@ select * from j1 cross join j2; Output: j2.id -> Seq Scan on public.j2 Output: j2.id + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (14 rows) -- ensure a natural join is marked as unique @@ -8356,8 +8351,8 @@ select * from j1 natural join j2; Output: j2.id -> Seq Scan on public.j2 Output: j2.id + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (14 rows) -- ensure a distinct clause allows the inner to become unique @@ -8381,8 +8376,8 @@ inner join (select distinct id from j3) j3 on j1.id = j3.id; Group Key: j3.id -> Seq Scan on public.j3 Output: j3.id + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (17 rows) -- ensure group by clause allows the inner to become unique @@ -8406,8 +8401,8 @@ inner join (select id from j3 group by id) j3 on j1.id = j3.id; Group Key: j3.id -> Seq Scan on public.j3 Output: j3.id + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (17 rows) drop table j1; @@ -8447,8 +8442,8 @@ inner join j2 on j1.id1 = j2.id1; Hash Key: j2.id1 -> Seq Scan on public.j2 Output: j2.id1, j2.id2 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (19 rows) -- ensure proper unique detection with multiple join quals @@ -8469,8 +8464,8 @@ inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2; Output: j2.id1, j2.id2 -> Seq Scan on public.j2 Output: j2.id1, j2.id2 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (14 rows) -- ensure we don't detect the join to be unique when quals are not part of the @@ -8496,8 +8491,8 @@ inner join j2 on j1.id1 = j2.id1 where j1.id2 = 1; Hash Key: j2.id1, 1 -> Seq Scan on public.j2 Output: j2.id1, j2.id2 + Settings: optimizer = 'off', enable_nestloop = 'on' Optimizer: Postgres query optimizer - Settings: enable_nestloop=on, optimizer=off (17 rows) -- as above, but for left joins. @@ -8521,8 +8516,8 @@ left join j2 on j1.id1 = j2.id1 where j1.id2 = 1; Hash Key: j2.id1, 1 -> Seq Scan on public.j2 Output: j2.id1, j2.id2 + Settings: optimizer = 'off', enable_nestloop = 'on' Optimizer: Postgres query optimizer - Settings: enable_nestloop=on, optimizer=off (17 rows) create unique index j1_id2_idx on j1(id2) where id2 is not null; @@ -8551,7 +8546,7 @@ inner join j2 on j1.id2 = j2.id2; Hash Key: j2.id2 -> Seq Scan on public.j2 Output: j2.id1, j2.id2 - Settings: enable_nestloop = 'on' + Settings: optimizer = 'off', enable_nestloop = 'on' Optimizer: Postgres query optimizer (19 rows) @@ -8665,8 +8660,8 @@ from onek t1, tenk1 t2 where exists (select 1 from tenk1 t3 where t3.thousand = t1.unique1 and t3.tenthous = t2.hundred) and t1.unique1 < 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: t1.unique1, t2.hundred -> Nested Loop @@ -8695,12 +8690,14 @@ where exists (select 1 from tenk1 t3 -> Index Only Scan using tenk1_hundred on public.tenk1 t2 Output: t2.hundred Index Cond: (t2.hundred = t3.tenthous) + Settings: optimizer = 'off', enable_mergejoin = 'on', enable_hashjoin = 'off', enable_nestloop = 'on', enable_seqscan = 'off', enable_bitmapscan = 'off' Optimizer: Postgres query optimizer - Settings: enable_bitmapscan=off, enable_mergejoin=on, enable_nestloop=on, enable_seqscan=off, jit=off, optimizer=off (30 rows) -- ... unless it actually is unique create table j3 as select unique1, tenthous from onek; +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'unique1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. vacuum analyze j3; create unique index on j3(unique1, tenthous); explain (verbose, costs off) @@ -8709,8 +8706,8 @@ from onek t1, tenk1 t2 where exists (select 1 from j3 where j3.unique1 = t1.unique1 and j3.tenthous = t2.hundred) and t1.unique1 < 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: t1.unique1, t2.hundred -> Nested Loop @@ -8733,13 +8730,15 @@ where exists (select 1 from j3 -> Index Only Scan using tenk1_hundred on public.tenk1 t2 Output: t2.hundred Index Cond: (t2.hundred = j3.tenthous) + Settings: optimizer = 'off', enable_mergejoin = 'on', enable_hashjoin = 'off', enable_nestloop = 'on', enable_seqscan = 'off', enable_bitmapscan = 'off' Optimizer: Postgres query optimizer - Settings: enable_bitmapscan=off, enable_mergejoin=on, enable_nestloop=on, enable_seqscan=off, jit=off, optimizer=off (24 rows) drop table j3; -- Test that we do not account for nullingrels when looking up statistics CREATE TABLE group_tbl (a INT, b INT); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO group_tbl SELECT 1, 1; CREATE STATISTICS group_tbl_stat (ndistinct) ON a, b FROM group_tbl; ANALYZE group_tbl; diff --git a/contrib/pax_storage/src/test/regress/expected/join_gp.out b/contrib/pax_storage/src/test/regress/expected/join_gp.out index 620ea962c5e..e6faad02410 100644 --- a/contrib/pax_storage/src/test/regress/expected/join_gp.out +++ b/contrib/pax_storage/src/test/regress/expected/join_gp.out @@ -15,22 +15,22 @@ create table nhtest (i numeric(10, 2)) distributed by (i); insert into nhtest values(100000.22); insert into nhtest values(300000.19); explain select * from nhtest a join nhtest b using (i); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=1.02..2.07 rows=2 width=11) - -> Hash Join (cost=1.02..2.07 rows=2 width=11) + QUERY PLAN +------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=567.25..155362.25 rows=5055210 width=16) + -> Hash Join (cost=567.25..87959.45 rows=1685070 width=16) Hash Cond: (a.i = b.i) - -> Seq Scan on nhtest a (cost=0.00..1.01 rows=1 width=11) - -> Hash (cost=1.01..1.01 rows=1 width=11) - -> Seq Scan on nhtest b (cost=0.00..1.01 rows=1 width=11) - Settings: enable_hashjoin=on; enable_mergejoin=off; enable_nestloop=off + -> Seq Scan on nhtest a (cost=0.00..271.00 rows=23700 width=16) + -> Hash (cost=271.00..271.00 rows=23700 width=16) + -> Seq Scan on nhtest b (cost=0.00..271.00 rows=23700 width=16) + Optimizer: Postgres query optimizer (7 rows) select * from nhtest a join nhtest b using (i); i ----------- - 300000.19 100000.22 + 300000.19 (2 rows) create temp table l(a int); @@ -98,6 +98,7 @@ set enable_mergejoin to on; set enable_nestloop to off; DROP TABLE IF EXISTS alpha; DROP TABLE IF EXISTS theta; +NOTICE: table "theta" does not exist, skipping CREATE TABLE alpha (i int, j int) distributed by (i); CREATE TABLE theta (i int, j char(10000000)) distributed by (i); INSERT INTO alpha values (1, 1), (2, 2); @@ -132,14 +133,14 @@ analyze t2; explain select count(*) from t1,t2 where t1.x = 100 and t1.x = t2.x; QUERY PLAN ------------------------------------------------------------------------------------------------------ - Aggregate (cost=10000000008.60..10000000008.61 rows=1 width=8) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10000000008.60 rows=4 width=0) - -> Nested Loop (cost=10000000000.00..10000000008.53 rows=2 width=0) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..4.27 rows=1 width=4) + Aggregate (cost=10000000002.92..10000000002.93 rows=1 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10000000002.91 rows=3 width=0) + -> Nested Loop (cost=10000000000.00..10000000002.86 rows=1 width=0) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.44 rows=1 width=4) Hash Key: t1.x - -> Seq Scan on t1 (cost=0.00..4.25 rows=1 width=4) + -> Seq Scan on t1 (cost=0.00..1.42 rows=1 width=4) Filter: (x = 100) - -> Seq Scan on t2 (cost=0.00..4.25 rows=1 width=4) + -> Seq Scan on t2 (cost=0.00..1.42 rows=1 width=4) Filter: (x = 100) Optimizer: Postgres query optimizer (10 rows) @@ -156,13 +157,13 @@ select count(*) from t1,t2 where t1.x = 100 and t1.x = t2.x; explain select * from t1,t2 where t1.x = 100 and t2.x >= t1.x; QUERY PLAN -------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10000000002.97 rows=3 width=24) - -> Nested Loop (cost=10000000000.00..10000000002.93 rows=1 width=24) + Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10000000002.91 rows=3 width=24) + -> Nested Loop (cost=10000000000.00..10000000002.87 rows=1 width=24) Join Filter: (t2.x >= t1.x) -> Seq Scan on t1 (cost=0.00..1.42 rows=1 width=12) Filter: (x = 100) - -> Materialize (cost=0.00..1.47 rows=3 width=12) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.46 rows=3 width=12) + -> Materialize (cost=0.00..1.44 rows=1 width=12) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.44 rows=1 width=12) -> Seq Scan on t2 (cost=0.00..1.42 rows=1 width=12) Filter: (x >= 100) Optimizer: Postgres query optimizer @@ -181,18 +182,17 @@ set optimizer_segments=2; explain select * from t1,t2 where t1.x = 100 and t1.x = t2.y and t1.x <= t2.x; QUERY PLAN -------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..9.14 rows=4 width=24) - -> Nested Loop (cost=0.00..9.14 rows=2 width=24) + Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10000000003.08 rows=3 width=24) + -> Nested Loop (cost=10000000000.00..10000000003.03 rows=1 width=24) Join Filter: (t1.x <= t2.x) - -> Seq Scan on t1 (cost=0.00..4.25 rows=1 width=12) - Filter: x = 100 - -> Materialize (cost=0.00..4.85 rows=1 width=12) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..4.79 rows=1 width=12) - -> Seq Scan on t2 (cost=0.00..4.75 rows=1 width=12) + -> Seq Scan on t1 (cost=0.00..1.42 rows=1 width=12) + Filter: (x = 100) + -> Materialize (cost=0.00..1.61 rows=1 width=12) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.60 rows=1 width=12) + -> Seq Scan on t2 (cost=0.00..1.58 rows=1 width=12) Filter: ((100 <= x) AND (y <= x) AND (y = 100)) - Settings: optimizer=off; optimizer_segments=2 - Optimizer status: Postgres query optimizer -(11 rows) + Optimizer: Postgres query optimizer +(10 rows) reset optimizer_segments; select * from t1,t2 where t1.x = 100 and t1.x = t2.y and t1.x <= t2.x; @@ -235,9 +235,9 @@ select count(*) from hjn_test, (select 3 as bar) foo where hjn_test.i = least (f select * from int4_tbl a join int4_tbl b on (a.f1 = (select f1 from int4_tbl c where c.f1=b.f1)); f1 | f1 -------------+------------- - -2147483647 | -2147483647 123456 | 123456 -123456 | -123456 + -2147483647 | -2147483647 0 | 0 2147483647 | 2147483647 (5 rows) @@ -255,8 +255,8 @@ insert into part4_tbl values select * from part4_tbl a join part4_tbl b on (a.f1 = (select f1 from int4_tbl c where c.f1=b.f1)); f1 | f1 ---------+--------- - 123456 | 123456 -123456 | -123456 + 123456 | 123456 0 | 0 (3 rows) @@ -279,17 +279,17 @@ left outer join (tjoin2 left outer join tjoin3 on tjoin2.id=tjoin3.id) on tjoin1 id | t | t ----+-----+----- 1 | 2-1 | 2-1 - 1 | 2-1 | 1-1 - 1 | 1-1 | 2-1 - 1 | 1-1 | 1-1 - 3 | | 1 | 2-1 | 2-1 1 | 2-1 | 1-1 + 1 | 2-1 | 1-1 + 1 | 1-1 | 2-1 1 | 1-1 | 2-1 1 | 1-1 | 1-1 - 3 | | + 1 | 1-1 | 1-1 2 | | 2 | | + 3 | | + 3 | | (12 rows) set enable_hashjoin to off; @@ -322,10 +322,10 @@ select * from int4_tbl a join int4_tbl b on (a.f1 = (select f1 from int4_tbl c w f1 | f1 -------------+------------- -2147483647 | -2147483647 - 123456 | 123456 - -123456 | -123456 0 | 0 2147483647 | 2147483647 + -123456 | -123456 + 123456 | 123456 (5 rows) reset enable_hashjoin; @@ -363,11 +363,11 @@ set enable_mergejoin to on; select * from foo where a not in (select c from bar where c <= 5); a | b ----+--- - 6 | 7 | - 8 | 9 | + 8 | 10 | + 6 | (5 rows) set enable_nestloop to off; @@ -484,8 +484,8 @@ insert into test_timestamp_t2 values(11 ,'2018-1-11'::timestamp); select * from test_timestamp_t1 t1 full outer join test_timestamp_t2 t2 on T1.id = T2.id and T1.field_dt = t2.field_tms; id | field_dt | id | field_tms ----+------------+----+-------------------------- - 10 | 01-10-2018 | 10 | Wed Jan 10 00:00:00 2018 11 | 01-11-2018 | 11 | Thu Jan 11 00:00:00 2018 + 10 | 01-10-2018 | 10 | Wed Jan 10 00:00:00 2018 (2 rows) -- test float type @@ -511,8 +511,8 @@ insert into test_int2 values(3, 10), (4, 20); select t1.id, t1.data, t2.id, t2.data from test_int1 t1, test_int2 t2 where t1.data = t2.data; id | data | id | data ----+------+----+------ - 1 | 10 | 3 | 10 2 | 20 | 4 | 20 + 1 | 10 | 3 | 10 (2 rows) -- Test to ensure that for full outer join on varchar columns, planner is successful in finding a sort operator in the catalog @@ -540,9 +540,7 @@ drop schema pred cascade; reset search_path; -- github issue 5370 cases drop table if exists t5370; -NOTICE: table "t5370" does not exist, skipping drop table if exists t5370_2; -NOTICE: table "t5370_2" does not exist, skipping create table t5370(id int,name text) distributed by(id); insert into t5370 select i,i from generate_series(1,1000) i; create table t5370_2 as select * from t5370 distributed by (id); @@ -551,16 +549,16 @@ analyze t5370; explain select * from t5370 a , t5370_2 b where a.name=b.name; QUERY PLAN ------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=45.50..92.25 rows=1000 width=14) - -> Hash Join (cost=45.50..92.25 rows=334 width=14) + Gather Motion 3:1 (slice1; segments: 3) (cost=15.17..44.08 rows=1000 width=14) + -> Hash Join (cost=15.17..30.75 rows=333 width=14) Hash Cond: (a.name = b.name) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..33.00 rows=334 width=7) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..11.00 rows=333 width=7) Hash Key: a.name - -> Seq Scan on t5370 a (cost=0.00..13.00 rows=334 width=7) - -> Hash (cost=33.00..33.00 rows=334 width=7) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..33.00 rows=334 width=7) + -> Seq Scan on t5370 a (cost=0.00..4.33 rows=333 width=7) + -> Hash (cost=11.00..11.00 rows=333 width=7) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..11.00 rows=333 width=7) Hash Key: b.name - -> Seq Scan on t5370_2 b (cost=0.00..13.00 rows=334 width=7) + -> Seq Scan on t5370_2 b (cost=0.00..4.33 rows=333 width=7) Optimizer: Postgres query optimizer (11 rows) @@ -706,25 +704,25 @@ explain (costs off) select * from t1 left join t2 on (t1.a = t2.a) join t3 on (t select * from t1 left join t2 on (t1.a = t2.a) join t3 on (t1.b = t3.b) where (t2.a is distinct from t3.a); a | b | c | a | b | c | a | b | c ---+---+---+---+---+---+---+---+--- - 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 + 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 (2 rows) -- ensure plan has a filter over left outer join explain select * from t3 join (select t1.a t1a, t1.b t1b, t1.c t1c, t2.a t2a, t2.b t2b, t2.c t2c from t1 left join t2 on (t1.a = t2.a)) t on (t1a = t3.a) WHERE (t2a IS NULL OR (t1c = t3.a)); QUERY PLAN --------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=20.27..37.13 rows=10 width=36) - -> Hash Right Join (cost=20.27..37.13 rows=4 width=36) + Gather Motion 3:1 (slice1; segments: 3) (cost=6.26..12.01 rows=10 width=36) + -> Hash Right Join (cost=6.26..11.88 rows=3 width=36) Hash Cond: (t2.a = t1.a) Filter: ((t2.a IS NULL) OR (t1.c = t3.a)) - -> Seq Scan on t2 (cost=0.00..12.99 rows=333 width=12) - -> Hash (cost=20.14..20.14 rows=4 width=24) - -> Hash Join (cost=2.04..20.14 rows=4 width=24) + -> Seq Scan on t2 (cost=0.00..4.33 rows=333 width=12) + -> Hash (cost=6.22..6.22 rows=3 width=24) + -> Hash Join (cost=1.02..6.22 rows=3 width=24) Hash Cond: (t1.a = t3.a) - -> Seq Scan on t1 (cost=0.00..13.00 rows=334 width=12) - -> Hash (cost=2.02..2.02 rows=1 width=12) - -> Seq Scan on t3 (cost=0.00..2.02 rows=1 width=12) + -> Seq Scan on t1 (cost=0.00..4.33 rows=333 width=12) + -> Hash (cost=1.01..1.01 rows=1 width=12) + -> Seq Scan on t3 (cost=0.00..1.01 rows=1 width=12) Optimizer: Postgres query optimizer (12 rows) @@ -741,38 +739,38 @@ explain select * from (select t1.a t1a, t1.b t1b, t2.a t2a, t2.b t2b from t1 lef join t3 t3_1 on tt1.t1b = t3_1.b and (tt1.t2a is NULL OR tt1.t1b = t3.b); QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=18.43..24.07 rows=3 width=56) - -> Hash Right Join (cost=18.43..24.03 rows=1 width=56) + Gather Motion 3:1 (slice1; segments: 3) (cost=18.39..24.02 rows=3 width=56) + -> Hash Right Join (cost=18.39..23.98 rows=1 width=56) Hash Cond: (t2_1.a = t1_1.a) Filter: ((t2_1.a IS NULL) OR (t1_1.b = t3.b)) -> Seq Scan on t2 t2_1 (cost=0.00..4.33 rows=333 width=8) - -> Hash (cost=18.42..18.42 rows=1 width=48) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=12.81..18.42 rows=1 width=48) + -> Hash (cost=18.37..18.37 rows=1 width=48) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=12.76..18.37 rows=1 width=48) Hash Key: t1_1.a - -> Hash Right Join (cost=12.81..18.40 rows=1 width=48) + -> Hash Right Join (cost=12.76..18.35 rows=1 width=48) Hash Cond: (t2.a = t1.a) -> Seq Scan on t2 (cost=0.00..4.33 rows=333 width=8) - -> Hash (cost=12.79..12.79 rows=1 width=40) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=7.48..12.79 rows=1 width=40) + -> Hash (cost=12.75..12.75 rows=1 width=40) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=7.44..12.75 rows=1 width=40) Hash Key: t1.a - -> Hash Join (cost=7.48..12.77 rows=1 width=40) + -> Hash Join (cost=7.44..12.73 rows=1 width=40) Hash Cond: (t1.b = t3.b) - -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=1.09..6.36 rows=3 width=20) + -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=1.06..6.33 rows=3 width=20) Hash Key: t1.b - -> Hash Join (cost=1.09..6.29 rows=3 width=20) + -> Hash Join (cost=1.06..6.27 rows=3 width=20) Hash Cond: (t1.b = t3_1.b) -> Seq Scan on t1 (cost=0.00..4.33 rows=333 width=8) - -> Hash (cost=1.05..1.05 rows=3 width=12) - -> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..1.05 rows=3 width=12) + -> Hash (cost=1.04..1.04 rows=2 width=12) + -> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..1.04 rows=2 width=12) -> Seq Scan on t3 t3_1 (cost=0.00..1.01 rows=1 width=12) - -> Hash (cost=6.36..6.36 rows=3 width=20) - -> Redistribute Motion 3:3 (slice6; segments: 3) (cost=1.09..6.36 rows=3 width=20) + -> Hash (cost=6.33..6.33 rows=3 width=20) + -> Redistribute Motion 3:3 (slice6; segments: 3) (cost=1.06..6.33 rows=3 width=20) Hash Key: t3.b - -> Hash Join (cost=1.09..6.29 rows=3 width=20) + -> Hash Join (cost=1.06..6.27 rows=3 width=20) Hash Cond: (t1_1.b = t3.b) -> Seq Scan on t1 t1_1 (cost=0.00..4.33 rows=333 width=8) - -> Hash (cost=1.05..1.05 rows=3 width=12) - -> Broadcast Motion 3:3 (slice7; segments: 3) (cost=0.00..1.05 rows=3 width=12) + -> Hash (cost=1.04..1.04 rows=2 width=12) + -> Broadcast Motion 3:3 (slice7; segments: 3) (cost=0.00..1.04 rows=2 width=12) -> Seq Scan on t3 (cost=0.00..1.01 rows=1 width=12) Optimizer: Postgres query optimizer (34 rows) @@ -784,8 +782,8 @@ select * from (select t1.a t1a, t1.b t1b, t2.a t2a, t2.b t2b from t1 left join t t1a | t1b | t2a | t2b | a | b | c | t1a | t1b | t2a | t2b | a | b | c -----+-----+-----+-----+---+---+---+-----+-----+-----+-----+---+---+--- 2 | 2 | 2 | 2 | | 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 - 2 | 2 | 2 | 2 | | 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 2 | 2 | 2 | 2 | 1 | 2 | 3 | 2 | 2 | 2 | 2 | | 2 | 2 + 2 | 2 | 2 | 2 | | 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 2 | 2 | 2 | 2 | 1 | 2 | 3 | 2 | 2 | 2 | 2 | 1 | 2 | 3 (4 rows) @@ -818,8 +816,8 @@ set optimizer_join_order = exhaustive2; select * from t1 join t2 on t1.a = t2.a join t3 on t1.b = t3.b; a | b | c | a | b | c | a | b | c ---+---+---+---+---+---+---+---+--- - 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 + 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 (2 rows) reset optimizer_join_order; @@ -858,11 +856,11 @@ explain select tenk1.unique2 >= 0 from tenk1 left join tenk2 on true limit 1; Limit (cost=0.32..0.36 rows=1 width=1) -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.32..0.44 rows=3 width=1) -> Limit (cost=0.32..0.40 rows=1 width=1) - -> Nested Loop Left Join (cost=0.32..2507776.74 rows=33333333 width=1) - -> Index Only Scan using tenk1_unique2 on tenk1 (cost=0.16..493.85 rows=3333 width=4) - -> Materialize (cost=0.16..677.18 rows=10000 width=0) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.16..627.18 rows=10000 width=0) - -> Index Only Scan using tenk2_hundred on tenk2 (cost=0.16..493.85 rows=3333 width=0) + -> Nested Loop Left Join (cost=0.32..2504243.35 rows=33333333 width=1) + -> Index Only Scan using tenk1_unique2 on tenk1 (cost=0.16..492.79 rows=3333 width=4) + -> Materialize (cost=0.16..676.13 rows=10000 width=0) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.16..626.13 rows=10000 width=0) + -> Index Only Scan using tenk2_unique2 on tenk2 (cost=0.16..492.79 rows=3333 width=0) Optimizer: Postgres query optimizer (9 rows) @@ -924,16 +922,16 @@ explain select * from generate_series(1, 5) g left join trep_join_gp on g = trep select * from generate_series(1, 5) g left join trep_join_gp on g = trep_join_gp.c1 join thash_join_gp on true; g | c1 | c2 | c1 | c2 ---+----+----+----+---- - 1 | 1 | 1 | 1 | 1 - 2 | 2 | 2 | 1 | 1 - 3 | | | 1 | 1 - 4 | | | 1 | 1 - 5 | | | 1 | 1 1 | 1 | 1 | 2 | 2 2 | 2 | 2 | 2 | 2 3 | | | 2 | 2 4 | | | 2 | 2 5 | | | 2 | 2 + 1 | 1 | 1 | 1 | 1 + 2 | 2 | 2 | 1 | 1 + 3 | | | 1 | 1 + 4 | | | 1 | 1 + 5 | | | 1 | 1 (10 rows) -- The following 4 tests are to check that general left join partition, we could redistribute the @@ -956,11 +954,11 @@ explain select * from generate_series(1, 5) g left join thash_join_gp on g = tha select * from generate_series(1, 5) g left join thash_join_gp on g = thash_join_gp.c1; g | c1 | c2 ---+----+---- + 5 | | 2 | 2 | 2 - 3 | | 4 | | + 3 | | 1 | 1 | 1 - 5 | | (5 rows) explain select * from generate_series(1, 5) g left join thash_join_gp on g = thash_join_gp.c2; @@ -982,10 +980,10 @@ explain select * from generate_series(1, 5) g left join thash_join_gp on g = tha select * from generate_series(1, 5) g left join thash_join_gp on g = thash_join_gp.c2; g | c1 | c2 ---+----+---- - 5 | | 2 | 2 | 2 - 3 | | 4 | | + 3 | | + 5 | | 1 | 1 | 1 (5 rows) @@ -1008,10 +1006,10 @@ explain select * from generate_series(1, 5) g left join trand_join_gp on g = tra select * from generate_series(1, 5) g left join trand_join_gp on g = trand_join_gp.c1; g | c1 | c2 ---+----+---- + 1 | | + 4 | | 2 | | 3 | | - 4 | | - 1 | | 5 | | (5 rows) @@ -1034,10 +1032,10 @@ explain select * from generate_series(1, 5) g full join trand_join_gp on g = tra select * from generate_series(1, 5) g full join trand_join_gp on g = trand_join_gp.c1; g | c1 | c2 ---+----+---- + 1 | | + 4 | | 2 | | 3 | | - 4 | | - 1 | | 5 | | (5 rows) @@ -1069,24 +1067,24 @@ select * from trep_join_gp left join thash_join_gp using (c1); explain select * from trep_join_gp left join trand_join_gp using (c1); QUERY PLAN ---------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=1.03..2.20 rows=4 width=12) - -> Hash Left Join (cost=1.03..2.13 rows=2 width=12) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.04..2.15 rows=3 width=12) + -> Hash Left Join (cost=1.04..2.11 rows=1 width=12) Hash Cond: (trep_join_gp.c1 = trand_join_gp.c1) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=0.00..1.06 rows=2 width=8) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=0.00..1.05 rows=1 width=8) Hash Key: trep_join_gp.c1 -> Seq Scan on trep_join_gp (cost=0.00..1.02 rows=2 width=8) - -> Hash (cost=1.02..1.02 rows=1 width=8) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.02 rows=1 width=8) + -> Hash (cost=1.03..1.03 rows=1 width=8) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.03 rows=1 width=8) Hash Key: trand_join_gp.c1 - -> Seq Scan on trand_join_gp (cost=0.00..1.00 rows=1 width=8) + -> Seq Scan on trand_join_gp (cost=0.00..1.01 rows=1 width=8) Optimizer: Postgres query optimizer (11 rows) select * from trep_join_gp left join trand_join_gp using (c1); c1 | c2 | c2 ----+----+---- - 2 | 2 | 1 | 1 | + 2 | 2 | (2 rows) explain select * from trep1_join_gp join thash_join_gp using (c1); @@ -1146,19 +1144,19 @@ analyze t_joinsize_2; analyze t_joinsize_3; -- the following query should not broadcast the join result of t_joinsize_1, t_joinsize_2. explain select * from (t_joinsize_1 join t_joinsize_2 on t_joinsize_1.c2 = t_joinsize_2.c2) join t_joinsize_3 on t_joinsize_3.c = t_joinsize_1.c1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=24.17..386.00 rows=20000 width=20) -> Hash Join (cost=24.17..119.33 rows=6667 width=20) - Hash Cond: (t_joinsize_2.c2 = t_joinsize_1_1_prt_2.c2) + Hash Cond: (t_joinsize_2.c2 = t_joinsize_1.c2) -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..11.00 rows=333 width=8) Hash Key: t_joinsize_2.c2 -> Seq Scan on t_joinsize_2 (cost=0.00..4.33 rows=333 width=8) -> Hash (cost=21.67..21.67 rows=200 width=12) -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=2.42..21.67 rows=200 width=12) - Hash Key: t_joinsize_1_1_prt_2.c2 + Hash Key: t_joinsize_1.c2 -> Hash Join (cost=2.42..17.67 rows=200 width=12) - Hash Cond: (t_joinsize_1_1_prt_2.c1 = t_joinsize_3.c) + Hash Cond: (t_joinsize_1.c1 = t_joinsize_3.c) -> Append (cost=0.00..12.00 rows=400 width=8) -> Seq Scan on t_joinsize_1_1_prt_2 t_joinsize_1_1 (cost=0.00..1.13 rows=13 width=8) -> Seq Scan on t_joinsize_1_1_prt_3 t_joinsize_1_2 (cost=0.00..1.13 rows=13 width=8) @@ -1221,19 +1219,19 @@ insert into t2_lateral_limit values (2, 2); insert into t2_lateral_limit values (3, 3); explain select * from t1_lateral_limit as t1 cross join lateral (select ((c).x+t2.b) as n from t2_lateral_limit as t2 order by n limit 1)s; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Nested Loop (cost=10000000001.06..10000000002.12 rows=4 width=41) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=37) - -> Seq Scan on t1_lateral_limit t1 (cost=0.00..1.01 rows=1 width=37) - -> Materialize (cost=1.06..1.08 rows=1 width=4) - -> Limit (cost=1.06..1.06 rows=1 width=4) - -> Sort (cost=1.06..1.06 rows=1 width=4) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------- + Nested Loop (cost=10000003406.25..10159073271.08 rows=46700 width=44) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..812.33 rows=46700 width=40) + -> Seq Scan on t1_lateral_limit t1 (cost=0.00..189.67 rows=15567 width=40) + -> Materialize (cost=3406.25..3406.26 rows=1 width=4) + -> Limit (cost=3406.25..3406.25 rows=1 width=4) + -> Sort (cost=3406.25..3621.50 rows=86100 width=4) Sort Key: (((t1.c).x + t2.b)) - -> Result (cost=0.00..1.05 rows=1 width=4) - -> Materialize (cost=0.00..1.03 rows=1 width=4) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=4) - -> Seq Scan on t2_lateral_limit t2 (cost=0.00..1.01 rows=1 width=4) + -> Result (cost=0.00..2975.75 rows=86100 width=4) + -> Materialize (cost=0.00..1899.50 rows=86100 width=4) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1469.00 rows=86100 width=4) + -> Seq Scan on t2_lateral_limit t2 (cost=0.00..321.00 rows=28700 width=4) Optimizer: Postgres query optimizer (12 rows) @@ -1286,18 +1284,18 @@ select * from t1_lateral_limit as t1 cross join lateral -- may add motions in the subquery's plan). explain select * from t1_lateral_limit t1 cross join lateral (select (c).x+t2.a, sum(t2.a+t2.b) from t2_lateral_limit t2 group by (c).x+t2.a)x; - QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Nested Loop (cost=10000000001.06..10000000002.12 rows=4 width=49) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=37) - -> Seq Scan on t1_lateral_limit t1 (cost=0.00..1.01 rows=1 width=37) - -> Materialize (cost=1.05..1.08 rows=1 width=12) - -> HashAggregate (cost=1.05..1.07 rows=1 width=12) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Nested Loop (cost=10000003621.50..10170175612.33 rows=46700000 width=52) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..812.33 rows=46700 width=40) + -> Seq Scan on t1_lateral_limit t1 (cost=0.00..189.67 rows=15567 width=40) + -> Materialize (cost=3621.50..3639.00 rows=1000 width=12) + -> HashAggregate (cost=3621.50..3634.00 rows=1000 width=12) Group Key: ((t1.c).x + t2.a) - -> Result (cost=0.00..1.05 rows=1 width=12) - -> Materialize (cost=0.00..1.03 rows=1 width=8) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=8) - -> Seq Scan on t2_lateral_limit t2 (cost=0.00..1.01 rows=1 width=8) + -> Result (cost=0.00..2975.75 rows=86100 width=12) + -> Materialize (cost=0.00..1899.50 rows=86100 width=8) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1469.00 rows=86100 width=8) + -> Seq Scan on t2_lateral_limit t2 (cost=0.00..321.00 rows=28700 width=8) Optimizer: Postgres query optimizer (11 rows) @@ -1305,8 +1303,8 @@ select * from t1_lateral_limit t1 cross join lateral (select (c).x+t2.a, sum(t2.a+t2.b) from t2_lateral_limit t2 group by (c).x+t2.a)x; a | b | c | ?column? | sum ---+---+-------+----------+----- - 1 | 1 | (1,1) | 4 | 6 1 | 1 | (1,1) | 3 | 4 + 1 | 1 | (1,1) | 4 | 6 1 | 2 | (2,2) | 5 | 6 1 | 2 | (2,2) | 4 | 4 (4 rows) @@ -1324,18 +1322,18 @@ inner join lateral on true; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------- - Nested Loop (cost=10000000001.08..10000000003.25 rows=3 width=20) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.04 rows=2 width=12) - -> Seq Scan on t_mylog_issue_8860 ml1 (cost=0.00..1.01 rows=1 width=12) - -> Materialize (cost=1.08..1.10 rows=1 width=8) - -> Limit (cost=1.08..1.08 rows=1 width=12) - -> Sort (cost=1.08..1.08 rows=2 width=12) + Nested Loop (cost=10000002890.33..10225160051.75 rows=77900 width=20) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1332.33 rows=77900 width=12) + -> Seq Scan on t_mylog_issue_8860 ml1 (cost=0.00..293.67 rows=25967 width=12) + -> Materialize (cost=2890.33..2890.35 rows=1 width=8) + -> Limit (cost=2890.33..2890.34 rows=1 width=12) + -> Sort (cost=2890.33..3085.08 rows=77900 width=12) Sort Key: t_mylog_issue_8860.log_date - -> Result (cost=0.00..1.07 rows=2 width=12) + -> Result (cost=0.00..2500.83 rows=77900 width=12) Filter: ((t_mylog_issue_8860.log_date > ml1.log_date) AND (t_mylog_issue_8860.myid = ml1.myid)) - -> Materialize (cost=0.00..1.05 rows=2 width=12) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.04 rows=2 width=12) - -> Seq Scan on t_mylog_issue_8860 (cost=0.00..1.01 rows=1 width=12) + -> Materialize (cost=0.00..1721.83 rows=77900 width=12) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1332.33 rows=77900 width=12) + -> Seq Scan on t_mylog_issue_8860 (cost=0.00..293.67 rows=25967 width=12) Optimizer: Postgres query optimizer (13 rows) @@ -1433,7 +1431,7 @@ select box(point(0.05*i, 0.05*i), point(0.05*i, 0.05*i)), from generate_series(0,10000) as i; vacuum analyze gist_tbl_github9733; create index gist_tbl_point_index_github9733 on gist_tbl_github9733 using gist (p); -ERROR: pax only support btree/hash/gin/bitmap indexes (pax_access_handle.cc:591) +ERROR: pax only support btree/hash/gin/bitmap indexes (pax_access_handle.cc:588) set enable_seqscan=off; set enable_bitmapscan=off; explain (costs off) @@ -1504,7 +1502,9 @@ reset enable_bitmapscan; --- Test that GUC enable_hashagg takes effect for SEMI join --- drop table if exists foo; +NOTICE: table "foo" does not exist, skipping drop table if exists bar; +NOTICE: table "bar" does not exist, skipping create table foo(a int) distributed by (a); create table bar(b int) distributed by (b); insert into foo select i from generate_series(1,10)i; @@ -1514,68 +1514,57 @@ analyze bar; set enable_hashagg to on; explain (costs off) select * from foo where exists (select 1 from bar where foo.a = bar.b); - QUERY PLAN ------------------------------------------------------------- + QUERY PLAN +------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> HashAggregate - Group Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: (bar.b = foo.a) - -> Seq Scan on bar - -> Hash - -> Seq Scan on foo + -> Hash Right Semi Join + Hash Cond: (bar.b = foo.a) + -> Seq Scan on bar + -> Hash + -> Seq Scan on foo Optimizer: Postgres query optimizer -(11 rows) +(7 rows) select * from foo where exists (select 1 from bar where foo.a = bar.b); a ---- - 10 + 1 + 5 + 6 9 + 10 + 2 3 - 7 4 - 5 + 7 8 - 1 - 2 - 6 (10 rows) set enable_hashagg to off; explain (costs off) select * from foo where exists (select 1 from bar where foo.a = bar.b); - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: (bar.b = foo.a) - -> Seq Scan on bar - -> Hash - -> Seq Scan on foo + -> Hash Right Semi Join + Hash Cond: (bar.b = foo.a) + -> Seq Scan on bar + -> Hash + -> Seq Scan on foo Optimizer: Postgres query optimizer -(14 rows) +(7 rows) select * from foo where exists (select 1 from bar where foo.a = bar.b); a ---- - 1 2 3 4 - 5 - 6 7 8 + 1 + 5 + 6 9 10 (10 rows) @@ -1672,14 +1661,14 @@ full join ( select r.id1, r.id2 from t_issue_10315 r group by r.id1, r.id2 ) tq_ on (coalesce(t.id1) = tq_all.id1 and t.id2 = tq_all.id2) ; id1 | id2 | id1 | id2 | id1 | id2 -----+-----+-----+-----+-----+----- - 2 | 2 | 2 | 2 | 2 | 2 + | | 1 | | | + | 2 | | | | 2 | | | | | + 2 | 2 | 2 | 2 | 2 | 2 | 1 | | | | - | 2 | | | | | | | 2 | | | | | 1 | | | | 2 | | | - | | 1 | | | | | | | | 2 | | | | | 1 | | | | 2 | @@ -1718,8 +1707,8 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on fooJoinPruning.c=barJoinPruning.p where fooJoinPruning.b>300 and fooJoinPruning.c in (select barJoinPruning.q from barJoinPruning ); QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=958.75..1562.82 rows=12983 width=12) - -> Hash Join (cost=958.75..1389.71 rows=4328 width=12) + Gather Motion 3:1 (slice1; segments: 3) (cost=958.75..1562.80 rows=12983 width=12) + -> Hash Join (cost=958.75..1389.69 rows=4328 width=12) Hash Cond: (foojoinpruning.c = barjoinpruning.q) -> Seq Scan on foojoinpruning (cost=0.00..358.58 rows=8656 width=12) Filter: (b > 300) @@ -1888,7 +1877,7 @@ drop table barJoinPruning; drop table t1JoinPruning; drop table t2JoinPruning; create table t1 (a int); -NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table. +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create table t2 (a int primary key, b int); create table t3 (a int primary key, b int); @@ -2018,8 +2007,8 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on fooJoinPruning.c=barJoinPruning.p where fooJoinPruning.b in (select barJoinPruning.q from fooJoinPruning where fooJoinPruning.a=barJoinPruning.r); QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=1633.60..1994.88 rows=78 width=12) - -> Hash Join (cost=1633.60..1993.84 rows=26 width=12) + Gather Motion 3:1 (slice1; segments: 3) (cost=1633.60..1994.56 rows=78 width=12) + -> Hash Join (cost=1633.60..1993.52 rows=26 width=12) Hash Cond: (foojoinpruning_1.a = barjoinpruning.r) -> Seq Scan on foojoinpruning foojoinpruning_1 (cost=0.00..293.67 rows=25967 width=4) -> Hash (cost=1633.27..1633.27 rows=26 width=16) @@ -2141,7 +2130,7 @@ union select foo.a, bar.b from foo join bar on foo.a = bar.a; -> Seq Scan on foo foo_1 -> Hash -> Seq Scan on bar bar_1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (17 rows) ------------------------------------- @@ -2164,7 +2153,7 @@ select bar.b,bar.c from bar left join foo on foo.a=bar.a; -> Append -> Seq Scan on foo -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (9 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a union @@ -2192,17 +2181,17 @@ select bar.b,bar.c from bar left join foo on foo.a=bar.a; -> Append -> Seq Scan on foo -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (5 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a union all select bar.b,bar.c from bar left join foo on foo.a=bar.a; b | c ---+---- - 2 | 30 - | 1 | 10 1 | 10 + 2 | 30 + | 1 | 10 1 | 10 2 | 20 @@ -2233,7 +2222,7 @@ select bar.b,bar.c from bar left join foo on foo.a=bar.a; Hash Key: "*SELECT* 1".b, "*SELECT* 1".c -> Subquery Scan on "*SELECT* 1" -> Seq Scan on foo - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (12 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a intersect @@ -2241,8 +2230,8 @@ select bar.b,bar.c from bar left join foo on foo.a=bar.a; b | c ---+---- | - 1 | 10 2 | 20 + 1 | 10 (3 rows) -------------------------------------------------------------------------------- @@ -2265,17 +2254,17 @@ select bar.b,bar.c from bar left join foo on foo.a=bar.a; Hash Key: "*SELECT* 1".b, "*SELECT* 1".c -> Subquery Scan on "*SELECT* 1" -> Seq Scan on foo - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (12 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a intersect all select bar.b,bar.c from bar left join foo on foo.a=bar.a; b | c ---+---- - | + 2 | 20 1 | 10 1 | 10 - 2 | 20 + | (4 rows) -------------------------------------------------------------------------------- @@ -2298,7 +2287,7 @@ select bar.b,bar.c from bar left join foo on foo.a=bar.a; Hash Key: "*SELECT* 2".b, "*SELECT* 2".c -> Subquery Scan on "*SELECT* 2" -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (12 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a except @@ -2329,7 +2318,7 @@ select bar.b,bar.c from bar left join foo on foo.a=bar.a; Hash Key: "*SELECT* 2".b, "*SELECT* 2".c -> Subquery Scan on "*SELECT* 2" -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (12 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a except all @@ -2367,22 +2356,22 @@ select bar.b,foo.c from bar left join foo on foo.a=bar.a; -> Seq Scan on foo foo_1 -> Hash -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (13 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a union select bar.b,foo.c from bar left join foo on foo.a=bar.a; b | c ---+---- - 2 | 10 | 2 | 30 | 3 3 | 30 1 | 10 - 1 | 30 2 | 20 + 1 | 30 | 20 + 2 | 10 (9 rows) -------------------------------------------------------------------------------- @@ -2404,13 +2393,18 @@ select bar.b,foo.c from bar left join foo on foo.a=bar.a; -> Seq Scan on foo foo_1 -> Hash -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (9 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a union all select bar.b,foo.c from bar left join foo on foo.a=bar.a; b | c ---+---- + 2 | 30 + | + 1 | 30 + 1 | 10 + 1 | 10 1 | 10 2 | 20 2 | 30 @@ -2418,11 +2412,6 @@ select bar.b,foo.c from bar left join foo on foo.a=bar.a; 2 | 10 | 20 3 | 30 - 2 | 30 - | - 1 | 30 - 1 | 10 - 1 | 10 (12 rows) -------------------------------------------------------------------------------- @@ -2451,7 +2440,7 @@ select bar.b,foo.c from bar left join foo on foo.a=bar.a; Hash Key: "*SELECT* 1".b, "*SELECT* 1".c -> Subquery Scan on "*SELECT* 1" -> Seq Scan on foo foo_1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (16 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a intersect @@ -2487,7 +2476,7 @@ select bar.b,foo.c from bar left join foo on foo.a=bar.a; Hash Key: "*SELECT* 1".b, "*SELECT* 1".c -> Subquery Scan on "*SELECT* 1" -> Seq Scan on foo foo_1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (16 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a intersect all @@ -2523,7 +2512,7 @@ select bar.b,foo.c from bar left join foo on foo.a=bar.a; -> Seq Scan on foo foo_1 -> Hash -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (16 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a except @@ -2562,7 +2551,7 @@ select bar.b,foo.c from bar left join foo on foo.a=bar.a; -> Seq Scan on foo foo_1 -> Hash -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (16 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a except all @@ -2658,10 +2647,10 @@ select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a; a1_pc | b1 | a | b -------+----+---+--- 1 | 1 | 1 | 1 + 5 | 5 | 5 | 5 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 - 5 | 5 | 5 | 5 (5 rows) -- Outer table: Partitioned table, Join Condition on Partition key: No, Result: DPE - No @@ -2689,10 +2678,10 @@ select * from bar_PT1 right join foo on bar_PT1.b1 =foo.a; a1_pc | b1 | a | b -------+----+---+--- 5 | 5 | 5 | 5 - 1 | 1 | 1 | 1 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 + 1 | 1 | 1 | 1 (5 rows) -- Outer,Inner table: Partitioned table, Join Condition on Partition key: Yes, Result: DPE - Yes @@ -2722,11 +2711,11 @@ explain (costs off) select * from bar_PT1 right join bar_PT3 on bar_PT1.a1_PC =b select * from bar_PT1 right join bar_PT3 on bar_PT1.a1_PC =bar_PT3.a3_PC; a1_pc | b1 | a3_pc | b3 -------+----+-------+---- + 1 | 1 | 1 | 1 5 | 5 | 5 | 5 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 - 1 | 1 | 1 | 1 (5 rows) -- Outer table: Not a Partitioned table, Join Condition on Partition key: Yes, Result: DPE - No @@ -2751,17 +2740,17 @@ explain (costs off) select * from foo right join bar_PT1 on foo.a=bar_PT1.a1_PC; select * from foo right join bar_PT1 on foo.a=bar_PT1.a1_PC; a | b | a1_pc | b1 ---+---+-------+---- - 5 | 5 | 5 | 5 - | | 6 | 6 - | | 9 | 9 - | | 10 | 10 - | | 11 | 11 + 1 | 1 | 1 | 1 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 | | 7 | 7 | | 8 | 8 - 1 | 1 | 1 | 1 + 5 | 5 | 5 | 5 + | | 6 | 6 + | | 9 | 9 + | | 10 | 10 + | | 11 | 11 (11 rows) -- Right join with predicate on the column of non partitioned table in 'where clause'. @@ -2850,8 +2839,8 @@ explain (costs off) select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a and foo.b>2; a1_pc | b1 | a | b -------+----+---+--- - | | 1 | 1 5 | 5 | 5 | 5 + | | 1 | 1 3 | 3 | 3 | 3 4 | 4 | 4 | 4 | | 2 | 2 @@ -2938,11 +2927,11 @@ explain (costs off) select * from bar_List_PT1 right join foo on bar_List_PT1.a1 select * from bar_List_PT1 right join foo on bar_List_PT1.a1_PC =foo.a; a1_pc | b1 | a | b -------+----+---+--- - 1 | 1 | 1 | 1 + 5 | 5 | 5 | 5 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 - 5 | 5 | 5 | 5 + 1 | 1 | 1 | 1 (5 rows) -- Outer,Inner table: Partitioned table, Join Condition on Partition key: Yes, Result: DPE - Yes @@ -2983,8 +2972,6 @@ explain (costs off) select * from bar_List_PT1 right join bar_List_PT2 on bar_Li select * from bar_List_PT1 right join bar_List_PT2 on bar_List_PT1.a1_PC =bar_List_PT2.a2_PC; a1_pc | b1 | a2_pc | b2 -------+----+-------+---- - 1 | 1 | 1 | 1 - 12 | 12 | 12 | 12 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 @@ -2995,6 +2982,8 @@ select * from bar_List_PT1 right join bar_List_PT2 on bar_List_PT1.a1_PC =bar_Li 9 | 9 | 9 | 9 10 | 10 | 10 | 10 11 | 11 | 11 | 11 + 1 | 1 | 1 | 1 + 12 | 12 | 12 | 12 (12 rows) -- Case-2 : Distribution colm <> Partition Key. @@ -3022,11 +3011,11 @@ explain (costs off) select * from bar_PT2 right join foo on bar_PT2.b2_PC =foo.a select * from bar_PT2 right join foo on bar_PT2.b2_PC =foo.a; a2 | b2_pc | a | b ----+-------+---+--- + 1 | 1 | 1 | 1 5 | 5 | 5 | 5 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 - 1 | 1 | 1 | 1 (5 rows) -- Outer,Inner table: Partitioned table, Join Condition on Partition key: Yes, Result: DPE - No @@ -3061,17 +3050,17 @@ explain (costs off) select * from bar_PT2 right join bar_PT1 on bar_PT2.b2_PC =b select * from bar_PT2 right join bar_PT1 on bar_PT2.b2_PC =bar_PT1.b1; a2 | b2_pc | a1_pc | b1 ----+-------+-------+---- - 5 | 5 | 5 | 5 - 6 | 6 | 6 | 6 - 9 | 9 | 9 | 9 - 10 | 10 | 10 | 10 - 11 | 11 | 11 | 11 1 | 1 | 1 | 1 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 7 | 7 | 7 | 7 8 | 8 | 8 | 8 + 5 | 5 | 5 | 5 + 6 | 6 | 6 | 6 + 9 | 9 | 9 | 9 + 10 | 10 | 10 | 10 + 11 | 11 | 11 | 11 (11 rows) drop table if exists foo; @@ -3086,10 +3075,10 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'cidr' HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO inverse values ('192.168.100.199'); explain SELECT 1 FROM inverse WHERE NOT (cidr <<= ANY(SELECT * FROM inverse)); - QUERY PLAN --------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10027702610.21 rows=16 width=4) - -> Nested Loop Left Anti Semi (Not-In) Join (cost=10000000000.00..10027702610.00 rows=5 width=4) + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10027703310.48 rows=52536 width=4) + -> Nested Loop Left Anti Semi (Not-In) Join (cost=10000000000.00..10027702610.00 rows=17512 width=4) Join Filter: (inverse.cidr <<= inverse_1.cidr) -> Seq Scan on inverse (cost=0.00..210.00 rows=17600 width=32) -> Materialize (cost=0.00..1178.00 rows=52800 width=32) @@ -3134,9 +3123,9 @@ explain select * from foo_varchar left join bar_char on foo_varchar.a=bar_char.p select * from foo_varchar left join bar_char on foo_varchar.a=bar_char.p; a | p ------+------- - 1 | 1 - 2 | 2 3 | 3 + 2 | 2 + 1 | 1 (3 rows) -- There is a plan change (from redistribution to broadcast) because a NULL @@ -3161,9 +3150,9 @@ explain select * from foo_varchar left join random_dis_char on foo_varchar.a=ran select * from foo_varchar left join random_dis_char on foo_varchar.a=random_dis_char.y; a | y ------+------- - 1 | 1 2 | 2 3 | 3 + 1 | 1 (3 rows) explain select * from bar_char left join random_dis_varchar on bar_char.p=random_dis_varchar.x; @@ -3208,9 +3197,9 @@ explain select * from foo_varchar inner join bar_char on foo_varchar.a=bar_char. select * from foo_varchar inner join bar_char on foo_varchar.a=bar_char.p; a | p ------+------- - 1 | 1 - 2 | 2 3 | 3 + 2 | 2 + 1 | 1 (3 rows) -- There is a plan change (from redistribution to broadcast) because a NULL @@ -3257,9 +3246,9 @@ explain select * from bar_char inner join random_dis_varchar on bar_char.p=rando select * from bar_char inner join random_dis_varchar on bar_char.p=random_dis_varchar.x; p | x -------+------ - 1 | 1 2 | 2 3 | 3 + 1 | 1 (3 rows) drop table foo_varchar; @@ -3274,7 +3263,9 @@ reset enable_nestloop; -- for "Left Semi Join with replicated outer table" ----------------------------------------------------------------- drop table if exists repli_t1; +NOTICE: table "repli_t1" does not exist, skipping drop table if exists dist_t1; +NOTICE: table "dist_t1" does not exist, skipping create table repli_t1 (a int) distributed replicated; insert into repli_t1 values(1); analyze repli_t1; @@ -3297,7 +3288,7 @@ explain (costs off) select * from repli_t1 where exists ( select 1 from dist_t1 -> Broadcast Motion 1:3 (slice3; segments: 1) -> Seq Scan on repli_t1 -> Seq Scan on dist_t1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (11 rows) select * from repli_t1 where exists ( select 1 from dist_t1 where repli_t1.a >= dist_t1.b); @@ -3325,7 +3316,7 @@ where exists (select 1 from dist_t1 as t4 where t3.aVal1 >= t4.b); -> Seq Scan on dist_t1 t4 -> Hash -> Seq Scan on repli_t1 t2 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (16 rows) select * from (select t1.a as aVal1, t2.a as aVal2 from repli_t1 as t1 , repli_t1 as t2 where t1.a = t2.a) as t3 @@ -3350,7 +3341,7 @@ explain (costs off) select * from repli_t1 where exists ( select 1 from dist_t1 -> Broadcast Motion 1:3 (slice3; segments: 1) -> Seq Scan on repli_t1 -> Seq Scan on dist_t1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (11 rows) select * from repli_t1 where exists ( select 1 from dist_t1 where repli_t1.a >= dist_t1.b); @@ -3369,7 +3360,7 @@ explain (costs off) select * from dist_t1 where exists ( select 1 from repli_t1 Join Filter: (repli_t1.a >= dist_t1.b) -> Seq Scan on dist_t1 -> Seq Scan on repli_t1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (6 rows) select * from dist_t1 where exists ( select 1 from repli_t1 where repli_t1.a >= dist_t1.b); @@ -3391,7 +3382,7 @@ explain (costs off) select * from repli_t1 as t1 where exists ( select 1 from r Join Filter: (t1.a >= t2.a) -> Seq Scan on repli_t1 t1 -> Seq Scan on repli_t1 t2 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (6 rows) select * from repli_t1 as t1 where exists ( select 1 from repli_t1 as t2 where t1.a >= t2.a); @@ -3412,7 +3403,7 @@ explain (costs off) select * from generate_series(1, 5) univ_t where exists ( se -> Seq Scan on dist_t1 -> Materialize -> Function Scan on generate_series univ_t - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (9 rows) select * from generate_series(1, 5) univ_t where exists ( select 1 from dist_t1 where univ_t >= dist_t1.b); @@ -3434,17 +3425,17 @@ explain (costs off) select * from dist_t1 where exists ( select 1 from generate_ Join Filter: (univ_t.univ_t >= dist_t1.b) -> Seq Scan on dist_t1 -> Function Scan on generate_series univ_t - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (6 rows) select * from dist_t1 where exists ( select 1 from generate_series(1, 5) univ_t where univ_t >= dist_t1.b); a | b ---+--- + 5 | 1 + 1 | 1 2 | 1 3 | 1 4 | 1 - 1 | 1 - 5 | 1 (5 rows) -- Outer - replicated, Inner - universal table @@ -3456,7 +3447,7 @@ explain (costs off)select * from repli_t1 where exists ( select 1 from generate_ Join Filter: (univ_t.univ_t >= repli_t1.a) -> Seq Scan on repli_t1 -> Function Scan on generate_series univ_t - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (6 rows) select * from repli_t1 where exists ( select 1 from generate_series(1, 5) univ_t where univ_t >= repli_t1.a); @@ -3475,7 +3466,7 @@ explain (costs off) select * from generate_series(1, 5) univ_t where exists ( se -> Function Scan on generate_series univ_t -> Materialize -> Seq Scan on repli_t1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (7 rows) select * from generate_series(1, 5) univ_t where exists ( select 1 from repli_t1 where univ_t >= repli_t1.a); @@ -3491,9 +3482,13 @@ select * from generate_series(1, 5) univ_t where exists ( select 1 from repli_t1 -- Explicitly defined primary key for replicated table --------------------------------------------------------- drop table if exists repli_t1_pk; +NOTICE: table "repli_t1_pk" does not exist, skipping drop table if exists repli_t2_pk; +NOTICE: table "repli_t2_pk" does not exist, skipping drop table if exists repli_t3_pk; +NOTICE: table "repli_t3_pk" does not exist, skipping drop table if exists repli_t4_pk; +NOTICE: table "repli_t4_pk" does not exist, skipping -- Outer - replicated, Inner - distributed table create table repli_t1_pk (a int, PRIMARY KEY(a)) distributed replicated; insert into repli_t1_pk values(1); @@ -3520,7 +3515,7 @@ explain (costs off) select * from repli_t1_pk where exists ( select 1 from dist_ -> Broadcast Motion 1:3 (slice3; segments: 1) -> Seq Scan on repli_t1_pk -> Seq Scan on dist_t1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (11 rows) select * from repli_t1_pk where exists ( select 1 from dist_t1 where repli_t1_pk.a >= dist_t1.b); @@ -3544,7 +3539,7 @@ explain (costs off) select * from repli_t1_pk where exists ( select 1 from dist_ -> Broadcast Motion 1:3 (slice3; segments: 1) -> Seq Scan on repli_t1_pk -> Seq Scan on dist_t1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (11 rows) select * from repli_t1_pk where exists ( select 1 from dist_t1 where repli_t1_pk.a >= dist_t1.b); @@ -3567,7 +3562,7 @@ explain (costs off) select * from repli_t2_pk where exists ( select 1 from dist_ -> Broadcast Motion 1:3 (slice3; segments: 1) -> Seq Scan on repli_t2_pk -> Seq Scan on dist_t1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (11 rows) select * from repli_t2_pk where exists ( select 1 from dist_t1 where repli_t2_pk.a >= dist_t1.b); @@ -3586,7 +3581,7 @@ explain (costs off) select * from repli_t3_pk where exists ( select 1 from dist_ -> Materialize -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on dist_t1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (8 rows) select * from repli_t3_pk where exists ( select 1 from dist_t1 where repli_t3_pk.a >= dist_t1.b); @@ -3605,7 +3600,7 @@ explain (costs off) select * from repli_t4_pk where exists ( select 1 from dist_ -> Materialize -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on dist_t1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (8 rows) select * from repli_t4_pk where exists ( select 1 from dist_t1 where repli_t4_pk.a >= dist_t1.b); diff --git a/contrib/pax_storage/src/test/regress/expected/join_gp_optimizer.out b/contrib/pax_storage/src/test/regress/expected/join_gp_optimizer.out index ba1543b8a46..5c48768e485 100644 --- a/contrib/pax_storage/src/test/regress/expected/join_gp_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/join_gp_optimizer.out @@ -29,8 +29,8 @@ explain select * from nhtest a join nhtest b using (i); select * from nhtest a join nhtest b using (i); i ----------- - 100000.22 300000.19 + 100000.22 (2 rows) create temp table l(a int); @@ -94,7 +94,6 @@ set enable_hashjoin to off; set enable_mergejoin to on; set enable_nestloop to off; DROP TABLE IF EXISTS alpha; -NOTICE: table "alpha" does not exist, skipping DROP TABLE IF EXISTS theta; NOTICE: table "theta" does not exist, skipping CREATE TABLE alpha (i int, j int) distributed by (i); @@ -129,8 +128,8 @@ analyze t2; -- infer over equalities -- explain select count(*) from t1,t2 where t1.x = 100 and t1.x = t2.x; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------ Aggregate (cost=0.00..862.00 rows=1 width=8) -> Hash Join (cost=0.00..862.00 rows=1 width=1) Hash Cond: (t1.x = t2.x) @@ -141,7 +140,7 @@ explain select count(*) from t1,t2 where t1.x = 100 and t1.x = t2.x; -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on t2 (cost=0.00..431.00 rows=1 width=4) Filter: (x = 100) - Optimizer: Pivotal Optimizer (GPORCA) version 3.64.0 + Optimizer: GPORCA (11 rows) select count(*) from t1,t2 where t1.x = 100 and t1.x = t2.x; @@ -156,16 +155,15 @@ select count(*) from t1,t2 where t1.x = 100 and t1.x = t2.x; explain select * from t1,t2 where t1.x = 100 and t2.x >= t1.x; QUERY PLAN ---------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324039.56 rows=34 width=24) - -> Nested Loop (cost=0.00..1324039.56 rows=12 width=24) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324039.11 rows=34 width=24) + -> Nested Loop (cost=0.00..1324039.11 rows=12 width=24) Join Filter: (t2.x >= t1.x) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=12) -> Seq Scan on t1 (cost=0.00..431.00 rows=1 width=12) Filter: (x = 100) -> Seq Scan on t2 (cost=0.00..431.00 rows=34 width=12) - Settings: optimizer=on - Optimizer status: Pivotal Optimizer (GPORCA) version 2.39.2 -(9 rows) + Optimizer: GPORCA +(8 rows) select * from t1,t2 where t1.x = 100 and t2.x >= t1.x; x | y | z | x | y | z @@ -190,7 +188,7 @@ explain select * from t1,t2 where t1.x = 100 and t1.x = t2.y and t1.x <= t2.x; -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=12) -> Seq Scan on t2 (cost=0.00..431.00 rows=1 width=12) Filter: (y = 100) - Optimizer: Pivotal Optimizer (GPORCA) version 3.64.0 + Optimizer: GPORCA (11 rows) reset optimizer_segments; @@ -234,10 +232,10 @@ select count(*) from hjn_test, (select 3 as bar) foo where hjn_test.i = least (f select * from int4_tbl a join int4_tbl b on (a.f1 = (select f1 from int4_tbl c where c.f1=b.f1)); f1 | f1 -------------+------------- - 2147483647 | 2147483647 - 123456 | 123456 -2147483647 | -2147483647 0 | 0 + 2147483647 | 2147483647 + 123456 | 123456 -123456 | -123456 (5 rows) @@ -252,11 +250,13 @@ insert into part4_tbl values (-1), (0), (1), (123455), (123456), (123457); select * from part4_tbl a join part4_tbl b on (a.f1 = (select f1 from int4_tbl c where c.f1=b.f1)); +NOTICE: One or more columns in the following table(s) do not have statistics: part4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. f1 | f1 ---------+--------- 0 | 0 - 123456 | 123456 -123456 | -123456 + 123456 | 123456 (3 rows) -- @@ -277,18 +277,18 @@ from tjoin1 left outer join (tjoin2 left outer join tjoin3 on tjoin2.id=tjoin3.id) on tjoin1.id=tjoin3.id; id | t | t ----+-----+----- + 2 | | + 2 | | 3 | | 3 | | - 1 | 2-1 | 1-1 - 1 | 2-1 | 2-1 + 1 | 1-1 | 1-1 1 | 1-1 | 1-1 1 | 1-1 | 2-1 - 2 | | + 1 | 1-1 | 2-1 + 1 | 2-1 | 1-1 1 | 2-1 | 1-1 1 | 2-1 | 2-1 - 1 | 1-1 | 1-1 - 1 | 1-1 | 2-1 - 2 | | + 1 | 2-1 | 2-1 (12 rows) set enable_hashjoin to off; @@ -320,10 +320,10 @@ select count(*) from hjn_test, (select 3 as bar) foo where hjn_test.i = least (f select * from int4_tbl a join int4_tbl b on (a.f1 = (select f1 from int4_tbl c where c.f1=b.f1)); f1 | f1 -------------+------------- - 2147483647 | 2147483647 - 123456 | 123456 -2147483647 | -2147483647 0 | 0 + 2147483647 | 2147483647 + 123456 | 123456 -123456 | -123456 (5 rows) @@ -340,11 +340,11 @@ create table bar (c int, d int) distributed randomly; insert into foo select generate_series(1,10); insert into bar select generate_series(1,10); explain select a from foo where a<1 and a>1 and not exists (select c from bar where c=a); - QUERY PLAN ------------------------------------------------------- + QUERY PLAN +------------------------------------------ Result (cost=0.00..0.00 rows=0 width=4) One-Time Filter: false - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (3 rows) select a from foo where a<1 and a>1 and not exists (select c from bar where c=a); @@ -363,8 +363,8 @@ select * from foo where a not in (select c from bar where c <= 5); a | b ----+--- 7 | - 6 | 8 | + 6 | 9 | 10 | (5 rows) @@ -536,9 +536,7 @@ drop schema pred cascade; reset search_path; -- github issue 5370 cases drop table if exists t5370; -NOTICE: table "t5370" does not exist, skipping drop table if exists t5370_2; -NOTICE: table "t5370_2" does not exist, skipping create table t5370(id int,name text) distributed by(id); insert into t5370 select i,i from generate_series(1,1000) i; create table t5370_2 as select * from t5370 distributed by (id); @@ -548,15 +546,15 @@ explain select * from t5370 a , t5370_2 b where a.name=b.name; QUERY PLAN -------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.25 rows=1000 width=14) - -> Hash Join (cost=0.00..862.20 rows=334 width=14) + -> Hash Join (cost=0.00..862.19 rows=334 width=14) Hash Cond: (a.name = b.name) -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.02 rows=334 width=7) Hash Key: a.name - -> Seq Scan on t5370 a (cost=0.00..431.01 rows=334 width=7) + -> Seq Scan on t5370 a (cost=0.00..431.00 rows=334 width=7) -> Hash (cost=431.02..431.02 rows=334 width=7) -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..431.02 rows=334 width=7) Hash Key: b.name - -> Seq Scan on t5370_2 b (cost=0.00..431.01 rows=334 width=7) + -> Seq Scan on t5370_2 b (cost=0.00..431.00 rows=334 width=7) Optimizer: GPORCA (11 rows) @@ -650,7 +648,7 @@ explain (costs off) select * from t1 left join t2 on (t1.a = t2.a) join t3 on (t -> Hash -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on t3 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (14 rows) select * from t1 left join t2 on (t1.a = t2.a) join t3 on (t1.b = t3.b) where (t2.a IS NULL OR (t1.c = t3.c)); @@ -673,7 +671,7 @@ explain (costs off) select * from t1 left join t2 on (t1.a = t2.a) join t3 on (t -> Seq Scan on t2 -> Hash -> Seq Scan on t3 - Optimizer: Pivotal Optimizer (GPORCA) version 3.75.0 + Optimizer: GPORCA (11 rows) select * from t1 left join t2 on (t1.a = t2.a) join t3 on (t1.b = t3.b) where (t2.a = t3.a); @@ -698,7 +696,7 @@ explain (costs off) select * from t1 left join t2 on (t1.a = t2.a) join t3 on (t -> Hash -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on t3 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (14 rows) select * from t1 left join t2 on (t1.a = t2.a) join t3 on (t1.b = t3.b) where (t2.a is distinct from t3.a); @@ -718,13 +716,13 @@ explain select * from t3 join (select t1.a t1a, t1.b t1b, t1.c t1c, t2.a t2a, t2 -> Hash Right Join (cost=0.00..1293.15 rows=2 width=36) Hash Cond: (t2.a = t1.a) -> Seq Scan on t2 (cost=0.00..431.01 rows=333 width=12) - -> Hash (cost=862.08..862.08 rows=1 width=24) - -> Hash Join (cost=0.00..862.08 rows=1 width=24) + -> Hash (cost=862.07..862.07 rows=1 width=24) + -> Hash Join (cost=0.00..862.07 rows=1 width=24) Hash Cond: (t1.a = t3.a) -> Seq Scan on t1 (cost=0.00..431.01 rows=334 width=12) -> Hash (cost=431.00..431.00 rows=1 width=12) -> Seq Scan on t3 (cost=0.00..431.00 rows=1 width=12) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) select * from t3 join (select t1.a t1a, t1.b t1b, t1.c t1c, t2.a t2a, t2.b t2b, t2.c t2c from t1 left join t2 on (t1.a = t2.a)) t on (t1a = t3.a) WHERE (t2a IS NULL OR (t1c = t3.a)); @@ -740,10 +738,10 @@ explain select * from (select t1.a t1a, t1.b t1b, t2.a t2a, t2.b t2b from t1 lef join t3 t3_1 on tt1.t1b = t3_1.b and (tt1.t2a is NULL OR tt1.t1b = t3.b); QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------- - Hash Join (cost=0.00..2586.30 rows=7 width=56) + Hash Join (cost=0.00..2586.29 rows=7 width=56) Hash Cond: (t1.b = t3.b) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1293.15 rows=3 width=28) - -> Hash Right Join (cost=0.00..1293.15 rows=1 width=28) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1293.14 rows=3 width=28) + -> Hash Right Join (cost=0.00..1293.14 rows=1 width=28) Hash Cond: (t2.a = t1.a) -> Seq Scan on t2 (cost=0.00..431.01 rows=333 width=8) -> Hash (cost=862.07..862.07 rows=1 width=20) @@ -753,11 +751,11 @@ explain select * from (select t1.a t1a, t1.b t1b, t2.a t2a, t2.b t2b from t1 lef -> Hash (cost=431.00..431.00 rows=2 width=12) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=2 width=12) -> Seq Scan on t3 t3_1 (cost=0.00..431.00 rows=1 width=12) - -> Hash (cost=1293.15..1293.15 rows=3 width=28) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..1293.15 rows=3 width=28) - -> Result (cost=0.00..1293.15 rows=1 width=28) + -> Hash (cost=1293.14..1293.14 rows=3 width=28) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..1293.14 rows=3 width=28) + -> Result (cost=0.00..1293.14 rows=1 width=28) Filter: ((t2_1.a IS NULL) OR (t1_1.b = t3.b)) - -> Hash Right Join (cost=0.00..1293.15 rows=1 width=28) + -> Hash Right Join (cost=0.00..1293.14 rows=1 width=28) Hash Cond: (t2_1.a = t1_1.a) -> Seq Scan on t2 t2_1 (cost=0.00..431.01 rows=333 width=8) -> Hash (cost=862.07..862.07 rows=1 width=20) @@ -776,10 +774,10 @@ select * from (select t1.a t1a, t1.b t1b, t2.a t2a, t2.b t2b from t1 left join t join t3 t3_1 on tt1.t1b = t3_1.b and (tt1.t2a is NULL OR tt1.t1b = t3.b); t1a | t1b | t2a | t2b | a | b | c | t1a | t1b | t2a | t2b | a | b | c -----+-----+-----+-----+---+---+---+-----+-----+-----+-----+---+---+--- - 2 | 2 | 2 | 2 | | 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 - 2 | 2 | 2 | 2 | | 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 2 | 2 | 2 | 2 | 1 | 2 | 3 | 2 | 2 | 2 | 2 | 1 | 2 | 3 + 2 | 2 | 2 | 2 | | 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 2 | 2 | 2 | 2 | 1 | 2 | 3 | 2 | 2 | 2 | 2 | | 2 | 2 + 2 | 2 | 2 | 2 | | 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 (4 rows) -- test different join order enumeration methods @@ -819,8 +817,8 @@ reset optimizer_join_order; select * from t1 join t2 on t1.a = t2.a join t3 on t1.b = t3.b; a | b | c | a | b | c | a | b | c ---+---+---+---+---+---+---+---+--- - 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 + 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 (2 rows) drop table t1, t2, t3; @@ -848,15 +846,15 @@ set enable_bitmapscan = 0; explain select tenk1.unique2 >= 0 from tenk1 left join tenk2 on true limit 1; QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Limit (cost=0.00..1885524.86 rows=1 width=1) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1885524.86 rows=1 width=1) - -> Limit (cost=0.00..1885524.86 rows=1 width=1) - -> Nested Loop Left Join (cost=0.00..1885491.53 rows=33336667 width=4) + Limit (cost=0.00..1885464.79 rows=1 width=1) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1885464.79 rows=1 width=1) + -> Limit (cost=0.00..1885464.79 rows=1 width=1) + -> Nested Loop Left Join (cost=0.00..1885431.45 rows=33336667 width=4) Join Filter: true - -> Seq Scan on tenk1 (cost=0.00..431.51 rows=3334 width=4) - -> Materialize (cost=0.00..431.70 rows=10000 width=1) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.69 rows=10000 width=1) - -> Seq Scan on tenk2 (cost=0.00..431.51 rows=3334 width=1) + -> Seq Scan on tenk1 (cost=0.00..431.48 rows=3334 width=4) + -> Materialize (cost=0.00..431.68 rows=10000 width=1) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.67 rows=10000 width=1) + -> Seq Scan on tenk2 (cost=0.00..431.48 rows=3334 width=1) Optimizer: GPORCA (10 rows) @@ -913,7 +911,7 @@ explain select * from generate_series(1, 5) g left join trep_join_gp on g = trep -> Materialize (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on thash_join_gp (cost=0.00..1.01 rows=1 width=8) Optimizer: Postgres query optimizer -(9 rows) +(10 rows) select * from generate_series(1, 5) g left join trep_join_gp on g = trep_join_gp.c1 join thash_join_gp on true; g | c1 | c2 | c1 | c2 @@ -950,11 +948,11 @@ explain select * from generate_series(1, 5) g left join thash_join_gp on g = tha select * from generate_series(1, 5) g left join thash_join_gp on g = thash_join_gp.c1; g | c1 | c2 ---+----+---- + 1 | 1 | 1 2 | 2 | 2 - 3 | | 4 | | + 3 | | 5 | | - 1 | 1 | 1 (5 rows) explain select * from generate_series(1, 5) g left join thash_join_gp on g = thash_join_gp.c2; @@ -976,11 +974,11 @@ explain select * from generate_series(1, 5) g left join thash_join_gp on g = tha select * from generate_series(1, 5) g left join thash_join_gp on g = thash_join_gp.c2; g | c1 | c2 ---+----+---- - 2 | 2 | 2 - 3 | | - 4 | | 1 | 1 | 1 5 | | + 2 | 2 | 2 + 4 | | + 3 | | (5 rows) explain select * from generate_series(1, 5) g left join trand_join_gp on g = trand_join_gp.c1; @@ -1002,10 +1000,10 @@ explain select * from generate_series(1, 5) g left join trand_join_gp on g = tra select * from generate_series(1, 5) g left join trand_join_gp on g = trand_join_gp.c1; g | c1 | c2 ---+----+---- - 1 | | + 4 | | 2 | | 3 | | - 4 | | + 1 | | 5 | | (5 rows) @@ -1029,10 +1027,10 @@ select * from generate_series(1, 5) g full join trand_join_gp on g = trand_join_ g | c1 | c2 ---+----+---- 1 | | + 5 | | + 4 | | 2 | | 3 | | - 4 | | - 5 | | (5 rows) -- The following 3 tests are to check that segmentGeneral left join partition @@ -1056,23 +1054,23 @@ explain select * from trep_join_gp left join thash_join_gp using (c1); select * from trep_join_gp left join thash_join_gp using (c1); c1 | c2 | c2 ----+----+---- - 1 | 1 | 1 2 | 2 | 2 + 1 | 1 | 1 (2 rows) explain select * from trep_join_gp left join trand_join_gp using (c1); QUERY PLAN ---------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=1.03..2.13 rows=4 width=12) - -> Hash Left Join (cost=1.03..2.13 rows=2 width=12) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.04..2.15 rows=3 width=12) + -> Hash Left Join (cost=1.04..2.11 rows=1 width=12) Hash Cond: (trep_join_gp.c1 = trand_join_gp.c1) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=0.00..1.06 rows=2 width=8) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=0.00..1.05 rows=1 width=8) Hash Key: trep_join_gp.c1 -> Seq Scan on trep_join_gp (cost=0.00..1.02 rows=2 width=8) - -> Hash (cost=1.02..1.02 rows=1 width=8) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.02 rows=1 width=8) + -> Hash (cost=1.03..1.03 rows=1 width=8) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.03 rows=1 width=8) Hash Key: trand_join_gp.c1 - -> Seq Scan on trand_join_gp (cost=0.00..1.00 rows=1 width=8) + -> Seq Scan on trand_join_gp (cost=0.00..1.01 rows=1 width=8) Optimizer: Postgres query optimizer (11 rows) @@ -1142,10 +1140,10 @@ analyze t_joinsize_3; explain select * from (t_joinsize_1 join t_joinsize_2 on t_joinsize_1.c2 = t_joinsize_2.c2) join t_joinsize_3 on t_joinsize_3.c = t_joinsize_1.c1; QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Hash Join (cost=0.00..1300.54 rows=99503 width=20) + Hash Join (cost=0.00..1300.53 rows=99503 width=20) Hash Cond: (t_joinsize_2.c2 = t_joinsize_1.c2) -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.04 rows=1000 width=8) - -> Seq Scan on t_joinsize_2 (cost=0.00..431.01 rows=334 width=8) + -> Seq Scan on t_joinsize_2 (cost=0.00..431.00 rows=334 width=8) -> Hash (cost=862.13..862.13 rows=598 width=12) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..862.13 rows=598 width=12) -> Hash Join (cost=0.00..862.10 rows=200 width=12) @@ -1188,7 +1186,7 @@ join t_randomly_dist_table on t_subquery_general.a = t_randomly_dist_table.c; -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) Hash Key: t_randomly_dist_table.c -> Seq Scan on t_randomly_dist_table (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) version 3.77.0 + Optimizer: GPORCA (13 rows) drop table t_randomly_dist_table; @@ -1211,19 +1209,19 @@ insert into t2_lateral_limit values (2, 2); insert into t2_lateral_limit values (3, 3); explain select * from t1_lateral_limit as t1 cross join lateral (select ((c).x+t2.b) as n from t2_lateral_limit as t2 order by n limit 1)s; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Nested Loop (cost=10000000001.06..10000000002.12 rows=4 width=41) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=37) - -> Seq Scan on t1_lateral_limit t1 (cost=0.00..1.01 rows=1 width=37) - -> Materialize (cost=1.06..1.08 rows=1 width=4) - -> Limit (cost=1.06..1.06 rows=1 width=4) - -> Sort (cost=1.06..1.06 rows=1 width=4) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------- + Nested Loop (cost=10000003406.25..10159073271.08 rows=46700 width=44) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..812.33 rows=46700 width=40) + -> Seq Scan on t1_lateral_limit t1 (cost=0.00..189.67 rows=15567 width=40) + -> Materialize (cost=3406.25..3406.26 rows=1 width=4) + -> Limit (cost=3406.25..3406.25 rows=1 width=4) + -> Sort (cost=3406.25..3621.50 rows=86100 width=4) Sort Key: (((t1.c).x + t2.b)) - -> Result (cost=0.00..1.05 rows=1 width=4) - -> Materialize (cost=0.00..1.03 rows=1 width=4) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=4) - -> Seq Scan on t2_lateral_limit t2 (cost=0.00..1.01 rows=1 width=4) + -> Result (cost=0.00..2975.75 rows=86100 width=4) + -> Materialize (cost=0.00..1899.50 rows=86100 width=4) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1469.00 rows=86100 width=4) + -> Seq Scan on t2_lateral_limit t2 (cost=0.00..321.00 rows=28700 width=4) Optimizer: Postgres query optimizer (12 rows) @@ -1276,18 +1274,18 @@ select * from t1_lateral_limit as t1 cross join lateral -- may add motions in the subquery's plan). explain select * from t1_lateral_limit t1 cross join lateral (select (c).x+t2.a, sum(t2.a+t2.b) from t2_lateral_limit t2 group by (c).x+t2.a)x; - QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Nested Loop (cost=10000000001.06..10000000002.12 rows=4 width=49) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=37) - -> Seq Scan on t1_lateral_limit t1 (cost=0.00..1.01 rows=1 width=37) - -> Materialize (cost=1.05..1.08 rows=1 width=12) - -> HashAggregate (cost=1.05..1.07 rows=1 width=12) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Nested Loop (cost=10000003621.50..10170175612.33 rows=46700000 width=52) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..812.33 rows=46700 width=40) + -> Seq Scan on t1_lateral_limit t1 (cost=0.00..189.67 rows=15567 width=40) + -> Materialize (cost=3621.50..3639.00 rows=1000 width=12) + -> HashAggregate (cost=3621.50..3634.00 rows=1000 width=12) Group Key: ((t1.c).x + t2.a) - -> Result (cost=0.00..1.05 rows=1 width=12) - -> Materialize (cost=0.00..1.03 rows=1 width=8) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=8) - -> Seq Scan on t2_lateral_limit t2 (cost=0.00..1.01 rows=1 width=8) + -> Result (cost=0.00..2975.75 rows=86100 width=12) + -> Materialize (cost=0.00..1899.50 rows=86100 width=8) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1469.00 rows=86100 width=8) + -> Seq Scan on t2_lateral_limit t2 (cost=0.00..321.00 rows=28700 width=8) Optimizer: Postgres query optimizer (11 rows) @@ -1295,8 +1293,8 @@ select * from t1_lateral_limit t1 cross join lateral (select (c).x+t2.a, sum(t2.a+t2.b) from t2_lateral_limit t2 group by (c).x+t2.a)x; a | b | c | ?column? | sum ---+---+-------+----------+----- - 1 | 1 | (1,1) | 4 | 6 1 | 1 | (1,1) | 3 | 4 + 1 | 1 | (1,1) | 4 | 6 1 | 2 | (2,2) | 5 | 6 1 | 2 | (2,2) | 4 | 4 (4 rows) @@ -1423,7 +1421,7 @@ select box(point(0.05*i, 0.05*i), point(0.05*i, 0.05*i)), from generate_series(0,10000) as i; vacuum analyze gist_tbl_github9733; create index gist_tbl_point_index_github9733 on gist_tbl_github9733 using gist (p); -ERROR: pax only support btree/hash/gin/bitmap indexes (pax_access_handle.cc:###) +ERROR: pax only support btree/hash/gin/bitmap indexes (pax_access_handle.cc:588) set enable_seqscan=off; set enable_bitmapscan=off; explain (costs off) @@ -1494,7 +1492,9 @@ reset enable_bitmapscan; --- Test that GUC enable_hashagg takes effect for SEMI join --- drop table if exists foo; +NOTICE: table "foo" does not exist, skipping drop table if exists bar; +NOTICE: table "bar" does not exist, skipping create table foo(a int) distributed by (a); create table bar(b int) distributed by (b); insert into foo select i from generate_series(1,10)i; @@ -1504,59 +1504,59 @@ analyze bar; set enable_hashagg to on; explain (costs off) select * from foo where exists (select 1 from bar where foo.a = bar.b); - QUERY PLAN ------------------------------------------- + QUERY PLAN +----------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join + -> Hash Right Semi Join Hash Cond: (foo.a = bar.b) - -> Seq Scan on foo - Filter: (NOT (a IS NULL)) + -> Seq Scan on bar -> Hash - -> Seq Scan on bar + -> Seq Scan on foo + Filter: (NOT (a IS NULL)) Optimizer: GPORCA (8 rows) select * from foo where exists (select 1 from bar where foo.a = bar.b); a ---- - 10 + 1 + 5 + 6 9 + 10 + 2 3 - 7 4 - 5 + 7 8 - 1 - 2 - 6 (10 rows) set enable_hashagg to off; explain (costs off) select * from foo where exists (select 1 from bar where foo.a = bar.b); - QUERY PLAN ------------------------------------------- + QUERY PLAN +----------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join + -> Hash Right Semi Join Hash Cond: (foo.a = bar.b) - -> Seq Scan on foo - Filter: (NOT (a IS NULL)) + -> Seq Scan on bar -> Hash - -> Seq Scan on bar + -> Seq Scan on foo + Filter: (NOT (a IS NULL)) Optimizer: GPORCA (8 rows) select * from foo where exists (select 1 from bar where foo.a = bar.b); a ---- - 1 2 3 4 - 5 - 6 7 8 + 1 + 5 + 6 9 10 (10 rows) @@ -1599,8 +1599,8 @@ select * from fix_param_a left join fix_param_b on -> Seq Scan on fix_param_c -> Hash -> Seq Scan on fix_param_a - Optimizer: Pivotal Optimizer (GPORCA) -(14 rows) + Optimizer: GPORCA +(15 rows) select * from fix_param_a left join fix_param_b on fix_param_a.i = fix_param_b.i and fix_param_b.j in @@ -1656,18 +1656,18 @@ on (coalesce(t.id1) = tq_all.id1 and t.id2 = tq_all.id2) ; -----+-----+-----+-----+-----+----- 2 | 2 | 2 | 2 | 2 | 2 2 | | | | | - | 1 | | | | | 2 | | | | - | | | 2 | | - | | | 1 | | - | | 2 | | | + 1 | | | | | | | 1 | | | - | | | | | 2 - | | | | | 1 + | | 2 | | | + | | | 2 | | + | | | | 1 | | | | | 2 | + | | | | | 2 + | 1 | | | | 1 | 1 | 1 | 1 | 1 | 1 - 1 | | | | | - | | | | 1 | + | | | 1 | | + | | | | | 1 (14 rows) drop table t_issue_10315; @@ -1714,8 +1714,8 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on fooJoinPruning.c=barJoinPruning.p where fooJoinPruning.b>300 and fooJoinPruning.c > ANY (select barJoinPruning.q from barJoinPruning ); QUERY PLAN ----------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.22 rows=1 width=12) - -> Seq Scan on foojoinpruning (cost=0.00..1324032.22 rows=1 width=12) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.21 rows=1 width=12) + -> Seq Scan on foojoinpruning (cost=0.00..1324032.21 rows=1 width=12) Filter: ((b > 300) AND (SubPlan 1)) SubPlan 1 -> Materialize (cost=0.00..431.00 rows=1 width=4) @@ -1728,8 +1728,8 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on fooJoinPruning.c=barJoinPruning.p where fooJoinPruning.b in (select fooJoinPruning.a from barJoinPruning); QUERY PLAN ------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.19 rows=1 width=12) - -> Nested Loop Semi Join (cost=0.00..1324032.19 rows=1 width=12) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.18 rows=1 width=12) + -> Nested Loop Semi Join (cost=0.00..1324032.18 rows=1 width=12) Join Filter: true -> Seq Scan on foojoinpruning (cost=0.00..431.00 rows=1 width=12) Filter: (b = a) @@ -1812,8 +1812,8 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on fooJoinPruning.g=barJoinPruning.p and fooJoinPruning.a=barJoinPruning.q where fooJoinPruning.c > ANY (select barJoinPruning.t from barJoinPruning ); QUERY PLAN ----------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.25 rows=1 width=28) - -> Seq Scan on foojoinpruning (cost=0.00..1324032.25 rows=1 width=28) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.24 rows=1 width=28) + -> Seq Scan on foojoinpruning (cost=0.00..1324032.24 rows=1 width=28) Filter: (SubPlan 1) SubPlan 1 -> Materialize (cost=0.00..431.00 rows=1 width=4) @@ -1826,8 +1826,8 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on fooJoinPruning.g=barJoinPruning.p and fooJoinPruning.a=barJoinPruning.q where fooJoinPruning.e in (select fooJoinPruning.f from barJoinPruning); QUERY PLAN ------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.17 rows=1 width=28) - -> Nested Loop Semi Join (cost=0.00..1324032.17 rows=1 width=28) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.16 rows=1 width=28) + -> Nested Loop Semi Join (cost=0.00..1324032.16 rows=1 width=28) Join Filter: true -> Seq Scan on foojoinpruning (cost=0.00..431.00 rows=1 width=28) Filter: (e = f) @@ -1943,8 +1943,8 @@ explain select barJoinPruning.* from fooJoinPruning left join barJoinPruning on explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on barJoinPruning.p in (select fooJoinPruning.b from fooJoinPruning ) where fooJoinPruning.c>100; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1330181.79 rows=2 width=12) - -> Nested Loop Left Join (cost=0.00..1330181.79 rows=1 width=12) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1330181.78 rows=2 width=12) + -> Nested Loop Left Join (cost=0.00..1330181.78 rows=1 width=12) Join Filter: true -> Seq Scan on foojoinpruning foojoinpruning_1 (cost=0.00..431.00 rows=1 width=12) Filter: (c > 100) @@ -2031,8 +2031,8 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on fooJoinPruning.a=barJoinPruning.p and fooJoinPruning.c=barJoinPruning.r or fooJoinPruning.d=barJoinPruning.s; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324033.62 rows=1 width=28) - -> Nested Loop Left Join (cost=0.00..1324033.62 rows=1 width=28) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324033.60 rows=1 width=28) + -> Nested Loop Left Join (cost=0.00..1324033.60 rows=1 width=28) Join Filter: (((foojoinpruning.a = barjoinpruning.p) AND (foojoinpruning.c = barjoinpruning.r)) OR (foojoinpruning.d = barjoinpruning.s)) -> Seq Scan on foojoinpruning (cost=0.00..431.00 rows=1 width=28) -> Materialize (cost=0.00..431.00 rows=1 width=12) @@ -2044,8 +2044,8 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on fooJoinPruning.a=barJoinPruning.p or fooJoinPruning.b=barJoinPruning.q where fooJoinPruning.b>300; QUERY PLAN ------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324033.17 rows=1 width=28) - -> Nested Loop Left Join (cost=0.00..1324033.17 rows=1 width=28) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324033.15 rows=1 width=28) + -> Nested Loop Left Join (cost=0.00..1324033.15 rows=1 width=28) Join Filter: ((foojoinpruning.a = barjoinpruning.p) OR (foojoinpruning.b = barjoinpruning.q)) -> Seq Scan on foojoinpruning (cost=0.00..431.00 rows=1 width=28) Filter: (b > 300) @@ -2151,12 +2151,12 @@ select foo.b,foo.c from foo left join bar on foo.a=bar.a union select bar.b,bar.c from bar left join foo on foo.a=bar.a; b | c ---+---- - 1 | 10 - 2 | 20 - 3 | 2 | 30 | 3 | + 1 | 10 + 2 | 20 + 3 | (6 rows) -------------------------------------------------------------------------------- @@ -2181,6 +2181,9 @@ select bar.b,bar.c from bar left join foo on foo.a=bar.a; ---+---- 1 | 10 1 | 10 + 2 | 30 + | + 1 | 10 1 | 10 2 | 20 2 | 30 @@ -2188,9 +2191,6 @@ select bar.b,bar.c from bar left join foo on foo.a=bar.a; 2 | 20 | 3 | - 2 | 30 - | - 1 | 10 (12 rows) -------------------------------------------------------------------------------- @@ -2286,15 +2286,15 @@ select bar.b,bar.c from bar left join foo on foo.a=bar.a; Group Key: foo.b, foo.c -> Sort Sort Key: foo.b, foo.c - -> Hash Anti Join + -> Hash Right Anti Join Hash Cond: ((NOT (foo.b IS DISTINCT FROM bar.b)) AND (NOT (foo.c IS DISTINCT FROM bar.c))) -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: foo.b, foo.c - -> Seq Scan on foo + Hash Key: bar.b, bar.c + -> Seq Scan on bar -> Hash -> Redistribute Motion 3:3 (slice3; segments: 3) - Hash Key: bar.b, bar.c - -> Seq Scan on bar + Hash Key: foo.b, foo.c + -> Seq Scan on foo Optimizer: GPORCA (15 rows) @@ -2386,11 +2386,11 @@ select bar.b,foo.c from bar left join foo on foo.a=bar.a; 3 | 30 | 3 | - 2 | 10 1 | 10 1 | 30 2 | 20 | 20 + 2 | 10 (9 rows) -------------------------------------------------------------------------------- @@ -2419,6 +2419,9 @@ select foo.b,foo.c from foo left join bar on foo.a=bar.a union all select bar.b,foo.c from bar left join foo on foo.a=bar.a; b | c ---+---- + 2 | 30 + | + 1 | 30 1 | 10 1 | 10 1 | 10 @@ -2428,9 +2431,6 @@ select bar.b,foo.c from bar left join foo on foo.a=bar.a; 2 | 10 | 20 3 | 30 - 2 | 30 - | - 1 | 30 (12 rows) -------------------------------------------------------------------------------- @@ -2601,12 +2601,12 @@ select foo.b,foo.c from foo left join bar on foo.a=bar.a except all select bar.b,foo.c from bar left join foo on foo.a=bar.a; b | c ---+---- + 1 | 10 + 2 | 20 2 | 30 2 | 30 | 3 | - 1 | 10 - 2 | 20 (6 rows) drop table foo; @@ -2683,11 +2683,11 @@ explain (costs off) select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a; a1_pc | b1 | a | b -------+----+---+--- - 1 | 1 | 1 | 1 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 5 | 5 | 5 | 5 + 1 | 1 | 1 | 1 (5 rows) -- Outer table: Partitioned table, Join Condition on Partition key: No, Result: DPE - No @@ -2709,11 +2709,11 @@ explain (costs off) select * from bar_PT1 right join foo on bar_PT1.b1 =foo.a; select * from bar_PT1 right join foo on bar_PT1.b1 =foo.a; a1_pc | b1 | a | b -------+----+---+--- - 1 | 1 | 1 | 1 + 5 | 5 | 5 | 5 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 - 5 | 5 | 5 | 5 + 1 | 1 | 1 | 1 (5 rows) -- Outer,Inner table: Partitioned table, Join Condition on Partition key: Yes, Result: DPE - Yes @@ -2735,11 +2735,11 @@ explain (costs off) select * from bar_PT1 right join bar_PT3 on bar_PT1.a1_PC =b select * from bar_PT1 right join bar_PT3 on bar_PT1.a1_PC =bar_PT3.a3_PC; a1_pc | b1 | a3_pc | b3 -------+----+-------+---- - 5 | 5 | 5 | 5 1 | 1 | 1 | 1 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 + 5 | 5 | 5 | 5 (5 rows) -- Outer table: Not a Partitioned table, Join Condition on Partition key: Yes, Result: DPE - No @@ -2759,12 +2759,12 @@ explain (costs off) select * from foo right join bar_PT1 on foo.a=bar_PT1.a1_PC; select * from foo right join bar_PT1 on foo.a=bar_PT1.a1_PC; a | b | a1_pc | b1 ---+---+-------+---- - 1 | 1 | 1 | 1 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 | | 7 | 7 | | 8 | 8 + 1 | 1 | 1 | 1 5 | 5 | 5 | 5 | | 6 | 6 | | 9 | 9 @@ -2816,11 +2816,11 @@ explain (costs off) select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a and bar_PT1.b1 =foo.b; a1_pc | b1 | a | b -------+----+---+--- + 5 | 5 | 5 | 5 1 | 1 | 1 | 1 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 - 5 | 5 | 5 | 5 (5 rows) explain (costs off) select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a and foo.b>2; @@ -2841,10 +2841,10 @@ explain (costs off) select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a and foo.b>2; a1_pc | b1 | a | b -------+----+---+--- - | | 1 | 1 3 | 3 | 3 | 3 4 | 4 | 4 | 4 | | 2 | 2 + | | 1 | 1 5 | 5 | 5 | 5 (5 rows) @@ -2875,17 +2875,17 @@ explain (costs off) select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a right join bar_PT2 on bar_PT1.a1_PC =bar_PT2.b2_PC; a1_pc | b1 | a | b | a2 | b2_pc -------+----+---+---+----+------- - 2 | 2 | 2 | 2 | 2 | 2 - 3 | 3 | 3 | 3 | 3 | 3 - 4 | 4 | 4 | 4 | 4 | 4 - | | | | 7 | 7 - | | | | 8 | 8 1 | 1 | 1 | 1 | 1 | 1 5 | 5 | 5 | 5 | 5 | 5 | | | | 6 | 6 | | | | 9 | 9 | | | | 10 | 10 | | | | 11 | 11 + 2 | 2 | 2 | 2 | 2 | 2 + 3 | 3 | 3 | 3 | 3 | 3 + 4 | 4 | 4 | 4 | 4 | 4 + | | | | 7 | 7 + | | | | 8 | 8 (11 rows) -- FOR LIST PARTITIONED TABLE @@ -2907,10 +2907,10 @@ explain (costs off) select * from bar_List_PT1 right join foo on bar_List_PT1.a1 select * from bar_List_PT1 right join foo on bar_List_PT1.a1_PC =foo.a; a1_pc | b1 | a | b -------+----+---+--- - 1 | 1 | 1 | 1 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 + 1 | 1 | 1 | 1 5 | 5 | 5 | 5 (5 rows) @@ -2933,18 +2933,18 @@ explain (costs off) select * from bar_List_PT1 right join bar_List_PT2 on bar_Li select * from bar_List_PT1 right join bar_List_PT2 on bar_List_PT1.a1_PC =bar_List_PT2.a2_PC; a1_pc | b1 | a2_pc | b2 -------+----+-------+---- - 1 | 1 | 1 | 1 - 12 | 12 | 12 | 12 - 2 | 2 | 2 | 2 - 3 | 3 | 3 | 3 - 4 | 4 | 4 | 4 - 7 | 7 | 7 | 7 - 8 | 8 | 8 | 8 5 | 5 | 5 | 5 6 | 6 | 6 | 6 9 | 9 | 9 | 9 10 | 10 | 10 | 10 11 | 11 | 11 | 11 + 2 | 2 | 2 | 2 + 3 | 3 | 3 | 3 + 4 | 4 | 4 | 4 + 7 | 7 | 7 | 7 + 8 | 8 | 8 | 8 + 1 | 1 | 1 | 1 + 12 | 12 | 12 | 12 (12 rows) -- Case-2 : Distribution colm <> Partition Key. @@ -2967,11 +2967,11 @@ explain (costs off) select * from bar_PT2 right join foo on bar_PT2.b2_PC =foo.a select * from bar_PT2 right join foo on bar_PT2.b2_PC =foo.a; a2 | b2_pc | a | b ----+-------+---+--- - 5 | 5 | 5 | 5 + 1 | 1 | 1 | 1 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 - 1 | 1 | 1 | 1 + 5 | 5 | 5 | 5 (5 rows) -- Outer,Inner table: Partitioned table, Join Condition on Partition key: Yes, Result: DPE - No @@ -2996,17 +2996,17 @@ explain (costs off) select * from bar_PT2 right join bar_PT1 on bar_PT2.b2_PC =b select * from bar_PT2 right join bar_PT1 on bar_PT2.b2_PC =bar_PT1.b1; a2 | b2_pc | a1_pc | b1 ----+-------+-------+---- - 2 | 2 | 2 | 2 - 3 | 3 | 3 | 3 - 4 | 4 | 4 | 4 - 7 | 7 | 7 | 7 - 8 | 8 | 8 | 8 - 1 | 1 | 1 | 1 5 | 5 | 5 | 5 6 | 6 | 6 | 6 9 | 9 | 9 | 9 10 | 10 | 10 | 10 11 | 11 | 11 | 11 + 1 | 1 | 1 | 1 + 2 | 2 | 2 | 2 + 3 | 3 | 3 | 3 + 4 | 4 | 4 | 4 + 7 | 7 | 7 | 7 + 8 | 8 | 8 | 8 (11 rows) drop table if exists foo; @@ -3023,15 +3023,15 @@ INSERT INTO inverse values ('192.168.100.199'); explain SELECT 1 FROM inverse WHERE NOT (cidr <<= ANY(SELECT * FROM inverse)); QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Result (cost=0.00..1324032.93 rows=1 width=4) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.93 rows=1 width=1) - -> Result (cost=0.00..1324032.93 rows=1 width=1) + Result (cost=0.00..1324032.91 rows=1 width=4) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.91 rows=1 width=1) + -> Result (cost=0.00..1324032.91 rows=1 width=1) Filter: (NOT CASE WHEN ((count((true))) > '0'::bigint) THEN CASE WHEN ((sum((CASE WHEN ((inverse_1.cidr <<= inverse.cidr) IS NULL) THEN 1 ELSE 0 END))) = (count((true)))) THEN NULL::boolean ELSE true END ELSE false END) - -> GroupAggregate (cost=0.00..1324032.93 rows=1 width=16) + -> GroupAggregate (cost=0.00..1324032.91 rows=1 width=16) Group Key: inverse_1.cidr, inverse_1.ctid, inverse_1.gp_segment_id - -> Sort (cost=0.00..1324032.93 rows=1 width=23) + -> Sort (cost=0.00..1324032.91 rows=1 width=23) Sort Key: inverse_1.cidr, inverse_1.ctid, inverse_1.gp_segment_id - -> Nested Loop Left Join (cost=0.00..1324032.93 rows=1 width=27) + -> Nested Loop Left Join (cost=0.00..1324032.91 rows=1 width=27) Join Filter: ((inverse_1.cidr <<= inverse.cidr) IS NOT FALSE) -> Seq Scan on inverse inverse_1 (cost=0.00..431.00 rows=1 width=18) -> Materialize (cost=0.00..431.00 rows=1 width=9) @@ -3063,8 +3063,8 @@ set enable_nestloop to on; explain select * from foo_varchar left join bar_char on foo_varchar.a=bar_char.p; QUERY PLAN --------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.83 rows=2 width=16) - -> Nested Loop Left Join (cost=0.00..1324032.83 rows=1 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.81 rows=2 width=16) + -> Nested Loop Left Join (cost=0.00..1324032.81 rows=1 width=16) Join Filter: ((foo_varchar.a)::bpchar = bar_char.p) -> Seq Scan on foo_varchar (cost=0.00..431.00 rows=1 width=8) -> Materialize (cost=0.00..431.00 rows=1 width=8) @@ -3076,9 +3076,9 @@ explain select * from foo_varchar left join bar_char on foo_varchar.a=bar_char.p select * from foo_varchar left join bar_char on foo_varchar.a=bar_char.p; a | p ------+------- - 2 | 2 1 | 1 3 | 3 + 2 | 2 (3 rows) -- There is a plan change (from redistribution to broadcast) because a NULL @@ -3087,8 +3087,8 @@ select * from foo_varchar left join bar_char on foo_varchar.a=bar_char.p; explain select * from foo_varchar left join random_dis_char on foo_varchar.a=random_dis_char.y; QUERY PLAN --------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.51 rows=2 width=16) - -> Nested Loop Left Join (cost=0.00..1324032.51 rows=1 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.50 rows=2 width=16) + -> Nested Loop Left Join (cost=0.00..1324032.50 rows=1 width=16) Join Filter: ((foo_varchar.a)::bpchar = random_dis_char.y) -> Seq Scan on foo_varchar (cost=0.00..431.00 rows=1 width=8) -> Materialize (cost=0.00..431.00 rows=1 width=8) @@ -3108,8 +3108,8 @@ select * from foo_varchar left join random_dis_char on foo_varchar.a=random_dis_ explain select * from bar_char left join random_dis_varchar on bar_char.p=random_dis_varchar.x; QUERY PLAN --------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.51 rows=2 width=16) - -> Nested Loop Left Join (cost=0.00..1324032.51 rows=1 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.50 rows=2 width=16) + -> Nested Loop Left Join (cost=0.00..1324032.50 rows=1 width=16) Join Filter: (bar_char.p = (random_dis_varchar.x)::bpchar) -> Seq Scan on bar_char (cost=0.00..431.00 rows=1 width=8) -> Materialize (cost=0.00..431.00 rows=1 width=8) @@ -3132,8 +3132,8 @@ select * from bar_char left join random_dis_varchar on bar_char.p=random_dis_var explain select * from foo_varchar inner join bar_char on foo_varchar.a=bar_char.p; QUERY PLAN --------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.79 rows=1 width=16) - -> Nested Loop (cost=0.00..1324032.79 rows=1 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.78 rows=1 width=16) + -> Nested Loop (cost=0.00..1324032.78 rows=1 width=16) Join Filter: ((foo_varchar.a)::bpchar = bar_char.p) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on foo_varchar (cost=0.00..431.00 rows=1 width=8) @@ -3144,9 +3144,9 @@ explain select * from foo_varchar inner join bar_char on foo_varchar.a=bar_char. select * from foo_varchar inner join bar_char on foo_varchar.a=bar_char.p; a | p ------+------- - 1 | 1 2 | 2 3 | 3 + 1 | 1 (3 rows) -- There is a plan change (from redistribution to broadcast) because a NULL @@ -3155,8 +3155,8 @@ select * from foo_varchar inner join bar_char on foo_varchar.a=bar_char.p; explain select * from foo_varchar inner join random_dis_char on foo_varchar.a=random_dis_char.y; QUERY PLAN --------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.48 rows=1 width=16) - -> Nested Loop (cost=0.00..1324032.48 rows=1 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.46 rows=1 width=16) + -> Nested Loop (cost=0.00..1324032.46 rows=1 width=16) Join Filter: ((foo_varchar.a)::bpchar = random_dis_char.y) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on random_dis_char (cost=0.00..431.00 rows=1 width=8) @@ -3168,15 +3168,15 @@ select * from foo_varchar inner join random_dis_char on foo_varchar.a=random_dis a | y ------+------- 2 | 2 - 3 | 3 1 | 1 + 3 | 3 (3 rows) explain select * from bar_char inner join random_dis_varchar on bar_char.p=random_dis_varchar.x; QUERY PLAN --------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.48 rows=1 width=16) - -> Nested Loop (cost=0.00..1324032.48 rows=1 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.46 rows=1 width=16) + -> Nested Loop (cost=0.00..1324032.46 rows=1 width=16) Join Filter: (bar_char.p = (random_dis_varchar.x)::bpchar) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on random_dis_varchar (cost=0.00..431.00 rows=1 width=8) @@ -3188,8 +3188,8 @@ select * from bar_char inner join random_dis_varchar on bar_char.p=random_dis_va p | x -------+------ 1 | 1 - 2 | 2 3 | 3 + 2 | 2 (3 rows) drop table foo_varchar; @@ -3309,10 +3309,10 @@ select * from dist_t1 where exists ( select 1 from repli_t1 where repli_t1.a >= a | b ---+--- 1 | 1 - 5 | 1 2 | 1 3 | 1 4 | 1 + 5 | 1 (5 rows) -- Both replicated table @@ -3377,10 +3377,10 @@ select * from dist_t1 where exists ( select 1 from generate_series(1, 5) univ_t a | b ---+--- 1 | 1 + 5 | 1 2 | 1 3 | 1 4 | 1 - 5 | 1 (5 rows) -- Outer - replicated, Inner - universal table diff --git a/contrib/pax_storage/src/test/regress/expected/join_optimizer.out b/contrib/pax_storage/src/test/regress/expected/join_optimizer.out index 8dc204ae381..cbbfaff55f0 100644 --- a/contrib/pax_storage/src/test/regress/expected/join_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/join_optimizer.out @@ -50,14 +50,14 @@ SELECT * i | j | t ---+---+------- 1 | 4 | one + 0 | | zero + 5 | 0 | five + 6 | 6 | six 2 | 3 | two 3 | 2 | three 4 | 1 | four - 5 | 0 | five - 6 | 6 | six 7 | 7 | seven 8 | 8 | eight - 0 | | zero | | null | 0 | zero (11 rows) @@ -66,15 +66,15 @@ SELECT * FROM J1_TBL tx; i | j | t ---+---+------- + 5 | 0 | five + 6 | 6 | six 1 | 4 | one + 0 | | zero 2 | 3 | two 3 | 2 | three 4 | 1 | four - 5 | 0 | five - 6 | 6 | six 7 | 7 | seven 8 | 8 | eight - 0 | | zero | | null | 0 | zero (11 rows) @@ -83,15 +83,15 @@ SELECT * FROM J1_TBL AS t1 (a, b, c); a | b | c ---+---+------- + 5 | 0 | five + 6 | 6 | six 1 | 4 | one + 0 | | zero 2 | 3 | two 3 | 2 | three 4 | 1 | four - 5 | 0 | five - 6 | 6 | six 7 | 7 | seven 8 | 8 | eight - 0 | | zero | | null | 0 | zero (11 rows) @@ -100,122 +100,122 @@ SELECT * FROM J1_TBL t1 (a, b, c); a | b | c ---+---+------- - 1 | 4 | one + 5 | 0 | five + 6 | 6 | six 2 | 3 | two 3 | 2 | three 4 | 1 | four - 5 | 0 | five - 6 | 6 | six 7 | 7 | seven 8 | 8 | eight - 0 | | zero | | null | 0 | zero + 1 | 4 | one + 0 | | zero (11 rows) SELECT * FROM J1_TBL t1 (a, b, c), J2_TBL t2 (d, e); a | b | c | d | e ---+---+-------+---+---- - 1 | 4 | one | 1 | -1 + 2 | 3 | two | 5 | -5 + 2 | 3 | two | 5 | -5 + 2 | 3 | two | 2 | 2 + 2 | 3 | two | 3 | -3 + 2 | 3 | two | 2 | 4 + 2 | 3 | two | | + 2 | 3 | two | | 0 2 | 3 | two | 1 | -1 + 2 | 3 | two | 0 | + 3 | 2 | three | 5 | -5 + 3 | 2 | three | 5 | -5 + 3 | 2 | three | 2 | 2 + 3 | 2 | three | 3 | -3 + 3 | 2 | three | 2 | 4 + 3 | 2 | three | | + 3 | 2 | three | | 0 3 | 2 | three | 1 | -1 + 3 | 2 | three | 0 | + 4 | 1 | four | 5 | -5 + 4 | 1 | four | 5 | -5 + 4 | 1 | four | 2 | 2 + 4 | 1 | four | 3 | -3 + 4 | 1 | four | 2 | 4 + 4 | 1 | four | | + 4 | 1 | four | | 0 4 | 1 | four | 1 | -1 - 5 | 0 | five | 1 | -1 - 6 | 6 | six | 1 | -1 + 4 | 1 | four | 0 | + 7 | 7 | seven | 5 | -5 + 7 | 7 | seven | 5 | -5 + 7 | 7 | seven | 2 | 2 + 7 | 7 | seven | 3 | -3 + 7 | 7 | seven | 2 | 4 + 7 | 7 | seven | | + 7 | 7 | seven | | 0 7 | 7 | seven | 1 | -1 + 7 | 7 | seven | 0 | + 8 | 8 | eight | 5 | -5 + 8 | 8 | eight | 5 | -5 + 8 | 8 | eight | 2 | 2 + 8 | 8 | eight | 3 | -3 + 8 | 8 | eight | 2 | 4 + 8 | 8 | eight | | + 8 | 8 | eight | | 0 8 | 8 | eight | 1 | -1 - 0 | | zero | 1 | -1 + 8 | 8 | eight | 0 | + | | null | 5 | -5 + | | null | 5 | -5 + | | null | 2 | 2 + | | null | 3 | -3 + | | null | 2 | 4 + | | null | | + | | null | | 0 | | null | 1 | -1 + | | null | 0 | + | 0 | zero | 5 | -5 + | 0 | zero | 5 | -5 + | 0 | zero | 2 | 2 + | 0 | zero | 3 | -3 + | 0 | zero | 2 | 4 + | 0 | zero | | + | 0 | zero | | 0 | 0 | zero | 1 | -1 - 1 | 4 | one | 2 | 2 - 2 | 3 | two | 2 | 2 - 3 | 2 | three | 2 | 2 - 4 | 1 | four | 2 | 2 + | 0 | zero | 0 | + 5 | 0 | five | 5 | -5 + 5 | 0 | five | 5 | -5 5 | 0 | five | 2 | 2 - 6 | 6 | six | 2 | 2 - 7 | 7 | seven | 2 | 2 - 8 | 8 | eight | 2 | 2 - 0 | | zero | 2 | 2 - | | null | 2 | 2 - | 0 | zero | 2 | 2 - 1 | 4 | one | 3 | -3 - 2 | 3 | two | 3 | -3 - 3 | 2 | three | 3 | -3 - 4 | 1 | four | 3 | -3 5 | 0 | five | 3 | -3 - 6 | 6 | six | 3 | -3 - 7 | 7 | seven | 3 | -3 - 8 | 8 | eight | 3 | -3 - 0 | | zero | 3 | -3 - | | null | 3 | -3 - | 0 | zero | 3 | -3 - 1 | 4 | one | 2 | 4 - 2 | 3 | two | 2 | 4 - 3 | 2 | three | 2 | 4 - 4 | 1 | four | 2 | 4 5 | 0 | five | 2 | 4 + 5 | 0 | five | | + 5 | 0 | five | | 0 + 5 | 0 | five | 1 | -1 + 5 | 0 | five | 0 | + 6 | 6 | six | 5 | -5 + 6 | 6 | six | 5 | -5 + 6 | 6 | six | 2 | 2 + 6 | 6 | six | 3 | -3 6 | 6 | six | 2 | 4 - 7 | 7 | seven | 2 | 4 - 8 | 8 | eight | 2 | 4 - 0 | | zero | 2 | 4 - | | null | 2 | 4 - | 0 | zero | 2 | 4 + 6 | 6 | six | | + 6 | 6 | six | | 0 + 6 | 6 | six | 1 | -1 + 6 | 6 | six | 0 | 1 | 4 | one | 5 | -5 - 2 | 3 | two | 5 | -5 - 3 | 2 | three | 5 | -5 - 4 | 1 | four | 5 | -5 - 5 | 0 | five | 5 | -5 - 6 | 6 | six | 5 | -5 - 7 | 7 | seven | 5 | -5 - 8 | 8 | eight | 5 | -5 - 0 | | zero | 5 | -5 - | | null | 5 | -5 - | 0 | zero | 5 | -5 1 | 4 | one | 5 | -5 - 2 | 3 | two | 5 | -5 - 3 | 2 | three | 5 | -5 - 4 | 1 | four | 5 | -5 - 5 | 0 | five | 5 | -5 - 6 | 6 | six | 5 | -5 - 7 | 7 | seven | 5 | -5 - 8 | 8 | eight | 5 | -5 - 0 | | zero | 5 | -5 - | | null | 5 | -5 - | 0 | zero | 5 | -5 + 1 | 4 | one | 1 | -1 1 | 4 | one | 0 | - 2 | 3 | two | 0 | - 3 | 2 | three | 0 | - 4 | 1 | four | 0 | - 5 | 0 | five | 0 | - 6 | 6 | six | 0 | - 7 | 7 | seven | 0 | - 8 | 8 | eight | 0 | - 0 | | zero | 0 | - | | null | 0 | - | 0 | zero | 0 | + 1 | 4 | one | 2 | 2 + 1 | 4 | one | 3 | -3 + 1 | 4 | one | 2 | 4 1 | 4 | one | | - 2 | 3 | two | | - 3 | 2 | three | | - 4 | 1 | four | | - 5 | 0 | five | | - 6 | 6 | six | | - 7 | 7 | seven | | - 8 | 8 | eight | | - 0 | | zero | | - | | null | | - | 0 | zero | | 1 | 4 | one | | 0 - 2 | 3 | two | | 0 - 3 | 2 | three | | 0 - 4 | 1 | four | | 0 - 5 | 0 | five | | 0 - 6 | 6 | six | | 0 - 7 | 7 | seven | | 0 - 8 | 8 | eight | | 0 + 0 | | zero | 5 | -5 + 0 | | zero | 5 | -5 + 0 | | zero | 1 | -1 + 0 | | zero | 0 | + 0 | | zero | 2 | 2 + 0 | | zero | 3 | -3 + 0 | | zero | 2 | 4 + 0 | | zero | | 0 | | zero | | 0 - | | null | | 0 - | 0 | zero | | 0 (99 rows) SELECT t1.a, t2.e @@ -223,13 +223,13 @@ SELECT t1.a, t2.e WHERE t1.a = t2.d; a | e ---+---- - 0 | + 5 | -5 + 5 | -5 1 | -1 + 0 | 2 | 2 - 2 | 4 3 | -3 - 5 | -5 - 5 | -5 + 2 | 4 (7 rows) -- @@ -241,105 +241,105 @@ SELECT * FROM J1_TBL CROSS JOIN J2_TBL; i | j | t | i | k ---+---+-------+---+---- - 1 | 4 | one | 1 | -1 - 2 | 3 | two | 1 | -1 - 3 | 2 | three | 1 | -1 - 4 | 1 | four | 1 | -1 - 5 | 0 | five | 1 | -1 - 6 | 6 | six | 1 | -1 - 7 | 7 | seven | 1 | -1 - 8 | 8 | eight | 1 | -1 - 0 | | zero | 1 | -1 - | | null | 1 | -1 - | 0 | zero | 1 | -1 - 1 | 4 | one | 2 | 2 + 2 | 3 | two | 5 | -5 + 2 | 3 | two | 5 | -5 2 | 3 | two | 2 | 2 - 3 | 2 | three | 2 | 2 - 4 | 1 | four | 2 | 2 - 5 | 0 | five | 2 | 2 - 6 | 6 | six | 2 | 2 - 7 | 7 | seven | 2 | 2 - 8 | 8 | eight | 2 | 2 - 0 | | zero | 2 | 2 - | | null | 2 | 2 - | 0 | zero | 2 | 2 - 1 | 4 | one | 3 | -3 2 | 3 | two | 3 | -3 + 2 | 3 | two | 2 | 4 + 2 | 3 | two | | + 2 | 3 | two | | 0 + 2 | 3 | two | 1 | -1 + 2 | 3 | two | 0 | + 3 | 2 | three | 5 | -5 + 3 | 2 | three | 5 | -5 + 3 | 2 | three | 2 | 2 3 | 2 | three | 3 | -3 + 3 | 2 | three | 2 | 4 + 3 | 2 | three | | + 3 | 2 | three | | 0 + 3 | 2 | three | 1 | -1 + 3 | 2 | three | 0 | + 4 | 1 | four | 5 | -5 + 4 | 1 | four | 5 | -5 + 4 | 1 | four | 2 | 2 4 | 1 | four | 3 | -3 - 5 | 0 | five | 3 | -3 - 6 | 6 | six | 3 | -3 + 4 | 1 | four | 2 | 4 + 4 | 1 | four | | + 4 | 1 | four | | 0 + 4 | 1 | four | 1 | -1 + 4 | 1 | four | 0 | + 7 | 7 | seven | 5 | -5 + 7 | 7 | seven | 5 | -5 + 7 | 7 | seven | 2 | 2 7 | 7 | seven | 3 | -3 + 7 | 7 | seven | 2 | 4 + 7 | 7 | seven | | + 7 | 7 | seven | | 0 + 7 | 7 | seven | 1 | -1 + 7 | 7 | seven | 0 | + 8 | 8 | eight | 5 | -5 + 8 | 8 | eight | 5 | -5 + 8 | 8 | eight | 2 | 2 8 | 8 | eight | 3 | -3 - 0 | | zero | 3 | -3 - | | null | 3 | -3 - | 0 | zero | 3 | -3 - 1 | 4 | one | 2 | 4 - 2 | 3 | two | 2 | 4 - 3 | 2 | three | 2 | 4 - 4 | 1 | four | 2 | 4 - 5 | 0 | five | 2 | 4 - 6 | 6 | six | 2 | 4 - 7 | 7 | seven | 2 | 4 8 | 8 | eight | 2 | 4 - 0 | | zero | 2 | 4 + 8 | 8 | eight | | + 8 | 8 | eight | | 0 + 8 | 8 | eight | 1 | -1 + 8 | 8 | eight | 0 | + | | null | 5 | -5 + | | null | 5 | -5 + | | null | 2 | 2 + | | null | 3 | -3 | | null | 2 | 4 + | | null | | + | | null | | 0 + | | null | 1 | -1 + | | null | 0 | + | 0 | zero | 5 | -5 + | 0 | zero | 5 | -5 + | 0 | zero | 2 | 2 + | 0 | zero | 3 | -3 | 0 | zero | 2 | 4 + | 0 | zero | | + | 0 | zero | | 0 + | 0 | zero | 1 | -1 + | 0 | zero | 0 | + 1 | 4 | one | 1 | -1 + 1 | 4 | one | 0 | 1 | 4 | one | 5 | -5 - 2 | 3 | two | 5 | -5 - 3 | 2 | three | 5 | -5 - 4 | 1 | four | 5 | -5 - 5 | 0 | five | 5 | -5 - 6 | 6 | six | 5 | -5 - 7 | 7 | seven | 5 | -5 - 8 | 8 | eight | 5 | -5 - 0 | | zero | 5 | -5 - | | null | 5 | -5 - | 0 | zero | 5 | -5 1 | 4 | one | 5 | -5 - 2 | 3 | two | 5 | -5 - 3 | 2 | three | 5 | -5 - 4 | 1 | four | 5 | -5 - 5 | 0 | five | 5 | -5 - 6 | 6 | six | 5 | -5 - 7 | 7 | seven | 5 | -5 - 8 | 8 | eight | 5 | -5 + 1 | 4 | one | 2 | 2 + 1 | 4 | one | 3 | -3 + 1 | 4 | one | 2 | 4 + 1 | 4 | one | | + 1 | 4 | one | | 0 + 0 | | zero | 1 | -1 + 0 | | zero | 0 | 0 | | zero | 5 | -5 - | | null | 5 | -5 - | 0 | zero | 5 | -5 - 1 | 4 | one | 0 | - 2 | 3 | two | 0 | - 3 | 2 | three | 0 | - 4 | 1 | four | 0 | + 0 | | zero | 5 | -5 + 0 | | zero | 2 | 2 + 0 | | zero | 3 | -3 + 0 | | zero | 2 | 4 + 0 | | zero | | + 0 | | zero | | 0 + 5 | 0 | five | 1 | -1 5 | 0 | five | 0 | - 6 | 6 | six | 0 | - 7 | 7 | seven | 0 | - 8 | 8 | eight | 0 | - 0 | | zero | 0 | - | | null | 0 | - | 0 | zero | 0 | - 1 | 4 | one | | - 2 | 3 | two | | - 3 | 2 | three | | - 4 | 1 | four | | + 5 | 0 | five | 5 | -5 + 5 | 0 | five | 5 | -5 + 5 | 0 | five | 2 | 2 + 5 | 0 | five | 3 | -3 + 5 | 0 | five | 2 | 4 5 | 0 | five | | - 6 | 6 | six | | - 7 | 7 | seven | | - 8 | 8 | eight | | - 0 | | zero | | - | | null | | - | 0 | zero | | - 1 | 4 | one | | 0 - 2 | 3 | two | | 0 - 3 | 2 | three | | 0 - 4 | 1 | four | | 0 5 | 0 | five | | 0 + 6 | 6 | six | 1 | -1 + 6 | 6 | six | 0 | + 6 | 6 | six | 5 | -5 + 6 | 6 | six | 5 | -5 + 6 | 6 | six | 2 | 2 + 6 | 6 | six | 3 | -3 + 6 | 6 | six | 2 | 4 + 6 | 6 | six | | 6 | 6 | six | | 0 - 7 | 7 | seven | | 0 - 8 | 8 | eight | | 0 - 0 | | zero | | 0 - | | null | | 0 - | 0 | zero | | 0 (99 rows) -- ambiguous column @@ -353,104 +353,104 @@ SELECT t1.i, k, t FROM J1_TBL t1 CROSS JOIN J2_TBL t2; i | k | t ---+----+------- - 1 | -1 | one - 2 | -1 | two - 3 | -1 | three - 4 | -1 | four + 5 | -5 | five + 5 | -5 | five 5 | -1 | five - 6 | -1 | six - 7 | -1 | seven - 8 | -1 | eight - 0 | -1 | zero - | -1 | null - | -1 | zero - 1 | 2 | one - 2 | 2 | two - 3 | 2 | three - 4 | 2 | four + 5 | | five 5 | 2 | five - 6 | 2 | six - 7 | 2 | seven - 8 | 2 | eight - 0 | 2 | zero - | 2 | null - | 2 | zero - 1 | -3 | one - 2 | -3 | two - 3 | -3 | three - 4 | -3 | four 5 | -3 | five - 6 | -3 | six - 7 | -3 | seven - 8 | -3 | eight - 0 | -3 | zero - | -3 | null - | -3 | zero - 1 | 4 | one - 2 | 4 | two - 3 | 4 | three - 4 | 4 | four 5 | 4 | five + 5 | | five + 5 | 0 | five + 6 | -5 | six + 6 | -5 | six + 6 | -1 | six + 6 | | six + 6 | 2 | six + 6 | -3 | six 6 | 4 | six - 7 | 4 | seven - 8 | 4 | eight - 0 | 4 | zero - | 4 | null - | 4 | zero + 6 | | six + 6 | 0 | six 1 | -5 | one - 2 | -5 | two - 3 | -5 | three - 4 | -5 | four - 5 | -5 | five - 6 | -5 | six - 7 | -5 | seven - 8 | -5 | eight - 0 | -5 | zero - | -5 | null - | -5 | zero 1 | -5 | one - 2 | -5 | two - 3 | -5 | three - 4 | -5 | four - 5 | -5 | five - 6 | -5 | six - 7 | -5 | seven - 8 | -5 | eight - 0 | -5 | zero - | -5 | null - | -5 | zero + 1 | -1 | one 1 | | one - 2 | | two - 3 | | three - 4 | | four - 5 | | five - 6 | | six - 7 | | seven - 8 | | eight - 0 | | zero - | | null - | | zero + 1 | 2 | one + 1 | -3 | one + 1 | 4 | one 1 | | one - 2 | | two - 3 | | three - 4 | | four - 5 | | five - 6 | | six - 7 | | seven - 8 | | eight - 0 | | zero - | | null - | | zero 1 | 0 | one + 0 | -5 | zero + 0 | -5 | zero + 0 | -1 | zero + 0 | | zero + 0 | 2 | zero + 0 | -3 | zero + 0 | 4 | zero + 0 | | zero + 0 | 0 | zero + 2 | -5 | two + 2 | -5 | two + 2 | -1 | two + 2 | | two + 2 | 2 | two + 2 | -3 | two + 2 | 4 | two + 2 | | two 2 | 0 | two + 3 | -5 | three + 3 | -5 | three + 3 | -1 | three + 3 | | three + 3 | 2 | three + 3 | -3 | three + 3 | 4 | three + 3 | | three 3 | 0 | three + 4 | -5 | four + 4 | -5 | four + 4 | -1 | four + 4 | | four + 4 | 2 | four + 4 | -3 | four + 4 | 4 | four + 4 | | four 4 | 0 | four - 5 | 0 | five - 6 | 0 | six + 7 | -5 | seven + 7 | -5 | seven + 7 | -1 | seven + 7 | | seven + 7 | 2 | seven + 7 | -3 | seven + 7 | 4 | seven + 7 | | seven 7 | 0 | seven + 8 | -5 | eight + 8 | -5 | eight + 8 | -1 | eight + 8 | | eight + 8 | 2 | eight + 8 | -3 | eight + 8 | 4 | eight + 8 | | eight 8 | 0 | eight - 0 | 0 | zero + | -5 | null + | -5 | null + | -1 | null + | | null + | 2 | null + | -3 | null + | 4 | null + | | null | 0 | null + | -5 | zero + | -5 | zero + | -1 | zero + | | zero + | 2 | zero + | -3 | zero + | 4 | zero + | | zero | 0 | zero (99 rows) @@ -459,104 +459,104 @@ SELECT ii, tt, kk AS tx (ii, jj, tt, ii2, kk); ii | tt | kk ----+-------+---- - 1 | one | -1 - 2 | two | -1 - 3 | three | -1 - 4 | four | -1 5 | five | -1 - 6 | six | -1 - 7 | seven | -1 - 8 | eight | -1 - 0 | zero | -1 - | null | -1 - | zero | -1 - 1 | one | 2 - 2 | two | 2 - 3 | three | 2 - 4 | four | 2 + 5 | five | + 5 | five | -5 + 5 | five | -5 5 | five | 2 - 6 | six | 2 - 7 | seven | 2 - 8 | eight | 2 - 0 | zero | 2 - | null | 2 - | zero | 2 - 1 | one | -3 - 2 | two | -3 - 3 | three | -3 - 4 | four | -3 5 | five | -3 - 6 | six | -3 - 7 | seven | -3 - 8 | eight | -3 - 0 | zero | -3 - | null | -3 - | zero | -3 - 1 | one | 4 - 2 | two | 4 - 3 | three | 4 - 4 | four | 4 5 | five | 4 + 5 | five | + 5 | five | 0 + 6 | six | -1 + 6 | six | + 6 | six | -5 + 6 | six | -5 + 6 | six | 2 + 6 | six | -3 6 | six | 4 - 7 | seven | 4 - 8 | eight | 4 - 0 | zero | 4 - | null | 4 - | zero | 4 + 6 | six | + 6 | six | 0 + 1 | one | -1 + 1 | one | 1 | one | -5 - 2 | two | -5 - 3 | three | -5 - 4 | four | -5 - 5 | five | -5 - 6 | six | -5 - 7 | seven | -5 - 8 | eight | -5 - 0 | zero | -5 - | null | -5 - | zero | -5 1 | one | -5 - 2 | two | -5 - 3 | three | -5 - 4 | four | -5 - 5 | five | -5 - 6 | six | -5 - 7 | seven | -5 - 8 | eight | -5 - 0 | zero | -5 - | null | -5 - | zero | -5 + 1 | one | 2 + 1 | one | -3 + 1 | one | 4 1 | one | - 2 | two | - 3 | three | - 4 | four | - 5 | five | - 6 | six | - 7 | seven | - 8 | eight | + 1 | one | 0 + 0 | zero | -1 0 | zero | - | null | - | zero | - 1 | one | - 2 | two | - 3 | three | - 4 | four | - 5 | five | - 6 | six | - 7 | seven | - 8 | eight | + 0 | zero | -5 + 0 | zero | -5 + 0 | zero | 2 + 0 | zero | -3 + 0 | zero | 4 0 | zero | - | null | - | zero | - 1 | one | 0 + 0 | zero | 0 + 2 | two | -1 + 2 | two | + 2 | two | -5 + 2 | two | -5 + 2 | two | 2 + 2 | two | -3 + 2 | two | 4 + 2 | two | 2 | two | 0 + 3 | three | -1 + 3 | three | + 3 | three | -5 + 3 | three | -5 + 3 | three | 2 + 3 | three | -3 + 3 | three | 4 + 3 | three | 3 | three | 0 + 4 | four | -1 + 4 | four | + 4 | four | -5 + 4 | four | -5 + 4 | four | 2 + 4 | four | -3 + 4 | four | 4 + 4 | four | 4 | four | 0 - 5 | five | 0 - 6 | six | 0 + 7 | seven | -1 + 7 | seven | + 7 | seven | -5 + 7 | seven | -5 + 7 | seven | 2 + 7 | seven | -3 + 7 | seven | 4 + 7 | seven | 7 | seven | 0 + 8 | eight | -1 + 8 | eight | + 8 | eight | -5 + 8 | eight | -5 + 8 | eight | 2 + 8 | eight | -3 + 8 | eight | 4 + 8 | eight | 8 | eight | 0 - 0 | zero | 0 + | null | -1 + | null | + | null | -5 + | null | -5 + | null | 2 + | null | -3 + | null | 4 + | null | | null | 0 + | zero | -1 + | zero | + | zero | -5 + | zero | -5 + | zero | 2 + | zero | -3 + | zero | 4 + | zero | | zero | 0 (99 rows) @@ -566,1001 +566,1001 @@ SELECT tx.ii, tx.jj, tx.kk ii | jj | kk ----+----+---- 1 | 4 | -1 - 2 | 3 | -1 - 3 | 2 | -1 - 4 | 1 | -1 - 5 | 0 | -1 - 6 | 6 | -1 - 7 | 7 | -1 - 8 | 8 | -1 - 0 | | -1 - | | -1 - | 0 | -1 + 1 | 4 | 1 | 4 | 2 - 2 | 3 | 2 - 3 | 2 | 2 - 4 | 1 | 2 - 5 | 0 | 2 - 6 | 6 | 2 - 7 | 7 | 2 - 8 | 8 | 2 - 0 | | 2 - | | 2 - | 0 | 2 1 | 4 | -3 - 2 | 3 | -3 - 3 | 2 | -3 - 4 | 1 | -3 - 5 | 0 | -3 - 6 | 6 | -3 - 7 | 7 | -3 - 8 | 8 | -3 - 0 | | -3 - | | -3 - | 0 | -3 1 | 4 | 4 - 2 | 3 | 4 - 3 | 2 | 4 - 4 | 1 | 4 - 5 | 0 | 4 - 6 | 6 | 4 - 7 | 7 | 4 - 8 | 8 | 4 - 0 | | 4 - | | 4 - | 0 | 4 + 1 | 4 | + 1 | 4 | 0 1 | 4 | -5 - 2 | 3 | -5 - 3 | 2 | -5 - 4 | 1 | -5 - 5 | 0 | -5 - 6 | 6 | -5 - 7 | 7 | -5 - 8 | 8 | -5 - 0 | | -5 - | | -5 - | 0 | -5 1 | 4 | -5 - 2 | 3 | -5 - 3 | 2 | -5 - 4 | 1 | -5 - 5 | 0 | -5 - 6 | 6 | -5 - 7 | 7 | -5 - 8 | 8 | -5 + 0 | | -1 + 0 | | + 0 | | 2 + 0 | | -3 + 0 | | 4 + 0 | | + 0 | | 0 0 | | -5 - | | -5 - | 0 | -5 - 1 | 4 | + 0 | | -5 + 2 | 3 | -5 + 2 | 3 | -5 + 2 | 3 | 2 + 2 | 3 | -3 + 2 | 3 | 4 2 | 3 | - 3 | 2 | - 4 | 1 | - 5 | 0 | - 6 | 6 | - 7 | 7 | - 8 | 8 | - 0 | | - | | - | 0 | - 1 | 4 | + 2 | 3 | 0 + 2 | 3 | -1 2 | 3 | + 3 | 2 | -5 + 3 | 2 | -5 + 3 | 2 | 2 + 3 | 2 | -3 + 3 | 2 | 4 + 3 | 2 | + 3 | 2 | 0 + 3 | 2 | -1 3 | 2 | + 4 | 1 | -5 + 4 | 1 | -5 + 4 | 1 | 2 + 4 | 1 | -3 + 4 | 1 | 4 4 | 1 | - 5 | 0 | - 6 | 6 | + 4 | 1 | 0 + 4 | 1 | -1 + 4 | 1 | + 7 | 7 | -5 + 7 | 7 | -5 + 7 | 7 | 2 + 7 | 7 | -3 + 7 | 7 | 4 + 7 | 7 | + 7 | 7 | 0 + 7 | 7 | -1 7 | 7 | + 8 | 8 | -5 + 8 | 8 | -5 + 8 | 8 | 2 + 8 | 8 | -3 + 8 | 8 | 4 8 | 8 | - 0 | | + 8 | 8 | 0 + 8 | 8 | -1 + 8 | 8 | + | | -5 + | | -5 + | | 2 + | | -3 + | | 4 | | + | | 0 + | | -1 + | | + | 0 | -5 + | 0 | -5 + | 0 | 2 + | 0 | -3 + | 0 | 4 | 0 | - 1 | 4 | 0 - 2 | 3 | 0 - 3 | 2 | 0 - 4 | 1 | 0 + | 0 | 0 + | 0 | -1 + | 0 | + 5 | 0 | 2 + 5 | 0 | -3 + 5 | 0 | 4 + 5 | 0 | 5 | 0 | 0 + 5 | 0 | -5 + 5 | 0 | -5 + 5 | 0 | -1 + 5 | 0 | + 6 | 6 | 2 + 6 | 6 | -3 + 6 | 6 | 4 + 6 | 6 | 6 | 6 | 0 - 7 | 7 | 0 - 8 | 8 | 0 - 0 | | 0 - | | 0 - | 0 | 0 + 6 | 6 | -5 + 6 | 6 | -5 + 6 | 6 | -1 + 6 | 6 | (99 rows) SELECT * FROM J1_TBL CROSS JOIN J2_TBL a CROSS JOIN J2_TBL b; i | j | t | i | k | i | k ---+---+-------+---+----+---+---- - 1 | 4 | one | 1 | -1 | 1 | -1 + 1 | 4 | one | 2 | 2 | 2 | 2 + 0 | | zero | 2 | 2 | 2 | 2 + 1 | 4 | one | 2 | 2 | 3 | -3 + 0 | | zero | 2 | 2 | 3 | -3 + 1 | 4 | one | 2 | 2 | 2 | 4 + 0 | | zero | 2 | 2 | 2 | 4 + 1 | 4 | one | 2 | 2 | | + 0 | | zero | 2 | 2 | | + 1 | 4 | one | 2 | 2 | | 0 + 0 | | zero | 2 | 2 | | 0 + 1 | 4 | one | 3 | -3 | 2 | 2 + 0 | | zero | 3 | -3 | 2 | 2 + 1 | 4 | one | 3 | -3 | 3 | -3 + 0 | | zero | 3 | -3 | 3 | -3 + 1 | 4 | one | 3 | -3 | 2 | 4 + 0 | | zero | 3 | -3 | 2 | 4 + 1 | 4 | one | 3 | -3 | | + 0 | | zero | 3 | -3 | | + 1 | 4 | one | 3 | -3 | | 0 + 0 | | zero | 3 | -3 | | 0 + 1 | 4 | one | 2 | 4 | 2 | 2 + 0 | | zero | 2 | 4 | 2 | 2 + 1 | 4 | one | 2 | 4 | 3 | -3 + 0 | | zero | 2 | 4 | 3 | -3 + 1 | 4 | one | 2 | 4 | 2 | 4 + 0 | | zero | 2 | 4 | 2 | 4 + 1 | 4 | one | 2 | 4 | | + 0 | | zero | 2 | 4 | | + 1 | 4 | one | 2 | 4 | | 0 + 0 | | zero | 2 | 4 | | 0 + 1 | 4 | one | | | 2 | 2 + 0 | | zero | | | 2 | 2 + 1 | 4 | one | | | 3 | -3 + 0 | | zero | | | 3 | -3 + 1 | 4 | one | | | 2 | 4 + 0 | | zero | | | 2 | 4 + 1 | 4 | one | | | | + 0 | | zero | | | | + 1 | 4 | one | | | | 0 + 0 | | zero | | | | 0 + 1 | 4 | one | | 0 | 2 | 2 + 0 | | zero | | 0 | 2 | 2 + 1 | 4 | one | | 0 | 3 | -3 + 0 | | zero | | 0 | 3 | -3 + 1 | 4 | one | | 0 | 2 | 4 + 0 | | zero | | 0 | 2 | 4 + 1 | 4 | one | | 0 | | + 0 | | zero | | 0 | | + 1 | 4 | one | | 0 | | 0 + 0 | | zero | | 0 | | 0 1 | 4 | one | 1 | -1 | 2 | 2 - 1 | 4 | one | 1 | -1 | 3 | -3 - 1 | 4 | one | 1 | -1 | 2 | 4 - 1 | 4 | one | 1 | -1 | 5 | -5 - 1 | 4 | one | 1 | -1 | 5 | -5 - 1 | 4 | one | 1 | -1 | 0 | - 1 | 4 | one | 1 | -1 | | - 1 | 4 | one | 1 | -1 | | 0 - 2 | 3 | two | 1 | -1 | 1 | -1 - 2 | 3 | two | 1 | -1 | 2 | 2 - 2 | 3 | two | 1 | -1 | 3 | -3 - 2 | 3 | two | 1 | -1 | 2 | 4 - 2 | 3 | two | 1 | -1 | 5 | -5 - 2 | 3 | two | 1 | -1 | 5 | -5 - 2 | 3 | two | 1 | -1 | 0 | - 2 | 3 | two | 1 | -1 | | - 2 | 3 | two | 1 | -1 | | 0 - 3 | 2 | three | 1 | -1 | 1 | -1 - 3 | 2 | three | 1 | -1 | 2 | 2 - 3 | 2 | three | 1 | -1 | 3 | -3 - 3 | 2 | three | 1 | -1 | 2 | 4 - 3 | 2 | three | 1 | -1 | 5 | -5 - 3 | 2 | three | 1 | -1 | 5 | -5 - 3 | 2 | three | 1 | -1 | 0 | - 3 | 2 | three | 1 | -1 | | - 3 | 2 | three | 1 | -1 | | 0 - 4 | 1 | four | 1 | -1 | 1 | -1 - 4 | 1 | four | 1 | -1 | 2 | 2 - 4 | 1 | four | 1 | -1 | 3 | -3 - 4 | 1 | four | 1 | -1 | 2 | 4 - 4 | 1 | four | 1 | -1 | 5 | -5 - 4 | 1 | four | 1 | -1 | 5 | -5 - 4 | 1 | four | 1 | -1 | 0 | - 4 | 1 | four | 1 | -1 | | - 4 | 1 | four | 1 | -1 | | 0 - 5 | 0 | five | 1 | -1 | 1 | -1 - 5 | 0 | five | 1 | -1 | 2 | 2 - 5 | 0 | five | 1 | -1 | 3 | -3 - 5 | 0 | five | 1 | -1 | 2 | 4 - 5 | 0 | five | 1 | -1 | 5 | -5 - 5 | 0 | five | 1 | -1 | 5 | -5 - 5 | 0 | five | 1 | -1 | 0 | - 5 | 0 | five | 1 | -1 | | - 5 | 0 | five | 1 | -1 | | 0 - 6 | 6 | six | 1 | -1 | 1 | -1 - 6 | 6 | six | 1 | -1 | 2 | 2 - 6 | 6 | six | 1 | -1 | 3 | -3 - 6 | 6 | six | 1 | -1 | 2 | 4 - 6 | 6 | six | 1 | -1 | 5 | -5 - 6 | 6 | six | 1 | -1 | 5 | -5 - 6 | 6 | six | 1 | -1 | 0 | - 6 | 6 | six | 1 | -1 | | - 6 | 6 | six | 1 | -1 | | 0 - 7 | 7 | seven | 1 | -1 | 1 | -1 - 7 | 7 | seven | 1 | -1 | 2 | 2 - 7 | 7 | seven | 1 | -1 | 3 | -3 - 7 | 7 | seven | 1 | -1 | 2 | 4 - 7 | 7 | seven | 1 | -1 | 5 | -5 - 7 | 7 | seven | 1 | -1 | 5 | -5 - 7 | 7 | seven | 1 | -1 | 0 | - 7 | 7 | seven | 1 | -1 | | - 7 | 7 | seven | 1 | -1 | | 0 - 8 | 8 | eight | 1 | -1 | 1 | -1 - 8 | 8 | eight | 1 | -1 | 2 | 2 - 8 | 8 | eight | 1 | -1 | 3 | -3 - 8 | 8 | eight | 1 | -1 | 2 | 4 - 8 | 8 | eight | 1 | -1 | 5 | -5 - 8 | 8 | eight | 1 | -1 | 5 | -5 - 8 | 8 | eight | 1 | -1 | 0 | - 8 | 8 | eight | 1 | -1 | | - 8 | 8 | eight | 1 | -1 | | 0 - 0 | | zero | 1 | -1 | 1 | -1 0 | | zero | 1 | -1 | 2 | 2 + 1 | 4 | one | 1 | -1 | 3 | -3 0 | | zero | 1 | -1 | 3 | -3 + 1 | 4 | one | 1 | -1 | 2 | 4 0 | | zero | 1 | -1 | 2 | 4 - 0 | | zero | 1 | -1 | 5 | -5 - 0 | | zero | 1 | -1 | 5 | -5 - 0 | | zero | 1 | -1 | 0 | + 1 | 4 | one | 1 | -1 | | 0 | | zero | 1 | -1 | | + 1 | 4 | one | 1 | -1 | | 0 0 | | zero | 1 | -1 | | 0 - | | null | 1 | -1 | 1 | -1 - | | null | 1 | -1 | 2 | 2 - | | null | 1 | -1 | 3 | -3 - | | null | 1 | -1 | 2 | 4 - | | null | 1 | -1 | 5 | -5 - | | null | 1 | -1 | 5 | -5 - | | null | 1 | -1 | 0 | - | | null | 1 | -1 | | - | | null | 1 | -1 | | 0 - | 0 | zero | 1 | -1 | 1 | -1 - | 0 | zero | 1 | -1 | 2 | 2 - | 0 | zero | 1 | -1 | 3 | -3 - | 0 | zero | 1 | -1 | 2 | 4 - | 0 | zero | 1 | -1 | 5 | -5 - | 0 | zero | 1 | -1 | 5 | -5 - | 0 | zero | 1 | -1 | 0 | - | 0 | zero | 1 | -1 | | - | 0 | zero | 1 | -1 | | 0 - 1 | 4 | one | 2 | 2 | 1 | -1 - 1 | 4 | one | 2 | 2 | 2 | 2 - 1 | 4 | one | 2 | 2 | 3 | -3 - 1 | 4 | one | 2 | 2 | 2 | 4 - 1 | 4 | one | 2 | 2 | 5 | -5 - 1 | 4 | one | 2 | 2 | 5 | -5 - 1 | 4 | one | 2 | 2 | 0 | - 1 | 4 | one | 2 | 2 | | - 1 | 4 | one | 2 | 2 | | 0 - 2 | 3 | two | 2 | 2 | 1 | -1 - 2 | 3 | two | 2 | 2 | 2 | 2 - 2 | 3 | two | 2 | 2 | 3 | -3 - 2 | 3 | two | 2 | 2 | 2 | 4 - 2 | 3 | two | 2 | 2 | 5 | -5 - 2 | 3 | two | 2 | 2 | 5 | -5 - 2 | 3 | two | 2 | 2 | 0 | - 2 | 3 | two | 2 | 2 | | - 2 | 3 | two | 2 | 2 | | 0 - 3 | 2 | three | 2 | 2 | 1 | -1 - 3 | 2 | three | 2 | 2 | 2 | 2 - 3 | 2 | three | 2 | 2 | 3 | -3 - 3 | 2 | three | 2 | 2 | 2 | 4 - 3 | 2 | three | 2 | 2 | 5 | -5 - 3 | 2 | three | 2 | 2 | 5 | -5 - 3 | 2 | three | 2 | 2 | 0 | - 3 | 2 | three | 2 | 2 | | - 3 | 2 | three | 2 | 2 | | 0 - 4 | 1 | four | 2 | 2 | 1 | -1 - 4 | 1 | four | 2 | 2 | 2 | 2 - 4 | 1 | four | 2 | 2 | 3 | -3 - 4 | 1 | four | 2 | 2 | 2 | 4 - 4 | 1 | four | 2 | 2 | 5 | -5 - 4 | 1 | four | 2 | 2 | 5 | -5 - 4 | 1 | four | 2 | 2 | 0 | - 4 | 1 | four | 2 | 2 | | - 4 | 1 | four | 2 | 2 | | 0 - 5 | 0 | five | 2 | 2 | 1 | -1 - 5 | 0 | five | 2 | 2 | 2 | 2 - 5 | 0 | five | 2 | 2 | 3 | -3 - 5 | 0 | five | 2 | 2 | 2 | 4 - 5 | 0 | five | 2 | 2 | 5 | -5 - 5 | 0 | five | 2 | 2 | 5 | -5 - 5 | 0 | five | 2 | 2 | 0 | - 5 | 0 | five | 2 | 2 | | - 5 | 0 | five | 2 | 2 | | 0 - 6 | 6 | six | 2 | 2 | 1 | -1 - 6 | 6 | six | 2 | 2 | 2 | 2 - 6 | 6 | six | 2 | 2 | 3 | -3 - 6 | 6 | six | 2 | 2 | 2 | 4 - 6 | 6 | six | 2 | 2 | 5 | -5 - 6 | 6 | six | 2 | 2 | 5 | -5 - 6 | 6 | six | 2 | 2 | 0 | - 6 | 6 | six | 2 | 2 | | - 6 | 6 | six | 2 | 2 | | 0 - 7 | 7 | seven | 2 | 2 | 1 | -1 - 7 | 7 | seven | 2 | 2 | 2 | 2 - 7 | 7 | seven | 2 | 2 | 3 | -3 - 7 | 7 | seven | 2 | 2 | 2 | 4 - 7 | 7 | seven | 2 | 2 | 5 | -5 - 7 | 7 | seven | 2 | 2 | 5 | -5 - 7 | 7 | seven | 2 | 2 | 0 | - 7 | 7 | seven | 2 | 2 | | - 7 | 7 | seven | 2 | 2 | | 0 - 8 | 8 | eight | 2 | 2 | 1 | -1 - 8 | 8 | eight | 2 | 2 | 2 | 2 - 8 | 8 | eight | 2 | 2 | 3 | -3 - 8 | 8 | eight | 2 | 2 | 2 | 4 - 8 | 8 | eight | 2 | 2 | 5 | -5 - 8 | 8 | eight | 2 | 2 | 5 | -5 - 8 | 8 | eight | 2 | 2 | 0 | - 8 | 8 | eight | 2 | 2 | | - 8 | 8 | eight | 2 | 2 | | 0 + 1 | 4 | one | 0 | | 2 | 2 + 0 | | zero | 0 | | 2 | 2 + 1 | 4 | one | 0 | | 3 | -3 + 0 | | zero | 0 | | 3 | -3 + 1 | 4 | one | 0 | | 2 | 4 + 0 | | zero | 0 | | 2 | 4 + 1 | 4 | one | 0 | | | + 0 | | zero | 0 | | | + 1 | 4 | one | 0 | | | 0 + 0 | | zero | 0 | | | 0 + 1 | 4 | one | 5 | -5 | 2 | 2 + 0 | | zero | 5 | -5 | 2 | 2 + 1 | 4 | one | 5 | -5 | 3 | -3 + 0 | | zero | 5 | -5 | 3 | -3 + 1 | 4 | one | 5 | -5 | 2 | 4 + 0 | | zero | 5 | -5 | 2 | 4 + 1 | 4 | one | 5 | -5 | | + 0 | | zero | 5 | -5 | | + 1 | 4 | one | 5 | -5 | | 0 + 0 | | zero | 5 | -5 | | 0 + 1 | 4 | one | 5 | -5 | 2 | 2 + 0 | | zero | 5 | -5 | 2 | 2 + 1 | 4 | one | 5 | -5 | 3 | -3 + 0 | | zero | 5 | -5 | 3 | -3 + 1 | 4 | one | 5 | -5 | 2 | 4 + 0 | | zero | 5 | -5 | 2 | 4 + 1 | 4 | one | 5 | -5 | | + 0 | | zero | 5 | -5 | | + 1 | 4 | one | 5 | -5 | | 0 + 0 | | zero | 5 | -5 | | 0 + 1 | 4 | one | 2 | 2 | 1 | -1 0 | | zero | 2 | 2 | 1 | -1 - 0 | | zero | 2 | 2 | 2 | 2 - 0 | | zero | 2 | 2 | 3 | -3 - 0 | | zero | 2 | 2 | 2 | 4 + 1 | 4 | one | 2 | 2 | 0 | + 0 | | zero | 2 | 2 | 0 | + 1 | 4 | one | 3 | -3 | 1 | -1 + 0 | | zero | 3 | -3 | 1 | -1 + 1 | 4 | one | 3 | -3 | 0 | + 0 | | zero | 3 | -3 | 0 | + 1 | 4 | one | 2 | 4 | 1 | -1 + 0 | | zero | 2 | 4 | 1 | -1 + 1 | 4 | one | 2 | 4 | 0 | + 0 | | zero | 2 | 4 | 0 | + 1 | 4 | one | | | 1 | -1 + 0 | | zero | | | 1 | -1 + 1 | 4 | one | | | 0 | + 0 | | zero | | | 0 | + 1 | 4 | one | | 0 | 1 | -1 + 0 | | zero | | 0 | 1 | -1 + 1 | 4 | one | | 0 | 0 | + 0 | | zero | | 0 | 0 | + 1 | 4 | one | 1 | -1 | 1 | -1 + 0 | | zero | 1 | -1 | 1 | -1 + 1 | 4 | one | 1 | -1 | 0 | + 0 | | zero | 1 | -1 | 0 | + 1 | 4 | one | 0 | | 1 | -1 + 0 | | zero | 0 | | 1 | -1 + 1 | 4 | one | 0 | | 0 | + 0 | | zero | 0 | | 0 | + 1 | 4 | one | 5 | -5 | 1 | -1 + 0 | | zero | 5 | -5 | 1 | -1 + 1 | 4 | one | 5 | -5 | 0 | + 0 | | zero | 5 | -5 | 0 | + 1 | 4 | one | 5 | -5 | 1 | -1 + 0 | | zero | 5 | -5 | 1 | -1 + 1 | 4 | one | 5 | -5 | 0 | + 0 | | zero | 5 | -5 | 0 | + 1 | 4 | one | 1 | -1 | 5 | -5 + 0 | | zero | 1 | -1 | 5 | -5 + 1 | 4 | one | 1 | -1 | 5 | -5 + 0 | | zero | 1 | -1 | 5 | -5 + 1 | 4 | one | 0 | | 5 | -5 + 0 | | zero | 0 | | 5 | -5 + 1 | 4 | one | 0 | | 5 | -5 + 0 | | zero | 0 | | 5 | -5 + 1 | 4 | one | 5 | -5 | 5 | -5 + 0 | | zero | 5 | -5 | 5 | -5 + 1 | 4 | one | 5 | -5 | 5 | -5 + 0 | | zero | 5 | -5 | 5 | -5 + 1 | 4 | one | 5 | -5 | 5 | -5 + 0 | | zero | 5 | -5 | 5 | -5 + 1 | 4 | one | 5 | -5 | 5 | -5 + 0 | | zero | 5 | -5 | 5 | -5 + 1 | 4 | one | 2 | 2 | 5 | -5 0 | | zero | 2 | 2 | 5 | -5 + 1 | 4 | one | 2 | 2 | 5 | -5 0 | | zero | 2 | 2 | 5 | -5 - 0 | | zero | 2 | 2 | 0 | - 0 | | zero | 2 | 2 | | - 0 | | zero | 2 | 2 | | 0 - | | null | 2 | 2 | 1 | -1 + 1 | 4 | one | 3 | -3 | 5 | -5 + 0 | | zero | 3 | -3 | 5 | -5 + 1 | 4 | one | 3 | -3 | 5 | -5 + 0 | | zero | 3 | -3 | 5 | -5 + 1 | 4 | one | 2 | 4 | 5 | -5 + 0 | | zero | 2 | 4 | 5 | -5 + 1 | 4 | one | 2 | 4 | 5 | -5 + 0 | | zero | 2 | 4 | 5 | -5 + 1 | 4 | one | | | 5 | -5 + 0 | | zero | | | 5 | -5 + 1 | 4 | one | | | 5 | -5 + 0 | | zero | | | 5 | -5 + 1 | 4 | one | | 0 | 5 | -5 + 0 | | zero | | 0 | 5 | -5 + 1 | 4 | one | | 0 | 5 | -5 + 0 | | zero | | 0 | 5 | -5 + 2 | 3 | two | 2 | 2 | 2 | 2 + 3 | 2 | three | 2 | 2 | 2 | 2 + 4 | 1 | four | 2 | 2 | 2 | 2 + 7 | 7 | seven | 2 | 2 | 2 | 2 + 8 | 8 | eight | 2 | 2 | 2 | 2 | | null | 2 | 2 | 2 | 2 - | | null | 2 | 2 | 3 | -3 - | | null | 2 | 2 | 2 | 4 - | | null | 2 | 2 | 5 | -5 - | | null | 2 | 2 | 5 | -5 - | | null | 2 | 2 | 0 | - | | null | 2 | 2 | | - | | null | 2 | 2 | | 0 - | 0 | zero | 2 | 2 | 1 | -1 | 0 | zero | 2 | 2 | 2 | 2 + 2 | 3 | two | 2 | 2 | 3 | -3 + 3 | 2 | three | 2 | 2 | 3 | -3 + 4 | 1 | four | 2 | 2 | 3 | -3 + 7 | 7 | seven | 2 | 2 | 3 | -3 + 8 | 8 | eight | 2 | 2 | 3 | -3 + | | null | 2 | 2 | 3 | -3 | 0 | zero | 2 | 2 | 3 | -3 + 2 | 3 | two | 2 | 2 | 2 | 4 + 3 | 2 | three | 2 | 2 | 2 | 4 + 4 | 1 | four | 2 | 2 | 2 | 4 + 7 | 7 | seven | 2 | 2 | 2 | 4 + 8 | 8 | eight | 2 | 2 | 2 | 4 + | | null | 2 | 2 | 2 | 4 | 0 | zero | 2 | 2 | 2 | 4 - | 0 | zero | 2 | 2 | 5 | -5 - | 0 | zero | 2 | 2 | 5 | -5 - | 0 | zero | 2 | 2 | 0 | + 2 | 3 | two | 2 | 2 | | + 3 | 2 | three | 2 | 2 | | + 4 | 1 | four | 2 | 2 | | + 7 | 7 | seven | 2 | 2 | | + 8 | 8 | eight | 2 | 2 | | + | | null | 2 | 2 | | | 0 | zero | 2 | 2 | | + 2 | 3 | two | 2 | 2 | | 0 + 3 | 2 | three | 2 | 2 | | 0 + 4 | 1 | four | 2 | 2 | | 0 + 7 | 7 | seven | 2 | 2 | | 0 + 8 | 8 | eight | 2 | 2 | | 0 + | | null | 2 | 2 | | 0 | 0 | zero | 2 | 2 | | 0 - 1 | 4 | one | 3 | -3 | 1 | -1 - 1 | 4 | one | 3 | -3 | 2 | 2 - 1 | 4 | one | 3 | -3 | 3 | -3 - 1 | 4 | one | 3 | -3 | 2 | 4 - 1 | 4 | one | 3 | -3 | 5 | -5 - 1 | 4 | one | 3 | -3 | 5 | -5 - 1 | 4 | one | 3 | -3 | 0 | - 1 | 4 | one | 3 | -3 | | - 1 | 4 | one | 3 | -3 | | 0 - 2 | 3 | two | 3 | -3 | 1 | -1 2 | 3 | two | 3 | -3 | 2 | 2 - 2 | 3 | two | 3 | -3 | 3 | -3 - 2 | 3 | two | 3 | -3 | 2 | 4 - 2 | 3 | two | 3 | -3 | 5 | -5 - 2 | 3 | two | 3 | -3 | 5 | -5 - 2 | 3 | two | 3 | -3 | 0 | - 2 | 3 | two | 3 | -3 | | - 2 | 3 | two | 3 | -3 | | 0 - 3 | 2 | three | 3 | -3 | 1 | -1 3 | 2 | three | 3 | -3 | 2 | 2 - 3 | 2 | three | 3 | -3 | 3 | -3 - 3 | 2 | three | 3 | -3 | 2 | 4 - 3 | 2 | three | 3 | -3 | 5 | -5 - 3 | 2 | three | 3 | -3 | 5 | -5 - 3 | 2 | three | 3 | -3 | 0 | - 3 | 2 | three | 3 | -3 | | - 3 | 2 | three | 3 | -3 | | 0 - 4 | 1 | four | 3 | -3 | 1 | -1 4 | 1 | four | 3 | -3 | 2 | 2 + 7 | 7 | seven | 3 | -3 | 2 | 2 + 8 | 8 | eight | 3 | -3 | 2 | 2 + | | null | 3 | -3 | 2 | 2 + | 0 | zero | 3 | -3 | 2 | 2 + 2 | 3 | two | 3 | -3 | 3 | -3 + 3 | 2 | three | 3 | -3 | 3 | -3 4 | 1 | four | 3 | -3 | 3 | -3 + 7 | 7 | seven | 3 | -3 | 3 | -3 + 8 | 8 | eight | 3 | -3 | 3 | -3 + | | null | 3 | -3 | 3 | -3 + | 0 | zero | 3 | -3 | 3 | -3 + 2 | 3 | two | 3 | -3 | 2 | 4 + 3 | 2 | three | 3 | -3 | 2 | 4 4 | 1 | four | 3 | -3 | 2 | 4 - 4 | 1 | four | 3 | -3 | 5 | -5 - 4 | 1 | four | 3 | -3 | 5 | -5 - 4 | 1 | four | 3 | -3 | 0 | + 7 | 7 | seven | 3 | -3 | 2 | 4 + 8 | 8 | eight | 3 | -3 | 2 | 4 + | | null | 3 | -3 | 2 | 4 + | 0 | zero | 3 | -3 | 2 | 4 + 2 | 3 | two | 3 | -3 | | + 3 | 2 | three | 3 | -3 | | 4 | 1 | four | 3 | -3 | | + 7 | 7 | seven | 3 | -3 | | + 8 | 8 | eight | 3 | -3 | | + | | null | 3 | -3 | | + | 0 | zero | 3 | -3 | | + 2 | 3 | two | 3 | -3 | | 0 + 3 | 2 | three | 3 | -3 | | 0 4 | 1 | four | 3 | -3 | | 0 - 5 | 0 | five | 3 | -3 | 1 | -1 - 5 | 0 | five | 3 | -3 | 2 | 2 - 5 | 0 | five | 3 | -3 | 3 | -3 - 5 | 0 | five | 3 | -3 | 2 | 4 - 5 | 0 | five | 3 | -3 | 5 | -5 - 5 | 0 | five | 3 | -3 | 5 | -5 - 5 | 0 | five | 3 | -3 | 0 | - 5 | 0 | five | 3 | -3 | | - 5 | 0 | five | 3 | -3 | | 0 - 6 | 6 | six | 3 | -3 | 1 | -1 - 6 | 6 | six | 3 | -3 | 2 | 2 - 6 | 6 | six | 3 | -3 | 3 | -3 - 6 | 6 | six | 3 | -3 | 2 | 4 - 6 | 6 | six | 3 | -3 | 5 | -5 - 6 | 6 | six | 3 | -3 | 5 | -5 - 6 | 6 | six | 3 | -3 | 0 | - 6 | 6 | six | 3 | -3 | | - 6 | 6 | six | 3 | -3 | | 0 - 7 | 7 | seven | 3 | -3 | 1 | -1 - 7 | 7 | seven | 3 | -3 | 2 | 2 - 7 | 7 | seven | 3 | -3 | 3 | -3 - 7 | 7 | seven | 3 | -3 | 2 | 4 - 7 | 7 | seven | 3 | -3 | 5 | -5 - 7 | 7 | seven | 3 | -3 | 5 | -5 - 7 | 7 | seven | 3 | -3 | 0 | - 7 | 7 | seven | 3 | -3 | | 7 | 7 | seven | 3 | -3 | | 0 - 8 | 8 | eight | 3 | -3 | 1 | -1 - 8 | 8 | eight | 3 | -3 | 2 | 2 - 8 | 8 | eight | 3 | -3 | 3 | -3 - 8 | 8 | eight | 3 | -3 | 2 | 4 - 8 | 8 | eight | 3 | -3 | 5 | -5 - 8 | 8 | eight | 3 | -3 | 5 | -5 - 8 | 8 | eight | 3 | -3 | 0 | - 8 | 8 | eight | 3 | -3 | | 8 | 8 | eight | 3 | -3 | | 0 - 0 | | zero | 3 | -3 | 1 | -1 - 0 | | zero | 3 | -3 | 2 | 2 - 0 | | zero | 3 | -3 | 3 | -3 - 0 | | zero | 3 | -3 | 2 | 4 - 0 | | zero | 3 | -3 | 5 | -5 - 0 | | zero | 3 | -3 | 5 | -5 - 0 | | zero | 3 | -3 | 0 | - 0 | | zero | 3 | -3 | | - 0 | | zero | 3 | -3 | | 0 - | | null | 3 | -3 | 1 | -1 - | | null | 3 | -3 | 2 | 2 - | | null | 3 | -3 | 3 | -3 - | | null | 3 | -3 | 2 | 4 - | | null | 3 | -3 | 5 | -5 - | | null | 3 | -3 | 5 | -5 - | | null | 3 | -3 | 0 | - | | null | 3 | -3 | | | | null | 3 | -3 | | 0 - | 0 | zero | 3 | -3 | 1 | -1 - | 0 | zero | 3 | -3 | 2 | 2 - | 0 | zero | 3 | -3 | 3 | -3 - | 0 | zero | 3 | -3 | 2 | 4 - | 0 | zero | 3 | -3 | 5 | -5 - | 0 | zero | 3 | -3 | 5 | -5 - | 0 | zero | 3 | -3 | 0 | - | 0 | zero | 3 | -3 | | | 0 | zero | 3 | -3 | | 0 - 1 | 4 | one | 2 | 4 | 1 | -1 - 1 | 4 | one | 2 | 4 | 2 | 2 - 1 | 4 | one | 2 | 4 | 3 | -3 - 1 | 4 | one | 2 | 4 | 2 | 4 - 1 | 4 | one | 2 | 4 | 5 | -5 - 1 | 4 | one | 2 | 4 | 5 | -5 - 1 | 4 | one | 2 | 4 | 0 | - 1 | 4 | one | 2 | 4 | | - 1 | 4 | one | 2 | 4 | | 0 - 2 | 3 | two | 2 | 4 | 1 | -1 2 | 3 | two | 2 | 4 | 2 | 2 - 2 | 3 | two | 2 | 4 | 3 | -3 - 2 | 3 | two | 2 | 4 | 2 | 4 - 2 | 3 | two | 2 | 4 | 5 | -5 - 2 | 3 | two | 2 | 4 | 5 | -5 - 2 | 3 | two | 2 | 4 | 0 | - 2 | 3 | two | 2 | 4 | | - 2 | 3 | two | 2 | 4 | | 0 - 3 | 2 | three | 2 | 4 | 1 | -1 3 | 2 | three | 2 | 4 | 2 | 2 - 3 | 2 | three | 2 | 4 | 3 | -3 - 3 | 2 | three | 2 | 4 | 2 | 4 - 3 | 2 | three | 2 | 4 | 5 | -5 - 3 | 2 | three | 2 | 4 | 5 | -5 - 3 | 2 | three | 2 | 4 | 0 | - 3 | 2 | three | 2 | 4 | | - 3 | 2 | three | 2 | 4 | | 0 - 4 | 1 | four | 2 | 4 | 1 | -1 4 | 1 | four | 2 | 4 | 2 | 2 + 7 | 7 | seven | 2 | 4 | 2 | 2 + 8 | 8 | eight | 2 | 4 | 2 | 2 + | | null | 2 | 4 | 2 | 2 + | 0 | zero | 2 | 4 | 2 | 2 + 2 | 3 | two | 2 | 4 | 3 | -3 + 3 | 2 | three | 2 | 4 | 3 | -3 4 | 1 | four | 2 | 4 | 3 | -3 + 7 | 7 | seven | 2 | 4 | 3 | -3 + 8 | 8 | eight | 2 | 4 | 3 | -3 + | | null | 2 | 4 | 3 | -3 + | 0 | zero | 2 | 4 | 3 | -3 + 2 | 3 | two | 2 | 4 | 2 | 4 + 3 | 2 | three | 2 | 4 | 2 | 4 4 | 1 | four | 2 | 4 | 2 | 4 - 4 | 1 | four | 2 | 4 | 5 | -5 - 4 | 1 | four | 2 | 4 | 5 | -5 - 4 | 1 | four | 2 | 4 | 0 | + 7 | 7 | seven | 2 | 4 | 2 | 4 + 8 | 8 | eight | 2 | 4 | 2 | 4 + | | null | 2 | 4 | 2 | 4 + | 0 | zero | 2 | 4 | 2 | 4 + 2 | 3 | two | 2 | 4 | | + 3 | 2 | three | 2 | 4 | | 4 | 1 | four | 2 | 4 | | + 7 | 7 | seven | 2 | 4 | | + 8 | 8 | eight | 2 | 4 | | + | | null | 2 | 4 | | + | 0 | zero | 2 | 4 | | + 2 | 3 | two | 2 | 4 | | 0 + 3 | 2 | three | 2 | 4 | | 0 4 | 1 | four | 2 | 4 | | 0 - 5 | 0 | five | 2 | 4 | 1 | -1 + 7 | 7 | seven | 2 | 4 | | 0 + 8 | 8 | eight | 2 | 4 | | 0 + | | null | 2 | 4 | | 0 + | 0 | zero | 2 | 4 | | 0 + 2 | 3 | two | | | 2 | 2 + 3 | 2 | three | | | 2 | 2 + 4 | 1 | four | | | 2 | 2 + 7 | 7 | seven | | | 2 | 2 + 8 | 8 | eight | | | 2 | 2 + | | null | | | 2 | 2 + | 0 | zero | | | 2 | 2 + 2 | 3 | two | | | 3 | -3 + 3 | 2 | three | | | 3 | -3 + 4 | 1 | four | | | 3 | -3 + 7 | 7 | seven | | | 3 | -3 + 8 | 8 | eight | | | 3 | -3 + | | null | | | 3 | -3 + | 0 | zero | | | 3 | -3 + 2 | 3 | two | | | 2 | 4 + 3 | 2 | three | | | 2 | 4 + 4 | 1 | four | | | 2 | 4 + 7 | 7 | seven | | | 2 | 4 + 8 | 8 | eight | | | 2 | 4 + | | null | | | 2 | 4 + | 0 | zero | | | 2 | 4 + 2 | 3 | two | | | | + 3 | 2 | three | | | | + 4 | 1 | four | | | | + 7 | 7 | seven | | | | + 8 | 8 | eight | | | | + | | null | | | | + | 0 | zero | | | | + 2 | 3 | two | | | | 0 + 3 | 2 | three | | | | 0 + 4 | 1 | four | | | | 0 + 7 | 7 | seven | | | | 0 + 8 | 8 | eight | | | | 0 + | | null | | | | 0 + | 0 | zero | | | | 0 + 2 | 3 | two | | 0 | 2 | 2 + 3 | 2 | three | | 0 | 2 | 2 + 4 | 1 | four | | 0 | 2 | 2 + 7 | 7 | seven | | 0 | 2 | 2 + 8 | 8 | eight | | 0 | 2 | 2 + | | null | | 0 | 2 | 2 + | 0 | zero | | 0 | 2 | 2 + 2 | 3 | two | | 0 | 3 | -3 + 3 | 2 | three | | 0 | 3 | -3 + 4 | 1 | four | | 0 | 3 | -3 + 7 | 7 | seven | | 0 | 3 | -3 + 8 | 8 | eight | | 0 | 3 | -3 + | | null | | 0 | 3 | -3 + | 0 | zero | | 0 | 3 | -3 + 2 | 3 | two | | 0 | 2 | 4 + 3 | 2 | three | | 0 | 2 | 4 + 4 | 1 | four | | 0 | 2 | 4 + 7 | 7 | seven | | 0 | 2 | 4 + 8 | 8 | eight | | 0 | 2 | 4 + | | null | | 0 | 2 | 4 + | 0 | zero | | 0 | 2 | 4 + 2 | 3 | two | | 0 | | + 3 | 2 | three | | 0 | | + 4 | 1 | four | | 0 | | + 7 | 7 | seven | | 0 | | + 8 | 8 | eight | | 0 | | + | | null | | 0 | | + | 0 | zero | | 0 | | + 2 | 3 | two | | 0 | | 0 + 3 | 2 | three | | 0 | | 0 + 4 | 1 | four | | 0 | | 0 + 7 | 7 | seven | | 0 | | 0 + 8 | 8 | eight | | 0 | | 0 + | | null | | 0 | | 0 + | 0 | zero | | 0 | | 0 + 2 | 3 | two | 1 | -1 | 2 | 2 + 3 | 2 | three | 1 | -1 | 2 | 2 + 4 | 1 | four | 1 | -1 | 2 | 2 + 7 | 7 | seven | 1 | -1 | 2 | 2 + 8 | 8 | eight | 1 | -1 | 2 | 2 + | | null | 1 | -1 | 2 | 2 + | 0 | zero | 1 | -1 | 2 | 2 + 2 | 3 | two | 1 | -1 | 3 | -3 + 3 | 2 | three | 1 | -1 | 3 | -3 + 4 | 1 | four | 1 | -1 | 3 | -3 + 7 | 7 | seven | 1 | -1 | 3 | -3 + 8 | 8 | eight | 1 | -1 | 3 | -3 + | | null | 1 | -1 | 3 | -3 + | 0 | zero | 1 | -1 | 3 | -3 + 2 | 3 | two | 1 | -1 | 2 | 4 + 3 | 2 | three | 1 | -1 | 2 | 4 + 4 | 1 | four | 1 | -1 | 2 | 4 + 7 | 7 | seven | 1 | -1 | 2 | 4 + 8 | 8 | eight | 1 | -1 | 2 | 4 + | | null | 1 | -1 | 2 | 4 + | 0 | zero | 1 | -1 | 2 | 4 + 2 | 3 | two | 1 | -1 | | + 3 | 2 | three | 1 | -1 | | + 4 | 1 | four | 1 | -1 | | + 7 | 7 | seven | 1 | -1 | | + 8 | 8 | eight | 1 | -1 | | + | | null | 1 | -1 | | + | 0 | zero | 1 | -1 | | + 2 | 3 | two | 1 | -1 | | 0 + 3 | 2 | three | 1 | -1 | | 0 + 4 | 1 | four | 1 | -1 | | 0 + 5 | 0 | five | 2 | 2 | 2 | 2 + 6 | 6 | six | 2 | 2 | 2 | 2 + 5 | 0 | five | 2 | 2 | 3 | -3 + 6 | 6 | six | 2 | 2 | 3 | -3 + 5 | 0 | five | 2 | 2 | 2 | 4 + 6 | 6 | six | 2 | 2 | 2 | 4 + 5 | 0 | five | 2 | 2 | | + 6 | 6 | six | 2 | 2 | | + 5 | 0 | five | 2 | 2 | | 0 + 6 | 6 | six | 2 | 2 | | 0 + 5 | 0 | five | 3 | -3 | 2 | 2 + 6 | 6 | six | 3 | -3 | 2 | 2 + 5 | 0 | five | 3 | -3 | 3 | -3 + 6 | 6 | six | 3 | -3 | 3 | -3 + 5 | 0 | five | 3 | -3 | 2 | 4 + 6 | 6 | six | 3 | -3 | 2 | 4 + 5 | 0 | five | 3 | -3 | | + 6 | 6 | six | 3 | -3 | | + 5 | 0 | five | 3 | -3 | | 0 + 6 | 6 | six | 3 | -3 | | 0 5 | 0 | five | 2 | 4 | 2 | 2 - 5 | 0 | five | 2 | 4 | 3 | -3 - 5 | 0 | five | 2 | 4 | 2 | 4 - 5 | 0 | five | 2 | 4 | 5 | -5 - 5 | 0 | five | 2 | 4 | 5 | -5 - 5 | 0 | five | 2 | 4 | 0 | - 5 | 0 | five | 2 | 4 | | - 5 | 0 | five | 2 | 4 | | 0 - 6 | 6 | six | 2 | 4 | 1 | -1 6 | 6 | six | 2 | 4 | 2 | 2 + 5 | 0 | five | 2 | 4 | 3 | -3 6 | 6 | six | 2 | 4 | 3 | -3 + 5 | 0 | five | 2 | 4 | 2 | 4 6 | 6 | six | 2 | 4 | 2 | 4 - 6 | 6 | six | 2 | 4 | 5 | -5 - 6 | 6 | six | 2 | 4 | 5 | -5 - 6 | 6 | six | 2 | 4 | 0 | + 5 | 0 | five | 2 | 4 | | 6 | 6 | six | 2 | 4 | | + 5 | 0 | five | 2 | 4 | | 0 6 | 6 | six | 2 | 4 | | 0 - 7 | 7 | seven | 2 | 4 | 1 | -1 - 7 | 7 | seven | 2 | 4 | 2 | 2 - 7 | 7 | seven | 2 | 4 | 3 | -3 - 7 | 7 | seven | 2 | 4 | 2 | 4 - 7 | 7 | seven | 2 | 4 | 5 | -5 - 7 | 7 | seven | 2 | 4 | 5 | -5 - 7 | 7 | seven | 2 | 4 | 0 | - 7 | 7 | seven | 2 | 4 | | - 7 | 7 | seven | 2 | 4 | | 0 - 8 | 8 | eight | 2 | 4 | 1 | -1 - 8 | 8 | eight | 2 | 4 | 2 | 2 - 8 | 8 | eight | 2 | 4 | 3 | -3 - 8 | 8 | eight | 2 | 4 | 2 | 4 - 8 | 8 | eight | 2 | 4 | 5 | -5 - 8 | 8 | eight | 2 | 4 | 5 | -5 - 8 | 8 | eight | 2 | 4 | 0 | - 8 | 8 | eight | 2 | 4 | | - 8 | 8 | eight | 2 | 4 | | 0 - 0 | | zero | 2 | 4 | 1 | -1 - 0 | | zero | 2 | 4 | 2 | 2 - 0 | | zero | 2 | 4 | 3 | -3 - 0 | | zero | 2 | 4 | 2 | 4 - 0 | | zero | 2 | 4 | 5 | -5 - 0 | | zero | 2 | 4 | 5 | -5 - 0 | | zero | 2 | 4 | 0 | - 0 | | zero | 2 | 4 | | - 0 | | zero | 2 | 4 | | 0 - | | null | 2 | 4 | 1 | -1 - | | null | 2 | 4 | 2 | 2 - | | null | 2 | 4 | 3 | -3 - | | null | 2 | 4 | 2 | 4 - | | null | 2 | 4 | 5 | -5 - | | null | 2 | 4 | 5 | -5 - | | null | 2 | 4 | 0 | - | | null | 2 | 4 | | - | | null | 2 | 4 | | 0 - | 0 | zero | 2 | 4 | 1 | -1 - | 0 | zero | 2 | 4 | 2 | 2 - | 0 | zero | 2 | 4 | 3 | -3 - | 0 | zero | 2 | 4 | 2 | 4 - | 0 | zero | 2 | 4 | 5 | -5 - | 0 | zero | 2 | 4 | 5 | -5 - | 0 | zero | 2 | 4 | 0 | - | 0 | zero | 2 | 4 | | - | 0 | zero | 2 | 4 | | 0 - 1 | 4 | one | 5 | -5 | 1 | -1 - 1 | 4 | one | 5 | -5 | 2 | 2 - 1 | 4 | one | 5 | -5 | 3 | -3 - 1 | 4 | one | 5 | -5 | 2 | 4 - 1 | 4 | one | 5 | -5 | 5 | -5 - 1 | 4 | one | 5 | -5 | 5 | -5 - 1 | 4 | one | 5 | -5 | 0 | - 1 | 4 | one | 5 | -5 | | - 1 | 4 | one | 5 | -5 | | 0 - 2 | 3 | two | 5 | -5 | 1 | -1 - 2 | 3 | two | 5 | -5 | 2 | 2 - 2 | 3 | two | 5 | -5 | 3 | -3 - 2 | 3 | two | 5 | -5 | 2 | 4 - 2 | 3 | two | 5 | -5 | 5 | -5 - 2 | 3 | two | 5 | -5 | 5 | -5 - 2 | 3 | two | 5 | -5 | 0 | - 2 | 3 | two | 5 | -5 | | - 2 | 3 | two | 5 | -5 | | 0 - 3 | 2 | three | 5 | -5 | 1 | -1 - 3 | 2 | three | 5 | -5 | 2 | 2 - 3 | 2 | three | 5 | -5 | 3 | -3 - 3 | 2 | three | 5 | -5 | 2 | 4 - 3 | 2 | three | 5 | -5 | 5 | -5 - 3 | 2 | three | 5 | -5 | 5 | -5 - 3 | 2 | three | 5 | -5 | 0 | - 3 | 2 | three | 5 | -5 | | - 3 | 2 | three | 5 | -5 | | 0 - 4 | 1 | four | 5 | -5 | 1 | -1 - 4 | 1 | four | 5 | -5 | 2 | 2 - 4 | 1 | four | 5 | -5 | 3 | -3 - 4 | 1 | four | 5 | -5 | 2 | 4 - 4 | 1 | four | 5 | -5 | 5 | -5 - 4 | 1 | four | 5 | -5 | 5 | -5 - 4 | 1 | four | 5 | -5 | 0 | - 4 | 1 | four | 5 | -5 | | - 4 | 1 | four | 5 | -5 | | 0 - 5 | 0 | five | 5 | -5 | 1 | -1 + 5 | 0 | five | | | 2 | 2 + 6 | 6 | six | | | 2 | 2 + 5 | 0 | five | | | 3 | -3 + 6 | 6 | six | | | 3 | -3 + 5 | 0 | five | | | 2 | 4 + 6 | 6 | six | | | 2 | 4 + 5 | 0 | five | | | | + 6 | 6 | six | | | | + 5 | 0 | five | | | | 0 + 6 | 6 | six | | | | 0 + 5 | 0 | five | | 0 | 2 | 2 + 6 | 6 | six | | 0 | 2 | 2 + 5 | 0 | five | | 0 | 3 | -3 + 6 | 6 | six | | 0 | 3 | -3 + 5 | 0 | five | | 0 | 2 | 4 + 6 | 6 | six | | 0 | 2 | 4 + 5 | 0 | five | | 0 | | + 6 | 6 | six | | 0 | | + 5 | 0 | five | | 0 | | 0 + 6 | 6 | six | | 0 | | 0 + 5 | 0 | five | 1 | -1 | 2 | 2 + 6 | 6 | six | 1 | -1 | 2 | 2 + 5 | 0 | five | 1 | -1 | 3 | -3 + 6 | 6 | six | 1 | -1 | 3 | -3 + 5 | 0 | five | 1 | -1 | 2 | 4 + 6 | 6 | six | 1 | -1 | 2 | 4 + 5 | 0 | five | 1 | -1 | | + 6 | 6 | six | 1 | -1 | | + 5 | 0 | five | 1 | -1 | | 0 + 6 | 6 | six | 1 | -1 | | 0 + 5 | 0 | five | 0 | | 2 | 2 + 6 | 6 | six | 0 | | 2 | 2 + 5 | 0 | five | 0 | | 3 | -3 + 6 | 6 | six | 0 | | 3 | -3 + 5 | 0 | five | 0 | | 2 | 4 + 6 | 6 | six | 0 | | 2 | 4 + 5 | 0 | five | 0 | | | + 6 | 6 | six | 0 | | | + 5 | 0 | five | 0 | | | 0 + 6 | 6 | six | 0 | | | 0 5 | 0 | five | 5 | -5 | 2 | 2 + 6 | 6 | six | 5 | -5 | 2 | 2 5 | 0 | five | 5 | -5 | 3 | -3 + 6 | 6 | six | 5 | -5 | 3 | -3 5 | 0 | five | 5 | -5 | 2 | 4 - 5 | 0 | five | 5 | -5 | 5 | -5 - 5 | 0 | five | 5 | -5 | 5 | -5 - 5 | 0 | five | 5 | -5 | 0 | + 6 | 6 | six | 5 | -5 | 2 | 4 5 | 0 | five | 5 | -5 | | + 6 | 6 | six | 5 | -5 | | 5 | 0 | five | 5 | -5 | | 0 - 6 | 6 | six | 5 | -5 | 1 | -1 + 6 | 6 | six | 5 | -5 | | 0 + 5 | 0 | five | 5 | -5 | 2 | 2 6 | 6 | six | 5 | -5 | 2 | 2 + 5 | 0 | five | 5 | -5 | 3 | -3 6 | 6 | six | 5 | -5 | 3 | -3 + 5 | 0 | five | 5 | -5 | 2 | 4 6 | 6 | six | 5 | -5 | 2 | 4 - 6 | 6 | six | 5 | -5 | 5 | -5 - 6 | 6 | six | 5 | -5 | 5 | -5 - 6 | 6 | six | 5 | -5 | 0 | + 5 | 0 | five | 5 | -5 | | 6 | 6 | six | 5 | -5 | | + 5 | 0 | five | 5 | -5 | | 0 6 | 6 | six | 5 | -5 | | 0 - 7 | 7 | seven | 5 | -5 | 1 | -1 - 7 | 7 | seven | 5 | -5 | 2 | 2 - 7 | 7 | seven | 5 | -5 | 3 | -3 - 7 | 7 | seven | 5 | -5 | 2 | 4 - 7 | 7 | seven | 5 | -5 | 5 | -5 - 7 | 7 | seven | 5 | -5 | 5 | -5 - 7 | 7 | seven | 5 | -5 | 0 | - 7 | 7 | seven | 5 | -5 | | - 7 | 7 | seven | 5 | -5 | | 0 - 8 | 8 | eight | 5 | -5 | 1 | -1 - 8 | 8 | eight | 5 | -5 | 2 | 2 - 8 | 8 | eight | 5 | -5 | 3 | -3 - 8 | 8 | eight | 5 | -5 | 2 | 4 - 8 | 8 | eight | 5 | -5 | 5 | -5 - 8 | 8 | eight | 5 | -5 | 5 | -5 - 8 | 8 | eight | 5 | -5 | 0 | - 8 | 8 | eight | 5 | -5 | | - 8 | 8 | eight | 5 | -5 | | 0 - 0 | | zero | 5 | -5 | 1 | -1 - 0 | | zero | 5 | -5 | 2 | 2 - 0 | | zero | 5 | -5 | 3 | -3 - 0 | | zero | 5 | -5 | 2 | 4 - 0 | | zero | 5 | -5 | 5 | -5 - 0 | | zero | 5 | -5 | 5 | -5 - 0 | | zero | 5 | -5 | 0 | - 0 | | zero | 5 | -5 | | - 0 | | zero | 5 | -5 | | 0 - | | null | 5 | -5 | 1 | -1 - | | null | 5 | -5 | 2 | 2 - | | null | 5 | -5 | 3 | -3 - | | null | 5 | -5 | 2 | 4 - | | null | 5 | -5 | 5 | -5 - | | null | 5 | -5 | 5 | -5 - | | null | 5 | -5 | 0 | - | | null | 5 | -5 | | - | | null | 5 | -5 | | 0 - | 0 | zero | 5 | -5 | 1 | -1 - | 0 | zero | 5 | -5 | 2 | 2 - | 0 | zero | 5 | -5 | 3 | -3 - | 0 | zero | 5 | -5 | 2 | 4 - | 0 | zero | 5 | -5 | 5 | -5 - | 0 | zero | 5 | -5 | 5 | -5 - | 0 | zero | 5 | -5 | 0 | - | 0 | zero | 5 | -5 | | - | 0 | zero | 5 | -5 | | 0 - 1 | 4 | one | 5 | -5 | 1 | -1 - 1 | 4 | one | 5 | -5 | 2 | 2 - 1 | 4 | one | 5 | -5 | 3 | -3 - 1 | 4 | one | 5 | -5 | 2 | 4 - 1 | 4 | one | 5 | -5 | 5 | -5 - 1 | 4 | one | 5 | -5 | 5 | -5 - 1 | 4 | one | 5 | -5 | 0 | - 1 | 4 | one | 5 | -5 | | - 1 | 4 | one | 5 | -5 | | 0 - 2 | 3 | two | 5 | -5 | 1 | -1 - 2 | 3 | two | 5 | -5 | 2 | 2 - 2 | 3 | two | 5 | -5 | 3 | -3 - 2 | 3 | two | 5 | -5 | 2 | 4 - 2 | 3 | two | 5 | -5 | 5 | -5 - 2 | 3 | two | 5 | -5 | 5 | -5 - 2 | 3 | two | 5 | -5 | 0 | - 2 | 3 | two | 5 | -5 | | - 2 | 3 | two | 5 | -5 | | 0 - 3 | 2 | three | 5 | -5 | 1 | -1 - 3 | 2 | three | 5 | -5 | 2 | 2 - 3 | 2 | three | 5 | -5 | 3 | -3 - 3 | 2 | three | 5 | -5 | 2 | 4 - 3 | 2 | three | 5 | -5 | 5 | -5 - 3 | 2 | three | 5 | -5 | 5 | -5 - 3 | 2 | three | 5 | -5 | 0 | - 3 | 2 | three | 5 | -5 | | - 3 | 2 | three | 5 | -5 | | 0 - 4 | 1 | four | 5 | -5 | 1 | -1 - 4 | 1 | four | 5 | -5 | 2 | 2 - 4 | 1 | four | 5 | -5 | 3 | -3 - 4 | 1 | four | 5 | -5 | 2 | 4 - 4 | 1 | four | 5 | -5 | 5 | -5 - 4 | 1 | four | 5 | -5 | 5 | -5 - 4 | 1 | four | 5 | -5 | 0 | - 4 | 1 | four | 5 | -5 | | - 4 | 1 | four | 5 | -5 | | 0 + 5 | 0 | five | 2 | 2 | 1 | -1 + 6 | 6 | six | 2 | 2 | 1 | -1 + 5 | 0 | five | 2 | 2 | 0 | + 6 | 6 | six | 2 | 2 | 0 | + 5 | 0 | five | 3 | -3 | 1 | -1 + 6 | 6 | six | 3 | -3 | 1 | -1 + 5 | 0 | five | 3 | -3 | 0 | + 6 | 6 | six | 3 | -3 | 0 | + 5 | 0 | five | 2 | 4 | 1 | -1 + 6 | 6 | six | 2 | 4 | 1 | -1 + 5 | 0 | five | 2 | 4 | 0 | + 6 | 6 | six | 2 | 4 | 0 | + 5 | 0 | five | | | 1 | -1 + 6 | 6 | six | | | 1 | -1 + 5 | 0 | five | | | 0 | + 6 | 6 | six | | | 0 | + 5 | 0 | five | | 0 | 1 | -1 + 6 | 6 | six | | 0 | 1 | -1 + 5 | 0 | five | | 0 | 0 | + 6 | 6 | six | | 0 | 0 | + 5 | 0 | five | 1 | -1 | 1 | -1 + 6 | 6 | six | 1 | -1 | 1 | -1 + 5 | 0 | five | 1 | -1 | 0 | + 6 | 6 | six | 1 | -1 | 0 | + 5 | 0 | five | 0 | | 1 | -1 + 6 | 6 | six | 0 | | 1 | -1 + 5 | 0 | five | 0 | | 0 | + 6 | 6 | six | 0 | | 0 | 5 | 0 | five | 5 | -5 | 1 | -1 - 5 | 0 | five | 5 | -5 | 2 | 2 - 5 | 0 | five | 5 | -5 | 3 | -3 - 5 | 0 | five | 5 | -5 | 2 | 4 - 5 | 0 | five | 5 | -5 | 5 | -5 - 5 | 0 | five | 5 | -5 | 5 | -5 + 6 | 6 | six | 5 | -5 | 1 | -1 5 | 0 | five | 5 | -5 | 0 | - 5 | 0 | five | 5 | -5 | | - 5 | 0 | five | 5 | -5 | | 0 + 6 | 6 | six | 5 | -5 | 0 | + 5 | 0 | five | 5 | -5 | 1 | -1 6 | 6 | six | 5 | -5 | 1 | -1 - 6 | 6 | six | 5 | -5 | 2 | 2 - 6 | 6 | six | 5 | -5 | 3 | -3 - 6 | 6 | six | 5 | -5 | 2 | 4 - 6 | 6 | six | 5 | -5 | 5 | -5 - 6 | 6 | six | 5 | -5 | 5 | -5 + 5 | 0 | five | 5 | -5 | 0 | 6 | 6 | six | 5 | -5 | 0 | - 6 | 6 | six | 5 | -5 | | - 6 | 6 | six | 5 | -5 | | 0 - 7 | 7 | seven | 5 | -5 | 1 | -1 + 5 | 0 | five | 1 | -1 | 5 | -5 + 6 | 6 | six | 1 | -1 | 5 | -5 + 5 | 0 | five | 1 | -1 | 5 | -5 + 6 | 6 | six | 1 | -1 | 5 | -5 + 5 | 0 | five | 0 | | 5 | -5 + 6 | 6 | six | 0 | | 5 | -5 + 5 | 0 | five | 0 | | 5 | -5 + 6 | 6 | six | 0 | | 5 | -5 + 5 | 0 | five | 5 | -5 | 5 | -5 + 6 | 6 | six | 5 | -5 | 5 | -5 + 5 | 0 | five | 5 | -5 | 5 | -5 + 6 | 6 | six | 5 | -5 | 5 | -5 + 5 | 0 | five | 5 | -5 | 5 | -5 + 6 | 6 | six | 5 | -5 | 5 | -5 + 5 | 0 | five | 5 | -5 | 5 | -5 + 6 | 6 | six | 5 | -5 | 5 | -5 + 5 | 0 | five | 2 | 2 | 5 | -5 + 6 | 6 | six | 2 | 2 | 5 | -5 + 5 | 0 | five | 2 | 2 | 5 | -5 + 6 | 6 | six | 2 | 2 | 5 | -5 + 5 | 0 | five | 3 | -3 | 5 | -5 + 6 | 6 | six | 3 | -3 | 5 | -5 + 5 | 0 | five | 3 | -3 | 5 | -5 + 6 | 6 | six | 3 | -3 | 5 | -5 + 5 | 0 | five | 2 | 4 | 5 | -5 + 6 | 6 | six | 2 | 4 | 5 | -5 + 5 | 0 | five | 2 | 4 | 5 | -5 + 6 | 6 | six | 2 | 4 | 5 | -5 + 5 | 0 | five | | | 5 | -5 + 6 | 6 | six | | | 5 | -5 + 5 | 0 | five | | | 5 | -5 + 6 | 6 | six | | | 5 | -5 + 5 | 0 | five | | 0 | 5 | -5 + 6 | 6 | six | | 0 | 5 | -5 + 5 | 0 | five | | 0 | 5 | -5 + 6 | 6 | six | | 0 | 5 | -5 + 7 | 7 | seven | 1 | -1 | | 0 + 8 | 8 | eight | 1 | -1 | | 0 + | | null | 1 | -1 | | 0 + | 0 | zero | 1 | -1 | | 0 + 2 | 3 | two | 0 | | 2 | 2 + 3 | 2 | three | 0 | | 2 | 2 + 4 | 1 | four | 0 | | 2 | 2 + 7 | 7 | seven | 0 | | 2 | 2 + 8 | 8 | eight | 0 | | 2 | 2 + | | null | 0 | | 2 | 2 + | 0 | zero | 0 | | 2 | 2 + 2 | 3 | two | 0 | | 3 | -3 + 3 | 2 | three | 0 | | 3 | -3 + 4 | 1 | four | 0 | | 3 | -3 + 7 | 7 | seven | 0 | | 3 | -3 + 8 | 8 | eight | 0 | | 3 | -3 + | | null | 0 | | 3 | -3 + | 0 | zero | 0 | | 3 | -3 + 2 | 3 | two | 0 | | 2 | 4 + 3 | 2 | three | 0 | | 2 | 4 + 4 | 1 | four | 0 | | 2 | 4 + 7 | 7 | seven | 0 | | 2 | 4 + 8 | 8 | eight | 0 | | 2 | 4 + | | null | 0 | | 2 | 4 + | 0 | zero | 0 | | 2 | 4 + 2 | 3 | two | 0 | | | + 3 | 2 | three | 0 | | | + 4 | 1 | four | 0 | | | + 7 | 7 | seven | 0 | | | + 8 | 8 | eight | 0 | | | + | | null | 0 | | | + | 0 | zero | 0 | | | + 2 | 3 | two | 0 | | | 0 + 3 | 2 | three | 0 | | | 0 + 4 | 1 | four | 0 | | | 0 + 7 | 7 | seven | 0 | | | 0 + 8 | 8 | eight | 0 | | | 0 + | | null | 0 | | | 0 + | 0 | zero | 0 | | | 0 + 2 | 3 | two | 5 | -5 | 2 | 2 + 3 | 2 | three | 5 | -5 | 2 | 2 + 4 | 1 | four | 5 | -5 | 2 | 2 7 | 7 | seven | 5 | -5 | 2 | 2 - 7 | 7 | seven | 5 | -5 | 3 | -3 - 7 | 7 | seven | 5 | -5 | 2 | 4 - 7 | 7 | seven | 5 | -5 | 5 | -5 - 7 | 7 | seven | 5 | -5 | 5 | -5 - 7 | 7 | seven | 5 | -5 | 0 | - 7 | 7 | seven | 5 | -5 | | - 7 | 7 | seven | 5 | -5 | | 0 - 8 | 8 | eight | 5 | -5 | 1 | -1 8 | 8 | eight | 5 | -5 | 2 | 2 - 8 | 8 | eight | 5 | -5 | 3 | -3 - 8 | 8 | eight | 5 | -5 | 2 | 4 - 8 | 8 | eight | 5 | -5 | 5 | -5 - 8 | 8 | eight | 5 | -5 | 5 | -5 - 8 | 8 | eight | 5 | -5 | 0 | - 8 | 8 | eight | 5 | -5 | | - 8 | 8 | eight | 5 | -5 | | 0 - 0 | | zero | 5 | -5 | 1 | -1 - 0 | | zero | 5 | -5 | 2 | 2 - 0 | | zero | 5 | -5 | 3 | -3 - 0 | | zero | 5 | -5 | 2 | 4 - 0 | | zero | 5 | -5 | 5 | -5 - 0 | | zero | 5 | -5 | 5 | -5 - 0 | | zero | 5 | -5 | 0 | - 0 | | zero | 5 | -5 | | - 0 | | zero | 5 | -5 | | 0 - | | null | 5 | -5 | 1 | -1 | | null | 5 | -5 | 2 | 2 + | 0 | zero | 5 | -5 | 2 | 2 + 2 | 3 | two | 5 | -5 | 3 | -3 + 3 | 2 | three | 5 | -5 | 3 | -3 + 4 | 1 | four | 5 | -5 | 3 | -3 + 7 | 7 | seven | 5 | -5 | 3 | -3 + 8 | 8 | eight | 5 | -5 | 3 | -3 | | null | 5 | -5 | 3 | -3 + | 0 | zero | 5 | -5 | 3 | -3 + 2 | 3 | two | 5 | -5 | 2 | 4 + 3 | 2 | three | 5 | -5 | 2 | 4 + 4 | 1 | four | 5 | -5 | 2 | 4 + 7 | 7 | seven | 5 | -5 | 2 | 4 + 8 | 8 | eight | 5 | -5 | 2 | 4 | | null | 5 | -5 | 2 | 4 - | | null | 5 | -5 | 5 | -5 - | | null | 5 | -5 | 5 | -5 - | | null | 5 | -5 | 0 | + | 0 | zero | 5 | -5 | 2 | 4 + 2 | 3 | two | 5 | -5 | | + 3 | 2 | three | 5 | -5 | | + 4 | 1 | four | 5 | -5 | | + 7 | 7 | seven | 5 | -5 | | + 8 | 8 | eight | 5 | -5 | | | | null | 5 | -5 | | + | 0 | zero | 5 | -5 | | + 2 | 3 | two | 5 | -5 | | 0 + 3 | 2 | three | 5 | -5 | | 0 + 4 | 1 | four | 5 | -5 | | 0 + 7 | 7 | seven | 5 | -5 | | 0 + 8 | 8 | eight | 5 | -5 | | 0 | | null | 5 | -5 | | 0 - | 0 | zero | 5 | -5 | 1 | -1 + | 0 | zero | 5 | -5 | | 0 + 2 | 3 | two | 5 | -5 | 2 | 2 + 3 | 2 | three | 5 | -5 | 2 | 2 + 4 | 1 | four | 5 | -5 | 2 | 2 + 7 | 7 | seven | 5 | -5 | 2 | 2 + 8 | 8 | eight | 5 | -5 | 2 | 2 + | | null | 5 | -5 | 2 | 2 | 0 | zero | 5 | -5 | 2 | 2 + 2 | 3 | two | 5 | -5 | 3 | -3 + 3 | 2 | three | 5 | -5 | 3 | -3 + 4 | 1 | four | 5 | -5 | 3 | -3 + 7 | 7 | seven | 5 | -5 | 3 | -3 + 8 | 8 | eight | 5 | -5 | 3 | -3 + | | null | 5 | -5 | 3 | -3 | 0 | zero | 5 | -5 | 3 | -3 + 2 | 3 | two | 5 | -5 | 2 | 4 + 3 | 2 | three | 5 | -5 | 2 | 4 + 4 | 1 | four | 5 | -5 | 2 | 4 + 7 | 7 | seven | 5 | -5 | 2 | 4 + 8 | 8 | eight | 5 | -5 | 2 | 4 + | | null | 5 | -5 | 2 | 4 | 0 | zero | 5 | -5 | 2 | 4 - | 0 | zero | 5 | -5 | 5 | -5 - | 0 | zero | 5 | -5 | 5 | -5 - | 0 | zero | 5 | -5 | 0 | + 2 | 3 | two | 5 | -5 | | + 3 | 2 | three | 5 | -5 | | + 4 | 1 | four | 5 | -5 | | + 7 | 7 | seven | 5 | -5 | | + 8 | 8 | eight | 5 | -5 | | + | | null | 5 | -5 | | | 0 | zero | 5 | -5 | | + 2 | 3 | two | 5 | -5 | | 0 + 3 | 2 | three | 5 | -5 | | 0 + 4 | 1 | four | 5 | -5 | | 0 + 7 | 7 | seven | 5 | -5 | | 0 + 8 | 8 | eight | 5 | -5 | | 0 + | | null | 5 | -5 | | 0 | 0 | zero | 5 | -5 | | 0 - 1 | 4 | one | 0 | | 1 | -1 - 1 | 4 | one | 0 | | 2 | 2 - 1 | 4 | one | 0 | | 3 | -3 - 1 | 4 | one | 0 | | 2 | 4 - 1 | 4 | one | 0 | | 5 | -5 - 1 | 4 | one | 0 | | 5 | -5 - 1 | 4 | one | 0 | | 0 | - 1 | 4 | one | 0 | | | - 1 | 4 | one | 0 | | | 0 - 2 | 3 | two | 0 | | 1 | -1 - 2 | 3 | two | 0 | | 2 | 2 - 2 | 3 | two | 0 | | 3 | -3 - 2 | 3 | two | 0 | | 2 | 4 - 2 | 3 | two | 0 | | 5 | -5 - 2 | 3 | two | 0 | | 5 | -5 - 2 | 3 | two | 0 | | 0 | - 2 | 3 | two | 0 | | | - 2 | 3 | two | 0 | | | 0 - 3 | 2 | three | 0 | | 1 | -1 - 3 | 2 | three | 0 | | 2 | 2 - 3 | 2 | three | 0 | | 3 | -3 - 3 | 2 | three | 0 | | 2 | 4 - 3 | 2 | three | 0 | | 5 | -5 - 3 | 2 | three | 0 | | 5 | -5 - 3 | 2 | three | 0 | | 0 | - 3 | 2 | three | 0 | | | - 3 | 2 | three | 0 | | | 0 - 4 | 1 | four | 0 | | 1 | -1 - 4 | 1 | four | 0 | | 2 | 2 - 4 | 1 | four | 0 | | 3 | -3 - 4 | 1 | four | 0 | | 2 | 4 - 4 | 1 | four | 0 | | 5 | -5 - 4 | 1 | four | 0 | | 5 | -5 - 4 | 1 | four | 0 | | 0 | - 4 | 1 | four | 0 | | | - 4 | 1 | four | 0 | | | 0 - 5 | 0 | five | 0 | | 1 | -1 - 5 | 0 | five | 0 | | 2 | 2 - 5 | 0 | five | 0 | | 3 | -3 - 5 | 0 | five | 0 | | 2 | 4 - 5 | 0 | five | 0 | | 5 | -5 - 5 | 0 | five | 0 | | 5 | -5 - 5 | 0 | five | 0 | | 0 | - 5 | 0 | five | 0 | | | - 5 | 0 | five | 0 | | | 0 - 6 | 6 | six | 0 | | 1 | -1 - 6 | 6 | six | 0 | | 2 | 2 - 6 | 6 | six | 0 | | 3 | -3 - 6 | 6 | six | 0 | | 2 | 4 - 6 | 6 | six | 0 | | 5 | -5 - 6 | 6 | six | 0 | | 5 | -5 - 6 | 6 | six | 0 | | 0 | - 6 | 6 | six | 0 | | | - 6 | 6 | six | 0 | | | 0 - 7 | 7 | seven | 0 | | 1 | -1 - 7 | 7 | seven | 0 | | 2 | 2 - 7 | 7 | seven | 0 | | 3 | -3 - 7 | 7 | seven | 0 | | 2 | 4 - 7 | 7 | seven | 0 | | 5 | -5 - 7 | 7 | seven | 0 | | 5 | -5 - 7 | 7 | seven | 0 | | 0 | - 7 | 7 | seven | 0 | | | - 7 | 7 | seven | 0 | | | 0 - 8 | 8 | eight | 0 | | 1 | -1 - 8 | 8 | eight | 0 | | 2 | 2 - 8 | 8 | eight | 0 | | 3 | -3 - 8 | 8 | eight | 0 | | 2 | 4 - 8 | 8 | eight | 0 | | 5 | -5 - 8 | 8 | eight | 0 | | 5 | -5 - 8 | 8 | eight | 0 | | 0 | - 8 | 8 | eight | 0 | | | - 8 | 8 | eight | 0 | | | 0 - 0 | | zero | 0 | | 1 | -1 - 0 | | zero | 0 | | 2 | 2 - 0 | | zero | 0 | | 3 | -3 - 0 | | zero | 0 | | 2 | 4 - 0 | | zero | 0 | | 5 | -5 - 0 | | zero | 0 | | 5 | -5 - 0 | | zero | 0 | | 0 | - 0 | | zero | 0 | | | - 0 | | zero | 0 | | | 0 - | | null | 0 | | 1 | -1 - | | null | 0 | | 2 | 2 - | | null | 0 | | 3 | -3 - | | null | 0 | | 2 | 4 - | | null | 0 | | 5 | -5 - | | null | 0 | | 5 | -5 - | | null | 0 | | 0 | - | | null | 0 | | | - | | null | 0 | | | 0 - | 0 | zero | 0 | | 1 | -1 - | 0 | zero | 0 | | 2 | 2 - | 0 | zero | 0 | | 3 | -3 - | 0 | zero | 0 | | 2 | 4 - | 0 | zero | 0 | | 5 | -5 - | 0 | zero | 0 | | 5 | -5 - | 0 | zero | 0 | | 0 | - | 0 | zero | 0 | | | - | 0 | zero | 0 | | | 0 - 1 | 4 | one | | | 1 | -1 - 1 | 4 | one | | | 2 | 2 - 1 | 4 | one | | | 3 | -3 - 1 | 4 | one | | | 2 | 4 - 1 | 4 | one | | | 5 | -5 - 1 | 4 | one | | | 5 | -5 - 1 | 4 | one | | | 0 | - 1 | 4 | one | | | | - 1 | 4 | one | | | | 0 + 2 | 3 | two | 2 | 2 | 1 | -1 + 3 | 2 | three | 2 | 2 | 1 | -1 + 4 | 1 | four | 2 | 2 | 1 | -1 + 7 | 7 | seven | 2 | 2 | 1 | -1 + 8 | 8 | eight | 2 | 2 | 1 | -1 + | | null | 2 | 2 | 1 | -1 + | 0 | zero | 2 | 2 | 1 | -1 + 2 | 3 | two | 2 | 2 | 0 | + 3 | 2 | three | 2 | 2 | 0 | + 4 | 1 | four | 2 | 2 | 0 | + 7 | 7 | seven | 2 | 2 | 0 | + 8 | 8 | eight | 2 | 2 | 0 | + | | null | 2 | 2 | 0 | + | 0 | zero | 2 | 2 | 0 | + 2 | 3 | two | 3 | -3 | 1 | -1 + 3 | 2 | three | 3 | -3 | 1 | -1 + 4 | 1 | four | 3 | -3 | 1 | -1 + 7 | 7 | seven | 3 | -3 | 1 | -1 + 8 | 8 | eight | 3 | -3 | 1 | -1 + | | null | 3 | -3 | 1 | -1 + | 0 | zero | 3 | -3 | 1 | -1 + 2 | 3 | two | 3 | -3 | 0 | + 3 | 2 | three | 3 | -3 | 0 | + 4 | 1 | four | 3 | -3 | 0 | + 7 | 7 | seven | 3 | -3 | 0 | + 8 | 8 | eight | 3 | -3 | 0 | + | | null | 3 | -3 | 0 | + | 0 | zero | 3 | -3 | 0 | + 2 | 3 | two | 2 | 4 | 1 | -1 + 3 | 2 | three | 2 | 4 | 1 | -1 + 4 | 1 | four | 2 | 4 | 1 | -1 + 7 | 7 | seven | 2 | 4 | 1 | -1 + 8 | 8 | eight | 2 | 4 | 1 | -1 + | | null | 2 | 4 | 1 | -1 + | 0 | zero | 2 | 4 | 1 | -1 + 2 | 3 | two | 2 | 4 | 0 | + 3 | 2 | three | 2 | 4 | 0 | + 4 | 1 | four | 2 | 4 | 0 | + 7 | 7 | seven | 2 | 4 | 0 | + 8 | 8 | eight | 2 | 4 | 0 | + | | null | 2 | 4 | 0 | + | 0 | zero | 2 | 4 | 0 | 2 | 3 | two | | | 1 | -1 - 2 | 3 | two | | | 2 | 2 - 2 | 3 | two | | | 3 | -3 - 2 | 3 | two | | | 2 | 4 - 2 | 3 | two | | | 5 | -5 - 2 | 3 | two | | | 5 | -5 - 2 | 3 | two | | | 0 | - 2 | 3 | two | | | | - 2 | 3 | two | | | | 0 3 | 2 | three | | | 1 | -1 - 3 | 2 | three | | | 2 | 2 - 3 | 2 | three | | | 3 | -3 - 3 | 2 | three | | | 2 | 4 - 3 | 2 | three | | | 5 | -5 - 3 | 2 | three | | | 5 | -5 - 3 | 2 | three | | | 0 | - 3 | 2 | three | | | | - 3 | 2 | three | | | | 0 4 | 1 | four | | | 1 | -1 - 4 | 1 | four | | | 2 | 2 - 4 | 1 | four | | | 3 | -3 - 4 | 1 | four | | | 2 | 4 - 4 | 1 | four | | | 5 | -5 - 4 | 1 | four | | | 5 | -5 - 4 | 1 | four | | | 0 | - 4 | 1 | four | | | | - 4 | 1 | four | | | | 0 - 5 | 0 | five | | | 1 | -1 - 5 | 0 | five | | | 2 | 2 - 5 | 0 | five | | | 3 | -3 - 5 | 0 | five | | | 2 | 4 - 5 | 0 | five | | | 5 | -5 - 5 | 0 | five | | | 5 | -5 - 5 | 0 | five | | | 0 | - 5 | 0 | five | | | | - 5 | 0 | five | | | | 0 - 6 | 6 | six | | | 1 | -1 - 6 | 6 | six | | | 2 | 2 - 6 | 6 | six | | | 3 | -3 - 6 | 6 | six | | | 2 | 4 - 6 | 6 | six | | | 5 | -5 - 6 | 6 | six | | | 5 | -5 - 6 | 6 | six | | | 0 | - 6 | 6 | six | | | | - 6 | 6 | six | | | | 0 7 | 7 | seven | | | 1 | -1 - 7 | 7 | seven | | | 2 | 2 - 7 | 7 | seven | | | 3 | -3 - 7 | 7 | seven | | | 2 | 4 - 7 | 7 | seven | | | 5 | -5 - 7 | 7 | seven | | | 5 | -5 - 7 | 7 | seven | | | 0 | - 7 | 7 | seven | | | | - 7 | 7 | seven | | | | 0 8 | 8 | eight | | | 1 | -1 - 8 | 8 | eight | | | 2 | 2 - 8 | 8 | eight | | | 3 | -3 - 8 | 8 | eight | | | 2 | 4 - 8 | 8 | eight | | | 5 | -5 - 8 | 8 | eight | | | 5 | -5 - 8 | 8 | eight | | | 0 | - 8 | 8 | eight | | | | - 8 | 8 | eight | | | | 0 - 0 | | zero | | | 1 | -1 - 0 | | zero | | | 2 | 2 - 0 | | zero | | | 3 | -3 - 0 | | zero | | | 2 | 4 - 0 | | zero | | | 5 | -5 - 0 | | zero | | | 5 | -5 - 0 | | zero | | | 0 | - 0 | | zero | | | | - 0 | | zero | | | | 0 | | null | | | 1 | -1 - | | null | | | 2 | 2 - | | null | | | 3 | -3 - | | null | | | 2 | 4 - | | null | | | 5 | -5 - | | null | | | 5 | -5 - | | null | | | 0 | - | | null | | | | - | | null | | | | 0 | 0 | zero | | | 1 | -1 - | 0 | zero | | | 2 | 2 - | 0 | zero | | | 3 | -3 - | 0 | zero | | | 2 | 4 - | 0 | zero | | | 5 | -5 - | 0 | zero | | | 5 | -5 + 2 | 3 | two | | | 0 | + 3 | 2 | three | | | 0 | + 4 | 1 | four | | | 0 | + 7 | 7 | seven | | | 0 | + 8 | 8 | eight | | | 0 | + | | null | | | 0 | | 0 | zero | | | 0 | - | 0 | zero | | | | - | 0 | zero | | | | 0 - 1 | 4 | one | | 0 | 1 | -1 - 1 | 4 | one | | 0 | 2 | 2 - 1 | 4 | one | | 0 | 3 | -3 - 1 | 4 | one | | 0 | 2 | 4 - 1 | 4 | one | | 0 | 5 | -5 - 1 | 4 | one | | 0 | 5 | -5 - 1 | 4 | one | | 0 | 0 | - 1 | 4 | one | | 0 | | - 1 | 4 | one | | 0 | | 0 2 | 3 | two | | 0 | 1 | -1 - 2 | 3 | two | | 0 | 2 | 2 - 2 | 3 | two | | 0 | 3 | -3 - 2 | 3 | two | | 0 | 2 | 4 - 2 | 3 | two | | 0 | 5 | -5 - 2 | 3 | two | | 0 | 5 | -5 - 2 | 3 | two | | 0 | 0 | - 2 | 3 | two | | 0 | | - 2 | 3 | two | | 0 | | 0 3 | 2 | three | | 0 | 1 | -1 - 3 | 2 | three | | 0 | 2 | 2 - 3 | 2 | three | | 0 | 3 | -3 - 3 | 2 | three | | 0 | 2 | 4 - 3 | 2 | three | | 0 | 5 | -5 - 3 | 2 | three | | 0 | 5 | -5 - 3 | 2 | three | | 0 | 0 | - 3 | 2 | three | | 0 | | - 3 | 2 | three | | 0 | | 0 4 | 1 | four | | 0 | 1 | -1 - 4 | 1 | four | | 0 | 2 | 2 - 4 | 1 | four | | 0 | 3 | -3 - 4 | 1 | four | | 0 | 2 | 4 - 4 | 1 | four | | 0 | 5 | -5 - 4 | 1 | four | | 0 | 5 | -5 - 4 | 1 | four | | 0 | 0 | - 4 | 1 | four | | 0 | | - 4 | 1 | four | | 0 | | 0 - 5 | 0 | five | | 0 | 1 | -1 - 5 | 0 | five | | 0 | 2 | 2 - 5 | 0 | five | | 0 | 3 | -3 - 5 | 0 | five | | 0 | 2 | 4 - 5 | 0 | five | | 0 | 5 | -5 - 5 | 0 | five | | 0 | 5 | -5 - 5 | 0 | five | | 0 | 0 | - 5 | 0 | five | | 0 | | - 5 | 0 | five | | 0 | | 0 - 6 | 6 | six | | 0 | 1 | -1 - 6 | 6 | six | | 0 | 2 | 2 - 6 | 6 | six | | 0 | 3 | -3 - 6 | 6 | six | | 0 | 2 | 4 - 6 | 6 | six | | 0 | 5 | -5 - 6 | 6 | six | | 0 | 5 | -5 - 6 | 6 | six | | 0 | 0 | - 6 | 6 | six | | 0 | | - 6 | 6 | six | | 0 | | 0 7 | 7 | seven | | 0 | 1 | -1 - 7 | 7 | seven | | 0 | 2 | 2 - 7 | 7 | seven | | 0 | 3 | -3 - 7 | 7 | seven | | 0 | 2 | 4 - 7 | 7 | seven | | 0 | 5 | -5 + 8 | 8 | eight | | 0 | 1 | -1 + | | null | | 0 | 1 | -1 + | 0 | zero | | 0 | 1 | -1 + 2 | 3 | two | | 0 | 0 | + 3 | 2 | three | | 0 | 0 | + 4 | 1 | four | | 0 | 0 | + 7 | 7 | seven | | 0 | 0 | + 8 | 8 | eight | | 0 | 0 | + | | null | | 0 | 0 | + | 0 | zero | | 0 | 0 | + 2 | 3 | two | 1 | -1 | 1 | -1 + 3 | 2 | three | 1 | -1 | 1 | -1 + 4 | 1 | four | 1 | -1 | 1 | -1 + 7 | 7 | seven | 1 | -1 | 1 | -1 + 8 | 8 | eight | 1 | -1 | 1 | -1 + | | null | 1 | -1 | 1 | -1 + | 0 | zero | 1 | -1 | 1 | -1 + 2 | 3 | two | 1 | -1 | 0 | + 3 | 2 | three | 1 | -1 | 0 | + 4 | 1 | four | 1 | -1 | 0 | + 7 | 7 | seven | 1 | -1 | 0 | + 8 | 8 | eight | 1 | -1 | 0 | + | | null | 1 | -1 | 0 | + | 0 | zero | 1 | -1 | 0 | + 2 | 3 | two | 0 | | 1 | -1 + 3 | 2 | three | 0 | | 1 | -1 + 4 | 1 | four | 0 | | 1 | -1 + 7 | 7 | seven | 0 | | 1 | -1 + 8 | 8 | eight | 0 | | 1 | -1 + | | null | 0 | | 1 | -1 + | 0 | zero | 0 | | 1 | -1 + 2 | 3 | two | 0 | | 0 | + 3 | 2 | three | 0 | | 0 | + 4 | 1 | four | 0 | | 0 | + 7 | 7 | seven | 0 | | 0 | + 8 | 8 | eight | 0 | | 0 | + | | null | 0 | | 0 | + | 0 | zero | 0 | | 0 | + 2 | 3 | two | 5 | -5 | 1 | -1 + 3 | 2 | three | 5 | -5 | 1 | -1 + 4 | 1 | four | 5 | -5 | 1 | -1 + 7 | 7 | seven | 5 | -5 | 1 | -1 + 8 | 8 | eight | 5 | -5 | 1 | -1 + | | null | 5 | -5 | 1 | -1 + | 0 | zero | 5 | -5 | 1 | -1 + 2 | 3 | two | 5 | -5 | 0 | + 3 | 2 | three | 5 | -5 | 0 | + 4 | 1 | four | 5 | -5 | 0 | + 7 | 7 | seven | 5 | -5 | 0 | + 8 | 8 | eight | 5 | -5 | 0 | + | | null | 5 | -5 | 0 | + | 0 | zero | 5 | -5 | 0 | + 2 | 3 | two | 5 | -5 | 1 | -1 + 3 | 2 | three | 5 | -5 | 1 | -1 + 4 | 1 | four | 5 | -5 | 1 | -1 + 7 | 7 | seven | 5 | -5 | 1 | -1 + 8 | 8 | eight | 5 | -5 | 1 | -1 + | | null | 5 | -5 | 1 | -1 + | 0 | zero | 5 | -5 | 1 | -1 + 2 | 3 | two | 5 | -5 | 0 | + 3 | 2 | three | 5 | -5 | 0 | + 4 | 1 | four | 5 | -5 | 0 | + 7 | 7 | seven | 5 | -5 | 0 | + 8 | 8 | eight | 5 | -5 | 0 | + | | null | 5 | -5 | 0 | + | 0 | zero | 5 | -5 | 0 | + 2 | 3 | two | 1 | -1 | 5 | -5 + 3 | 2 | three | 1 | -1 | 5 | -5 + 4 | 1 | four | 1 | -1 | 5 | -5 + 7 | 7 | seven | 1 | -1 | 5 | -5 + 8 | 8 | eight | 1 | -1 | 5 | -5 + | | null | 1 | -1 | 5 | -5 + | 0 | zero | 1 | -1 | 5 | -5 + 2 | 3 | two | 1 | -1 | 5 | -5 + 3 | 2 | three | 1 | -1 | 5 | -5 + 4 | 1 | four | 1 | -1 | 5 | -5 + 7 | 7 | seven | 1 | -1 | 5 | -5 + 8 | 8 | eight | 1 | -1 | 5 | -5 + | | null | 1 | -1 | 5 | -5 + | 0 | zero | 1 | -1 | 5 | -5 + 2 | 3 | two | 0 | | 5 | -5 + 3 | 2 | three | 0 | | 5 | -5 + 4 | 1 | four | 0 | | 5 | -5 + 7 | 7 | seven | 0 | | 5 | -5 + 8 | 8 | eight | 0 | | 5 | -5 + | | null | 0 | | 5 | -5 + | 0 | zero | 0 | | 5 | -5 + 2 | 3 | two | 0 | | 5 | -5 + 3 | 2 | three | 0 | | 5 | -5 + 4 | 1 | four | 0 | | 5 | -5 + 7 | 7 | seven | 0 | | 5 | -5 + 8 | 8 | eight | 0 | | 5 | -5 + | | null | 0 | | 5 | -5 + | 0 | zero | 0 | | 5 | -5 + 2 | 3 | two | 5 | -5 | 5 | -5 + 3 | 2 | three | 5 | -5 | 5 | -5 + 4 | 1 | four | 5 | -5 | 5 | -5 + 7 | 7 | seven | 5 | -5 | 5 | -5 + 8 | 8 | eight | 5 | -5 | 5 | -5 + | | null | 5 | -5 | 5 | -5 + | 0 | zero | 5 | -5 | 5 | -5 + 2 | 3 | two | 5 | -5 | 5 | -5 + 3 | 2 | three | 5 | -5 | 5 | -5 + 4 | 1 | four | 5 | -5 | 5 | -5 + 7 | 7 | seven | 5 | -5 | 5 | -5 + 8 | 8 | eight | 5 | -5 | 5 | -5 + | | null | 5 | -5 | 5 | -5 + | 0 | zero | 5 | -5 | 5 | -5 + 2 | 3 | two | 5 | -5 | 5 | -5 + 3 | 2 | three | 5 | -5 | 5 | -5 + 4 | 1 | four | 5 | -5 | 5 | -5 + 7 | 7 | seven | 5 | -5 | 5 | -5 + 8 | 8 | eight | 5 | -5 | 5 | -5 + | | null | 5 | -5 | 5 | -5 + | 0 | zero | 5 | -5 | 5 | -5 + 2 | 3 | two | 5 | -5 | 5 | -5 + 3 | 2 | three | 5 | -5 | 5 | -5 + 4 | 1 | four | 5 | -5 | 5 | -5 + 7 | 7 | seven | 5 | -5 | 5 | -5 + 8 | 8 | eight | 5 | -5 | 5 | -5 + | | null | 5 | -5 | 5 | -5 + | 0 | zero | 5 | -5 | 5 | -5 + 2 | 3 | two | 2 | 2 | 5 | -5 + 3 | 2 | three | 2 | 2 | 5 | -5 + 4 | 1 | four | 2 | 2 | 5 | -5 + 7 | 7 | seven | 2 | 2 | 5 | -5 + 8 | 8 | eight | 2 | 2 | 5 | -5 + | | null | 2 | 2 | 5 | -5 + | 0 | zero | 2 | 2 | 5 | -5 + 2 | 3 | two | 2 | 2 | 5 | -5 + 3 | 2 | three | 2 | 2 | 5 | -5 + 4 | 1 | four | 2 | 2 | 5 | -5 + 7 | 7 | seven | 2 | 2 | 5 | -5 + 8 | 8 | eight | 2 | 2 | 5 | -5 + | | null | 2 | 2 | 5 | -5 + | 0 | zero | 2 | 2 | 5 | -5 + 2 | 3 | two | 3 | -3 | 5 | -5 + 3 | 2 | three | 3 | -3 | 5 | -5 + 4 | 1 | four | 3 | -3 | 5 | -5 + 7 | 7 | seven | 3 | -3 | 5 | -5 + 8 | 8 | eight | 3 | -3 | 5 | -5 + | | null | 3 | -3 | 5 | -5 + | 0 | zero | 3 | -3 | 5 | -5 + 2 | 3 | two | 3 | -3 | 5 | -5 + 3 | 2 | three | 3 | -3 | 5 | -5 + 4 | 1 | four | 3 | -3 | 5 | -5 + 7 | 7 | seven | 3 | -3 | 5 | -5 + 8 | 8 | eight | 3 | -3 | 5 | -5 + | | null | 3 | -3 | 5 | -5 + | 0 | zero | 3 | -3 | 5 | -5 + 2 | 3 | two | 2 | 4 | 5 | -5 + 3 | 2 | three | 2 | 4 | 5 | -5 + 4 | 1 | four | 2 | 4 | 5 | -5 + 7 | 7 | seven | 2 | 4 | 5 | -5 + 8 | 8 | eight | 2 | 4 | 5 | -5 + | | null | 2 | 4 | 5 | -5 + | 0 | zero | 2 | 4 | 5 | -5 + 2 | 3 | two | 2 | 4 | 5 | -5 + 3 | 2 | three | 2 | 4 | 5 | -5 + 4 | 1 | four | 2 | 4 | 5 | -5 + 7 | 7 | seven | 2 | 4 | 5 | -5 + 8 | 8 | eight | 2 | 4 | 5 | -5 + | | null | 2 | 4 | 5 | -5 + | 0 | zero | 2 | 4 | 5 | -5 + 2 | 3 | two | | | 5 | -5 + 3 | 2 | three | | | 5 | -5 + 4 | 1 | four | | | 5 | -5 + 7 | 7 | seven | | | 5 | -5 + 8 | 8 | eight | | | 5 | -5 + | | null | | | 5 | -5 + | 0 | zero | | | 5 | -5 + 2 | 3 | two | | | 5 | -5 + 3 | 2 | three | | | 5 | -5 + 4 | 1 | four | | | 5 | -5 + 7 | 7 | seven | | | 5 | -5 + 8 | 8 | eight | | | 5 | -5 + | | null | | | 5 | -5 + | 0 | zero | | | 5 | -5 + 2 | 3 | two | | 0 | 5 | -5 + 3 | 2 | three | | 0 | 5 | -5 + 4 | 1 | four | | 0 | 5 | -5 7 | 7 | seven | | 0 | 5 | -5 - 7 | 7 | seven | | 0 | 0 | - 7 | 7 | seven | | 0 | | - 7 | 7 | seven | | 0 | | 0 - 8 | 8 | eight | | 0 | 1 | -1 - 8 | 8 | eight | | 0 | 2 | 2 - 8 | 8 | eight | | 0 | 3 | -3 - 8 | 8 | eight | | 0 | 2 | 4 8 | 8 | eight | | 0 | 5 | -5 - 8 | 8 | eight | | 0 | 5 | -5 - 8 | 8 | eight | | 0 | 0 | - 8 | 8 | eight | | 0 | | - 8 | 8 | eight | | 0 | | 0 - 0 | | zero | | 0 | 1 | -1 - 0 | | zero | | 0 | 2 | 2 - 0 | | zero | | 0 | 3 | -3 - 0 | | zero | | 0 | 2 | 4 - 0 | | zero | | 0 | 5 | -5 - 0 | | zero | | 0 | 5 | -5 - 0 | | zero | | 0 | 0 | - 0 | | zero | | 0 | | - 0 | | zero | | 0 | | 0 - | | null | | 0 | 1 | -1 - | | null | | 0 | 2 | 2 - | | null | | 0 | 3 | -3 - | | null | | 0 | 2 | 4 - | | null | | 0 | 5 | -5 | | null | | 0 | 5 | -5 - | | null | | 0 | 0 | - | | null | | 0 | | - | | null | | 0 | | 0 - | 0 | zero | | 0 | 1 | -1 - | 0 | zero | | 0 | 2 | 2 - | 0 | zero | | 0 | 3 | -3 - | 0 | zero | | 0 | 2 | 4 | 0 | zero | | 0 | 5 | -5 + 2 | 3 | two | | 0 | 5 | -5 + 3 | 2 | three | | 0 | 5 | -5 + 4 | 1 | four | | 0 | 5 | -5 + 7 | 7 | seven | | 0 | 5 | -5 + 8 | 8 | eight | | 0 | 5 | -5 + | | null | | 0 | 5 | -5 | 0 | zero | | 0 | 5 | -5 - | 0 | zero | | 0 | 0 | - | 0 | zero | | 0 | | - | 0 | zero | | 0 | | 0 (891 rows) -- @@ -1578,13 +1578,13 @@ SELECT * FROM J1_TBL INNER JOIN J2_TBL USING (i); i | j | t | k ---+---+-------+---- - 0 | | zero | 1 | 4 | one | -1 - 2 | 3 | two | 2 - 2 | 3 | two | 4 - 3 | 2 | three | -3 + 0 | | zero | 5 | 0 | five | -5 5 | 0 | five | -5 + 2 | 3 | two | 4 + 2 | 3 | two | 2 + 3 | 2 | three | -3 (7 rows) -- Same as above, slightly different syntax @@ -1592,10 +1592,10 @@ SELECT * FROM J1_TBL JOIN J2_TBL USING (i); i | j | t | k ---+---+-------+---- - 0 | | zero | 1 | 4 | one | -1 - 2 | 3 | two | 2 + 0 | | zero | 2 | 3 | two | 4 + 2 | 3 | two | 2 3 | 2 | three | -3 5 | 0 | five | -5 5 | 0 | five | -5 @@ -1686,26 +1686,26 @@ SELECT * FROM J1_TBL NATURAL JOIN J2_TBL; i | j | t | k ---+---+-------+---- - 0 | | zero | - 1 | 4 | one | -1 - 2 | 3 | two | 2 2 | 3 | two | 4 + 2 | 3 | two | 2 3 | 2 | three | -3 5 | 0 | five | -5 5 | 0 | five | -5 + 1 | 4 | one | -1 + 0 | | zero | (7 rows) SELECT * FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (a, d); a | b | c | d ---+---+-------+---- - 0 | | zero | - 1 | 4 | one | -1 - 2 | 3 | two | 2 2 | 3 | two | 4 + 2 | 3 | two | 2 3 | 2 | three | -3 5 | 0 | five | -5 5 | 0 | five | -5 + 1 | 4 | one | -1 + 0 | | zero | (7 rows) SELECT * @@ -1723,13 +1723,13 @@ SELECT * FROM J1_TBL t1 (a, b) NATURAL JOIN J2_TBL t2 (a); a | b | t | k ---+---+-------+---- - 0 | | zero | + 5 | 0 | five | -5 + 5 | 0 | five | -5 1 | 4 | one | -1 - 2 | 3 | two | 2 + 0 | | zero | 2 | 3 | two | 4 + 2 | 3 | two | 2 3 | 2 | three | -3 - 5 | 0 | five | -5 - 5 | 0 | five | -5 (7 rows) -- @@ -1739,13 +1739,13 @@ SELECT * FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.i); i | j | t | i | k ---+---+-------+---+---- - 0 | | zero | 0 | + 5 | 0 | five | 5 | -5 + 5 | 0 | five | 5 | -5 1 | 4 | one | 1 | -1 - 2 | 3 | two | 2 | 2 + 0 | | zero | 0 | 2 | 3 | two | 2 | 4 + 2 | 3 | two | 2 | 2 3 | 2 | three | 3 | -3 - 5 | 0 | five | 5 | -5 - 5 | 0 | five | 5 | -5 (7 rows) SELECT * @@ -1765,14 +1765,14 @@ SELECT * i | j | t | i | k ---+---+-------+---+--- 1 | 4 | one | 2 | 2 - 2 | 3 | two | 2 | 2 0 | | zero | 2 | 2 1 | 4 | one | 2 | 4 + 0 | | zero | 2 | 4 + 0 | | zero | | 0 + 2 | 3 | two | 2 | 2 2 | 3 | two | 2 | 4 3 | 2 | three | 2 | 4 4 | 1 | four | 2 | 4 - 0 | | zero | 2 | 4 - 0 | | zero | | 0 (9 rows) -- @@ -1823,13 +1823,13 @@ SELECT * FROM J1_TBL RIGHT OUTER JOIN J2_TBL USING (i); i | j | t | k ---+---+-------+---- - 0 | | zero | 1 | 4 | one | -1 - 2 | 3 | two | 2 - 2 | 3 | two | 4 - 3 | 2 | three | -3 + 0 | | zero | 5 | 0 | five | -5 5 | 0 | five | -5 + 2 | 3 | two | 2 + 3 | 2 | three | -3 + 2 | 3 | two | 4 | | | | | | 0 (9 rows) @@ -1838,15 +1838,15 @@ SELECT * FROM J1_TBL RIGHT JOIN J2_TBL USING (i); i | j | t | k ---+---+-------+---- - 0 | | zero | 1 | 4 | one | -1 + 0 | | zero | 2 | 3 | two | 2 - 2 | 3 | two | 4 3 | 2 | three | -3 - 5 | 0 | five | -5 - 5 | 0 | five | -5 + 2 | 3 | two | 4 | | | | | | 0 + 5 | 0 | five | -5 + 5 | 0 | five | -5 (9 rows) SELECT * @@ -1914,32 +1914,27 @@ select * from int4_tbl i4, tenk1 a where exists(select * from tenk1 b where a.twothousand = b.twothousand and a.fivethous <> b.fivethous) and i4.f1 = a.tenthous; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) - -> HashAggregate - Group Key: i4.f1, i4.ctid, i4.gp_segment_id, a.unique1, a.unique2, a.two, a.four, a.ten, a.twenty, a.hundred, a.thousand, a.twothousand, a.fivethous, a.tenthous, a.odd, a.even, a.stringu1, a.stringu2, a.string4, a.ctid, a.gp_segment_id + -> Hash Right Semi Join + Hash Cond: (a.twothousand = b.twothousand) + Join Filter: (a.fivethous <> b.fivethous) -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: i4.ctid, i4.gp_segment_id, a.ctid, a.gp_segment_id - -> GroupAggregate - Group Key: i4.f1, i4.ctid, i4.gp_segment_id, a.unique1, a.unique2, a.two, a.four, a.ten, a.twenty, a.hundred, a.thousand, a.twothousand, a.fivethous, a.tenthous, a.odd, a.even, a.stringu1, a.stringu2, a.string4, a.ctid, a.gp_segment_id - -> Sort - Sort Key: i4.ctid, i4.gp_segment_id, a.ctid, a.gp_segment_id - -> Hash Join - Hash Cond: (b.twothousand = a.twothousand) - Join Filter: (a.fivethous <> b.fivethous) - -> Seq Scan on tenk1 b - -> Hash - -> Broadcast Motion 3:3 (slice3; segments: 3) - -> Hash Join - Hash Cond: (a.tenthous = i4.f1) - -> Seq Scan on tenk1 a - Filter: (NOT (twothousand IS NULL)) - -> Hash - -> Broadcast Motion 3:3 (slice4; segments: 3) - -> Seq Scan on int4_tbl i4 + Hash Key: b.twothousand + -> Seq Scan on tenk1 b + -> Hash + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: a.twothousand + -> Hash Join + Hash Cond: (a.tenthous = i4.f1) + -> Seq Scan on tenk1 a + Filter: (NOT (twothousand IS NULL)) + -> Hash + -> Broadcast Motion 3:3 (slice4; segments: 3) + -> Seq Scan on int4_tbl i4 Optimizer: GPORCA -(23 rows) +(18 rows) -- -- More complicated constructs @@ -1968,8 +1963,8 @@ SELECT * FROM t1 FULL JOIN t2 USING (name) FULL JOIN t3 USING (name); ------+----+----+---- bb | 11 | 12 | 13 cc | | 22 | 23 - dd | | | 33 ee | | 42 | + dd | | | 33 (4 rows) -- @@ -1994,8 +1989,8 @@ LEFT JOIN USING (name); name | n | n ------+----+---- - bb | 12 | 13 ee | 42 | + bb | 12 | 13 cc | 22 | 23 (3 rows) @@ -2006,10 +2001,10 @@ FULL JOIN USING (name); name | n | n ------+----+---- - bb | 12 | 13 - dd | | 33 ee | 42 | cc | 22 | 23 + bb | 12 | 13 + dd | | 33 (4 rows) -- Cases with non-nullable expressions in subquery results; @@ -2020,8 +2015,8 @@ NATURAL INNER JOIN (SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; name | s2_n | s2_2 | s3_n | s3_2 ------+------+------+------+------ - bb | 12 | 2 | 13 | 3 cc | 22 | 2 | 23 | 3 + bb | 12 | 2 | 13 | 3 (2 rows) SELECT * FROM @@ -2031,8 +2026,8 @@ NATURAL LEFT JOIN name | s2_n | s2_2 | s3_n | s3_2 ------+------+------+------+------ ee | 42 | 2 | | - bb | 12 | 2 | 13 | 3 cc | 22 | 2 | 23 | 3 + bb | 12 | 2 | 13 | 3 (3 rows) SELECT * FROM @@ -2041,10 +2036,10 @@ NATURAL FULL JOIN (SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; name | s2_n | s2_2 | s3_n | s3_2 ------+------+------+------+------ - bb | 12 | 2 | 13 | 3 - dd | | | 33 | 3 ee | 42 | 2 | | cc | 22 | 2 | 23 | 3 + bb | 12 | 2 | 13 | 3 + dd | | | 33 | 3 (4 rows) SELECT * FROM @@ -2068,8 +2063,8 @@ NATURAL FULL JOIN ------+------+------+------+------+------+------ bb | 11 | 1 | 12 | 2 | 13 | 3 cc | | | 22 | 2 | 23 | 3 - dd | | | | | 33 | 3 ee | | | 42 | 2 | | + dd | | | | | 33 | 3 (4 rows) SELECT * FROM @@ -2082,9 +2077,9 @@ NATURAL FULL JOIN ) ss2; name | s1_n | s2_n | s3_n ------+------+------+------ + ee | | 42 | bb | 11 | 12 | 13 dd | | | 33 - ee | | 42 | cc | | 22 | 23 (4 rows) @@ -2112,10 +2107,10 @@ FULL JOIN ON (s1_n = s2_n); name | s1_n | name | s2_n ------+------+------+------ + bb | 11 | | | | ee | 2 - | | bb | 2 | | cc | 2 - bb | 11 | | + | | bb | 2 (4 rows) -- Test for propagation of nullability constraints into sub-joins @@ -2137,73 +2132,73 @@ insert into y values (4,null); select * from x; x1 | x2 ----+---- + 1 | 11 + 5 | 2 | 22 3 | 4 | 44 - 1 | 11 - 5 | (5 rows) select * from y; y1 | y2 ----+----- + 1 | 111 2 | 222 3 | 333 4 | - 1 | 111 (4 rows) select * from x left join y on (x1 = y1 and x2 is not null); x1 | x2 | y1 | y2 ----+----+----+----- - 1 | 11 | 1 | 111 5 | | | 2 | 22 | 2 | 222 3 | | | 4 | 44 | 4 | + 1 | 11 | 1 | 111 (5 rows) select * from x left join y on (x1 = y1 and y2 is not null); x1 | x2 | y1 | y2 ----+----+----+----- + 5 | | | 2 | 22 | 2 | 222 3 | | 3 | 333 4 | 44 | | 1 | 11 | 1 | 111 - 5 | | | (5 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 - 5 | | | | 5 | 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | 3 | 4 | 44 | 4 | | 4 | 44 + 1 | 11 | 1 | 111 | 1 | 11 + 5 | | | | 5 | (5 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1 and x2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | | 4 | 44 | 4 | | 4 | 44 5 | | | | | + 1 | 11 | 1 | 111 | 1 | 11 (5 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1 and y2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 5 | | | | | + 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | 3 | 4 | 44 | 4 | | | - 1 | 11 | 1 | 111 | 1 | 11 + 5 | | | | | (5 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) @@ -2211,10 +2206,10 @@ on (x1 = xx1 and xx2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- 1 | 11 | 1 | 111 | 1 | 11 - 5 | | | | | 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | | 4 | 44 | 4 | | 4 | 44 + 5 | | | | | (5 rows) -- these should NOT give the same answers as above @@ -2231,18 +2226,18 @@ select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1) where (y2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | 3 | + 1 | 11 | 1 | 111 | 1 | 11 (3 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1) where (xx2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- + 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 4 | 44 | 4 | | 4 | 44 - 1 | 11 | 1 | 111 | 1 | 11 (3 rows) -- @@ -2297,7 +2292,7 @@ select aa, bb, unique1, unique1 ------------------------------------- Result One-Time Filter: false - Optimizer: GPORCA + Optimizer: Postgres query optimizer (3 rows) select aa, bb, unique1, unique1 @@ -2314,8 +2309,8 @@ explain (costs off) select * from int8_tbl i1 left join (int8_tbl i2 join (select 123 as x) ss on i2.q1 = x) on i1.q2 = i2.q2 order by 1, 2; - QUERY PLAN ------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Merge Key: i1.q1, i1.q2 -> Sort @@ -2336,7 +2331,7 @@ order by 1, 2; -> Result Filter: ((123) = 123) -> Result - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (21 rows) select * from int8_tbl i1 left join (int8_tbl i2 join @@ -2424,8 +2419,8 @@ from int4_tbl t1, int4_tbl t2 left join int4_tbl t3 on t3.f1 > 0 left join int4_tbl t4 on t3.f1 > 1 where t4.f1 is null; - QUERY PLAN --------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -2463,8 +2458,8 @@ select * from int4_tbl t1 left join int4_tbl t2 on true left join int4_tbl t3 on t2.f1 > 0 left join int4_tbl t4 on t3.f1 > 0; - QUERY PLAN --------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: (t3.f1 > 0) @@ -2490,8 +2485,8 @@ select * from onek t1 left join onek t2 on t1.unique1 = t2.unique1 left join onek t3 on t2.unique1 != t3.unique1 left join onek t4 on t3.unique1 = t4.unique1; - QUERY PLAN --------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Left Join Hash Cond: (t3.unique1 = t4.unique1) @@ -2517,8 +2512,8 @@ select * from int4_tbl t1 left join int4_tbl t3 on t2.f1 = t3.f1 left join int4_tbl t4 on t3.f1 = t4.f1) s on true inner join int4_tbl t5 on true; - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: true @@ -2547,8 +2542,8 @@ select * from int4_tbl t1 left join int4_tbl t2 on true left join int4_tbl t3 on true left join int4_tbl t4 on t2.f1 = t3.f1; - QUERY PLAN --------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: (t2.f1 = t3.f1) @@ -2574,8 +2569,8 @@ select * from int4_tbl t1 left join int4_tbl t2 on true left join int4_tbl t3 on t2.f1 = t3.f1 left join int4_tbl t4 on t3.f1 != t4.f1; - QUERY PLAN --------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: (t3.f1 <> t4.f1) @@ -2601,8 +2596,8 @@ select * from int4_tbl t1 left join (int4_tbl t2 left join int4_tbl t3 on t2.f1 > 0) on t2.f1 > 1 left join int4_tbl t4 on t2.f1 > 2 and t3.f1 > 3 where t1.f1 = coalesce(t2.f1, 1); - QUERY PLAN --------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: ((t2.f1 > 2) AND (t3.f1 > 3)) @@ -2633,8 +2628,8 @@ select * from int4_tbl t1 where t3.f1 is null) s left join tenk1 t4 on s.f1 > 1) on s.f1 = t1.f1; - QUERY PLAN --------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Right Join Hash Cond: (t2.f1 = t1.f1) @@ -2663,8 +2658,8 @@ select * from int4_tbl t1 where t2.f1 <> coalesce(t3.f1, -1)) s left join tenk1 t4 on s.f1 > 1) on s.f1 = t1.f1; - QUERY PLAN --------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Right Join Hash Cond: (t2.f1 = t1.f1) @@ -2691,8 +2686,8 @@ select * from onek t1 left join onek t2 on t1.unique1 = t2.unique1 left join onek t3 on t2.unique1 = t3.unique1 left join onek t4 on t3.unique1 = t4.unique1 and t2.unique2 = t4.unique2; - QUERY PLAN ------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Hash Left Join Hash Cond: ((t3.unique1 = t4.unique1) AND (t2.unique2 = t4.unique2)) @@ -2715,8 +2710,8 @@ select * from int8_tbl t1 left join (int8_tbl t2 left join int8_tbl t3 full join int8_tbl t4 on false on false) left join int8_tbl t5 on t2.q1 = t5.q1 on t2.q2 = 123; - QUERY PLAN --------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: true @@ -2742,8 +2737,8 @@ select * from int8_tbl t1 left join lateral (select * from int8_tbl t3 where t3.q1 = t2.q1 offset 0) s on t2.q1 = 1; - QUERY PLAN ------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------ Nested Loop Left Join -> Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on int8_tbl t1 @@ -2758,7 +2753,7 @@ select * from int8_tbl t1 -> Materialize -> Gather Motion 3:1 (slice3; segments: 3) -> Seq Scan on int8_tbl t3 - Optimizer: GPORCA + Optimizer: Postgres query optimizer (15 rows) explain (costs off) @@ -2767,8 +2762,8 @@ select * from int8_tbl t1 left join lateral (select * from generate_series(t2.q1, 100)) s on t2.q1 = 1; - QUERY PLAN ---------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join -> Seq Scan on int8_tbl t1 @@ -2778,7 +2773,7 @@ select * from int8_tbl t1 Join Filter: (t2.q1 = 1) -> Seq Scan on int8_tbl t2 -> Function Scan on generate_series - Optimizer: GPORCA + Optimizer: Postgres query optimizer (10 rows) explain (costs off) @@ -2787,15 +2782,15 @@ select * from int8_tbl t1 left join lateral (select t2.q1 from int8_tbl t3) s on t2.q1 = 1; -ERROR: could not devise a query plan for the given query +ERROR: could not devise a query plan for the given query (pathnode.c:285) explain (costs off) select * from onek t1 left join onek t2 on true left join lateral (select * from onek t3 where t3.two = t2.two offset 0) s on t2.unique1 = 1; - QUERY PLAN ------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------ Nested Loop Left Join -> Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on onek t1 @@ -2813,7 +2808,7 @@ select * from onek t1 -> Materialize -> Gather Motion 3:1 (slice3; segments: 3) -> Seq Scan on onek t3 - Optimizer: GPORCA + Optimizer: Postgres query optimizer (18 rows) -- @@ -2844,25 +2839,25 @@ select * from on j1_tbl.i = j2_tbl.i and j1_tbl.i = j2_tbl.k; --order none i | j | t | i | k ---+---+-------+---+---- - | | | 0 | - 0 | | zero | | - | | | 1 | -1 - 1 | 4 | one | | - | | | 5 | -5 - | | | 5 | -5 - 5 | 0 | five | | - 6 | 6 | six | | 2 | 3 | two | 2 | 2 - | | | 2 | 4 - | | | 3 | -3 - | | | | 0 - | | | | 3 | 2 | three | | 4 | 1 | four | | 7 | 7 | seven | | 8 | 8 | eight | | | | null | | | 0 | zero | | + | | | | + | | | 2 | 4 + | | | 3 | -3 + | | | | 0 + 5 | 0 | five | | + 6 | 6 | six | | + | | | 5 | -5 + | | | 5 | -5 + 1 | 4 | one | | + 0 | | zero | | + | | | 1 | -1 + | | | 0 | (19 rows) reset enable_mergejoin; @@ -2878,8 +2873,8 @@ select count(*) from left join (select * from tenk1 y order by y.unique2) y on x.thousand = y.unique2 and x.twothousand = y.hundred and x.fivethous = y.unique2; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- Finalize Aggregate -> Gather Motion 3:1 (slice1; segments: 3) -> Partial Aggregate @@ -2892,7 +2887,7 @@ select count(*) from -> Redistribute Motion 3:3 (slice3; segments: 3) Hash Key: y.unique2, y.hundred, y.unique2 -> Seq Scan on tenk1 y - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) select count(*) from @@ -2920,8 +2915,8 @@ select x.thousand, x.twothousand, count(*) from tenk1 x inner join tenk1 y on x.thousand = y.thousand group by x.thousand, x.twothousand order by x.thousand desc, x.twothousand; - QUERY PLAN ------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Merge Key: x.thousand, x.twothousand -> Sort @@ -3006,11 +3001,11 @@ insert into t2a values (200, 2001); select * from t1 left join t2 on (t1.a = t2.a); a | b | a | b -----+------+-----+------ - 15 | 20 | | 200 | 1000 | 200 | 2000 200 | 1000 | 200 | 2001 100 | 100 | | 5 | 10 | | + 15 | 20 | | (5 rows) -- Test matching of column name with wrong alias @@ -3072,8 +3067,8 @@ select tt1.*, tt2.* from tt1 left join tt2 on tt1.joincol = tt2.joincol; tt1_id | joincol | tt2_id | joincol --------+---------+--------+--------- 2 | | | - 1 | 11 | 21 | 11 1 | 11 | 22 | 11 + 1 | 11 | 21 | 11 (3 rows) select tt1.*, tt2.* from tt2 right join tt1 on tt1.joincol = tt2.joincol; @@ -3099,8 +3094,8 @@ set enable_nestloop to off; explain (costs off) select * from tbl_ra t1 where not exists (select 1 from tbl_ra t2 where t2.b = t1.a) and t1.b < 2; - QUERY PLAN ------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Result Filter: (COALESCE((count(*)), '0'::bigint) = '0'::bigint) @@ -3124,25 +3119,25 @@ select * from tbl_ra t1 where not exists (select 1 from tbl_ra t2 where t2.b = t1.a) and t1.b < 2; a | b ------+--- - 100 | 0 - 101 | 1 - 200 | 0 - 201 | 1 - 300 | 0 + 501 | 1 301 | 1 - 400 | 0 - 401 | 1 500 | 0 - 501 | 1 - 600 | 0 - 601 | 1 - 700 | 0 - 701 | 1 800 | 0 + 1000 | 0 + 700 | 0 801 | 1 + 101 | 1 + 300 | 0 900 | 0 + 201 | 1 + 400 | 0 + 401 | 1 + 200 | 0 + 100 | 0 + 701 | 1 901 | 1 - 1000 | 0 + 600 | 0 + 601 | 1 (19 rows) reset enable_hashjoin; @@ -3171,7 +3166,7 @@ select count(*) from tenk1 a, tenk1 b Hash Key: b.thousand -> Seq Scan on tenk1 b Filter: ((fivethous % 10) < 10) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (14 rows) select count(*) from tenk1 a, tenk1 b @@ -3208,8 +3203,8 @@ LEFT JOIN ( ) AS d ON (a.f1 = d.f1) WHERE COALESCE(d.f1, 0) = 0 ORDER BY 1; - QUERY PLAN --------------------------------------------------- + QUERY PLAN +------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Merge Key: a.f1 -> Sort @@ -3253,8 +3248,8 @@ reset enable_nestloop; explain (costs off) select a.* from tenk1 a where unique1 in (select unique2 from tenk1 b); - QUERY PLAN ----------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Hash Semi Join Hash Cond: (a.unique1 = b.unique2) @@ -3270,8 +3265,8 @@ where unique1 in (select unique2 from tenk1 b); explain (costs off) select a.* from tenk1 a where unique1 not in (select unique2 from tenk1 b); - QUERY PLAN --------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Left Anti Semi (Not-In) Join Hash Cond: (a.unique1 = b.unique2) @@ -3285,8 +3280,8 @@ where unique1 not in (select unique2 from tenk1 b); explain (costs off) select a.* from tenk1 a where exists (select 1 from tenk1 b where a.unique1 = b.unique2); - QUERY PLAN --------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Hash Semi Join Hash Cond: (a.unique1 = b.unique2) @@ -3303,8 +3298,8 @@ where exists (select 1 from tenk1 b where a.unique1 = b.unique2); explain (costs off) select a.* from tenk1 a where not exists (select 1 from tenk1 b where a.unique1 = b.unique2); - QUERY PLAN ------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Hash Anti Join Hash Cond: (a.unique1 = b.unique2) @@ -3320,8 +3315,8 @@ where not exists (select 1 from tenk1 b where a.unique1 = b.unique2); explain (costs off) select a.* from tenk1 a left join tenk1 b on a.unique1 = b.unique2 where b.unique2 is null; - QUERY PLAN ------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Result Filter: (b.unique2 IS NULL) @@ -3376,7 +3371,7 @@ where not exists ( -> Hash -> Gather Motion 3:1 (slice5; segments: 3) -> Seq Scan on tt4x t5 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (24 rows) -- @@ -3494,12 +3489,12 @@ set enable_mergejoin = 1; set enable_hashjoin = 0; set enable_nestloop = 0; create temp table a (i integer); -create temp table b (x integer, y integer); -select * from a left join b on i = x and i = y and x = i; NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +create temp table b (x integer, y integer); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'x' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +select * from a left join b on i = x and i = y and x = i; i | x | y ---+---+--- (0 rows) @@ -3511,12 +3506,12 @@ rollback; begin; create type mycomptype as (id int, v bigint); create temp table tidv (idv mycomptype); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'idv' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create index on tidv (idv); analyze tidv; explain (costs off) select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; -NOTICE: One or more columns in the following table(s) do not have statistics: tidv -HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN ---------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) @@ -3692,8 +3687,8 @@ SELECT qq, unique1 ( SELECT COALESCE(q2, -1) AS qq FROM int8_tbl b ) AS ss2 USING (qq) INNER JOIN tenk1 c ON qq = unique2; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -3747,12 +3742,14 @@ create temp table nt2 ( b2 boolean, foreign key (nt1_id) references nt1(id) ); +WARNING: referential integrity (FOREIGN KEY) constraints are not supported in Apache Cloudberry, will not be enforced create temp table nt3 ( id int primary key, nt2_id int, c1 boolean, foreign key (nt2_id) references nt2(id) ); +WARNING: referential integrity (FOREIGN KEY) constraints are not supported in Apache Cloudberry, will not be enforced insert into nt1 values (1,true,true); ANALYZE nt1; insert into nt1 values (2,true,false); @@ -3851,7 +3848,7 @@ order by 1,2; -> Materialize -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on int8_tbl t3 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (24 rows) -- @@ -3890,27 +3887,7 @@ select * from right join int4_tbl as i43 on (i43.f1 > 1) where ss1.loc = ss1.lat) as ss2 where i41.f1 > 0; -ERROR: could not devise a query plan for the given query (pathnode.c:277) ---start_ignore ---GPDB_14_MERGE_FIXME: We need to make plan work. One idea is generate a gather ---motion for relations. Even it is not efficient, but better than error out here. - QUERY PLAN --------------------------------------------------- - Nested Loop - -> Nested Loop - -> Seq Scan on int4_tbl i41 - Filter: (f1 > 0) - -> Nested Loop - Join Filter: (i41.f1 = i42.f1) - -> Seq Scan on int8_tbl i81 - -> Materialize - -> Seq Scan on int4_tbl i42 - -> Materialize - -> Seq Scan on int4_tbl i43 - Filter: (f1 > 1) - Optimizer: GPORCA -(12 rows) ---end_ignore +ERROR: could not devise a query plan for the given query (pathnode.c:285) select * from int4_tbl as i41, lateral @@ -3921,34 +3898,7 @@ select * from right join int4_tbl as i43 on (i43.f1 > 1) where ss1.loc = ss1.lat) as ss2 where i41.f1 > 0; -ERROR: could not devise a query plan for the given query (pathnode.c:277) ---start_ignore ---GPDB_14_MERGE_FIXME: We need to make plan work. One idea is generate a gather ---motion for relations. Even it is not efficient, but better than error out here. - f1 | x -------------+--- - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 -(20 rows) ---end_ignore +ERROR: could not devise a query plan for the given query (pathnode.c:285) -- -- test the corner cases FULL JOIN ON TRUE and FULL JOIN ON FALSE -- @@ -4034,7 +3984,7 @@ where q1 = thousand or q2 = thousand; -> Hash -> Broadcast Motion 3:3 (slice4; segments: 3) -> Seq Scan on int4_tbl - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (22 rows) explain (costs off) @@ -4203,8 +4153,8 @@ select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from left join tenk1 t2 on (subq1.y1 = t2.unique1) where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; - QUERY PLAN ---------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------- Hash Join Hash Cond: ((11) = t1.unique2) Join Filter: (t1.stringu1 > t2.stringu2) @@ -4217,7 +4167,7 @@ where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; -> Hash Join Hash Cond: ((0) = i1.f1) -> Result - One-Time Filter: (gp_execution_segment() = ###) + One-Time Filter: (gp_execution_segment() = 2) -> Hash Left Join Hash Cond: ((1) = (1)) -> Result @@ -4235,7 +4185,7 @@ where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; -> Bitmap Index Scan on tenk1_unique2 Index Cond: ((unique2 < 42) AND (unique2 = 11)) Optimizer: GPORCA -(27 rows) +(30 rows) select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 @@ -4303,8 +4253,8 @@ where b; -> Result -> Result One-Time Filter: (true) - Optimizer: GPORCA -(6 rows) + Optimizer: Postgres query optimizer +(7 rows) select * from (select 0 as z) as t1 @@ -4326,8 +4276,8 @@ explain (verbose, costs off) with ctetable as not materialized ( select 1 as f1 ) select * from ctetable c1 where f1 in ( select c3.f1 from ctetable c2 full join ctetable c3 on true ); - QUERY PLAN ------------------------------------- + QUERY PLAN +------------------------------------- Hash Semi Join Output: (1) Hash Cond: ((1) = (1)) @@ -4343,7 +4293,8 @@ where f1 in ( select c3.f1 from ctetable c2 full join ctetable c3 on true ); Output: (1) -> Result Output: 1 - Optimizer: GPORCA + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer (17 rows) with ctetable as not materialized ( select 1 as f1 ) @@ -4361,12 +4312,13 @@ from int4_tbl t1 inner join (int8_tbl t2 left join information_schema.column_udt_usage on null) on null; - QUERY PLAN ----------------------------------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------------------------------- Result Output: 'regression'::information_schema.sql_identifier, (c.relname)::information_schema.sql_identifier One-Time Filter: false - Optimizer: GPORCA + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer (5 rows) -- Test handling of qual pushdown to appendrel members with non-Var outputs @@ -4375,8 +4327,8 @@ select * from int4_tbl left join ( select text 'foo' union all select text 'bar' ) ss(x) on true where ss.x is null; - QUERY PLAN ----------------------------------------------------- + QUERY PLAN +----------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: f1, ('foo'::text) -> Result @@ -4396,6 +4348,7 @@ where ss.x is null; Output: ('bar'::text) -> Result Output: 'bar'::text + Settings: optimizer = 'on' Optimizer: GPORCA (21 rows) @@ -4428,8 +4381,8 @@ explain (verbose, costs off) select unique1, x.* from tenk1, (select *, random() from f_immutable_int4(1) x) x where x = unique1; - QUERY PLAN ------------------------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: unique1, (1), (random()) -> Nested Loop @@ -4446,7 +4399,7 @@ where x = unique1; -> Index Only Scan using tenk1_unique1 on public.tenk1 Output: unique1 Index Cond: ((tenk1.unique1 = (1)) AND (tenk1.unique1 = 1)) - Settings: enable_nestloop = 'on', enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on', enable_nestloop = 'on' Optimizer: GPORCA (18 rows) @@ -4478,11 +4431,11 @@ select unique1 from tenk1, lateral f_immutable_int4(1) x where x = unique1; explain (costs off) select unique1 from tenk1, lateral f_immutable_int4(1) x where x in (select 17); - QUERY PLAN --------------------------- + QUERY PLAN +------------------------------------- Result One-Time Filter: false - Optimizer: GPORCA + Optimizer: Postgres query optimizer (3 rows) explain (costs off) @@ -4511,7 +4464,7 @@ select unique1, x from tenk1 left join f_immutable_int4(1) x on unique1 = x; -> Seq Scan on tenk1 -> Hash -> Result - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) explain (costs off) @@ -4548,11 +4501,11 @@ select unique1, x from tenk1 full join f_immutable_int4(1) x on unique1 = x; -- check that pullup of a const function allows further const-folding explain (costs off) select unique1 from tenk1, f_immutable_int4(1) x where x = 42; - QUERY PLAN ---------------------------------------- + QUERY PLAN +-------------------------- Result One-Time Filter: false - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) reset enable_nestloop; @@ -4596,13 +4549,13 @@ create function mki4(int) returns int4_tbl as $$select row($1)::int4_tbl$$ language sql; explain (verbose, costs off) select * from mki8(1,2); - QUERY PLAN ---------------------------------------- + QUERY PLAN +------------------------------------ Function Scan on mki8 Output: q1, q2 Function Call: '(1,2)'::int8_tbl Settings: optimizer = 'on' - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) select * from mki8(1,2); @@ -4613,13 +4566,13 @@ select * from mki8(1,2); explain (verbose, costs off) select * from mki4(42); - QUERY PLAN ---------------------------------------- + QUERY PLAN +----------------------------------- Function Scan on mki4 Output: f1 Function Call: '(42)'::int4_tbl Settings: optimizer = 'on' - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) select * from mki4(42); @@ -4638,8 +4591,8 @@ explain (verbose, costs off) select (t2.*).unique1, f_field_select(t2) from tenk1 t1 left join onek t2 on t1.unique1 = t2.unique1 left join int8_tbl t3 on true; - QUERY PLAN --------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: t2.unique1, t2.unique2 -> Hash Left Join @@ -4657,6 +4610,7 @@ select (t2.*).unique1, f_field_select(t2) from tenk1 t1 Output: t2.unique1, t2.unique2 -> Seq Scan on public.onek t2 Output: t2.unique1, t2.unique2 + Settings: optimizer = 'on' Optimizer: GPORCA (19 rows) @@ -4668,8 +4622,8 @@ drop function f_field_select(t onek); explain (costs off) select * from tenk1 a join tenk1 b on (a.unique1 = 1 and b.unique1 = 2) or (a.unique2 = 3 and b.hundred = 4); - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -4695,14 +4649,14 @@ select * from tenk1 a join tenk1 b on Index Cond: (unique1 = 2) -> Bitmap Index Scan on tenk1_hundred Index Cond: (hundred = 4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (26 rows) explain (costs off) select * from tenk1 a join tenk1 b on (a.unique1 = 1 and b.unique1 = 2) or (a.unique2 = 3 and b.ten = 4); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -4723,7 +4677,7 @@ select * from tenk1 a join tenk1 b on Index Cond: (unique1 = 1) -> Bitmap Index Scan on tenk1_unique2 Index Cond: (unique2 = 3) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (21 rows) explain (costs off) @@ -4943,8 +4897,8 @@ select * from ) ss where fault = 122 order by fault; - QUERY PLAN ----------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Merge Key: ((COALESCE(tenk1.unique1, '-1'::integer) + int8_tbl.q1)) -> Sort @@ -4960,7 +4914,7 @@ order by fault; -> Redistribute Motion 3:3 (slice3; segments: 3) Hash Key: int8_tbl.q2 -> Seq Scan on int8_tbl - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (16 rows) select * from @@ -5010,8 +4964,8 @@ explain (costs off) select q1, unique2, thousand, hundred from int8_tbl a left join tenk1 b on q1 = unique2 where coalesce(thousand,123) = q1 and q1 = coalesce(hundred,123); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Result Filter: ((COALESCE(b.thousand, 123) = a.q1) AND (a.q1 = COALESCE(b.hundred, 123))) @@ -5022,7 +4976,7 @@ select q1, unique2, thousand, hundred -> Seq Scan on tenk1 b -> Hash -> Seq Scan on int8_tbl a - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) select q1, unique2, thousand, hundred @@ -5103,8 +5057,8 @@ select a.unique1, b.unique1, c.unique1, coalesce(b.twothousand, a.twothousand) explain (costs off) select * from int8_tbl t1 left join int8_tbl t2 on t1.q2 = t2.q1, lateral (select * from int8_tbl t3 where t2.q1 = t2.q2) ss; - QUERY PLAN ------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop -> Hash Left Join @@ -5118,23 +5072,23 @@ select * from int8_tbl t1 left join int8_tbl t2 on t1.q2 = t2.q1, -> Materialize -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on int8_tbl t3 - Optimizer: GPORCA + Optimizer: Postgres query optimizer (14 rows) select * from int8_tbl t1 left join int8_tbl t2 on t1.q2 = t2.q1, lateral (select * from int8_tbl t3 where t2.q1 = t2.q2) ss; q1 | q2 | q1 | q2 | q1 | q2 ------------------+------------------+------------------+------------------+------------------+------------------- - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 456 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 456 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 456 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 456 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 (10 rows) -- @@ -5178,8 +5132,9 @@ using (join_key); Output: (666), i1.f1 -> Seq Scan on public.int4_tbl i1 Output: 666, i1.f1 - Optimizer: Pivotal Optimizer (GPORCA) -(24 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(25 rows) select foo1.join_key as foo1_id, foo3.join_key AS foo3_id, bug_field from (values (0),(1)) foo1(join_key) @@ -5257,11 +5212,11 @@ on (i0.f1 = ss0.f1) order by i0.f1, x; f1 | x | f1 | q1 | q2 -------------+-----+-------------+------------------+----- + -2147483647 | 123 | -2147483647 | 4567890123456789 | 123 + -123456 | 123 | -123456 | 4567890123456789 | 123 0 | 123 | 0 | 4567890123456789 | 123 123456 | 123 | 123456 | 4567890123456789 | 123 - -123456 | 123 | -123456 | 4567890123456789 | 123 2147483647 | 123 | 2147483647 | 4567890123456789 | 123 - -2147483647 | 123 | -2147483647 | 4567890123456789 | 123 (5 rows) -- @@ -5500,8 +5455,8 @@ select t1.* from on (i8.q2 = i4.f1); f1 ------------------- - doh! hi de ho neighbor + doh! (2 rows) explain (verbose, costs off) @@ -5562,8 +5517,8 @@ select * from 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) -- check handling of a variable-free qual for a non-commutable outer join @@ -5575,14 +5530,14 @@ left join from pg_class c left join pg_namespace n on n.oid = c.relnamespace where c.relkind = 'r' ) ss2 on false; - QUERY PLAN -------------------------------- + QUERY PLAN +------------------------------------- Nested Loop Left Join Join Filter: false -> Result -> Result One-Time Filter: false - Optimizer: GPORCA + Optimizer: Postgres query optimizer (6 rows) -- check handling of apparently-commutable outer joins with non-commutable @@ -5595,8 +5550,8 @@ select 1 from join int4_tbl i42 on ss1.a is null or i8.q1 <> i8.q2 right join (select 2 as b) ss2 on ss2.b < i4.f1; - QUERY PLAN --------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------- Nested Loop Left Join Join Filter: ((2) < i4.f1) -> Result @@ -5688,12 +5643,13 @@ select 1 from right join (select 1 as z) as ss2 on true) on false, lateral (select i4.f1, ss1.n from int8_tbl as i8 limit 1) as ss3; - QUERY PLAN -------------------------- + QUERY PLAN +------------------------------------- Result Output: 1 One-Time Filter: false - Optimizer: GPORCA + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer (5 rows) select 1 from @@ -5723,11 +5679,11 @@ select 1 from t t1 on false where t3.a = coalesce(t5.a,1)) as s2 on true; - QUERY PLAN -------------------------- + QUERY PLAN +------------------------------------- Result One-Time Filter: false - Optimizer: GPORCA + Optimizer: Postgres query optimizer (3 rows) rollback; @@ -5748,46 +5704,53 @@ select ss2.* from on i41.f1 = ss1.c1, lateral (select i41.*, i8.*, ss1.* from text_tbl limit 1) ss2 where ss1.c2 = 0; - QUERY PLAN ------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------ Nested Loop Output: (i41.f1), (i8.q1), (i8.q2), (i42.f1), (i43.f1), ((42)) - -> Gather Motion 3:1 (slice1; segments: 3) - Output: i41.f1, i42.f1, i8.q1, i8.q2, i43.f1, (42) - -> Nested Loop - Output: i41.f1, i42.f1, i8.q1, i8.q2, i43.f1, 42 - -> Nested Loop - Output: i41.f1, i42.f1, i8.q1, i8.q2 - -> Redistribute Motion 3:3 (slice2; segments: 3) - Output: i41.f1, i42.f1 - Hash Key: 0 - -> Hash Join - Output: i41.f1, i42.f1 - Hash Cond: (i41.f1 = i42.f1) - -> Seq Scan on public.int4_tbl i41 - Output: i41.f1 - -> Hash - Output: i42.f1 - -> Seq Scan on public.int4_tbl i42 - Output: i42.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) + -> Gather Motion 1:1 (slice1; segments: 1) + Output: i8.q1, i8.q2 + -> Seq Scan on public.int8_tbl i8 + Output: i8.q1, i8.q2 + Filter: (i8.q1 = 0) -> Materialize - Output: (i41.f1), (i8.q1), (i8.q2), (i42.f1), (i43.f1), ((42)) - -> Limit - Output: (i41.f1), (i8.q1), (i8.q2), (i42.f1), (i43.f1), ((42)) - -> Result - Output: i41.f1, i8.q1, i8.q2, i42.f1, i43.f1, (42) - -> Materialize - -> Gather Motion 3:1 (slice3; segments: 3) - -> Seq Scan on public.text_tbl + Output: i43.f1, (i41.f1), (i8.q1), (i8.q2), (i42.f1), (i43.f1), ((42)) + -> Nested Loop + Output: i43.f1, (i41.f1), (i8.q1), (i8.q2), (i42.f1), (i43.f1), ((42)) + -> Materialize + Output: i41.f1, i42.f1, i43.f1, (42) + -> Gather Motion 3:1 (slice2; segments: 3) + Output: i41.f1, i42.f1, i43.f1, (42) + -> Nested Loop + Output: i41.f1, i42.f1, i43.f1, 42 + -> Broadcast Motion 1:3 (slice3; segments: 1) + Output: i43.f1 + -> Seq Scan on public.int4_tbl i43 + Output: i43.f1 + Filter: (i43.f1 = 0) + -> Materialize + Output: i41.f1, i42.f1 + -> Hash Join + Output: i41.f1, i42.f1 + Hash Cond: (i41.f1 = i42.f1) + -> Seq Scan on public.int4_tbl i41 + Output: i41.f1 + -> Hash + Output: i42.f1 + -> Seq Scan on public.int4_tbl i42 + Output: i42.f1 + -> Materialize + Output: (i41.f1), (i8.q1), (i8.q2), (i42.f1), (i43.f1), ((42)) + -> Limit + Output: (i41.f1), (i8.q1), (i8.q2), (i42.f1), (i43.f1), ((42)) + -> Result + Output: i41.f1, i8.q1, i8.q2, i42.f1, i43.f1, (42) + -> Materialize + -> Gather Motion 3:1 (slice4; segments: 3) + -> Seq Scan on public.text_tbl Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(37 rows) +(44 rows) --end_ignore select ss2.* from @@ -5812,8 +5775,8 @@ select * from left join (tenk1 as a1 full join (select 1 as id) as yy on (a1.unique1 = yy.id)) on (xx.id = coalesce(yy.id)); - QUERY PLAN ------------------------------------------------- + QUERY PLAN +------------------------------------------------------ Hash Right Join Hash Cond: (COALESCE((1)) = (1)) -> Hash Full Join @@ -5889,8 +5852,8 @@ explain (verbose, costs off) select a.q2, b.q1 from int8_tbl a left join int8_tbl b on a.q2 = coalesce(b.q1, 1) where coalesce(b.q1, 1) > 0; - QUERY PLAN -------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: a.q2, b.q1 -> Result @@ -5911,8 +5874,8 @@ explain (verbose, costs off) Hash Key: COALESCE(b.q1, '1'::bigint) -> Seq Scan on public.int8_tbl b Output: b.q1 + Settings: optimizer = 'on', enable_hashjoin = 'off', enable_nestloop = 'off', enable_mergejoin = 'on' Optimizer: GPORCA - Settings: enable_hashjoin = 'off', enable_mergejoin = 'on' (22 rows) select a.q2, b.q1 @@ -5920,16 +5883,16 @@ select a.q2, b.q1 where coalesce(b.q1, 1) > 0; q2 | q1 -------------------+------------------ - 123 | 123 - 123 | 123 - 456 | 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 + -4567890123456789 | + 456 | 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 - -4567890123456789 | + 123 | 123 + 123 | 123 (10 rows) reset enable_hashjoin; @@ -5942,8 +5905,8 @@ explain (costs off) select a.unique1, b.unique2 from onek a left join onek b on a.unique1 = b.unique2 where b.unique2 = any (select q1 from int8_tbl c where c.q1 < b.unique1); - QUERY PLAN ------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Hash Semi Join Hash Cond: ((b.unique2)::bigint = c.q1) @@ -5976,8 +5939,8 @@ explain (costs off) select a.unique1, b.unique2 from onek a full join onek b on a.unique1 = b.unique2 where a.unique1 = 42; - QUERY PLAN ---------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------- Hash Left Join Hash Cond: (a.unique1 = b.unique2) -> Gather Motion 3:1 (slice1; segments: 3) @@ -6002,8 +5965,8 @@ explain (costs off) select a.unique1, b.unique2 from onek a full join onek b on a.unique1 = b.unique2 where b.unique2 = 43; - QUERY PLAN ------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Result Filter: (b.unique2 = 43) @@ -6029,8 +5992,8 @@ explain (costs off) select a.unique1, b.unique2 from onek a full join onek b on a.unique1 = b.unique2 where a.unique1 = 42 and b.unique2 = 42; - QUERY PLAN ---------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -6060,8 +6023,8 @@ select * from full join (select * from (values(456,2)) w(v1,v2) join int8_tbl i82 on q2=v1) ss2 on true; - QUERY PLAN ------------------------------------------------------ + QUERY PLAN +------------------------------------------------------ Merge Full Join -> Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on int8_tbl i81 @@ -6070,7 +6033,7 @@ on true; -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on int8_tbl i82 Filter: (q2 = 456) - Optimizer: GPORCA + Optimizer: Postgres query optimizer (9 rows) select * from @@ -6107,7 +6070,7 @@ explain (costs off) SELECT a.* FROM a LEFT JOIN b ON a.b_id = b.id; ------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on a - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) explain (costs off) SELECT b.* FROM b LEFT JOIN c ON b.c_id = c.id; @@ -6115,7 +6078,7 @@ explain (costs off) SELECT b.* FROM b LEFT JOIN c ON b.c_id = c.id; ------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on b - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) explain (costs off) @@ -6125,7 +6088,7 @@ explain (costs off) ------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on a - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) -- check optimization of outer join within another special join @@ -6358,7 +6321,7 @@ on t1.q1 = t2.q1; -> Hash -> Seq Scan on int8_tbl t1 Optimizer: GPORCA -(21 rows) +(22 rows) -- pseudoconstant based on an outer-level Param explain (costs off) @@ -6411,7 +6374,7 @@ select d.* from d left join (select * from b group by b.id, b.c_id) s ------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on d - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) -- similarly, but keying off a DISTINCT clause @@ -6422,7 +6385,7 @@ select d.* from d left join (select distinct * from b) s ------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on d - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) -- join removal is not possible when the GROUP BY contains a column that is @@ -6515,7 +6478,7 @@ select 1 from (select a.id FROM a left join b on a.b_id = b.id) q, -> Seq Scan on a -> Function Scan on generate_series gs Filter: (a.id = i) - Optimizer: GPORCA + Optimizer: Postgres query optimizer (6 rows) -- check join removal within RHS of an outer join @@ -6541,11 +6504,12 @@ select c.id, ss.a from c CREATE TEMP TABLE parted_b (id int PRIMARY KEY) partition by range(id); CREATE TEMP TABLE parted_b1 partition of parted_b for values from (0) to (10); +NOTICE: table has parent, setting distribution columns to match parent table -- test join removals on a partitioned table explain (costs off) select a.* from a left join parted_b pb on a.b_id = pb.id; - QUERY PLAN ------------------------------------------ + QUERY PLAN +------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on a Optimizer: GPORCA @@ -6580,9 +6544,9 @@ select p.*, linked from parent p on (p.k = ss.k); k | pd | linked ---+----+-------- - 1 | 10 | t 2 | 20 | 3 | 30 | + 1 | 10 | t (3 rows) explain (costs off) @@ -6612,11 +6576,11 @@ explain (costs off) select p.* from parent p left join child c on (p.k = c.k) where p.k = 1 and p.k = 2; - QUERY PLAN ---------------------------------------- + QUERY PLAN +-------------------------- Result One-Time Filter: false - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) select p.* from @@ -6630,11 +6594,11 @@ explain (costs off) select p.* from (parent p left join child c on (p.k = c.k)) join parent x on p.k = x.k where p.k = 1 and p.k = 2; - QUERY PLAN ---------------------------------------- + QUERY PLAN +-------------------------- Result One-Time Filter: false - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) -- bug 5255: this is not optimizable by join removal @@ -6668,11 +6632,11 @@ SELECT * FROM ON true; x | q1 | q2 | y ---+------------------+-------------------+------------------ - 1 | 4567890123456789 | 123 | 42 - 1 | 123 | 456 | 123 - 1 | 123 | 4567890123456789 | 123 1 | 4567890123456789 | 4567890123456789 | 4567890123456789 1 | 4567890123456789 | -4567890123456789 | 4567890123456789 + 1 | 123 | 456 | 123 + 1 | 123 | 4567890123456789 | 123 + 1 | 4567890123456789 | 123 | 42 (5 rows) -- join removal bug #17769: can't remove if there's a pushed-down reference @@ -6681,8 +6645,8 @@ SELECT q2 FROM (SELECT * FROM int8_tbl LEFT JOIN innertab ON q2 = id) ss WHERE COALESCE(dat1, 0) = q1; - QUERY PLAN ---------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Result Filter: (COALESCE(innertab.dat1, '0'::bigint) = int8_tbl.q1) @@ -6703,11 +6667,12 @@ SELECT q2 FROM FROM int8_tbl LEFT JOIN innertab ON q2 = id) ss RIGHT JOIN int4_tbl ON NULL WHERE x >= x; - QUERY PLAN -------------------------- + QUERY PLAN +---------------------------- Result Output: NULL::bigint One-Time Filter: false + Settings: optimizer = 'on' Optimizer: GPORCA (5 rows) @@ -6718,8 +6683,8 @@ FROM int4_tbl JOIN ((SELECT 42 AS x FROM int8_tbl LEFT JOIN innertab ON q1 = id) AS ss1 RIGHT JOIN tenk1 ON NULL) ON tenk1.unique1 = ss1.x OR tenk1.unique2 = ss1.x; - QUERY PLAN -------------------------- + QUERY PLAN +-------------------------- Result One-Time Filter: false Optimizer: GPORCA @@ -6808,8 +6773,8 @@ from t t1 from t t2 left join t t3 on t2.a = t3.a) s on true where t1.a = s.c; - QUERY PLAN --------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------- Result -> Gather Motion 3:1 (slice1; segments: 3) -> Hash Join @@ -6850,8 +6815,8 @@ from t t1 on true left join t t4 on true where s.a < s.c; - QUERY PLAN --------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------- Result -> Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop @@ -6877,8 +6842,8 @@ from t t1 on true left join t t4 on true where s.a < s.c; - QUERY PLAN --------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join -> Nested Loop @@ -6889,7 +6854,7 @@ where s.a < s.c; -> Materialize -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on t t4 - Optimizer: GPORCA + Optimizer: Postgres query optimizer (11 rows) select t1.a, s.* @@ -6958,6 +6923,7 @@ where q2 = 456; -- a PHV that's been translated to a child rel create temp table parttbl (a integer primary key) partition by range (a); create temp table parttbl1 partition of parttbl for values from (1) to (100); +NOTICE: table has parent, setting distribution columns to match parent table insert into parttbl values (11), (12); set optimizer_enable_dynamicindexonlyscan=off; explain (costs off) @@ -6965,8 +6931,10 @@ select * from (select *, 12 as phv from parttbl) as ss right join int4_tbl on true where ss.a = ss.phv and f1 = 0; - QUERY PLAN ----------------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: parttbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +---------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -6987,6 +6955,8 @@ select * from (select *, 12 as phv from parttbl) as ss right join int4_tbl on true where ss.a = ss.phv and f1 = 0; +NOTICE: One or more columns in the following table(s) do not have statistics: parttbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | phv | f1 ----+-----+---- 12 | 12 | 0 @@ -7054,11 +7024,12 @@ explain (verbose, costs off) select 1 from (select * from int8_tbl where q1 <> (select 42) offset 0) ss where false; - QUERY PLAN -------------------------- + QUERY PLAN +---------------------------- Result Output: NULL::integer One-Time Filter: false + Settings: optimizer = 'on' Optimizer: GPORCA (5 rows) @@ -7128,8 +7099,8 @@ from int4_tbl x left join lateral (select unique1, unique2 from tenk1 where f1 = | 123456 | -123456 9998 | 0 - | -2147483647 | 2147483647 + | -2147483647 (5 rows) explain (costs off) @@ -7151,21 +7122,21 @@ explain (costs off) select *, (select r from (select q1 as q2) x, (select q2 as r) y) from int8_tbl; q1 | q2 | r ------------------+-------------------+------------------- + 123 | 456 | 456 + 123 | 4567890123456789 | 4567890123456789 4567890123456789 | 123 | 123 4567890123456789 | 4567890123456789 | 4567890123456789 4567890123456789 | -4567890123456789 | -4567890123456789 - 123 | 456 | 456 - 123 | 4567890123456789 | 4567890123456789 (5 rows) select *, (select r from (select q1 as q2) x, lateral (select q2 as r) y) from int8_tbl; q1 | q2 | r ------------------+-------------------+------------------ + 123 | 456 | 123 + 123 | 4567890123456789 | 123 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 4567890123456789 | -4567890123456789 | 4567890123456789 - 123 | 456 | 123 - 123 | 4567890123456789 | 123 (5 rows) -- lateral with function in FROM @@ -7177,8 +7148,8 @@ select count(*) from tenk1 a, lateral generate_series(1,two) g; explain (costs off) select count(*) from tenk1 a, lateral generate_series(1,two) g; - QUERY PLAN ------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Finalize Aggregate -> Gather Motion 3:1 (slice1; segments: 3) -> Partial Aggregate @@ -7193,8 +7164,8 @@ explain (costs off) explain (costs off) select count(*) from tenk1 a cross join lateral generate_series(1,two) g; - QUERY PLAN ------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Finalize Aggregate -> Gather Motion 3:1 (slice1; segments: 3) -> Partial Aggregate @@ -7204,14 +7175,14 @@ explain (costs off) Cache Key: a.two Cache Mode: binary -> Function Scan on generate_series g - Optimizer: GPORCA + Optimizer: Postgres query optimizer (10 rows) -- don't need the explicit LATERAL keyword for functions explain (costs off) select count(*) from tenk1 a, generate_series(1,two) g; - QUERY PLAN ------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Finalize Aggregate -> Gather Motion 3:1 (slice1; segments: 3) -> Partial Aggregate @@ -7327,12 +7298,12 @@ explain (costs off) int8_tbl x left join lateral (select a.q1 from int4_tbl y) ss(z) on x.q2 = ss.z order by a.q1, a.q2, x.q1, x.q2, ss.z; -ERROR: could not devise a query plan for the given query (pathnode.c:277) +ERROR: could not devise a query plan for the given query (pathnode.c:285) select * from int8_tbl a, int8_tbl x left join lateral (select a.q1 from int4_tbl y) ss(z) on x.q2 = ss.z order by a.q1, a.q2, x.q1, x.q2, ss.z; -ERROR: could not devise a query plan for the given query (pathnode.c:277) +ERROR: could not devise a query plan for the given query (pathnode.c:285) --end_ignore -- lateral reference to a join alias variable select * from (select f1/2 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1, @@ -7346,11 +7317,11 @@ select * from (select f1 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1, lateral (values(x)) ss2(y); x | f1 | y -------------+-------------+------------- - 123456 | 123456 | 123456 - -123456 | -123456 | -123456 0 | 0 | 0 2147483647 | 2147483647 | 2147483647 -2147483647 | -2147483647 | -2147483647 + 123456 | 123456 | 123456 + -123456 | -123456 | -123456 (5 rows) select * from ((select f1/2 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1) j, @@ -7425,14 +7396,14 @@ select * from lateral (values(x.q1,y.q1,y.q2)) v(xq1,yq1,yq2); q1 | q2 | q1 | q2 | xq1 | yq1 | yq2 ------------------+-------------------+------------------+-------------------+------------------+------------------+------------------- - 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 123 - 4567890123456789 | -4567890123456789 | | | 4567890123456789 | | 123 | 456 | | | 123 | | 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | -4567890123456789 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 123 | 4567890123456789 | 4567890123456789 | 123 | 123 | 4567890123456789 | 123 + 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 123 + 4567890123456789 | -4567890123456789 | | | 4567890123456789 | | 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 123 | 123 | 456 | 4567890123456789 | 123 | 456 (10 rows) @@ -7442,16 +7413,16 @@ select * from lateral (select x.q1,y.q1,y.q2) v(xq1,yq1,yq2); q1 | q2 | q1 | q2 | xq1 | yq1 | yq2 ------------------+-------------------+------------------+-------------------+------------------+------------------+------------------- - 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 - 4567890123456789 | 123 | 123 | 456 | 4567890123456789 | 123 | 456 - 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 123 - 4567890123456789 | -4567890123456789 | | | 4567890123456789 | | 123 | 456 | | | 123 | | 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | -4567890123456789 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 123 | 4567890123456789 | 4567890123456789 | 123 | 123 | 4567890123456789 | 123 + 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 123 + 4567890123456789 | -4567890123456789 | | | 4567890123456789 | | + 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 + 4567890123456789 | 123 | 123 | 456 | 4567890123456789 | 123 | 456 (10 rows) select x.* from @@ -7459,16 +7430,16 @@ select x.* from lateral (select x.q1,y.q1,y.q2) v(xq1,yq1,yq2); q1 | q2 ------------------+------------------- - 4567890123456789 | 123 - 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 123 | 456 123 | 4567890123456789 123 | 4567890123456789 123 | 4567890123456789 + 4567890123456789 | 4567890123456789 + 4567890123456789 | 4567890123456789 + 4567890123456789 | 4567890123456789 + 4567890123456789 | -4567890123456789 + 4567890123456789 | 123 + 4567890123456789 | 123 (10 rows) select v.* from @@ -7477,24 +7448,24 @@ select v.* from lateral (select x.q1,y.q1 union all select x.q2,y.q2) v(vx,vy); vx | vy -------------------+------------------- + -4567890123456789 | + 4567890123456789 | + 456 | + 123 | 4567890123456789 | 123 - 123 | 4567890123456789 - 4567890123456789 | 123 - 123 | 456 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 + 4567890123456789 | -4567890123456789 4567890123456789 | 4567890123456789 4567890123456789 | 123 - 4567890123456789 | - -4567890123456789 | - 123 | - 456 | + 123 | 4567890123456789 + 4567890123456789 | 4567890123456789 123 | 4567890123456789 4567890123456789 | -4567890123456789 123 | 4567890123456789 - 4567890123456789 | 4567890123456789 + 123 | 456 + 4567890123456789 | 123 123 | 4567890123456789 4567890123456789 | 123 (20 rows) @@ -7505,26 +7476,26 @@ select v.* from lateral (select x.q1,y.q1 union all select x.q2,y.q2) v(vx,vy); vx | vy -------------------+------------------- + -4567890123456789 | + 4567890123456789 | + 456 | + 123 | + 4567890123456789 | 123 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 + 4567890123456789 | -4567890123456789 4567890123456789 | 4567890123456789 4567890123456789 | 123 - 4567890123456789 | - -4567890123456789 | - 123 | - 456 | - 123 | 4567890123456789 - 4567890123456789 | -4567890123456789 123 | 4567890123456789 4567890123456789 | 4567890123456789 123 | 4567890123456789 - 4567890123456789 | 123 + 4567890123456789 | -4567890123456789 + 123 | 4567890123456789 + 123 | 456 4567890123456789 | 123 123 | 4567890123456789 4567890123456789 | 123 - 123 | 456 (20 rows) select v.* from @@ -7533,24 +7504,24 @@ select v.* from lateral (select x.q1,y.q1 from onerow union all select x.q2,y.q2 from onerow) v(vx,vy); vx | vy -------------------+------------------- + -4567890123456789 | + 4567890123456789 | + 456 | + 123 | 4567890123456789 | 123 123 | 4567890123456789 - 4567890123456789 | 123 - 123 | 456 4567890123456789 | 4567890123456789 + 123 | 4567890123456789 4567890123456789 | -4567890123456789 + 123 | 4567890123456789 + 4567890123456789 | 123 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 - 4567890123456789 | 123 - 4567890123456789 | - -4567890123456789 | - 123 | - 456 | - 123 | 4567890123456789 4567890123456789 | -4567890123456789 - 123 | 4567890123456789 4567890123456789 | 4567890123456789 + 123 | 456 + 4567890123456789 | 123 123 | 4567890123456789 4567890123456789 | 123 (20 rows) @@ -7582,14 +7553,14 @@ select * from lateral (select *, a.q2 as x from int8_tbl b) ss on a.q2 = ss.q1; q1 | q2 | q1 | q2 | x ------------------+-------------------+------------------+-------------------+------------------ - 123 | 456 | | | - 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 4567890123456789 | -4567890123456789 | | | + 123 | 456 | | | + 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 4567890123456789 | 123 | 123 | 456 | 123 4567890123456789 | 123 | 123 | 4567890123456789 | 123 (10 rows) @@ -7621,16 +7592,16 @@ select * from lateral (select *, coalesce(a.q2, 42) as x from int8_tbl b) ss on a.q2 = ss.q1; q1 | q2 | q1 | q2 | x ------------------+-------------------+------------------+-------------------+------------------ - 4567890123456789 | 123 | 123 | 456 | 123 - 4567890123456789 | 123 | 123 | 4567890123456789 | 123 - 123 | 456 | | | - 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 4567890123456789 | -4567890123456789 | | | + 123 | 456 | | | + 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 + 4567890123456789 | 123 | 123 | 456 | 123 + 4567890123456789 | 123 | 123 | 4567890123456789 | 123 (10 rows) -- lateral can result in join conditions appearing below their @@ -7660,8 +7631,8 @@ select * from int4_tbl i left join f1 | f1 -------------+---- 0 | 0 - 2147483647 | -2147483647 | + 2147483647 | 123456 | -123456 | (5 rows) @@ -7680,8 +7651,9 @@ select * from int4_tbl i left join -> Seq Scan on public.int2_tbl j Output: j.f1, COALESCE(i.*) Filter: (i.f1 = j.f1) + Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(10 rows) +(11 rows) select * from int4_tbl i left join lateral (select coalesce(i) from int2_tbl j where i.f1 = j.f1) k on true; @@ -7739,31 +7711,31 @@ select * from int4_tbl a, ) ss; f1 | f1 | q1 | q2 -------------+-------------+----+---- - 123456 | -123456 | | - 123456 | 123456 | | - 123456 | 0 | | - 123456 | 2147483647 | | - 123456 | -2147483647 | | - -123456 | -123456 | | - -123456 | 123456 | | - -123456 | 0 | | - -123456 | 2147483647 | | - -123456 | -2147483647 | | - 0 | -123456 | | - 0 | 123456 | | 0 | 0 | | 0 | 2147483647 | | 0 | -2147483647 | | - 2147483647 | -123456 | | - 2147483647 | 123456 | | + 0 | 123456 | | + 0 | -123456 | | 2147483647 | 0 | | 2147483647 | 2147483647 | | 2147483647 | -2147483647 | | - -2147483647 | -123456 | | - -2147483647 | 123456 | | + 2147483647 | 123456 | | + 2147483647 | -123456 | | -2147483647 | 0 | | -2147483647 | 2147483647 | | -2147483647 | -2147483647 | | + -2147483647 | 123456 | | + -2147483647 | -123456 | | + 123456 | 0 | | + 123456 | 2147483647 | | + 123456 | -2147483647 | | + 123456 | 123456 | | + 123456 | -123456 | | + -123456 | 0 | | + -123456 | 2147483647 | | + -123456 | -2147483647 | | + -123456 | 123456 | | + -123456 | -123456 | | (25 rows) -- lateral reference in a PlaceHolderVar evaluated at join level @@ -7776,13 +7748,13 @@ select * from (select b.q1 as bq1, c.q1 as cq1, least(a.q1,b.q1,c.q1) from int8_tbl b cross join int8_tbl c) ss on a.q2 = ss.bq1; -ERROR: could not devise a query plan for the given query (pathnode.c:275) +ERROR: could not devise a query plan for the given query (pathnode.c:285) select * from int8_tbl a left join lateral (select b.q1 as bq1, c.q1 as cq1, least(a.q1,b.q1,c.q1) from int8_tbl b cross join int8_tbl c) ss on a.q2 = ss.bq1; -ERROR: could not devise a query plan for the given query (pathnode.c:275) +ERROR: could not devise a query plan for the given query (pathnode.c:285) -- case requiring nested PlaceHolderVars explain (verbose, costs off) select * from @@ -7831,7 +7803,8 @@ select * from Output: ((COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2))) -> Result Output: (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)) - Optimizer: GPORCA + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer (38 rows) -- another case requiring nested PlaceHolderVars @@ -7840,8 +7813,8 @@ select * from (select 0 as val0) as ss0 left join (select 1 as val) as ss1 on true left join lateral (select ss1.val as val_filtered where false) as ss2 on true; - QUERY PLAN -------------------------------- + QUERY PLAN +------------------------------------- Nested Loop Left Join Output: 0, (1), ((1)) Join Filter: false @@ -7850,7 +7823,8 @@ select * from -> Result Output: (1) One-Time Filter: false - Optimizer: GPORCA + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer (10 rows) select * from @@ -7874,8 +7848,8 @@ select c.*,a.*,ss1.q1,ss2.q1,ss3.* from lateral (select q1, coalesce(ss1.x,q2) as y from int8_tbl d) ss2 ) on c.q2 = ss2.q1, lateral (select * from int4_tbl i where ss2.y > f1) ss3; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: c.q1, c.q2, a.q1, a.q2, b.q1, d.q1, i.f1 -> Nested Loop @@ -7927,8 +7901,9 @@ select c.*,a.*,ss1.q1,ss2.q1,ss3.* from Hash Key: c.q2 -> Seq Scan on public.int8_tbl c Output: c.q1, c.q2 + Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(49 rows) +(53 rows) -- check processing of postponed quals (bug #9041) explain (verbose, costs off) @@ -7954,7 +7929,8 @@ select * from Output: (3) -> Result Output: 3 - Optimizer: GPORCA + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer (17 rows) -- a new postponed-quals issue (bug #17768) @@ -8002,8 +7978,9 @@ select * from int8_tbl i8 left join lateral -> Result Output: f1, i8.q2 One-Time Filter: false + Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(10 rows) +(12 rows) explain (verbose, costs off) select * from int8_tbl i8 left join lateral @@ -8019,8 +7996,9 @@ select * from int8_tbl i8 left join lateral -> Result Output: f1, f1, i8.q2 One-Time Filter: false + Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(10 rows) +(11 rows) -- check handling of nested appendrels inside LATERAL select * from @@ -8072,8 +8050,9 @@ select * from Output: tenk1.unique1, tenk1.unique2 -> Seq Scan on public.tenk1 Output: tenk1.unique1, tenk1.unique2 + Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(20 rows) +(21 rows) select * from (values (0,9998), (1,1000)) v(id,x), @@ -8221,12 +8200,12 @@ select t1.b, ss.phv from join_ut1 t1 left join lateral (select t2.a as t2a, t3.a t3a, least(t1.a, t2.a, t3.a) phv from join_pt1 t2 join join_ut1 t3 on t2.a = t3.b) ss on t1.a = ss.t2a order by t1.a; -ERROR: could not devise a query plan for the given query (pathnode.c:275) +ERROR: could not devise a query plan for the given query (pathnode.c:285) select t1.b, ss.phv from join_ut1 t1 left join lateral (select t2.a as t2a, t3.a t3a, least(t1.a, t2.a, t3.a) phv from join_pt1 t2 join join_ut1 t3 on t2.a = t3.b) ss on t1.a = ss.t2a order by t1.a; -ERROR: could not devise a query plan for the given query (pathnode.c:275) +ERROR: could not devise a query plan for the given query (pathnode.c:285) -- end_ignore drop table join_pt1; drop table join_ut1; @@ -8235,6 +8214,8 @@ drop table join_ut1; -- begin; create table fkest (x integer, x10 integer, x10b integer, x100 integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'x' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into fkest select x, x/10, x/10, x/100 from generate_series(1,1000) x; create unique index on fkest(x, x10, x100); analyze fkest; @@ -8264,6 +8245,7 @@ select * from fkest f1 alter table fkest add constraint fk foreign key (x, x10b, x100) references fkest (x, x10, x100); +WARNING: referential integrity (FOREIGN KEY) constraints are not supported in Apache Cloudberry, will not be enforced explain (costs off) select * from fkest f1 join fkest f2 on (f1.x = f2.x and f1.x10 = f2.x10b and f1.x100 = f2.x100) @@ -8308,6 +8290,7 @@ insert into fkest select x/10, x%10, x from generate_series(1,1000*10) x; insert into fkest1 select x/10, x%10 from generate_series(1,1000*10) x; alter table fkest1 add constraint fkest1_a_b_fkey foreign key (a,b) references fkest; +WARNING: referential integrity (FOREIGN KEY) constraints are not supported in Apache Cloudberry, will not be enforced analyze fkest; analyze fkest1; explain (costs off) @@ -8681,7 +8664,7 @@ inner join j2 on j1.id1 = j2.id1 where j1.id2 = 1; -> Index Only Scan using j2_pkey on public.j2 Output: j2.id1, j2.id2 Index Cond: (j2.id1 = j1.id1) - Settings: enable_nestloop = 'on', optimizer = 'on' + Settings: optimizer = 'on', enable_nestloop = 'on' Optimizer: GPORCA (15 rows) @@ -8705,13 +8688,13 @@ left join j2 on j1.id1 = j2.id1 where j1.id2 = 1; Output: j2.id1, j2.id2 -> Seq Scan on public.j2 Output: j2.id1, j2.id2 - Settings: enable_nestloop = 'on', optimizer = 'on' + Settings: optimizer = 'on', enable_nestloop = 'on' Optimizer: GPORCA (16 rows) create unique index j1_id2_idx on j1(id2) where id2 is not null; -DETAIL: Distribution key column "id1" is not included in the constraint. ERROR: UNIQUE index must contain all columns in the table's distribution key +DETAIL: Distribution key column "id1" is not included in the constraint. -- ensure we don't use a partial unique index as unique proofs explain (verbose, costs off) select * from j1 @@ -8871,7 +8854,7 @@ where exists (select 1 from tenk1 t3 -> Index Only Scan using tenk1_thous_tenthous on public.tenk1 t3 Output: t3.thousand, t3.tenthous Index Cond: (t3.thousand < 1) - Settings: enable_bitmapscan = 'off', enable_hashjoin = 'off', enable_mergejoin = 'on', enable_nestloop = 'on', enable_seqscan = 'off', optimizer = 'on' + Settings: optimizer = 'on', enable_mergejoin = 'on', enable_hashjoin = 'off', enable_nestloop = 'on', enable_seqscan = 'off', enable_bitmapscan = 'off' Optimizer: GPORCA (24 rows) @@ -8911,13 +8894,15 @@ where exists (select 1 from j3 -> Seq Scan on public.j3 Output: j3.unique1, j3.tenthous Filter: (j3.unique1 < 1) - Settings: enable_bitmapscan = 'off', enable_hashjoin = 'off', enable_mergejoin = 'on', enable_nestloop = 'on', enable_seqscan = 'off', optimizer = 'on' + Settings: optimizer = 'on', enable_mergejoin = 'on', enable_hashjoin = 'off', enable_nestloop = 'on', enable_seqscan = 'off', enable_bitmapscan = 'off' Optimizer: GPORCA (24 rows) drop table j3; -- Test that we do not account for nullingrels when looking up statistics CREATE TABLE group_tbl (a INT, b INT); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO group_tbl SELECT 1, 1; CREATE STATISTICS group_tbl_stat (ndistinct) ON a, b FROM group_tbl; ANALYZE group_tbl; @@ -8925,8 +8910,8 @@ EXPLAIN (COSTS OFF) SELECT 1 FROM group_tbl t1 LEFT JOIN (SELECT a c1, COALESCE(a) c2 FROM group_tbl t2) s ON TRUE GROUP BY s.c1, s.c2; - QUERY PLAN --------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------- Result -> Gather Motion 3:1 (slice1; segments: 3) -> GroupAggregate diff --git a/contrib/pax_storage/src/test/regress/expected/memoize_optimizer.out b/contrib/pax_storage/src/test/regress/expected/memoize_optimizer.out index a082828630c..5a6a3987b11 100644 --- a/contrib/pax_storage/src/test/regress/expected/memoize_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/memoize_optimizer.out @@ -249,8 +249,12 @@ DROP TABLE strtest; -- Ensure memoize works with partitionwise join SET enable_partitionwise_join TO on; CREATE TABLE prt (a int) PARTITION BY RANGE(a); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TABLE prt_p1 PARTITION OF prt FOR VALUES FROM (0) TO (10); +NOTICE: table has parent, setting distribution columns to match parent table CREATE TABLE prt_p2 PARTITION OF prt FOR VALUES FROM (10) TO (20); +NOTICE: table has parent, setting distribution columns to match parent table INSERT INTO prt VALUES (0), (0), (0), (0); INSERT INTO prt VALUES (10), (10), (10), (10); CREATE INDEX iprt_p1_a ON prt_p1 (a); @@ -269,6 +273,7 @@ SELECT * FROM prt t1 INNER JOIN prt t2 ON t1.a = t2.a;', false); -> Dynamic Seq Scan on prt t2 (actual rows=3 loops=N) Number of partitions to scan: 2 (out of 2) Partitions scanned: Avg 1.4 x 3 workers of 5 scans. Max 2 parts (seg2). + Optimizer: GPORCA (10 rows) -- Ensure memoize works with parameterized union-all Append path @@ -303,32 +308,29 @@ WHERE unique1 < 3 SELECT 1 FROM tenk1 t1 INNER JOIN tenk1 t2 ON t1.unique1 = t2.hundred WHERE t0.ten = t1.twenty AND t0.two <> t2.four OFFSET 0); - QUERY PLAN ------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> GroupAggregate - Group Key: t0.unique1, t0.ctid, t0.gp_segment_id - -> Sort - Sort Key: t0.ctid, t0.gp_segment_id + -> Hash Right Semi Join + Hash Cond: (t0.ten = t1.twenty) + Join Filter: (t0.two <> t2.four) + -> Result -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: t0.ctid, t0.gp_segment_id - -> Streaming HashAggregate - Group Key: t0.unique1, t0.ctid, t0.gp_segment_id - -> Nested Loop - Join Filter: ((t0.ten = t1.twenty) AND (t0.two <> t2.four)) - -> Broadcast Motion 3:3 (slice4; segments: 3) - -> Seq Scan on tenk1 t0 - Filter: (unique1 < 3) - -> Materialize - -> Nested Loop - Join Filter: (t1.unique1 = t2.hundred) - -> Seq Scan on tenk1 t1 - -> Materialize - -> Redistribute Motion 3:3 (slice3; segments: 3) - Hash Key: t2.hundred - -> Seq Scan on tenk1 t2 + Hash Key: t1.twenty + -> Nested Loop + Join Filter: (t1.unique1 = t2.hundred) + -> Seq Scan on tenk1 t1 + -> Materialize + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t2.hundred + -> Seq Scan on tenk1 t2 + -> Hash + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: t0.ten + -> Seq Scan on tenk1 t0 + Filter: (unique1 < 3) Optimizer: GPORCA -(23 rows) +(20 rows) -- Ensure the above query returns the correct result SELECT unique1 FROM tenk1 t0 diff --git a/contrib/pax_storage/src/test/regress/expected/partition_join.out b/contrib/pax_storage/src/test/regress/expected/partition_join.out index 39084feb830..e1b04863202 100644 --- a/contrib/pax_storage/src/test/regress/expected/partition_join.out +++ b/contrib/pax_storage/src/test/regress/expected/partition_join.out @@ -2,6 +2,9 @@ -- PARTITION_JOIN -- Test partitionwise join between partitioned tables -- +-- start_ignore +set gp_use_streaming_hashagg = off; +-- end_ignore -- Disable ORCA since it does support partition-wise joins set optimizer to off; -- Enable partitionwise join, which by default is disabled. @@ -2473,12 +2476,12 @@ SELECT COUNT(*) FROM prt1_l t1 LEFT JOIN LATERAL (SELECT t1.b AS t1b, t2.* FROM prt2_l t2) s ON t1.a = s.b AND t1.b = s.a AND t1.c = s.c WHERE s.t1b = s.a; -ERROR: could not pull up equivalence class using projected target list (pathkeys.c:1615) +ERROR: could not pull up equivalence class using projected target list (pathkeys.c:1618) SELECT COUNT(*) FROM prt1_l t1 LEFT JOIN LATERAL (SELECT t1.b AS t1b, t2.* FROM prt2_l t2) s ON t1.a = s.b AND t1.b = s.a AND t1.c = s.c WHERE s.t1b = s.a; -ERROR: could not pull up equivalence class using projected target list (pathkeys.c:1615) +ERROR: could not pull up equivalence class using projected target list (pathkeys.c:1618) RESET max_parallel_workers_per_gather; -- join with one side empty EXPLAIN (COSTS OFF) @@ -4141,54 +4144,33 @@ SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = -- semi join EXPLAIN (COSTS OFF) SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; - QUERY PLAN --------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Merge Key: t1.a -> Sort Sort Key: t1.a -> Append - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) - -> Seq Scan on plt2_adv_p1 t2_1 - -> Hash - -> Seq Scan on plt1_adv_p1 t1_1 - Filter: (b < 10) - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice3; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) - -> Seq Scan on plt2_adv_p2 t2_2 - -> Hash - -> Seq Scan on plt1_adv_p2 t1_2 - Filter: (b < 10) - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice4; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) - -> Seq Scan on plt2_adv_p3 t2_3 - -> Hash - -> Seq Scan on plt1_adv_p3 t1_3 - Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3 t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) Optimizer: Postgres query optimizer -(45 rows) +(24 rows) SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; a | b | c @@ -4371,54 +4353,33 @@ SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = -- semi join EXPLAIN (COSTS OFF) SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; - QUERY PLAN --------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Merge Key: t1.a -> Sort Sort Key: t1.a -> Append - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) - -> Seq Scan on plt2_adv_p1 t2_1 - -> Hash - -> Seq Scan on plt1_adv_p1 t1_1 - Filter: (b < 10) - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice3; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) - -> Seq Scan on plt2_adv_p2 t2_2 - -> Hash - -> Seq Scan on plt1_adv_p2 t1_2 - Filter: (b < 10) - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice4; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) - -> Seq Scan on plt2_adv_p3 t2_3 - -> Hash - -> Seq Scan on plt1_adv_p3 t1_3 - Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3 t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) Optimizer: Postgres query optimizer -(45 rows) +(24 rows) SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; a | b | c @@ -4638,39 +4599,29 @@ SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = -- semi join EXPLAIN (COSTS OFF) SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; - QUERY PLAN ------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Merge Key: t1.a -> Sort Sort Key: t1.a - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: ((t2.a = t1.a) AND (t2.c = t1.c)) - -> Append - Partition Selectors: $0 - -> Seq Scan on plt2_adv_p1 t2_1 - -> Seq Scan on plt2_adv_p2_1 t2_2 - -> Seq Scan on plt2_adv_p2_2 t2_3 - -> Seq Scan on plt2_adv_p3 t2_4 - -> Hash - -> Partition Selector (selector id: $0) - -> Result - -> Append - -> Seq Scan on plt1_adv_p1 t1_1 - Filter: (b < 10) - -> Seq Scan on plt1_adv_p2 t1_2 - Filter: (b < 10) - -> Seq Scan on plt1_adv_p3 t1_3 - Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2.a = t1.a) AND (t2.c = t1.c)) + -> Append + -> Seq Scan on plt2_adv_p1 t2_1 + -> Seq Scan on plt2_adv_p2_1 t2_2 + -> Seq Scan on plt2_adv_p2_2 t2_3 + -> Seq Scan on plt2_adv_p3 t2_4 + -> Hash + -> Append + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) Optimizer: Postgres query optimizer -(30 rows) +(20 rows) -- left join EXPLAIN (COSTS OFF) @@ -4815,54 +4766,33 @@ SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = -- semi join EXPLAIN (COSTS OFF) SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; - QUERY PLAN --------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Merge Key: t1.a -> Sort Sort Key: t1.a -> Append - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) - -> Seq Scan on plt2_adv_p1 t2_1 - -> Hash - -> Seq Scan on plt1_adv_p1_null t1_1 - Filter: (b < 10) - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice3; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) - -> Seq Scan on plt2_adv_p2 t2_2 - -> Hash - -> Seq Scan on plt1_adv_p2 t1_2 - Filter: (b < 10) - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice4; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) - -> Seq Scan on plt2_adv_p3_null t2_3 - -> Hash - -> Seq Scan on plt1_adv_p3 t1_3 - Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1_null t1_1 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3_null t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) Optimizer: Postgres query optimizer -(45 rows) +(24 rows) SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; a | b | c diff --git a/contrib/pax_storage/src/test/regress/expected/qp_correlated_query.out b/contrib/pax_storage/src/test/regress/expected/qp_correlated_query.out index 59a3abc3cbf..b694f18cb1d 100644 --- a/contrib/pax_storage/src/test/regress/expected/qp_correlated_query.out +++ b/contrib/pax_storage/src/test/regress/expected/qp_correlated_query.out @@ -76,10 +76,10 @@ commit; select a, x from qp_csq_t1, qp_csq_t2 where qp_csq_t1.a in (select x); a | x ---+--- - 1 | 1 - 3 | 3 5 | 5 + 3 | 3 7 | 7 + 1 | 1 (4 rows) select A.i from A where A.i in (select B.i from B where A.i = B.i) order by A.i; @@ -174,11 +174,11 @@ select * from A where exists (select * from B where A.i in (select C.i from C wh Gather Motion 3:1 (slice1; segments: 3) -> Hash Semi Join Hash Cond: (a.i = b.i) - -> Hash Semi Join - Hash Cond: (a.i = c.i) - -> Seq Scan on a + -> Hash Right Semi Join + Hash Cond: (c.i = a.i) + -> Seq Scan on c -> Hash - -> Seq Scan on c + -> Seq Scan on a -> Hash -> Seq Scan on b Optimizer: Postgres query optimizer @@ -194,8 +194,8 @@ select * from A where exists (select * from B where A.i in (select C.i from C wh -- Test for ALL_SUBLINK pull-up based on both left-hand and right-hand input explain (costs off) select * from A,B where exists (select * from C where B.i not in (select C.i from C where C.i != 10)); - QUERY PLAN ---------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Semi Join -> Nested Loop @@ -218,11 +218,11 @@ select * from A,B where exists (select * from C where B.i not in (select C.i fro select * from A,B where exists (select * from C where B.i not in (select C.i from C where C.i != 10)); i | j | i | j ----+----+----+--- - 78 | -1 | 88 | 1 - 1 | 1 | 88 | 1 19 | 5 | 88 | 1 99 | 62 | 88 | 1 1 | 1 | 88 | 1 + 1 | 1 | 88 | 1 + 78 | -1 | 88 | 1 (5 rows) -- -- -- -- @@ -378,13 +378,13 @@ select A.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i i explain select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i not in (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=20000000003.86..20000000004.00 rows=10 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000003.86..20000000004.28 rows=30 width=12) + Limit (cost=20000000004.94..20000000005.08 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000004.94..20000000005.36 rows=30 width=12) Merge Key: a.i, b.i, c.j - -> Limit (cost=20000000003.86..20000000003.88 rows=10 width=12) - -> Sort (cost=20000000003.85..20000000003.90 rows=18 width=12) + -> Limit (cost=20000000004.94..20000000004.96 rows=10 width=12) + -> Sort (cost=20000000004.94..20000000004.98 rows=18 width=12) Sort Key: a.i, b.i, c.j - -> Nested Loop (cost=20000000000.00..20000000003.48 rows=18 width=12) + -> Nested Loop (cost=20000000000.00..20000000004.56 rows=18 width=12) -> Nested Loop (cost=10000000000.00..10000000002.08 rows=2 width=8) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.04 rows=1 width=4) -> Seq Scan on a (cost=0.00..1.02 rows=1 width=4) @@ -428,36 +428,36 @@ select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j explain select A.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i not in (select B.i from B where C.i = B.i and B.i !=10)) order by A.j limit 10; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=20000000100.52..20000000100.75 rows=10 width=4) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=20000000100.52..20000000100.75 rows=10 width=4) + Limit (cost=20000000005.04..20000000005.18 rows=10 width=4) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000005.04..20000000005.46 rows=30 width=4) Merge Key: a.j - -> Limit (cost=20000000100.52..20000000100.55 rows=4 width=4) - -> Sort (cost=20000000100.52..20000000100.66 rows=18 width=4) + -> Limit (cost=20000000005.04..20000000005.06 rows=10 width=4) + -> Sort (cost=20000000005.04..20000000005.08 rows=18 width=4) Sort Key: a.j - -> Nested Loop (cost=20000000000.00..20000000099.36 rows=18 width=4) - -> Nested Loop (cost=10000000000.00..10000000094.04 rows=2 width=4) - -> Seq Scan on a (cost=0.00..90.47 rows=1 width=4) + -> Nested Loop (cost=20000000000.00..20000000004.66 rows=18 width=4) + -> Nested Loop (cost=10000000000.00..10000000002.18 rows=2 width=4) + -> Seq Scan on a (cost=0.00..1.02 rows=1 width=4) Filter: (j = (SubPlan 2)) SubPlan 2 - -> Result (cost=0.00..17.68 rows=5 width=4) + -> Result (cost=0.00..1.16 rows=4 width=4) Filter: (c_1.j = a.j) - -> Materialize (cost=0.00..17.68 rows=5 width=4) - -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..17.66 rows=2 width=4) - -> Seq Scan on c c_1 (cost=0.00..17.57 rows=2 width=4) + -> Materialize (cost=0.00..1.11 rows=4 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.09 rows=4 width=4) + -> Seq Scan on c c_1 (cost=0.00..1.03 rows=2 width=4) Filter: (SubPlan 1) SubPlan 1 - -> Result (cost=0.00..3.20 rows=5 width=4) + -> Result (cost=0.00..1.17 rows=5 width=4) Filter: (c_1.i = b_1.i) - -> Materialize (cost=0.00..3.20 rows=5 width=4) - -> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..3.17 rows=2 width=4) - -> Seq Scan on b b_1 (cost=0.00..3.08 rows=2 width=4) + -> Materialize (cost=0.00..1.12 rows=5 width=4) + -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..1.09 rows=5 width=4) + -> Seq Scan on b b_1 (cost=0.00..1.02 rows=2 width=4) Filter: (i <> 10) - -> Materialize (cost=0.00..3.39 rows=6 width=0) - -> Broadcast Motion 3:3 (slice1; segments: 3) (cost=0.00..3.30 rows=6 width=0) - -> Seq Scan on b (cost=0.00..3.06 rows=2 width=0) - -> Materialize (cost=0.00..3.58 rows=9 width=0) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..3.45 rows=9 width=0) - -> Seq Scan on c (cost=0.00..3.09 rows=3 width=0) + -> Materialize (cost=0.00..1.13 rows=6 width=0) + -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..1.10 rows=6 width=0) + -> Seq Scan on b (cost=0.00..1.02 rows=2 width=0) + -> Materialize (cost=0.00..1.19 rows=9 width=0) + -> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..1.15 rows=9 width=0) + -> Seq Scan on c (cost=0.00..1.03 rows=3 width=0) Optimizer: Postgres query optimizer (31 rows) @@ -479,21 +479,21 @@ select A.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i n explain select A.i from A where A.j = (select C.j from C where C.j = A.j and C.i = any (select B.i from B where C.i = B.i and B.i !=10)); QUERY PLAN --------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..35.42 rows=1 width=4) - -> Seq Scan on a (cost=0.00..35.42 rows=1 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.04 rows=1 width=4) + -> Seq Scan on a (cost=0.00..1.02 rows=1 width=4) Filter: (j = (SubPlan 1)) SubPlan 1 - -> Hash Semi Join (cost=3.26..6.67 rows=6 width=4) + -> Hash Semi Join (cost=1.18..2.55 rows=5 width=4) Hash Cond: (c.i = b.i) - -> Result (cost=0.00..3.31 rows=9 width=8) + -> Result (cost=0.00..1.28 rows=9 width=8) Filter: (c.j = a.j) - -> Materialize (cost=0.00..3.31 rows=9 width=8) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..3.27 rows=3 width=8) - -> Seq Scan on c (cost=0.00..3.09 rows=3 width=8) - -> Hash (cost=3.20..3.20 rows=2 width=4) - -> Materialize (cost=0.00..3.20 rows=5 width=4) - -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..3.17 rows=2 width=4) - -> Seq Scan on b (cost=0.00..3.08 rows=2 width=4) + -> Materialize (cost=0.00..1.19 rows=9 width=8) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.15 rows=9 width=8) + -> Seq Scan on c (cost=0.00..1.03 rows=3 width=8) + -> Hash (cost=1.12..1.12 rows=5 width=4) + -> Materialize (cost=0.00..1.12 rows=5 width=4) + -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..1.09 rows=5 width=4) + -> Seq Scan on b (cost=0.00..1.02 rows=2 width=4) Filter: (i <> 10) Optimizer: Postgres query optimizer (17 rows) @@ -513,10 +513,10 @@ select A.i from A where A.j = (select C.j from C where C.j = A.j and C.i = any ( select a, x from qp_csq_t1, qp_csq_t2 where qp_csq_t1.a = any (select x); a | x ---+--- - 1 | 1 - 3 | 3 5 | 5 + 3 | 3 7 | 7 + 1 | 1 (4 rows) select a, x from qp_csq_t1, qp_csq_t2 where qp_csq_t1.a = any (select x) order by a, x; @@ -590,20 +590,16 @@ select * from A where A.j = any (select C.j from C,B where C.j = A.j and B.i = a -- Planner should fail due to skip-level correlation not supported. ORCA should pass select * from A,B where A.j = any (select C.j from C where C.j = A.j and B.i = any (select C.i from C where C.i != 10 and C.i = A.i)) order by 1,2,3,4; ERROR: correlated subquery with skip-level correlations is not supported --- start_ignore --- GPDB_96_MERGE_FIXME: we used to propagate the (i <> 10) qual to the Seq Scans on --- 'c'. Investigate why we lost that --- end_ignore explain select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i = any (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=20000000003.86..20000000004.00 rows=10 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000003.86..20000000004.28 rows=30 width=12) + Limit (cost=20000000004.94..20000000005.08 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000004.94..20000000005.36 rows=30 width=12) Merge Key: a.i, b.i, c.j - -> Limit (cost=20000000003.86..20000000003.88 rows=10 width=12) - -> Sort (cost=20000000003.85..20000000003.90 rows=18 width=12) + -> Limit (cost=20000000004.94..20000000004.96 rows=10 width=12) + -> Sort (cost=20000000004.94..20000000004.98 rows=18 width=12) Sort Key: a.i, b.i, c.j - -> Nested Loop (cost=20000000000.00..20000000003.48 rows=18 width=12) + -> Nested Loop (cost=20000000000.00..20000000004.56 rows=18 width=12) -> Nested Loop (cost=10000000000.00..10000000002.08 rows=2 width=8) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.04 rows=1 width=4) -> Seq Scan on a (cost=0.00..1.02 rows=1 width=4) @@ -646,36 +642,36 @@ select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j explain select A.i, B.i, C.j from A, B, C where A.j = any ( select C.j from C where not exists(select C.i from C,A where C.i = A.i and C.i =10)) order by A.i, B.i, C.j limit 10; QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=20000000007.72..20000000007.86 rows=10 width=12) + Limit (cost=20000000007.69..20000000007.83 rows=10 width=12) InitPlan 1 (returns $0) (slice6) - -> Gather Motion 1:1 (slice7; segments: 1) (cost=10000000000.00..10000000002.11 rows=3 width=0) - -> Nested Loop (cost=10000000000.00..10000000002.07 rows=1 width=0) + -> Gather Motion 1:1 (slice7; segments: 1) (cost=10000000000.00..10000000002.11 rows=3 width=4) + -> Nested Loop (cost=10000000000.00..10000000002.07 rows=1 width=4) -> Seq Scan on c c_2 (cost=0.00..1.04 rows=1 width=4) Filter: (i = 10) -> Seq Scan on a a_1 (cost=0.00..1.02 rows=1 width=4) Filter: (i = 10) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000007.72..20000000008.15 rows=30 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000007.69..20000000008.11 rows=30 width=12) Merge Key: a.i, b.i, c.j - -> Limit (cost=20000000007.72..20000000007.75 rows=10 width=12) - -> Sort (cost=20000000007.70..20000000007.92 rows=90 width=12) + -> Limit (cost=20000000007.69..20000000007.71 rows=10 width=12) + -> Sort (cost=20000000007.69..20000000007.91 rows=90 width=12) Sort Key: a.i, b.i, c.j - -> Result (cost=20000000001.13..20000000005.75 rows=90 width=12) + -> Result (cost=20000000001.07..20000000005.74 rows=90 width=12) One-Time Filter: (NOT $0) - -> Nested Loop (cost=20000000001.13..20000000005.75 rows=90 width=12) + -> Nested Loop (cost=20000000001.07..20000000005.74 rows=90 width=12) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=6 width=4) -> Seq Scan on b (cost=0.00..1.02 rows=2 width=4) - -> Materialize (cost=10000000001.13..10000000003.57 rows=15 width=8) - -> Nested Loop (cost=10000000001.13..10000000003.49 rows=15 width=8) - -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=1.13..2.27 rows=5 width=4) - -> Hash Semi Join (cost=1.13..2.20 rows=2 width=4) - Hash Cond: (a.j = c_1.j) - -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..1.05 rows=2 width=8) - Hash Key: a.j - -> Seq Scan on a (cost=0.00..1.02 rows=2 width=8) - -> Hash (cost=1.09..1.09 rows=3 width=4) - -> Redistribute Motion 3:3 (slice5; segments: 3) (cost=0.00..1.09 rows=3 width=4) - Hash Key: c_1.j - -> Seq Scan on c c_1 (cost=0.00..1.03 rows=3 width=4) + -> Materialize (cost=10000000001.07..10000000003.56 rows=15 width=8) + -> Nested Loop (cost=10000000001.07..10000000003.48 rows=15 width=8) + -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=1.07..2.26 rows=5 width=4) + -> Hash Right Semi Join (cost=1.07..2.19 rows=2 width=4) + Hash Cond: (c_1.j = a.j) + -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..1.09 rows=3 width=4) + Hash Key: c_1.j + -> Seq Scan on c c_1 (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.05..1.05 rows=2 width=8) + -> Redistribute Motion 3:3 (slice5; segments: 3) (cost=0.00..1.05 rows=2 width=8) + Hash Key: a.j + -> Seq Scan on a (cost=0.00..1.02 rows=2 width=8) -> Materialize (cost=0.00..1.04 rows=3 width=4) -> Seq Scan on c (cost=0.00..1.03 rows=3 width=4) Optimizer: Postgres query optimizer @@ -699,10 +695,10 @@ select A.i, B.i, C.j from A, B, C where A.j = any ( select C.j from C where not explain select A.i, B.i, C.j from A, B, C where A.j = any (select C.j from C where C.j = A.j and not exists (select sum(B.i) from B where C.i = B.i and C.i !=10)) order by A.i, B.i, C.j limit 10; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- - Limit (cost=20000000004.85..20000000004.99 rows=10 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000004.85..20000000005.28 rows=30 width=12) + Limit (cost=20000000004.84..20000000004.98 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000004.84..20000000005.27 rows=30 width=12) Merge Key: a.i, b.i, c.j - -> Limit (cost=20000000004.85..20000000004.88 rows=10 width=12) + -> Limit (cost=20000000004.84..20000000004.87 rows=10 width=12) -> Sort (cost=20000000004.84..20000000004.95 rows=45 width=12) Sort Key: a.i, b.i, c.j -> Nested Loop (cost=20000000000.00..20000000003.87 rows=45 width=12) @@ -785,16 +781,16 @@ select * from A,B where exists (select * from C where C.j = A.j and B.i = all (s explain select A.i, B.i, C.j from A, B, C where A.j = (select sum(C.j) from C where C.j = A.j and C.i = all (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=20000000006.84..20000000006.98 rows=10 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000006.84..20000000007.26 rows=30 width=12) + Limit (cost=20000000006.82..20000000006.96 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000006.82..20000000007.24 rows=30 width=12) Merge Key: a.i, b.i, c.j - -> Limit (cost=20000000006.84..20000000006.86 rows=10 width=12) + -> Limit (cost=20000000006.82..20000000006.84 rows=10 width=12) -> Sort (cost=20000000006.82..20000000006.99 rows=67 width=12) Sort Key: a.i, b.i, c.j -> Nested Loop (cost=20000000001.11..20000000005.36 rows=67 width=12) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.15 rows=9 width=4) -> Seq Scan on c (cost=0.00..1.03 rows=3 width=4) - -> Materialize (cost=10000000001.11..10000000003.39 rows=7 width=8) + -> Materialize (cost=10000000001.11..10000000003.38 rows=7 width=8) -> Nested Loop (cost=10000000001.11..10000000003.35 rows=7 width=8) -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=1.11..2.23 rows=4 width=4) -> Hash Join (cost=1.11..2.18 rows=1 width=4) @@ -841,18 +837,18 @@ select A.i, B.i, C.j from A, B, C where A.j = (select sum(C.j) from C where C.j explain select A.i, B.i, C.j from A, B, C where A.j < all ( select C.j from C where not exists(select C.i from C,A where C.i = A.i and C.i =10)) order by A.i, B.i, C.j limit 10; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------ - Limit (cost=30000000007.49..30000000007.64 rows=10 width=12) + Limit (cost=30000000007.49..30000000007.63 rows=10 width=12) InitPlan 1 (returns $0) (slice5) - -> Gather Motion 1:1 (slice6; segments: 1) (cost=10000000000.00..10000000002.11 rows=3 width=0) - -> Nested Loop (cost=10000000000.00..10000000002.07 rows=1 width=0) + -> Gather Motion 1:1 (slice6; segments: 1) (cost=10000000000.00..10000000002.11 rows=3 width=4) + -> Nested Loop (cost=10000000000.00..10000000002.07 rows=1 width=4) -> Seq Scan on c c_2 (cost=0.00..1.04 rows=1 width=4) Filter: (i = 10) -> Seq Scan on a a_1 (cost=0.00..1.02 rows=1 width=4) Filter: (i = 10) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=30000000007.49..30000000007.92 rows=30 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=30000000007.49..30000000007.91 rows=30 width=12) Merge Key: a.i, b.i, c.j - -> Limit (cost=30000000007.49..30000000007.52 rows=10 width=12) - -> Sort (cost=30000000007.48..30000000007.63 rows=60 width=12) + -> Limit (cost=30000000007.49..30000000007.51 rows=10 width=12) + -> Sort (cost=30000000007.49..30000000007.64 rows=60 width=12) Sort Key: a.i, b.i, c.j -> Nested Loop (cost=30000000000.00..30000000006.19 rows=60 width=12) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.15 rows=9 width=4) @@ -881,10 +877,10 @@ select A.i, B.i, C.j from A, B, C where A.j < all ( select C.j from C where not explain select A.i, B.i, C.j from A, B, C where A.j = all (select C.j from C where C.j = A.j and not exists (select sum(B.i) from B where C.i = B.i and C.i !=10)) order by A.i, B.i, C.j limit 10; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- - Limit (cost=20000000004.85..20000000004.99 rows=10 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000004.85..20000000005.28 rows=30 width=12) + Limit (cost=20000000004.84..20000000004.98 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000004.84..20000000005.27 rows=30 width=12) Merge Key: a.i, b.i, c.j - -> Limit (cost=20000000004.85..20000000004.88 rows=10 width=12) + -> Limit (cost=20000000004.84..20000000004.87 rows=10 width=12) -> Sort (cost=20000000004.84..20000000004.95 rows=45 width=12) Sort Key: a.i, b.i, c.j -> Nested Loop (cost=20000000000.00..20000000003.87 rows=45 width=12) @@ -1031,20 +1027,20 @@ select * from A,B where exists (select * from C where C.j = A.j and exists (sele ----+----+----+---- 1 | 1 | 2 | 7 1 | 1 | 2 | 7 - 99 | 62 | 2 | 7 78 | -1 | 2 | 7 - 99 | 62 | -1 | 62 - 99 | 62 | 32 | 5 - 78 | -1 | -1 | 62 - 78 | -1 | 32 | 5 + 99 | 62 | 2 | 7 1 | 1 | -1 | 62 1 | 1 | 32 | 5 1 | 1 | -1 | 62 1 | 1 | 32 | 5 - 99 | 62 | 1 | 43 - 99 | 62 | 1 | 1 + 78 | -1 | -1 | 62 + 78 | -1 | 32 | 5 + 99 | 62 | -1 | 62 + 99 | 62 | 32 | 5 78 | -1 | 1 | 43 78 | -1 | 1 | 1 + 99 | 62 | 1 | 43 + 99 | 62 | 1 | 1 1 | 1 | 1 | 43 1 | 1 | 1 | 1 1 | 1 | 1 | 43 @@ -1156,9 +1152,9 @@ select * from A,B,C where C.i = A.i and exists (select C.j where C.j = B.j and A select b from qp_csq_t1 where not exists(select * from qp_csq_t2 where y=a); b --- - 4 6 8 + 4 (3 rows) select b from qp_csq_t1 where not exists(select * from qp_csq_t2 where y=a) order by b; @@ -1229,44 +1225,43 @@ select * from A where not exists (select sum(C.i) from C where C.i = A.i); explain select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 0); QUERY PLAN ---------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.05 rows=5 width=8) - -> Seq Scan on a (cost=0.00..3.05 rows=2 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.08 rows=5 width=8) + -> Seq Scan on a (cost=0.00..1.02 rows=2 width=8) Optimizer: Postgres query optimizer (3 rows) select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 0); i | j ----+---- - 19 | 5 - 99 | 62 - 78 | -1 1 | 1 1 | 1 + 78 | -1 + 19 | 5 + 99 | 62 (5 rows) explain select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 5 offset 3); QUERY PLAN ---------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.05 rows=5 width=8) - -> Seq Scan on a (cost=0.00..3.05 rows=2 width=8) - Settings: optimizer=off - Optimizer status: Postgres query optimizer -(4 rows) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.08 rows=5 width=8) + -> Seq Scan on a (cost=0.00..1.02 rows=2 width=8) + Optimizer: Postgres query optimizer +(3 rows) select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 5 offset 3); i | j ----+---- 19 | 5 + 99 | 62 1 | 1 1 | 1 - 99 | 62 78 | -1 (5 rows) explain select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 1 offset 0); QUERY PLAN ------------------------------------------ - Result (cost=0.00..0.01 rows=1 width=0) + Result (cost=0.00..0.00 rows=0 width=0) One-Time Filter: false Optimizer: Postgres query optimizer (3 rows) @@ -1279,20 +1274,20 @@ select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 1 explain select C.j from C where not exists (select max(B.i) from B where C.i = B.i having max(B.i) is not null) order by C.j; QUERY PLAN --------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=31.39..31.40 rows=5 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.04..1.10 rows=4 width=4) Merge Key: c.j - -> Sort (cost=31.39..31.40 rows=2 width=4) + -> Sort (cost=1.04..1.04 rows=2 width=4) Sort Key: c.j - -> Seq Scan on c (cost=0.00..31.34 rows=2 width=4) - Filter: NOT ((SubPlan 1)) + -> Seq Scan on c (cost=0.00..1.03 rows=2 width=4) + Filter: (NOT (SubPlan 1)) SubPlan 1 - -> Aggregate (cost=3.13..3.14 rows=1 width=4) - Filter: max(b.i) IS NOT NULL - -> Result (cost=0.00..3.08 rows=1 width=4) - Filter: c.i = b.i - -> Materialize (cost=0.00..3.08 rows=1 width=4) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..3.08 rows=1 width=4) - -> Seq Scan on b (cost=0.00..3.08 rows=1 width=4) + -> Aggregate (cost=1.21..1.22 rows=1 width=4) + Filter: (max(b.i) IS NOT NULL) + -> Result (cost=0.00..1.19 rows=6 width=4) + Filter: (c.i = b.i) + -> Materialize (cost=0.00..1.13 rows=6 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=6 width=4) + -> Seq Scan on b (cost=0.00..1.02 rows=2 width=4) Optimizer: Postgres query optimizer (15 rows) @@ -1308,11 +1303,11 @@ select C.j from C where not exists (select max(B.i) from B where C.i = B.i havi explain select C.j from C where not exists (select max(B.i) from B where C.i = B.i offset 1000) order by C.j; QUERY PLAN ---------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=3.23..3.26 rows=9 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.05..1.18 rows=9 width=4) Merge Key: j - -> Sort (cost=3.23..3.26 rows=3 width=4) + -> Sort (cost=1.05..1.06 rows=3 width=4) Sort Key: j - -> Seq Scan on c (cost=0.00..3.09 rows=3 width=4) + -> Seq Scan on c (cost=0.00..1.03 rows=3 width=4) Optimizer: Postgres query optimizer (6 rows) @@ -1333,15 +1328,15 @@ select C.j from C where not exists (select max(B.i) from B where C.i = B.i offs explain select C.j from C where not exists (select rank() over (order by B.i) from B where C.i = B.i) order by C.j; QUERY PLAN ---------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=6.33..6.33 rows=4 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=2.11..2.16 rows=3 width=4) Merge Key: c.j - -> Sort (cost=6.33..6.33 rows=2 width=4) + -> Sort (cost=2.11..2.11 rows=1 width=4) Sort Key: c.j - -> Hash Anti Join (cost=3.14..6.30 rows=2 width=4) + -> Hash Anti Join (cost=1.04..2.10 rows=1 width=4) Hash Cond: (c.i = b.i) - -> Seq Scan on c (cost=0.00..3.09 rows=3 width=8) - -> Hash (cost=3.06..3.06 rows=2 width=4) - -> Seq Scan on b (cost=0.00..3.06 rows=2 width=4) + -> Seq Scan on c (cost=0.00..1.03 rows=3 width=8) + -> Hash (cost=1.02..1.02 rows=2 width=4) + -> Seq Scan on b (cost=0.00..1.02 rows=2 width=4) Optimizer: Postgres query optimizer (10 rows) @@ -1375,14 +1370,14 @@ select * from A where not exists (select sum(C.i) from C where C.i = A.i group b explain select A.i from A where not exists (select B.i from B where B.i in (select C.i from C) and B.i = A.i); QUERY PLAN ---------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.10..3.22 rows=3 width=4) - -> Hash Right Anti Join (cost=2.10..3.17 rows=1 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=2.08..3.21 rows=3 width=4) + -> Hash Right Anti Join (cost=2.08..3.16 rows=1 width=4) Hash Cond: (b.i = a.i) - -> Hash Semi Join (cost=1.07..2.12 rows=2 width=4) - Hash Cond: (b.i = c.i) - -> Seq Scan on b (cost=0.00..1.02 rows=2 width=4) - -> Hash (cost=1.03..1.03 rows=3 width=4) - -> Seq Scan on c (cost=0.00..1.03 rows=3 width=4) + -> Hash Right Semi Join (cost=1.04..2.11 rows=2 width=4) + Hash Cond: (c.i = b.i) + -> Seq Scan on c (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.02..1.02 rows=2 width=4) + -> Seq Scan on b (cost=0.00..1.02 rows=2 width=4) -> Hash (cost=1.02..1.02 rows=2 width=4) -> Seq Scan on a (cost=0.00..1.02 rows=2 width=4) Optimizer: Postgres query optimizer @@ -1391,31 +1386,27 @@ explain select A.i from A where not exists (select B.i from B where B.i in (sele select A.i from A where not exists (select B.i from B where B.i in (select C.i from C) and B.i = A.i); i ---- + 19 99 78 - 19 (3 rows) --- start_ignore --- GPDB_96_MERGE_FIXME: we used to propagate the (i <> 10) qual to the Seq Scans on --- 'c' and 'a'. Investigate why we lost that --- end_ignore explain select * from B where not exists (select * from C,A where C.i in (select C.i from C where C.i = A.i and C.i != 10) AND B.i = C.i); - QUERY PLAN -------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=3.15..4.30 rows=3 width=8) - -> Hash Right Anti Join (cost=3.15..4.25 rows=1 width=8) + QUERY PLAN +------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=3.16..4.29 rows=3 width=8) + -> Hash Right Anti Join (cost=3.16..4.24 rows=1 width=8) Hash Cond: (c.i = b.i) - -> Hash Semi Join (cost=2.11..3.19 rows=2 width=4) - Hash Cond: (a.i = c_1.i) - -> Hash Join (cost=1.04..2.10 rows=2 width=8) - Hash Cond: (c.i = a.i) - -> Seq Scan on c (cost=0.00..1.03 rows=3 width=4) - -> Hash (cost=1.02..1.02 rows=2 width=4) - -> Seq Scan on a (cost=0.00..1.02 rows=2 width=4) - -> Hash (cost=1.04..1.04 rows=3 width=4) - -> Seq Scan on c c_1 (cost=0.00..1.04 rows=3 width=4) - Filter: (i <> 10) + -> Hash Right Semi Join (cost=2.12..3.18 rows=2 width=4) + Hash Cond: (c_1.i = a.i) + -> Seq Scan on c c_1 (cost=0.00..1.04 rows=3 width=4) + Filter: (i <> 10) + -> Hash (cost=2.10..2.10 rows=2 width=8) + -> Hash Join (cost=1.04..2.10 rows=2 width=8) + Hash Cond: (c.i = a.i) + -> Seq Scan on c (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.02..1.02 rows=2 width=4) + -> Seq Scan on a (cost=0.00..1.02 rows=2 width=4) -> Hash (cost=1.02..1.02 rows=2 width=8) -> Seq Scan on b (cost=0.00..1.02 rows=2 width=8) Optimizer: Postgres query optimizer @@ -1424,31 +1415,31 @@ explain select * from B where not exists (select * from C,A where C.i in (select select * from B where not exists (select * from C,A where C.i in (select C.i from C where C.i = A.i and C.i != 10) AND B.i = C.i); i | j ----+---- - 88 | 1 - -1 | 62 2 | 7 + -1 | 62 32 | 5 + 88 | 1 (4 rows) explain select * from A where A.i in (select C.j from C,B where B.i in (select i from C)); - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=10000000013.48..10000000015.62 rows=6 width=8) - -> Hash Semi Join (cost=10000000013.48..10000000015.62 rows=2 width=8) - Hash Cond: (a.i = c.j) - -> Seq Scan on a (cost=0.00..2.05 rows=2 width=8) - -> Hash (cost=10000000012.81..10000000012.81 rows=18 width=4) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=10000000003.20..10000000012.81 rows=18 width=4) - Hash Key: c.j - -> Nested Loop (cost=10000000003.20..10000000011.73 rows=18 width=4) - -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=3.20..6.59 rows=6 width=0) - -> Hash Semi Join (cost=3.20..6.35 rows=2 width=0) - Hash Cond: (b.i = c_1.i) - -> Seq Scan on b (cost=0.00..3.06 rows=2 width=4) - -> Hash (cost=3.09..3.09 rows=3 width=4) - -> Seq Scan on c c_1 (cost=0.00..3.09 rows=3 width=4) - -> Materialize (cost=0.00..3.13 rows=3 width=4) - -> Seq Scan on c (cost=0.00..3.09 rows=3 width=4) + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=10000000002.08..10000000005.01 rows=6 width=8) + -> Hash Right Semi Join (cost=10000000002.08..10000000004.93 rows=2 width=8) + Hash Cond: (c.j = a.i) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=10000000001.05..10000000003.81 rows=18 width=4) + Hash Key: c.j + -> Nested Loop (cost=10000000001.05..10000000003.45 rows=18 width=4) + -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=1.04..2.19 rows=6 width=0) + -> Hash Right Semi Join (cost=1.04..2.11 rows=2 width=0) + Hash Cond: (c_1.i = b.i) + -> Seq Scan on c c_1 (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.02..1.02 rows=2 width=4) + -> Seq Scan on b (cost=0.00..1.02 rows=2 width=4) + -> Materialize (cost=0.00..1.04 rows=3 width=4) + -> Seq Scan on c (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.02..1.02 rows=2 width=8) + -> Seq Scan on a (cost=0.00..1.02 rows=2 width=8) Optimizer: Postgres query optimizer (17 rows) @@ -1475,9 +1466,9 @@ explain select * from A where not exists (select sum(c.i) from C where C.i = A.i select * from A where not exists (select sum(c.i) from C where C.i = A.i group by C.i having c.i > 3); i | j ----+--- - 19 | 5 1 | 1 1 | 1 + 19 | 5 (3 rows) -- ---------------------------------------------------------------------- @@ -1557,10 +1548,10 @@ update D set i = 11111 from C where C.i = D.i and exists (select C.j from C,B wh select * from D; i | j -------+---- - 19 | 5 - 99 | 62 11111 | 1 11111 | 1 + 19 | 5 + 99 | 62 11111 | -1 (5 rows) @@ -1570,8 +1561,8 @@ select * from D; -------+---- 11111 | 1 11111 | 1 - 11111 | -1 19 | 5 + 11111 | -1 22222 | 62 (5 rows) @@ -2133,6 +2124,8 @@ select A.i, B.i, C.j from A, B, C where exists (select C.j from C group by C.j h begin; create table csq_emp(name text, department text, salary numeric); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'name' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into csq_emp values('a','adept',11200.00); insert into csq_emp values('b','adept',22222.00); insert into csq_emp values('c','bdept',99222.00); @@ -2182,6 +2175,8 @@ create table job ( EMPNO VARCHAR(4), jobtitle VARCHAR(20) ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'empno' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into job (EMPNO, Jobtitle) values ('01','Tester'); insert into job (EMPNO, Jobtitle) values ('02','Accountant'); insert into job (EMPNO, Jobtitle) values ('03','Developer'); @@ -3571,10 +3566,10 @@ ANALYZE qp_tab3; EXPLAIN SELECT a FROM qp_tab1 f1 LEFT JOIN qp_tab2 on a=c WHERE NOT EXISTS(SELECT 1 FROM qp_tab1 f2 WHERE f1.a = f2.a); QUERY PLAN ------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.04..3.14 rows=4 width=4) - -> Hash Anti Join (cost=2.04..3.14 rows=2 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=2.04..3.13 rows=3 width=4) + -> Hash Anti Join (cost=2.04..3.08 rows=1 width=4) Hash Cond: (f1.a = f2.a) - -> Hash Left Join (cost=1.02..2.07 rows=2 width=4) + -> Hash Left Join (cost=1.02..2.05 rows=1 width=4) Hash Cond: (f1.a = qp_tab2.c) -> Seq Scan on qp_tab1 f1 (cost=0.00..1.01 rows=1 width=4) -> Hash (cost=1.01..1.01 rows=1 width=4) @@ -3587,7 +3582,7 @@ EXPLAIN SELECT a FROM qp_tab1 f1 LEFT JOIN qp_tab2 on a=c WHERE NOT EXISTS(SELEC EXPLAIN SELECT DISTINCT a FROM qp_tab1 WHERE NOT (SELECT TRUE FROM qp_tab2 WHERE EXISTS (SELECT * FROM qp_tab3 WHERE qp_tab2.c = qp_tab3.e)); QUERY PLAN ------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=1.02..10001.04 rows=1 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.02..1.04 rows=1 width=4) Merge Key: qp_tab1.a InitPlan 1 (returns $0) (slice2) -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.02..2.09 rows=3 width=1) @@ -3596,7 +3591,7 @@ EXPLAIN SELECT DISTINCT a FROM qp_tab1 WHERE NOT (SELECT TRUE FROM qp_tab2 WHERE -> Seq Scan on qp_tab2 (cost=0.00..1.01 rows=1 width=4) -> Hash (cost=1.01..1.01 rows=1 width=4) -> Seq Scan on qp_tab3 (cost=0.00..1.01 rows=1 width=4) - -> Unique (cost=1.02..10001.03 rows=0 width=4) + -> Unique (cost=1.02..1.03 rows=0 width=4) Group Key: qp_tab1.a -> Sort (cost=1.02..1.02 rows=1 width=4) Sort Key: qp_tab1.a @@ -3675,16 +3670,16 @@ SELECT * FROM qp_non_eq_a INNER JOIN qp_non_eq_b ON qp_non_eq_a.f = qp_non_eq_b. EXPLAIN SELECT * FROM qp_non_eq_a, qp_non_eq_b WHERE qp_non_eq_a.i = qp_non_eq_b.i AND qp_non_eq_a.i = ANY('{1,2,3}'::integer[]); QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 2:1 (slice1; segments: 2) (cost=1.05..3.12 rows=4 width=24) - -> Hash Join (cost=1.05..3.12 rows=2 width=24) - Hash Cond: qp_non_eq_a.i = qp_non_eq_b.i - -> Seq Scan on qp_non_eq_a (cost=0.00..2.03 rows=1 width=12) - Filter: i = ANY ('{1,2,3}'::integer[]) - -> Hash (cost=1.03..1.03 rows=1 width=12) - -> Seq Scan on qp_non_eq_b (cost=0.00..1.03 rows=1 width=12) - Filter: i = ANY ('{1,2,3}'::integer[]) + Gather Motion 2:1 (slice1; segments: 2) (cost=1.03..2.10 rows=3 width=24) + -> Hash Join (cost=1.03..2.05 rows=1 width=24) + Hash Cond: (qp_non_eq_a.i = qp_non_eq_b.i) + -> Seq Scan on qp_non_eq_a (cost=0.00..1.01 rows=1 width=12) + Filter: (i = ANY ('{1,2,3}'::integer[])) + -> Hash (cost=1.01..1.01 rows=1 width=12) + -> Seq Scan on qp_non_eq_b (cost=0.00..1.01 rows=1 width=12) + Filter: (i = ANY ('{1,2,3}'::integer[])) Optimizer: Postgres query optimizer -(10 rows) +(9 rows) SELECT * FROM qp_non_eq_a, qp_non_eq_b WHERE qp_non_eq_a.i = qp_non_eq_b.i AND qp_non_eq_a.i = ANY('{1,2,3}'::integer[]); i | f | i | f @@ -3752,37 +3747,37 @@ analyze supplier; set optimizer_enforce_subplans = 1; -- with TVF explain select x1.a, (select count(*) from generate_series(1, x1.a)) from t1 x1; - QUERY PLAN -------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..39.57 rows=3 width=4) - -> Seq Scan on t1 x1 (cost=0.00..39.57 rows=1 width=4) + QUERY PLAN +-------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..13.56 rows=3 width=12) + -> Seq Scan on t1 x1 (cost=0.00..13.52 rows=1 width=12) SubPlan 1 -> Aggregate (cost=12.50..12.51 rows=1 width=8) - -> Function Scan on generate_series (cost=0.00..10.00 rows=334 width=0) - Optimizer: legacy query optimizer + -> Function Scan on generate_series (cost=0.00..10.00 rows=1000 width=0) + Optimizer: Postgres query optimizer (6 rows) select x1.a, (select count(*) from generate_series(1, x1.a)) from t1 x1; a | count ---+------- + 1 | 1 2 | 2 3 | 3 - 1 | 1 (3 rows) -- with limit explain select t1.a, (select count(*) c from (select city from supplier limit t1.a) x) from t1; QUERY PLAN --------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..4.00 rows=3 width=12) - -> Seq Scan on t1 (cost=0.00..4.00 rows=1 width=12) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.30 rows=3 width=12) + -> Seq Scan on t1 (cost=0.00..1.26 rows=1 width=12) SubPlan 1 - -> Aggregate (cost=0.65..0.66 rows=1 width=8) - -> Limit (cost=0.00..0.64 rows=1 width=32) - -> Result (cost=0.00..3.17 rows=5 width=32) - -> Materialize (cost=0.00..3.17 rows=5 width=0) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..3.15 rows=2 width=0) - -> Seq Scan on supplier (cost=0.00..3.05 rows=2 width=0) + -> Aggregate (cost=0.24..0.25 rows=1 width=8) + -> Limit (cost=0.00..0.23 rows=1 width=32) + -> Result (cost=0.00..1.16 rows=5 width=32) + -> Materialize (cost=0.00..1.11 rows=5 width=0) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.08 rows=5 width=0) + -> Seq Scan on supplier (cost=0.00..1.02 rows=2 width=0) Optimizer: Postgres query optimizer (10 rows) @@ -3798,48 +3793,48 @@ select t1.a, (select count(*) c from (select city from supplier limit t1.a) x) f explain select t1.*, (select count(*) as ct from generate_series(1, a), t1) from t1; QUERY PLAN --------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..30000000173.36 rows=3 width=8) - -> Seq Scan on t1 (cost=0.00..30000000173.36 rows=1 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..10000000057.12 rows=3 width=16) + -> Seq Scan on t1 (cost=0.00..10000000057.08 rows=1 width=16) SubPlan 1 - -> Aggregate (cost=10000000057.10..10000000057.11 rows=1 width=8) - -> Nested Loop (cost=10000000000.00..10000000049.60 rows=3000 width=0) + -> Aggregate (cost=10000000056.06..10000000056.07 rows=1 width=8) + -> Nested Loop (cost=10000000000.00..10000000048.56 rows=3000 width=0) -> Function Scan on generate_series (cost=0.00..10.00 rows=1000 width=0) - -> Materialize (cost=0.00..2.10 rows=3 width=0) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..2.09 rows=1 width=0) - -> Seq Scan on t1 t1_1 (cost=0.00..2.03 rows=1 width=0) + -> Materialize (cost=0.00..1.06 rows=3 width=0) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.05 rows=3 width=0) + -> Seq Scan on t1 t1_1 (cost=0.00..1.01 rows=1 width=0) Optimizer: Postgres query optimizer (10 rows) select t1.*, (select count(*) as ct from generate_series(1, a), t1) from t1; a | b | ct ---+---+---- - 1 | 1 | 3 2 | 2 | 6 3 | 3 | 9 + 1 | 1 | 3 (3 rows) explain select * from t1 where 0 < (select count(*) from generate_series(1, a), t1); QUERY PLAN --------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..30000000173.37 rows=1 width=8) - -> Seq Scan on t1 (cost=0.00..30000000173.37 rows=1 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=8) + -> Seq Scan on t1 (cost=0.00..1.01 rows=1 width=8) Filter: (0 < (SubPlan 1)) SubPlan 1 - -> Aggregate (cost=10000000057.10..10000000057.11 rows=1 width=8) - -> Nested Loop (cost=10000000000.00..10000000049.60 rows=3000 width=0) + -> Aggregate (cost=10000000056.06..10000000056.07 rows=1 width=8) + -> Nested Loop (cost=10000000000.00..10000000048.56 rows=3000 width=0) -> Function Scan on generate_series (cost=0.00..10.00 rows=1000 width=0) - -> Materialize (cost=0.00..2.10 rows=3 width=0) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..2.09 rows=1 width=0) - -> Seq Scan on t1 t1_1 (cost=0.00..2.03 rows=1 width=0) + -> Materialize (cost=0.00..1.06 rows=3 width=0) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.05 rows=3 width=0) + -> Seq Scan on t1 t1_1 (cost=0.00..1.01 rows=1 width=0) Optimizer: Postgres query optimizer (11 rows) select * from t1 where 0 < (select count(*) from generate_series(1, a), t1); a | b ---+--- - 1 | 1 2 | 2 3 | 3 + 1 | 1 (3 rows) reset optimizer_enforce_subplans; diff --git a/contrib/pax_storage/src/test/regress/expected/qp_correlated_query_optimizer.out b/contrib/pax_storage/src/test/regress/expected/qp_correlated_query_optimizer.out index e1e10d4eb9b..4f8cb982707 100644 --- a/contrib/pax_storage/src/test/regress/expected/qp_correlated_query_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/qp_correlated_query_optimizer.out @@ -76,10 +76,10 @@ commit; select a, x from qp_csq_t1, qp_csq_t2 where qp_csq_t1.a in (select x); a | x ---+--- - 1 | 1 - 3 | 3 5 | 5 + 3 | 3 7 | 7 + 1 | 1 (4 rows) select A.i from A where A.i in (select B.i from B where A.i = B.i) order by A.i; @@ -186,8 +186,8 @@ select * from A where exists (select * from B where A.i in (select C.i from C wh -> Hash -> Seq Scan on b Filter: (NOT (i IS NULL)) - Optimizer: Pivotal Optimizer (GPORCA) version 2.70.0 -(15 rows) + Optimizer: GPORCA +(16 rows) select * from A where exists (select * from B where A.i in (select C.i from C where C.i = B.i)); i | j @@ -231,11 +231,11 @@ select * from A,B where exists (select * from C where B.i not in (select C.i fro select * from A,B where exists (select * from C where B.i not in (select C.i from C where C.i != 10)); i | j | i | j ----+----+----+--- - 78 | -1 | 88 | 1 - 1 | 1 | 88 | 1 19 | 5 | 88 | 1 99 | 62 | 88 | 1 1 | 1 | 88 | 1 + 1 | 1 | 88 | 1 + 78 | -1 | 88 | 1 (5 rows) -- -- -- -- @@ -391,29 +391,29 @@ select A.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i i explain select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i not in (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=0.00..1390613111661.99 rows=10 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1390613111661.99 rows=10 width=12) + Limit (cost=0.00..1390613076186.88 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1390613076186.88 rows=10 width=12) Merge Key: a.i, b_1.i, c_1.j - -> Limit (cost=0.00..1390613111661.99 rows=4 width=12) - -> Sort (cost=0.00..1390613111661.99 rows=90 width=12) + -> Limit (cost=0.00..1390613076186.88 rows=4 width=12) + -> Sort (cost=0.00..1390613076186.88 rows=90 width=12) Sort Key: a.i, b_1.i, c_1.j - -> Nested Loop (cost=0.00..1390613111661.95 rows=90 width=12) + -> Nested Loop (cost=0.00..1390613076186.84 rows=90 width=12) Join Filter: true - -> Nested Loop (cost=0.00..1324033.29 rows=18 width=8) + -> Nested Loop (cost=0.00..1324033.26 rows=18 width=8) Join Filter: true -> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..431.00 rows=6 width=4) -> Seq Scan on b b_1 (cost=0.00..431.00 rows=2 width=4) -> Seq Scan on c c_1 (cost=0.00..431.00 rows=3 width=4) - -> Materialize (cost=0.00..1356696152.56 rows=5 width=4) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1356696152.56 rows=5 width=4) - -> Seq Scan on a (cost=0.00..1356696152.56 rows=2 width=4) + -> Materialize (cost=0.00..1356696117.95 rows=5 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1356696117.95 rows=5 width=4) + -> Seq Scan on a (cost=0.00..1356696117.95 rows=2 width=4) Filter: (j = (SubPlan 2)) SubPlan 2 - -> Result (cost=0.00..1324036.59 rows=1 width=4) + -> Result (cost=0.00..1324036.55 rows=1 width=4) Filter: (c.j = a.j) - -> Materialize (cost=0.00..1324036.58 rows=9 width=4) - -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..1324036.58 rows=9 width=4) - -> Seq Scan on c (cost=0.00..1324036.58 rows=3 width=4) + -> Materialize (cost=0.00..1324036.55 rows=9 width=4) + -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..1324036.55 rows=9 width=4) + -> Seq Scan on c (cost=0.00..1324036.55 rows=3 width=4) Filter: (SubPlan 1) SubPlan 1 -> Result (cost=0.00..431.00 rows=1 width=1) @@ -425,7 +425,7 @@ explain select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..431.00 rows=6 width=4) -> Seq Scan on b (cost=0.00..431.00 rows=2 width=4) Filter: (i <> 10) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (35 rows) select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i not in (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; @@ -446,23 +446,23 @@ select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j explain select A.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i not in (select B.i from B where C.i = B.i and B.i !=10)) order by A.j limit 10; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=0.00..1390613110663.90 rows=10 width=4) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1390613110663.90 rows=10 width=4) + Limit (cost=0.00..1390613075188.78 rows=10 width=4) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1390613075188.78 rows=10 width=4) Merge Key: a.j - -> Limit (cost=0.00..1390613110663.90 rows=4 width=4) - -> Sort (cost=0.00..1390613110663.90 rows=90 width=4) + -> Limit (cost=0.00..1390613075188.78 rows=4 width=4) + -> Sort (cost=0.00..1390613075188.78 rows=90 width=4) Sort Key: a.j - -> Nested Loop (cost=0.00..1390613110663.88 rows=90 width=4) + -> Nested Loop (cost=0.00..1390613075188.77 rows=90 width=4) Join Filter: true - -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..1356696152.54 rows=5 width=4) - -> Seq Scan on a (cost=0.00..1356696152.54 rows=2 width=4) + -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..1356696117.93 rows=5 width=4) + -> Seq Scan on a (cost=0.00..1356696117.93 rows=2 width=4) Filter: (j = (SubPlan 2)) SubPlan 2 - -> Result (cost=0.00..1324036.59 rows=1 width=4) + -> Result (cost=0.00..1324036.55 rows=1 width=4) Filter: (c_1.j = a.j) - -> Materialize (cost=0.00..1324036.58 rows=9 width=4) - -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..1324036.58 rows=9 width=4) - -> Seq Scan on c c_1 (cost=0.00..1324036.58 rows=3 width=4) + -> Materialize (cost=0.00..1324036.55 rows=9 width=4) + -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..1324036.55 rows=9 width=4) + -> Seq Scan on c c_1 (cost=0.00..1324036.55 rows=3 width=4) Filter: (SubPlan 1) SubPlan 1 -> Result (cost=0.00..431.00 rows=1 width=1) @@ -474,13 +474,13 @@ explain select A.j from A, B, C where A.j = (select C.j from C where C.j = A.j a -> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..431.00 rows=6 width=4) -> Seq Scan on b b_1 (cost=0.00..431.00 rows=2 width=4) Filter: (i <> 10) - -> Materialize (cost=0.00..1324032.34 rows=18 width=1) - -> Nested Loop (cost=0.00..1324032.34 rows=18 width=1) + -> Materialize (cost=0.00..1324032.31 rows=18 width=1) + -> Nested Loop (cost=0.00..1324032.31 rows=18 width=1) Join Filter: true -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=6 width=1) -> Seq Scan on b (cost=0.00..431.00 rows=2 width=1) -> Seq Scan on c (cost=0.00..431.00 rows=3 width=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (35 rows) select A.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i not in (select B.i from B where C.i = B.i and B.i !=10)) order by A.j limit 10; @@ -501,8 +501,8 @@ select A.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i n explain select A.i from A where A.j = (select C.j from C where C.j = A.j and C.i = any (select B.i from B where C.i = B.i and B.i !=10)); QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1765379.74 rows=5 width=4) - -> Seq Scan on a (cost=0.00..1765379.74 rows=2 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1765379.96 rows=5 width=4) + -> Seq Scan on a (cost=0.00..1765379.96 rows=2 width=4) Filter: (j = (SubPlan 1)) SubPlan 1 -> Result (cost=0.00..862.00 rows=1 width=4) @@ -512,11 +512,12 @@ explain select A.i from A where A.j = (select C.j from C where C.j = A.j and C.i -> Hash Semi Join (cost=0.00..862.00 rows=2 width=4) Hash Cond: ((c.i = b.i) AND (c.i = b.i)) -> Seq Scan on c (cost=0.00..431.00 rows=3 width=8) + Filter: (i <> 10) -> Hash (cost=431.00..431.00 rows=2 width=4) -> Seq Scan on b (cost=0.00..431.00 rows=2 width=4) Filter: (i <> 10) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 -(15 rows) + Optimizer: GPORCA +(16 rows) select A.i from A where A.j = (select C.j from C where C.j = A.j and C.i = any (select B.i from B where C.i = B.i and B.i !=10)); i @@ -533,10 +534,10 @@ select A.i from A where A.j = (select C.j from C where C.j = A.j and C.i = any ( select a, x from qp_csq_t1, qp_csq_t2 where qp_csq_t1.a = any (select x); a | x ---+--- - 1 | 1 3 | 3 - 5 | 5 7 | 7 + 1 | 1 + 5 | 5 (4 rows) select a, x from qp_csq_t1, qp_csq_t2 where qp_csq_t1.a = any (select x) order by a, x; @@ -620,22 +621,22 @@ select * from A,B where A.j = any (select C.j from C where C.j = A.j and B.i = a explain select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i = any (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=0.00..3164000462.21 rows=10 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3164000462.21 rows=10 width=12) + Limit (cost=0.00..3164000483.91 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3164000483.91 rows=10 width=12) Merge Key: a.i, b_1.i, c_1.j - -> Limit (cost=0.00..3164000462.21 rows=4 width=12) - -> Sort (cost=0.00..3164000462.21 rows=90 width=12) + -> Limit (cost=0.00..3164000483.91 rows=4 width=12) + -> Sort (cost=0.00..3164000483.91 rows=90 width=12) Sort Key: a.i, b_1.i, c_1.j - -> Nested Loop (cost=0.00..3164000462.17 rows=90 width=12) + -> Nested Loop (cost=0.00..3164000483.87 rows=90 width=12) Join Filter: true - -> Nested Loop (cost=0.00..1324033.29 rows=18 width=8) + -> Nested Loop (cost=0.00..1324033.26 rows=18 width=8) Join Filter: true -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..431.00 rows=6 width=4) -> Seq Scan on b b_1 (cost=0.00..431.00 rows=2 width=4) -> Seq Scan on c c_1 (cost=0.00..431.00 rows=3 width=4) - -> Materialize (cost=0.00..1765379.90 rows=5 width=4) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1765379.90 rows=5 width=4) - -> Seq Scan on a (cost=0.00..1765379.90 rows=2 width=4) + -> Materialize (cost=0.00..1765379.96 rows=5 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1765379.96 rows=5 width=4) + -> Seq Scan on a (cost=0.00..1765379.96 rows=2 width=4) Filter: (j = (SubPlan 1)) SubPlan 1 -> Result (cost=0.00..862.00 rows=1 width=4) @@ -645,11 +646,12 @@ explain select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C -> Hash Semi Join (cost=0.00..862.00 rows=2 width=4) Hash Cond: ((c.i = b.i) AND (c.i = b.i)) -> Seq Scan on c (cost=0.00..431.00 rows=3 width=8) + Filter: (i <> 10) -> Hash (cost=431.00..431.00 rows=2 width=4) -> Seq Scan on b (cost=0.00..431.00 rows=2 width=4) Filter: (i <> 10) - Optimizer: Pivotal Optimizer (GPORCA) -(29 rows) + Optimizer: GPORCA +(30 rows) select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i = any (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; i | i | j @@ -669,17 +671,17 @@ select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j explain select A.i, B.i, C.j from A, B, C where A.j = any ( select C.j from C where not exists(select C.i from C,A where C.i = A.i and C.i =10)) order by A.i, B.i, C.j limit 10; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=0.00..1358457987.42 rows=4 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1358457987.42 rows=10 width=12) + Limit (cost=0.00..1358457961.93 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1358457961.93 rows=10 width=12) Merge Key: a.i, b.i, c.j - -> Limit (cost=0.00..1358457987.42 rows=4 width=12) - -> Sort (cost=0.00..1358457987.42 rows=90 width=12) + -> Limit (cost=0.00..1358457961.93 rows=4 width=12) + -> Sort (cost=0.00..1358457961.93 rows=90 width=12) Sort Key: a.i, b.i, c.j - -> Hash Semi Join (cost=0.00..1358457987.38 rows=90 width=12) - Hash Cond: a.j = c_2.j - -> Nested Loop (cost=0.00..1356692610.50 rows=90 width=16) + -> Hash Semi Join (cost=0.00..1358457961.89 rows=90 width=12) + Hash Cond: (a.j = c_2.j) + -> Nested Loop (cost=0.00..1356692585.11 rows=90 width=16) Join Filter: true - -> Nested Loop (cost=0.00..1324033.12 rows=10 width=12) + -> Nested Loop (cost=0.00..1324033.10 rows=10 width=12) Join Filter: true -> Seq Scan on a (cost=0.00..431.00 rows=2 width=8) -> Materialize (cost=0.00..431.00 rows=6 width=4) @@ -688,21 +690,21 @@ explain select A.i, B.i, C.j from A, B, C where A.j = any ( select C.j from C wh -> Materialize (cost=0.00..431.00 rows=9 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=9 width=4) -> Seq Scan on c (cost=0.00..431.00 rows=3 width=4) - -> Hash (cost=1765376.85..1765376.85 rows=9 width=4) - -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..1765376.85 rows=9 width=4) - -> Nested Loop Anti Join (cost=0.00..1765376.85 rows=3 width=4) + -> Hash (cost=1765376.76..1765376.76 rows=9 width=4) + -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..1765376.76 rows=9 width=4) + -> Nested Loop Anti Join (cost=0.00..1765376.76 rows=3 width=4) Join Filter: true -> Seq Scan on c c_2 (cost=0.00..431.00 rows=3 width=4) - -> Materialize (cost=0.00..862.00 rows=2 width=1) - -> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..862.00 rows=2 width=1) + -> Materialize (cost=0.00..862.00 rows=1 width=1) + -> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..862.00 rows=1 width=1) -> Hash Join (cost=0.00..862.00 rows=1 width=1) - Hash Cond: c_1.i = a_1.i + Hash Cond: (c_1.i = a_1.i) -> Seq Scan on c c_1 (cost=0.00..431.00 rows=1 width=4) - Filter: i = 10 AND i = 10 + Filter: ((i = 10) AND (i = 10)) -> Hash (cost=431.00..431.00 rows=1 width=4) -> Seq Scan on a a_1 (cost=0.00..431.00 rows=1 width=4) - Filter: i = 10 AND i = 10 - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 + Filter: ((i = 10) AND (i = 10)) + Optimizer: GPORCA (34 rows) select A.i, B.i, C.j from A, B, C where A.j = any ( select C.j from C where not exists(select C.i from C,A where C.i = A.i and C.i =10)) order by A.i, B.i, C.j limit 10; @@ -723,15 +725,15 @@ select A.i, B.i, C.j from A, B, C where A.j = any ( select C.j from C where not explain select A.i, B.i, C.j from A, B, C where A.j = any (select C.j from C where C.j = A.j and not exists (select sum(B.i) from B where C.i = B.i and C.i !=10)) order by A.i, B.i, C.j limit 10; QUERY PLAN --------------------------------------------------------------------------------------------------------------------- - Limit (cost=0.00..1356692061.89 rows=10 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1356692061.89 rows=10 width=12) + Limit (cost=0.00..1356692028.03 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1356692028.03 rows=10 width=12) Merge Key: a.i, b.i, c.j - -> Limit (cost=0.00..1356692061.89 rows=4 width=12) - -> Sort (cost=0.00..1356692061.89 rows=18 width=12) + -> Limit (cost=0.00..1356692028.03 rows=4 width=12) + -> Sort (cost=0.00..1356692028.03 rows=18 width=12) Sort Key: a.i, b.i, c.j - -> Nested Loop (cost=0.00..1356692061.89 rows=18 width=12) + -> Nested Loop (cost=0.00..1356692028.03 rows=18 width=12) Join Filter: true - -> Nested Loop (cost=0.00..1324032.59 rows=2 width=8) + -> Nested Loop (cost=0.00..1324032.56 rows=2 width=8) Join Filter: true -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=4) -> Hash Semi Join (cost=0.00..431.00 rows=1 width=4) @@ -811,30 +813,30 @@ select * from A,B where exists (select * from C where C.j = A.j and B.i = all (s explain select A.i, B.i, C.j from A, B, C where A.j = (select sum(C.j) from C where C.j = A.j and C.i = all (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=0.00..2712506248.09 rows=10 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2712506248.09 rows=10 width=12) + Limit (cost=0.00..2712506178.88 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2712506178.88 rows=10 width=12) Merge Key: a.i, b_1.i, c_1.j - -> Limit (cost=0.00..2712506248.09 rows=4 width=12) - -> Sort (cost=0.00..2712506248.09 rows=90 width=12) + -> Limit (cost=0.00..2712506178.88 rows=4 width=12) + -> Sort (cost=0.00..2712506178.88 rows=90 width=12) Sort Key: a.i, b_1.i, c_1.j - -> Nested Loop (cost=0.00..2712506248.05 rows=90 width=12) + -> Nested Loop (cost=0.00..2712506178.84 rows=90 width=12) Join Filter: true - -> Nested Loop (cost=0.00..1324033.29 rows=18 width=8) + -> Nested Loop (cost=0.00..1324033.26 rows=18 width=8) Join Filter: true -> Broadcast Motion 3:3 (slice6; segments: 3) (cost=0.00..431.00 rows=6 width=4) -> Seq Scan on b b_1 (cost=0.00..431.00 rows=2 width=4) -> Seq Scan on c c_1 (cost=0.00..431.00 rows=3 width=4) - -> Materialize (cost=0.00..1324467.58 rows=5 width=4) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1324467.58 rows=5 width=4) - -> Hash Join (cost=0.00..1324467.58 rows=2 width=4) + -> Materialize (cost=0.00..1324467.55 rows=5 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1324467.55 rows=5 width=4) + -> Hash Join (cost=0.00..1324467.55 rows=2 width=4) Hash Cond: (((sum(c.j)) = (a.j)::bigint) AND (c.j = a.j)) - -> GroupAggregate (cost=0.00..1324036.58 rows=3 width=12) + -> GroupAggregate (cost=0.00..1324036.55 rows=3 width=12) Group Key: c.j - -> Sort (cost=0.00..1324036.58 rows=3 width=4) + -> Sort (cost=0.00..1324036.55 rows=3 width=4) Sort Key: c.j - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1324036.58 rows=3 width=4) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1324036.55 rows=3 width=4) Hash Key: c.j - -> Seq Scan on c (cost=0.00..1324036.58 rows=3 width=4) + -> Seq Scan on c (cost=0.00..1324036.55 rows=3 width=4) Filter: (SubPlan 1) SubPlan 1 -> Result (cost=0.00..431.00 rows=1 width=1) @@ -850,7 +852,7 @@ explain select A.i, B.i, C.j from A, B, C where A.j = (select sum(C.j) from C wh -> Redistribute Motion 3:3 (slice5; segments: 3) (cost=0.00..431.00 rows=2 width=8) Hash Key: a.j -> Seq Scan on a (cost=0.00..431.00 rows=2 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (40 rows) select A.i, B.i, C.j from A, B, C where A.j = (select sum(C.j) from C where C.j = A.j and C.i = all (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; @@ -871,17 +873,17 @@ select A.i, B.i, C.j from A, B, C where A.j = (select sum(C.j) from C where C.j explain select A.i, B.i, C.j from A, B, C where A.j < all ( select C.j from C where not exists(select C.i from C,A where C.i = A.i and C.i =10)) order by A.i, B.i, C.j limit 10; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=0.00..1391061420469.59 rows=4 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1391061420469.59 rows=10 width=12) + Limit (cost=0.00..1391061394375.33 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1391061394375.33 rows=10 width=12) Merge Key: a_1.i, b.i, c_2.j - -> Limit (cost=0.00..1391061420469.59 rows=4 width=12) - -> Sort (cost=0.00..1391061420469.59 rows=36 width=12) + -> Limit (cost=0.00..1391061394375.33 rows=4 width=12) + -> Sort (cost=0.00..1391061394375.33 rows=36 width=12) Sort Key: a_1.i, b.i, c_2.j - -> Nested Loop Left Anti Semi (Not-In) Join (cost=0.00..1391061420469.58 rows=36 width=12) - Join Filter: a_1.j >= c_1.j - -> Nested Loop (cost=0.00..1356692610.50 rows=90 width=16) + -> Nested Loop Left Anti Semi (Not-In) Join (cost=0.00..1391061394375.31 rows=36 width=12) + Join Filter: (a_1.j >= c_1.j) + -> Nested Loop (cost=0.00..1356692585.11 rows=90 width=16) Join Filter: true - -> Nested Loop (cost=0.00..1324033.12 rows=10 width=12) + -> Nested Loop (cost=0.00..1324033.10 rows=10 width=12) Join Filter: true -> Seq Scan on a a_1 (cost=0.00..431.00 rows=2 width=8) -> Materialize (cost=0.00..431.00 rows=6 width=4) @@ -890,21 +892,21 @@ explain select A.i, B.i, C.j from A, B, C where A.j < all ( select C.j from C wh -> Materialize (cost=0.00..431.00 rows=9 width=4) -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..431.00 rows=9 width=4) -> Seq Scan on c c_2 (cost=0.00..431.00 rows=3 width=4) - -> Materialize (cost=0.00..1765376.85 rows=9 width=4) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1765376.85 rows=9 width=4) - -> Nested Loop Anti Join (cost=0.00..1765376.85 rows=3 width=4) + -> Materialize (cost=0.00..1765376.76 rows=9 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1765376.76 rows=9 width=4) + -> Nested Loop Anti Join (cost=0.00..1765376.76 rows=3 width=4) Join Filter: true -> Seq Scan on c c_1 (cost=0.00..431.00 rows=3 width=4) - -> Materialize (cost=0.00..862.00 rows=2 width=1) - -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..862.00 rows=2 width=1) + -> Materialize (cost=0.00..862.00 rows=1 width=1) + -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..862.00 rows=1 width=1) -> Hash Join (cost=0.00..862.00 rows=1 width=1) - Hash Cond: c.i = a.i + Hash Cond: (c.i = a.i) -> Seq Scan on c (cost=0.00..431.00 rows=1 width=4) - Filter: i = 10 AND i = 10 + Filter: ((i = 10) AND (i = 10)) -> Hash (cost=431.00..431.00 rows=1 width=4) -> Seq Scan on a (cost=0.00..431.00 rows=1 width=4) - Filter: i = 10 AND i = 10 - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 + Filter: ((i = 10) AND (i = 10)) + Optimizer: GPORCA (34 rows) select A.i, B.i, C.j from A, B, C where A.j < all ( select C.j from C where not exists(select C.i from C,A where C.i = A.i and C.i =10)) order by A.i, B.i, C.j limit 10; @@ -915,22 +917,22 @@ select A.i, B.i, C.j from A, B, C where A.j < all ( select C.j from C where not explain select A.i, B.i, C.j from A, B, C where A.j = all (select C.j from C where C.j = A.j and not exists (select sum(B.i) from B where C.i = B.i and C.i !=10)) order by A.i, B.i, C.j limit 10; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=0.00..2260124027.48 rows=10 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2260124027.48 rows=10 width=12) + Limit (cost=0.00..2260123981.35 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2260123981.35 rows=10 width=12) Merge Key: a.i, b.i, c.j - -> Limit (cost=0.00..2260124027.48 rows=4 width=12) - -> Sort (cost=0.00..2260124027.48 rows=18 width=12) + -> Limit (cost=0.00..2260123981.34 rows=4 width=12) + -> Sort (cost=0.00..2260123981.34 rows=18 width=12) Sort Key: a.i, b.i, c.j - -> Nested Loop (cost=0.00..2260124027.48 rows=18 width=12) + -> Nested Loop (cost=0.00..2260123981.34 rows=18 width=12) Join Filter: true - -> Nested Loop (cost=0.00..1324033.29 rows=18 width=8) + -> Nested Loop (cost=0.00..1324033.26 rows=18 width=8) Join Filter: true -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..431.00 rows=6 width=4) -> Seq Scan on b (cost=0.00..431.00 rows=2 width=4) -> Seq Scan on c (cost=0.00..431.00 rows=3 width=4) - -> Materialize (cost=0.00..882688.08 rows=1 width=4) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..882688.08 rows=1 width=4) - -> Seq Scan on a (cost=0.00..882688.08 rows=1 width=4) + -> Materialize (cost=0.00..882688.06 rows=1 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..882688.06 rows=1 width=4) + -> Seq Scan on a (cost=0.00..882688.06 rows=1 width=4) Filter: (SubPlan 1) SubPlan 1 -> Result (cost=0.00..0.00 rows=1 width=1) @@ -938,7 +940,7 @@ explain select A.i, B.i, C.j from A, B, C where A.j = all (select C.j from C whe -> Aggregate (cost=0.00..0.00 rows=0 width=16) -> Result (cost=0.00..0.00 rows=0 width=4) One-Time Filter: false - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (24 rows) select A.i, B.i, C.j from A, B, C where A.j = all (select C.j from C where C.j = A.j and not exists (select sum(B.i) from B where C.i = B.i and C.i !=10)) order by A.i, B.i, C.j limit 10; @@ -1066,26 +1068,26 @@ select * from A where exists (select * from C,B where C.j = A.j and exists (sele select * from A,B where exists (select * from C where C.j = A.j and exists (select * from C where C.i = B.i)); i | j | i | j ----+----+----+---- + 99 | 62 | -1 | 62 + 99 | 62 | 32 | 5 + 1 | 1 | -1 | 62 1 | 1 | 32 | 5 + 1 | 1 | -1 | 62 1 | 1 | 32 | 5 - 99 | 62 | 32 | 5 + 78 | -1 | -1 | 62 78 | -1 | 32 | 5 - 1 | 1 | 1 | 43 - 1 | 1 | -1 | 62 - 1 | 1 | 1 | 1 + 99 | 62 | 2 | 7 1 | 1 | 2 | 7 - 1 | 1 | 1 | 43 - 1 | 1 | -1 | 62 - 1 | 1 | 1 | 1 1 | 1 | 2 | 7 + 78 | -1 | 2 | 7 99 | 62 | 1 | 43 - 99 | 62 | -1 | 62 99 | 62 | 1 | 1 - 99 | 62 | 2 | 7 + 1 | 1 | 1 | 43 + 1 | 1 | 1 | 1 + 1 | 1 | 1 | 43 + 1 | 1 | 1 | 1 78 | -1 | 1 | 43 - 78 | -1 | -1 | 62 78 | -1 | 1 | 1 - 78 | -1 | 2 | 7 (20 rows) select * from A where exists (select * from B, C where C.j = A.j and exists (select sum(C.i) from C where C.i != 10 and C.i = B.i)) order by 1, 2; @@ -1193,8 +1195,8 @@ select * from A,B,C where C.i = A.i and exists (select C.j where C.j = B.j and A select b from qp_csq_t1 where not exists(select * from qp_csq_t2 where y=a); b --- - 4 6 + 4 8 (3 rows) @@ -1266,73 +1268,70 @@ select * from A where not exists (select sum(C.i) from C where C.i = A.i); explain select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 0); QUERY PLAN --------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..882688.12 rows=5 width=8) - -> Nested Loop Anti Join (cost=0.00..882688.12 rows=2 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..882688.11 rows=5 width=8) + -> Nested Loop Anti Join (cost=0.00..882688.11 rows=2 width=8) Join Filter: true -> Seq Scan on a (cost=0.00..431.00 rows=2 width=8) -> Result (cost=0.00..0.00 rows=0 width=1) One-Time Filter: false - Settings: optimizer=on - Optimizer status: Pivotal Optimizer (GPORCA) version 2.42.0 -(8 rows) + Optimizer: GPORCA +(7 rows) select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 0); i | j ----+---- - 19 | 5 - 99 | 62 - 78 | -1 1 | 1 1 | 1 + 78 | -1 + 19 | 5 + 99 | 62 (5 rows) explain select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 5 offset 3); QUERY PLAN -------------------------------------------------------------------------------------------------------------- - Result (cost=0.00..1324035.78 rows=2 width=8) - Filter: (subplan) + Result (cost=0.00..1324035.75 rows=5 width=8) + Filter: (SubPlan 1) -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=5 width=8) -> Seq Scan on a (cost=0.00..431.00 rows=2 width=8) SubPlan 1 -> Limit (cost=0.00..431.00 rows=1 width=8) -> Aggregate (cost=0.00..431.00 rows=1 width=8) -> Result (cost=0.00..431.00 rows=1 width=4) - Filter: c.i = $0 - -> Materialize (cost=0.00..431.00 rows=3 width=4) + Filter: (c.i = a.i) + -> Materialize (cost=0.00..431.00 rows=9 width=4) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=9 width=4) -> Seq Scan on c (cost=0.00..431.00 rows=3 width=4) - Settings: optimizer=on - Optimizer status: Pivotal Optimizer (GPORCA) version 2.42.0 -(14 rows) + Optimizer: GPORCA +(13 rows) select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 5 offset 3); i | j ----+---- 19 | 5 + 99 | 62 1 | 1 1 | 1 - 99 | 62 78 | -1 (5 rows) explain select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 1 offset 0); QUERY PLAN -------------------------------------------------------------------------------------------------------------- - Result (cost=0.00..1324035.78 rows=2 width=8) - Filter: (subplan) + Result (cost=0.00..1324035.75 rows=5 width=8) + Filter: (SubPlan 1) -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=5 width=8) -> Seq Scan on a (cost=0.00..431.00 rows=2 width=8) SubPlan 1 -> Limit (cost=0.00..431.00 rows=1 width=8) -> Aggregate (cost=0.00..431.00 rows=1 width=8) -> Result (cost=0.00..431.00 rows=1 width=4) - Filter: c.i = $0 - -> Materialize (cost=0.00..431.00 rows=3 width=4) + Filter: (c.i = a.i) + -> Materialize (cost=0.00..431.00 rows=9 width=4) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=9 width=4) -> Seq Scan on c (cost=0.00..431.00 rows=3 width=4) - Settings: optimizer=on - Optimizer status: Pivotal Optimizer (GPORCA) version 2.42.0 -(14 rows) + Optimizer: GPORCA +(13 rows) select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 1 offset 0); i | j @@ -1347,19 +1346,18 @@ explain select C.j from C where not exists (select max(B.i) from B where C.i = -> Sort (cost=0.00..862.00 rows=2 width=4) Sort Key: c.j -> Hash Anti Join (cost=0.00..862.00 rows=2 width=4) - Hash Cond: c.i = b.i + Hash Cond: (c.i = b.i) -> Seq Scan on c (cost=0.00..431.00 rows=3 width=8) -> Hash (cost=431.00..431.00 rows=1 width=4) -> Result (cost=0.00..431.00 rows=1 width=4) - Filter: NOT (max(b.i)) IS NULL + Filter: (NOT ((max(b.i)) IS NULL)) -> GroupAggregate (cost=0.00..431.00 rows=2 width=8) - Group By: b.i + Group Key: b.i -> Sort (cost=0.00..431.00 rows=2 width=4) Sort Key: b.i -> Seq Scan on b (cost=0.00..431.00 rows=2 width=4) - Settings: optimizer=on - Optimizer status: Pivotal Optimizer (GPORCA) version 2.34.0 -(17 rows) + Optimizer: GPORCA +(16 rows) select C.j from C where not exists (select max(B.i) from B where C.i = B.i having max(B.i) is not null) order by C.j; j @@ -1373,24 +1371,23 @@ select C.j from C where not exists (select max(B.i) from B where C.i = B.i havi explain select C.j from C where not exists (select max(B.i) from B where C.i = B.i offset 1000) order by C.j; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324036.36 rows=9 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324036.33 rows=9 width=4) Merge Key: c.j - -> Result (cost=0.00..1324036.36 rows=3 width=4) - -> Sort (cost=0.00..1324036.36 rows=3 width=4) + -> Result (cost=0.00..1324036.33 rows=3 width=4) + -> Sort (cost=0.00..1324036.33 rows=3 width=4) Sort Key: c.j - -> Seq Scan on c (cost=0.00..1324036.36 rows=3 width=4) - Filter: (subplan) + -> Seq Scan on c (cost=0.00..1324036.33 rows=3 width=4) + Filter: (SubPlan 1) SubPlan 1 -> Limit (cost=0.00..431.00 rows=1 width=4) -> Aggregate (cost=0.00..431.00 rows=1 width=4) -> Result (cost=0.00..431.00 rows=1 width=4) - Filter: $0 = b.i + Filter: (c.i = b.i) -> Materialize (cost=0.00..431.00 rows=6 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=6 width=4) -> Seq Scan on b (cost=0.00..431.00 rows=2 width=4) - Settings: optimizer=on - Optimizer status: Pivotal Optimizer (GPORCA) version 2.34.0 -(17 rows) + Optimizer: GPORCA +(16 rows) select C.j from C where not exists (select max(B.i) from B where C.i = B.i offset 1000) order by C.j; j @@ -1409,12 +1406,12 @@ select C.j from C where not exists (select max(B.i) from B where C.i = B.i offs explain select C.j from C where not exists (select rank() over (order by B.i) from B where C.i = B.i) order by C.j; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324036.36 rows=9 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324036.74 rows=9 width=4) Merge Key: c.j - -> Result (cost=0.00..1324036.36 rows=3 width=4) - -> Sort (cost=0.00..1324036.36 rows=3 width=4) + -> Result (cost=0.00..1324036.74 rows=3 width=4) + -> Sort (cost=0.00..1324036.74 rows=3 width=4) Sort Key: c.j - -> Seq Scan on c (cost=0.00..1324036.36 rows=3 width=4) + -> Seq Scan on c (cost=0.00..1324036.74 rows=3 width=4) Filter: (SubPlan 1) SubPlan 1 -> WindowAgg (cost=0.00..431.00 rows=1 width=4) @@ -1426,7 +1423,7 @@ explain select C.j from C where not exists (select rank() over (order by B.i) fr -> Materialize (cost=0.00..431.00 rows=6 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=6 width=4) -> Seq Scan on b (cost=0.00..431.00 rows=2 width=4) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (18 rows) select C.j from C where not exists (select rank() over (order by B.i) from B where C.i = B.i) order by C.j; @@ -1439,19 +1436,19 @@ select C.j from C where not exists (select rank() over (order by B.i) from B wh (4 rows) explain select * from A where not exists (select sum(C.i) from C where C.i = A.i group by a.i); - QUERY PLAN ------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=2 width=8) -> Hash Anti Join (cost=0.00..862.00 rows=1 width=8) - Hash Cond: a.i = c.i + Hash Cond: (a.i = c.i) -> Seq Scan on a (cost=0.00..431.00 rows=2 width=8) -> Hash (cost=431.00..431.00 rows=3 width=4) -> GroupAggregate (cost=0.00..431.00 rows=3 width=4) - Group By: c.i + Group Key: c.i -> Sort (cost=0.00..431.00 rows=3 width=4) Sort Key: c.i -> Seq Scan on c (cost=0.00..431.00 rows=3 width=4) - Optimizer status: Pivotal Optimizer (GPORCA) version 2.46.1 + Optimizer: GPORCA (11 rows) select * from A where not exists (select sum(C.i) from C where C.i = A.i group by a.i); @@ -1461,94 +1458,93 @@ select * from A where not exists (select sum(C.i) from C where C.i = A.i group b (1 row) explain select A.i from A where not exists (select B.i from B where B.i in (select C.i from C) and B.i = A.i); - QUERY PLAN ---------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1293.00 rows=2 width=4) - -> Hash Anti Join (cost=0.00..1293.00 rows=1 width=4) - Hash Cond: a.i = b.i - -> Seq Scan on a (cost=0.00..431.00 rows=2 width=4) - -> Hash (cost=862.00..862.00 rows=2 width=4) - -> Hash Semi Join (cost=0.00..862.00 rows=2 width=4) - Hash Cond: b.i = c.i + -> Hash Right Anti Join (cost=0.00..1293.00 rows=1 width=4) + Hash Cond: (a.i = b.i) + -> Hash Right Semi Join (cost=0.00..862.00 rows=2 width=4) + Hash Cond: (b.i = c.i) + -> Seq Scan on c (cost=0.00..431.00 rows=3 width=4) + -> Hash (cost=431.00..431.00 rows=2 width=4) -> Seq Scan on b (cost=0.00..431.00 rows=2 width=4) - -> Hash (cost=431.00..431.00 rows=3 width=4) - -> Seq Scan on c (cost=0.00..431.00 rows=3 width=4) - Settings: optimizer=on - Optimizer status: Pivotal Optimizer (GPORCA) version 2.40.3 -(12 rows) + -> Hash (cost=431.00..431.00 rows=2 width=4) + -> Seq Scan on a (cost=0.00..431.00 rows=2 width=4) + Optimizer: GPORCA +(11 rows) select A.i from A where not exists (select B.i from B where B.i in (select C.i from C) and B.i = A.i); i ---- + 19 99 78 - 19 (3 rows) explain select * from B where not exists (select * from C,A where C.i in (select C.i from C where C.i = A.i and C.i != 10) AND B.i = C.i); QUERY PLAN --------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324895.10 rows=1 width=8) - -> Hash Anti Join (cost=0.00..1324895.10 rows=1 width=8) - Hash Cond: b.i = c.i + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324895.07 rows=1 width=8) + -> Hash Anti Join (cost=0.00..1324895.07 rows=1 width=8) + Hash Cond: (b.i = c.i) -> Seq Scan on b (cost=0.00..431.00 rows=2 width=8) - -> Hash (cost=1324464.10..1324464.10 rows=13 width=4) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1324464.10 rows=13 width=4) + -> Hash (cost=1324464.07..1324464.07 rows=3 width=4) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1324464.07 rows=3 width=4) Hash Key: c.i - -> Hash Semi Join (cost=0.00..1324464.10 rows=13 width=4) - Hash Cond: a.i = c_1.i AND c.i = c_1.i - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1324033.09 rows=15 width=8) + -> Hash Semi Join (cost=0.00..1324464.07 rows=3 width=4) + Hash Cond: ((a.i = c_1.i) AND (c.i = c_1.i)) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1324033.06 rows=15 width=8) Hash Key: a.i - -> Nested Loop (cost=0.00..1324033.09 rows=15 width=8) + -> Nested Loop (cost=0.00..1324033.06 rows=15 width=8) Join Filter: true -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..431.00 rows=5 width=4) -> Seq Scan on a (cost=0.00..431.00 rows=2 width=4) -> Seq Scan on c (cost=0.00..431.00 rows=3 width=4) -> Hash (cost=431.00..431.00 rows=3 width=4) -> Seq Scan on c c_1 (cost=0.00..431.00 rows=3 width=4) - Filter: i <> 10 - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 + Filter: (i <> 10) + Optimizer: GPORCA (20 rows) select * from B where not exists (select * from C,A where C.i in (select C.i from C where C.i = A.i and C.i != 10) AND B.i = C.i); i | j ----+---- - 88 | 1 - -1 | 62 2 | 7 + -1 | 62 32 | 5 + 88 | 1 (4 rows) explain select * from A where A.i in (select C.j from C,B where B.i in (select i from C)); QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324895.30 rows=5 width=8) - -> Hash Join (cost=0.00..1324895.30 rows=2 width=8) - Hash Cond: a.i = c.j + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324895.27 rows=5 width=8) + -> Hash Join (cost=0.00..1324895.27 rows=2 width=8) + Hash Cond: (a.i = c.j) -> Seq Scan on a (cost=0.00..431.00 rows=2 width=8) - -> Hash (cost=1324464.30..1324464.30 rows=3 width=4) - -> GroupAggregate (cost=0.00..1324464.30 rows=3 width=4) + -> Hash (cost=1324464.27..1324464.27 rows=3 width=4) + -> GroupAggregate (cost=0.00..1324464.27 rows=3 width=4) Group Key: c.j - -> Sort (cost=0.00..1324464.30 rows=3 width=4) + -> Sort (cost=0.00..1324464.27 rows=3 width=4) Sort Key: c.j - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1324464.30 rows=3 width=4) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1324464.27 rows=3 width=4) Hash Key: c.j - -> GroupAggregate (cost=0.00..1324464.30 rows=3 width=4) + -> GroupAggregate (cost=0.00..1324464.27 rows=3 width=4) Group Key: c.j - -> Sort (cost=0.00..1324464.30 rows=18 width=4) + -> Sort (cost=0.00..1324464.27 rows=18 width=4) Sort Key: c.j - -> Hash Semi Join (cost=0.00..1324464.30 rows=18 width=4) - Hash Cond: b.i = c_1.i - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1324033.29 rows=18 width=8) + -> Hash Semi Join (cost=0.00..1324464.26 rows=18 width=4) + Hash Cond: (b.i = c_1.i) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1324033.26 rows=18 width=8) Hash Key: b.i - -> Nested Loop (cost=0.00..1324033.29 rows=18 width=8) + -> Nested Loop (cost=0.00..1324033.26 rows=18 width=8) Join Filter: true -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..431.00 rows=6 width=4) -> Seq Scan on b (cost=0.00..431.00 rows=2 width=4) -> Seq Scan on c (cost=0.00..431.00 rows=3 width=4) -> Hash (cost=431.00..431.00 rows=3 width=4) -> Seq Scan on c c_1 (cost=0.00..431.00 rows=3 width=4) - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 + Optimizer: GPORCA (27 rows) select * from A where A.i in (select C.j from C,B where B.i in (select i from C)); @@ -1563,7 +1559,7 @@ explain select * from A where not exists (select sum(c.i) from C where C.i = A.i --------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=2 width=8) -> Hash Anti Join (cost=0.00..862.00 rows=1 width=8) - Hash Cond: a.i = c.i + Hash Cond: (a.i = c.i) -> Seq Scan on a (cost=0.00..431.00 rows=2 width=8) -> Hash (cost=431.00..431.00 rows=2 width=4) -> GroupAggregate (cost=0.00..431.00 rows=2 width=4) @@ -1571,16 +1567,16 @@ explain select * from A where not exists (select sum(c.i) from C where C.i = A.i -> Sort (cost=0.00..431.00 rows=2 width=4) Sort Key: c.i -> Seq Scan on c (cost=0.00..431.00 rows=2 width=4) - Filter: i > 3 - Optimizer: Pivotal Optimizer (GPORCA) version 2.55.13 + Filter: (i > 3) + Optimizer: GPORCA (12 rows) select * from A where not exists (select sum(c.i) from C where C.i = A.i group by C.i having c.i > 3); i | j ----+--- - 19 | 5 1 | 1 1 | 1 + 19 | 5 (3 rows) -- ---------------------------------------------------------------------- @@ -1608,7 +1604,7 @@ select * from qp_csq_t4 order by a; update qp_csq_t4 set a = (select y from qp_csq_t2 where x=a) where b < 8; INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner -DETAIL: DXL-to-PlStmt Translation: Attribute number 21 not found in project list +DETAIL: DXL-to-PlStmt Translation: Attribute number 13 not found in project list select * from qp_csq_t4 order by a; a | b ----+--- @@ -1620,7 +1616,7 @@ select * from qp_csq_t4 order by a; update qp_csq_t4 set a = 9999 where qp_csq_t4.a = (select max(x) from qp_csq_t2); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner -DETAIL: DXL-to-PlStmt Translation: Attribute number 23 not found in project list +DETAIL: DXL-to-PlStmt Translation: Attribute number 15 not found in project list select * from qp_csq_t4 order by a; a | b ------+--- @@ -1632,7 +1628,7 @@ select * from qp_csq_t4 order by a; update qp_csq_t4 set a = (select max(y) from qp_csq_t2 where x=a) where qp_csq_t4.a = (select min(x) from qp_csq_t2); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner -DETAIL: DXL-to-PlStmt Translation: Attribute number 35 not found in project list +DETAIL: DXL-to-PlStmt Translation: Attribute number 23 not found in project list select * from qp_csq_t4 order by a; a | b ------+--- @@ -1644,7 +1640,7 @@ select * from qp_csq_t4 order by a; update qp_csq_t4 set a = 8888 where (select (y*2)>b from qp_csq_t2 where a=x); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner -DETAIL: DXL-to-PlStmt Translation: Attribute number 22 not found in project list +DETAIL: DXL-to-PlStmt Translation: Attribute number 14 not found in project list select * from qp_csq_t4 order by a; a | b ------+--- @@ -1656,7 +1652,7 @@ select * from qp_csq_t4 order by a; update qp_csq_t4 set a = 3333 where qp_csq_t4.a in (select x from qp_csq_t2); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner -DETAIL: DXL-to-PlStmt Translation: Attribute number 25 not found in project list +DETAIL: DXL-to-PlStmt Translation: Attribute number 17 not found in project list select * from qp_csq_t4 order by a; a | b ------+--- @@ -1668,26 +1664,26 @@ select * from qp_csq_t4 order by a; update D set i = 11111 from C where C.i = D.i and exists (select C.j from C,B where C.j = B.j and D.j < 10); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner -DETAIL: DXL-to-PlStmt Translation: Attribute number 45 not found in project list +DETAIL: DXL-to-PlStmt Translation: Attribute number 29 not found in project list select * from D; i | j -------+---- - 19 | 5 - 99 | 62 11111 | 1 11111 | 1 + 19 | 5 + 99 | 62 11111 | -1 (5 rows) update D set i = 22222 from C where C.i = D.i and not exists (select C.j from C,B where C.j = B.j and D.j < 10); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner -DETAIL: DXL-to-PlStmt Translation: Attribute number 45 not found in project list +DETAIL: DXL-to-PlStmt Translation: Attribute number 29 not found in project list select * from D; i | j -------+---- - 19 | 5 11111 | 1 11111 | 1 + 19 | 5 11111 | -1 22222 | 62 (5 rows) @@ -2275,6 +2271,8 @@ select A.i, B.i, C.j from A, B, C where exists (select C.j from C group by C.j h begin; create table csq_emp(name text, department text, salary numeric); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'name' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into csq_emp values('a','adept',11200.00); insert into csq_emp values('b','adept',22222.00); insert into csq_emp values('c','bdept',99222.00); @@ -2324,6 +2322,8 @@ create table job ( EMPNO VARCHAR(4), jobtitle VARCHAR(20) ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'empno' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into job (EMPNO, Jobtitle) values ('01','Tester'); insert into job (EMPNO, Jobtitle) values ('02','Accountant'); insert into job (EMPNO, Jobtitle) values ('03','Developer'); @@ -2406,7 +2406,7 @@ commit; UPDATE product SET product_price = product_price * .9 where product_name NOT IN (SELECT DISTINCT product_name FROM product_order); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner -DETAIL: DXL-to-PlStmt Translation: Attribute number 35 not found in project list +DETAIL: DXL-to-PlStmt Translation: Attribute number 27 not found in project list SELECT * FROM product order by product_name; product_name | product_price | quantity_on_hand | last_stock_date --------------+---------------+------------------+----------------- @@ -3730,20 +3730,17 @@ EXPLAIN SELECT a FROM qp_tab1 f1 LEFT JOIN qp_tab2 on a=c WHERE NOT EXISTS(SELEC Optimizer: GPORCA (11 rows) --- start_ignore -GPDB_12_MERGE_FIXME: Fallsback due to unsupported exec location. --- end_ignore EXPLAIN SELECT DISTINCT a FROM qp_tab1 WHERE NOT (SELECT TRUE FROM qp_tab2 WHERE EXISTS (SELECT * FROM qp_tab3 WHERE qp_tab2.c = qp_tab3.e)); QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1765377.02 rows=1 width=4) - -> GroupAggregate (cost=0.00..1765377.02 rows=1 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1765377.03 rows=1 width=4) + -> GroupAggregate (cost=0.00..1765377.03 rows=1 width=4) Group Key: qp_tab1.a - -> Sort (cost=0.00..1765377.02 rows=1 width=4) + -> Sort (cost=0.00..1765377.03 rows=1 width=4) Sort Key: qp_tab1.a - -> Result (cost=0.00..1765377.02 rows=1 width=4) + -> Result (cost=0.00..1765377.03 rows=1 width=4) Filter: (NOT (true)) - -> Nested Loop Left Join (cost=0.00..1765377.02 rows=1 width=5) + -> Nested Loop Left Join (cost=0.00..1765377.03 rows=1 width=5) Join Filter: true -> Seq Scan on qp_tab1 (cost=0.00..431.00 rows=1 width=4) -> Assert (cost=0.00..862.00 rows=1 width=1) @@ -3755,10 +3752,11 @@ EXPLAIN SELECT DISTINCT a FROM qp_tab1 WHERE NOT (SELECT TRUE FROM qp_tab2 WHERE -> Hash Semi Join (cost=0.00..862.00 rows=1 width=1) Hash Cond: (qp_tab2.c = qp_tab3.e) -> Seq Scan on qp_tab2 (cost=0.00..431.00 rows=1 width=4) + Filter: (NOT (c IS NULL)) -> Hash (cost=431.00..431.00 rows=1 width=4) -> Seq Scan on qp_tab3 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) -(22 rows) + Optimizer: GPORCA +(23 rows) SELECT DISTINCT a FROM qp_tab1 WHERE NOT (SELECT TRUE FROM qp_tab2 WHERE EXISTS (SELECT * FROM qp_tab3 WHERE qp_tab2.c = qp_tab3.e)); a @@ -3783,34 +3781,34 @@ EXPLAIN SELECT * FROM qp_non_eq_a, qp_non_eq_b WHERE qp_non_eq_a.f = qp_non_eq_b ---------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=2 width=24) -> Hash Join (cost=0.00..862.00 rows=1 width=24) - Hash Cond: qp_non_eq_b.f = qp_non_eq_a.f + Hash Cond: (qp_non_eq_b.f = qp_non_eq_a.f) -> Seq Scan on qp_non_eq_b (cost=0.00..431.00 rows=1 width=12) -> Hash (cost=431.00..431.00 rows=1 width=12) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=12) -> Seq Scan on qp_non_eq_a (cost=0.00..431.00 rows=1 width=12) - Filter: f::text <> '-0'::text - Optimizer: Pivotal Optimizer (GPORCA) version 2.72.0 + Filter: ((f)::text <> '-0'::text) + Optimizer: GPORCA (9 rows) SELECT * FROM qp_non_eq_a, qp_non_eq_b WHERE qp_non_eq_a.f = qp_non_eq_b.f AND qp_non_eq_a.f::text <> '-0'; i | f | i | f ---+---+---+---- - 1 | 0 | 1 | -0 1 | 0 | 3 | 0 + 1 | 0 | 1 | -0 (2 rows) EXPLAIN SELECT * FROM qp_non_eq_a INNER JOIN qp_non_eq_b ON qp_non_eq_a.f = qp_non_eq_b.f AND CASE WHEN qp_non_eq_b.f::text = '-0' THEN 1 ELSE -1::float8 END < '0'; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=2 width=24) -> Hash Join (cost=0.00..862.00 rows=1 width=24) - Hash Cond: qp_non_eq_a.f = qp_non_eq_b.f + Hash Cond: (qp_non_eq_a.f = qp_non_eq_b.f) -> Seq Scan on qp_non_eq_a (cost=0.00..431.00 rows=1 width=12) -> Hash (cost=431.00..431.00 rows=1 width=12) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=12) -> Seq Scan on qp_non_eq_b (cost=0.00..431.00 rows=1 width=12) - Filter: CASE WHEN f::text = '-0'::text THEN 1::double precision ELSE (-1)::double precision END < 0::double precision - Optimizer: Pivotal Optimizer (GPORCA) version 2.72.0 + Filter: (CASE WHEN ((f)::text = '-0'::text) THEN '1'::double precision ELSE '-1'::double precision END < '0'::double precision) + Optimizer: GPORCA (9 rows) SELECT * FROM qp_non_eq_a INNER JOIN qp_non_eq_b ON qp_non_eq_a.f = qp_non_eq_b.f AND CASE WHEN qp_non_eq_b.f::text = '-0' THEN 1 ELSE -1::float8 END < '0'; @@ -3821,17 +3819,17 @@ SELECT * FROM qp_non_eq_a INNER JOIN qp_non_eq_b ON qp_non_eq_a.f = qp_non_eq_b. (2 rows) EXPLAIN SELECT * FROM qp_non_eq_a, qp_non_eq_b WHERE qp_non_eq_a.i = qp_non_eq_b.i AND qp_non_eq_a.i = ANY('{1,2,3}'::integer[]); - QUERY PLAN --------------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=2 width=24) -> Hash Join (cost=0.00..862.00 rows=1 width=24) - Hash Cond: qp_non_eq_a.i = qp_non_eq_b.i + Hash Cond: (qp_non_eq_a.i = qp_non_eq_b.i) -> Seq Scan on qp_non_eq_a (cost=0.00..431.00 rows=1 width=12) - Filter: (i = ANY ('{1,2,3}'::integer[])) AND (i = 1 OR i = 2 OR i = 3) + Filter: ((i = ANY ('{1,2,3}'::integer[])) AND (i = ANY ('{1,2,3}'::integer[]))) -> Hash (cost=431.00..431.00 rows=1 width=12) -> Seq Scan on qp_non_eq_b (cost=0.00..431.00 rows=1 width=12) - Filter: i = 1 OR i = 2 OR i = 3 - Optimizer: Pivotal Optimizer (GPORCA) version 2.72.0 + Filter: (i = ANY ('{1,2,3}'::integer[])) + Optimizer: GPORCA (9 rows) SELECT * FROM qp_non_eq_a, qp_non_eq_b WHERE qp_non_eq_a.i = qp_non_eq_b.i AND qp_non_eq_a.i = ANY('{1,2,3}'::integer[]); @@ -3845,12 +3843,12 @@ EXPLAIN SELECT * FROM qp_non_eq_a, qp_non_eq_b WHERE qp_non_eq_a.i = qp_non_eq_b -------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=1 width=24) -> Hash Join (cost=0.00..862.00 rows=1 width=24) - Hash Cond: qp_non_eq_a.i = qp_non_eq_b.i + Hash Cond: (qp_non_eq_a.i = qp_non_eq_b.i) -> Seq Scan on qp_non_eq_a (cost=0.00..431.00 rows=1 width=12) - Filter: i::numeric = ANY ('{1,2,3}'::numeric[]) + Filter: ((i)::numeric = ANY ('{1,2,3}'::numeric[])) -> Hash (cost=431.00..431.00 rows=1 width=12) -> Seq Scan on qp_non_eq_b (cost=0.00..431.00 rows=1 width=12) - Optimizer: Pivotal Optimizer (GPORCA) version 2.72.0 + Optimizer: GPORCA (8 rows) SELECT * FROM qp_non_eq_a, qp_non_eq_b WHERE qp_non_eq_a.i = qp_non_eq_b.i AND qp_non_eq_a.i = ANY('{1,2,3}'::numeric[]); @@ -3902,35 +3900,35 @@ set optimizer_enforce_subplans = 1; explain select x1.a, (select count(*) from generate_series(1, x1.a)) from t1 x1; QUERY PLAN ------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..882708.48 rows=3 width=12) - -> Seq Scan on t1 x1 (cost=0.00..882708.48 rows=334 width=12) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..882708.47 rows=3 width=12) + -> Seq Scan on t1 x1 (cost=0.00..882708.47 rows=334 width=12) SubPlan 1 -> Aggregate (cost=0.00..0.00 rows=1 width=8) -> Function Scan on generate_series (cost=0.00..0.00 rows=334 width=1) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (6 rows) select x1.a, (select count(*) from generate_series(1, x1.a)) from t1 x1; a | count ---+------- - 1 | 1 2 | 2 3 | 3 + 1 | 1 (3 rows) -- with limit explain select t1.a, (select count(*) c from (select city from supplier limit t1.a) x) from t1; QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324051.59 rows=3 width=12) - -> Seq Scan on t1 (cost=0.00..1324051.59 rows=334 width=12) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324051.57 rows=3 width=12) + -> Seq Scan on t1 (cost=0.00..1324051.57 rows=334 width=12) SubPlan 1 -> Aggregate (cost=0.00..431.00 rows=1 width=8) -> Limit (cost=0.00..431.00 rows=5 width=1) -> Materialize (cost=0.00..431.00 rows=5 width=1) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=5 width=1) -> Seq Scan on supplier (cost=0.00..431.00 rows=2 width=1) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (9 rows) select t1.a, (select count(*) c from (select city from supplier limit t1.a) x) from t1; @@ -3945,43 +3943,43 @@ select t1.a, (select count(*) c from (select city from supplier limit t1.a) x) f explain select t1.*, (select count(*) as ct from generate_series(1, a), t1) from t1; QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1808684647.64 rows=3 width=16) - -> Seq Scan on t1 (cost=0.00..1808684647.64 rows=334 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1808684640.71 rows=3 width=16) + -> Seq Scan on t1 (cost=0.00..1808684640.71 rows=334 width=16) SubPlan 1 - -> Aggregate (cost=0.00..1765431.58 rows=1 width=8) - -> Nested Loop (cost=0.00..1765431.58 rows=1000 width=1) + -> Aggregate (cost=0.00..1765431.57 rows=1 width=8) + -> Nested Loop (cost=0.00..1765431.57 rows=3000 width=1) Join Filter: true -> Materialize (cost=0.00..431.00 rows=3 width=1) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=3 width=1) -> Seq Scan on t1 t1_1 (cost=0.00..431.00 rows=1 width=1) -> Function Scan on generate_series (cost=0.00..0.00 rows=334 width=1) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (11 rows) select t1.*, (select count(*) as ct from generate_series(1, a), t1) from t1; a | b | ct ---+---+---- - 1 | 1 | 3 2 | 2 | 6 3 | 3 | 9 + 1 | 1 | 3 (3 rows) explain select * from t1 where 0 < (select count(*) from generate_series(1, a), t1); QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1808684647.65 rows=3 width=8) - -> Result (cost=0.00..1808684647.65 rows=1 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1808684640.72 rows=3 width=8) + -> Result (cost=0.00..1808684640.72 rows=1 width=8) Filter: (0 < (SubPlan 1)) - -> Seq Scan on t1 (cost=0.00..1808684647.64 rows=334 width=16) + -> Seq Scan on t1 (cost=0.00..1808684640.71 rows=334 width=16) SubPlan 1 - -> Aggregate (cost=0.00..1765431.58 rows=1 width=8) - -> Nested Loop (cost=0.00..1765431.58 rows=1000 width=1) + -> Aggregate (cost=0.00..1765431.57 rows=1 width=8) + -> Nested Loop (cost=0.00..1765431.57 rows=3000 width=1) Join Filter: true -> Materialize (cost=0.00..431.00 rows=3 width=1) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=3 width=1) -> Seq Scan on t1 t1_1 (cost=0.00..431.00 rows=1 width=1) -> Function Scan on generate_series (cost=0.00..0.00 rows=334 width=1) - Optimizer: PQO version 3.27.0 + Optimizer: GPORCA (13 rows) select * from t1 where 0 < (select count(*) from generate_series(1, a), t1); diff --git a/contrib/pax_storage/src/test/regress/expected/qp_subquery_optimizer.out b/contrib/pax_storage/src/test/regress/expected/qp_subquery_optimizer.out index 4a5a3be132b..6a88dba4280 100644 --- a/contrib/pax_storage/src/test/regress/expected/qp_subquery_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/qp_subquery_optimizer.out @@ -105,12 +105,12 @@ SELECT '' AS six, f1 AS "Correlated Field", f2 AS "Second Field" WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL1 WHERE f1 = upper.f1); six | Correlated Field | Second Field -----+------------------+-------------- + | 1 | 2 + | 1 | 1 | 2 | 3 | 3 | 4 | 2 | 2 | 3 | 3 - | 1 | 2 - | 1 | 1 (6 rows) SELECT '' AS six, f1 AS "Correlated Field", f3 AS "Second Field" @@ -119,11 +119,11 @@ SELECT '' AS six, f1 AS "Correlated Field", f3 AS "Second Field" (SELECT f2 FROM SUBSELECT_TBL1 WHERE CAST(upper.f2 AS float) = f3); six | Correlated Field | Second Field -----+------------------+-------------- + | 1 | 1 | 2 | 4 | 3 | 5 | 2 | 2 | 3 | 3 - | 1 | 1 (5 rows) SELECT '' AS six, f1 AS "Correlated Field", f3 AS "Second Field" @@ -133,9 +133,9 @@ SELECT '' AS six, f1 AS "Correlated Field", f3 AS "Second Field" six | Correlated Field | Second Field -----+------------------+-------------- | 6 | 8 - | 1 | 3 | 2 | 4 | 3 | 5 + | 1 | 3 (4 rows) SELECT '' AS five, f1 AS "Correlated Field" @@ -188,8 +188,6 @@ select * from ( SELECT '' AS "col", * FROM join_tab1 AS tx)A; -----+---+---+------- | 1 | 4 | one | 0 | | zero - | 5 | 0 | five - | 6 | 6 | six | 2 | 3 | two | 3 | 2 | three | 4 | 1 | four @@ -197,6 +195,8 @@ select * from ( SELECT '' AS "col", * FROM join_tab1 AS tx)A; | 8 | 8 | eight | | | null | | 0 | zero + | 5 | 0 | five + | 6 | 6 | six (11 rows) @@ -205,8 +205,6 @@ select * from ( SELECT '' AS "col", * FROM join_tab1 AS tx) AS A; -----+---+---+------- | 5 | 0 | five | 6 | 6 | six - | 1 | 4 | one - | 0 | | zero | 2 | 3 | two | 3 | 2 | three | 4 | 1 | four @@ -214,6 +212,8 @@ select * from ( SELECT '' AS "col", * FROM join_tab1 AS tx) AS A; | 8 | 8 | eight | | | null | | 0 | zero + | 1 | 4 | one + | 0 | | zero (11 rows) @@ -238,10 +238,10 @@ select * from(SELECT '' AS "col", t1.a, t2.e FROM join_tab1 t1 (a, b, c), join_t WHERE t1.a = t2.d)as A; col | a | e -----+---+---- - | 1 | -1 - | 0 | | 5 | -5 | 5 | -5 + | 1 | -1 + | 0 | | 2 | 2 | 3 | -3 | 2 | 4 @@ -418,8 +418,8 @@ select name from emp_list where sal>(select avg(sal) from emp_list); select name from emp_list where sal<(select avg(sal) from emp_list); name ---------------------- - empone emptwo + empone (2 rows) @@ -469,13 +469,13 @@ select i,j,t from (select * from (select i,j,t from join_tab1)as dtab1 UNION select * from(select i,j,t from join_tab4) as dtab2 )as mtab; i | j | t ---+---+-------- - 0 | | zero - 1 | 4 | one - 1 | 7 | sunday 5 | 0 | five 5 | 3 | thuday 6 | 2 | friday 6 | 6 | six + 0 | | zero + 1 | 4 | one + 1 | 7 | sunday 2 | 3 | two 2 | 6 | monday 3 | 2 | three @@ -583,28 +583,27 @@ FROM join_tab1 out1, join_tab2 out2; - 0 - 0 + 0 + 0 + 0 - 0 - 0 @@ -643,23 +642,24 @@ FROM join_tab1 out1, join_tab2 out2; - 0 - 0 - 0 + 0 + 0 + 0 + 0 @@ -990,8 +990,8 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery a | b ---+--- - 5 | 3 | 4 + 5 | (2 rows) select t1.a, t2.b from t1 left join t2 on (t1.a=t2.a and ((t1.a,t2.b) not in (select i1.a,i1.b from i1))); @@ -1000,8 +1000,8 @@ DETAIL: Falling back to Postgres-based planner because GPORCA does not support a | b ---+--- 5 | - 1 | 3 | 4 + 1 | (3 rows) -- @@ -1012,9 +1012,9 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery a | b ---+--- - 5 | 3 | 4 | 8 + 5 | (3 rows) -- not in subquery with a row var in FULL JOIN condition @@ -1023,9 +1023,9 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery a | b ---+--- - 5 | 3 | 4 | 8 + 5 | 1 | | 2 (5 rows) @@ -1062,10 +1062,10 @@ commit; select Tbl01.*,foo(Tbl01.a) as foo from Tbl01; -- showing foo values a | b | c | foo ---+----+----+----- - 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | | 11 | 12 | 13 + 1 | 2 | 3 | (4 rows) select Tbl01.* from Tbl01 where foo(Tbl01.a) not in (select a from Tbl03); @@ -1193,8 +1193,8 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery a | b ---+--- - 5 | 6 3 | 4 + 5 | 6 (2 rows) select Tbl04.* from Tbl04 where (Tbl04.a,Tbl04.b) not in (select Tbl05.a,Tbl05.b from Tbl05,i3 where Tbl05.a = i3.a and Tbl05.b = i3.b); @@ -1202,8 +1202,8 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery a | b ---+--- - 3 | 4 5 | 6 + 3 | 4 (2 rows) select Tbl04.* from Tbl04 where (Tbl04.a,Tbl04.b) not in (select Tbl05.a,Tbl05.b from Tbl05,i3 where Tbl05.a < i3.a and Tbl05.b > i3.b); @@ -1212,8 +1212,8 @@ DETAIL: Falling back to Postgres-based planner because GPORCA does not support a | b ---+--- 3 | 4 - 5 | 6 1 | 2 + 5 | 6 (3 rows) -- non-null constant values @@ -1222,15 +1222,15 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery a | b ---+--- - 5 | 6 3 | 4 + 5 | 6 (2 rows) select Tbl04.* from Tbl04 where (Tbl04.a,Tbl04.b) not in ((1,2)); a | b ---+--- - 3 | 4 5 | 6 + 3 | 4 (2 rows) -- multiple NOT-IN expressions @@ -1282,15 +1282,15 @@ select Tbl04.* from Tbl04 where Tbl04.a NOT IN (select Tbl09.a from Tbl09 where select Tbl04.* from Tbl04 where Tbl04.a NOT IN (select i3.a from i3); a | b ---+--- - 5 | 6 3 | 4 + 5 | 6 (2 rows) select Tbl04.* from Tbl04 where Tbl04.a NOT IN (select Tbl05.a from Tbl05 left join i3 on (Tbl05.a=i3.a)); a | b ---+--- - 5 | 6 3 | 4 + 5 | 6 (2 rows) -- @@ -1360,9 +1360,9 @@ DETAIL: Falling back to Postgres-based planner because GPORCA does not support select Tbl09.a, Tbl09.b from Tbl09; a | b ---+--- - 5 | - | 8 1 | 2 + | 8 + 5 | (3 rows) select Tbl04.* from Tbl04 where (Tbl04.a,Tbl04.b) not in (select Tbl09.a,Tbl09.b from Tbl09); -- expected: (3,4) @@ -1376,9 +1376,9 @@ DETAIL: Falling back to Postgres-based planner because GPORCA does not support select Tbl09.a, Tbl09.b from Tbl09 group by Tbl09.a, Tbl09.b; a | b ---+--- + | 8 1 | 2 5 | - | 8 (3 rows) select Tbl04.* from Tbl04 where (Tbl04.a,Tbl04.b) not in (select Tbl09.a, Tbl09.b from Tbl09 group by Tbl09.a, Tbl09.b); -- expected: (3,4) @@ -1405,8 +1405,8 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery a | b ---+--- - 5 | 6 3 | 4 + 5 | 6 (2 rows) select Tbl04.* from Tbl04 where (Tbl04.a,Tbl04.b) NOT IN (select i3.a,i3.b from Tbl07 left join i3 on (i3.a=Tbl07.a and i3.b=Tbl07.b) where i3.a > 2); @@ -1450,8 +1450,8 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery a | b ---+--- - 5 | 6 3 | 4 + 5 | 6 (2 rows) -- Cases where the planner "should have" determined not-nullabitlity @@ -1460,8 +1460,8 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery a | b ---+--- - 3 | 4 5 | 6 + 3 | 4 (2 rows) select Tbl04.* from Tbl04 where (Tbl04.a,Tbl04.b) not in (select Tbl05.a,Tbl05.b from Tbl05 where (Tbl05.a IN (select i3.a from i3)) AND (Tbl05.b IN (select i3.b from i3))); @@ -1547,8 +1547,8 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery a | b ---------+--------- - oak | barrett florian | waas + oak | barrett (2 rows) -- @@ -1628,13 +1628,13 @@ select * from TblUp1; a | b -----+--- 1 | 2 - 100 | 6 100 | 4 + 100 | 6 (3 rows) update TblUp2 set a=100 where a not in (select a from TblUp4); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner -DETAIL: DXL-to-PlStmt Translation: Attribute number 26 not found in project list +DETAIL: DXL-to-PlStmt Translation: Attribute number 18 not found in project list select * from TblUp2; a | b -----+--- @@ -1933,15 +1933,15 @@ from ( a1 | checkcol ----+---------- 1 | true - 5 | true - 6 | false - 9 | false - 10 | false 2 | true 3 | true 4 | true 7 | false 8 | false + 5 | true + 6 | false + 9 | false + 10 | false (10 rows) -- check various [NOT] EXISTS subqueries on materialized views @@ -1951,8 +1951,8 @@ create materialized view v as select a, b from t distributed randomly; select * from v where exists (select a from v); a | b ---+--- - 2 | | 3 + 2 | 1 | 1 (3 rows) @@ -1964,17 +1964,17 @@ select * from v where exists (select a from v limit 0); select * from v where exists (select a from v where a=2); a | b ---+--- - 1 | 1 - 2 | | 3 + 2 | + 1 | 1 (3 rows) select * from v where exists (select a from v where a<>2); a | b ---+--- - 1 | 1 2 | | 3 + 1 | 1 (3 rows) select * from v where not exists (select a from v); @@ -1985,9 +1985,9 @@ select * from v where not exists (select a from v); select * from v where not exists (select a from v limit 0); a | b ---+--- + 1 | 1 2 | | 3 - 1 | 1 (3 rows) select * from v where not exists (select a from v where a=2); @@ -2003,9 +2003,9 @@ select * from v where not exists (select a from v where a<>2); select * from v where exists (select b from v); a | b ---+--- - 2 | | 3 1 | 1 + 2 | (3 rows) select * from v where exists (select b from v limit 0); @@ -2021,9 +2021,9 @@ select * from v where exists (select b from v where b=2); select * from v where exists (select b from v where b<>2); a | b ---+--- - 1 | 1 - 2 | | 3 + 2 | + 1 | 1 (3 rows) select * from v where not exists (select b from v); @@ -2034,17 +2034,17 @@ select * from v where not exists (select b from v); select * from v where not exists (select b from v limit 0); a | b ---+--- - 1 | 1 - 2 | | 3 + 2 | + 1 | 1 (3 rows) select * from v where not exists (select b from v where b=2); a | b ---+--- 2 | - | 3 1 | 1 + | 3 (3 rows) select * from v where not exists (select b from v where b<>2); @@ -2063,9 +2063,9 @@ WHERE EXISTS WHERE t2.param = t1.param); param ------- - 2 - 1 3 + 1 + 2 (3 rows) EXPLAIN (COSTS OFF) SELECT * FROM (SELECT BTRIM(p1.b) AS param FROM tab1 p1 JOIN tab1 p2 USING(a)) t1 @@ -2073,26 +2073,26 @@ WHERE EXISTS (SELECT 1 FROM (SELECT BTRIM(p1.b) AS param FROM tab1 p1 JOIN tab1 p2 USING(a)) t2 WHERE t2.param = t1.param); - QUERY PLAN ---------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join - Hash Cond: (btrim(p1.b) = btrim(p1_1.b)) - -> Hash Join - Hash Cond: (p1.a = p2.a) - -> Seq Scan on tab1 p1 - Filter: (NOT (btrim(b) IS NULL)) - -> Hash - -> Broadcast Motion 3:3 (slice2; segments: 3) - -> Seq Scan on tab1 p2 + -> Hash Right Semi Join + Hash Cond: (btrim(p1_1.b) = btrim(p1.b)) + -> Broadcast Motion 3:3 (slice2; segments: 3) + -> Hash Join + Hash Cond: (p1.a = p2.a) + -> Seq Scan on tab1 p1 + -> Hash + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Seq Scan on tab1 p2 -> Hash - -> Broadcast Motion 3:3 (slice3; segments: 3) - -> Hash Join - Hash Cond: (p1_1.a = p2_1.a) - -> Seq Scan on tab1 p1_1 - -> Hash - -> Broadcast Motion 3:3 (slice4; segments: 3) - -> Seq Scan on tab1 p2_1 + -> Hash Join + Hash Cond: (p1_1.a = p2_1.a) + -> Seq Scan on tab1 p1_1 + Filter: (NOT (btrim(b) IS NULL)) + -> Hash + -> Broadcast Motion 3:3 (slice4; segments: 3) + -> Seq Scan on tab1 p2_1 Optimizer: GPORCA (19 rows) @@ -2106,9 +2106,9 @@ WHERE EXISTS WHERE t2.param = t1.param); param ------- - 2 - 1 3 + 1 + 2 (3 rows) EXPLAIN (COSTS OFF) SELECT * FROM (SELECT BTRIM(p1.b) AS param FROM tab1 p1 JOIN tab1 p2 USING(a)) t1 diff --git a/contrib/pax_storage/src/test/regress/expected/rpt_joins.out b/contrib/pax_storage/src/test/regress/expected/rpt_joins.out index fe4f0e0dcbe..c869b335f2e 100644 --- a/contrib/pax_storage/src/test/regress/expected/rpt_joins.out +++ b/contrib/pax_storage/src/test/regress/expected/rpt_joins.out @@ -1,6 +1,10 @@ -- -- Tests for joins between replicated tables -- +-- start_ignore +create extension if not exists gp_debug_numsegments; +NOTICE: extension "gp_debug_numsegments" already exists, skipping +-- end_ignore create schema rpt_joins; set search_path to rpt_joins, public; -- @@ -46,104 +50,104 @@ SELECT '' AS "xxx", * FROM J1_TBL CROSS JOIN J2_TBL; xxx | i | j | t | i | k -----+---+---+-------+---+---- - | 8 | 8 | eight | 1 | -1 - | 8 | 8 | eight | 2 | 2 - | 8 | 8 | eight | 3 | -3 - | 8 | 8 | eight | 2 | 4 - | 8 | 8 | eight | 5 | -5 - | 8 | 8 | eight | 5 | -5 - | 8 | 8 | eight | 0 | - | 8 | 8 | eight | | - | 8 | 8 | eight | | 0 + | 5 | 0 | five | 1 | -1 + | 6 | 6 | six | 1 | -1 + | 5 | 0 | five | 2 | 2 + | 6 | 6 | six | 2 | 2 + | 5 | 0 | five | 3 | -3 + | 6 | 6 | six | 3 | -3 + | 5 | 0 | five | 2 | 4 + | 6 | 6 | six | 2 | 4 + | 5 | 0 | five | 5 | -5 + | 6 | 6 | six | 5 | -5 + | 5 | 0 | five | 5 | -5 + | 6 | 6 | six | 5 | -5 + | 5 | 0 | five | 0 | + | 6 | 6 | six | 0 | + | 5 | 0 | five | | + | 6 | 6 | six | | + | 5 | 0 | five | | 0 + | 6 | 6 | six | | 0 | 1 | 4 | one | 1 | -1 - | 1 | 4 | one | 2 | 2 - | 1 | 4 | one | 3 | -3 - | 1 | 4 | one | 2 | 4 - | 1 | 4 | one | 5 | -5 - | 1 | 4 | one | 5 | -5 - | 1 | 4 | one | 0 | - | 1 | 4 | one | | - | 1 | 4 | one | | 0 - | 2 | 3 | two | 1 | -1 - | 2 | 3 | two | 2 | 2 - | 2 | 3 | two | 3 | -3 - | 2 | 3 | two | 2 | 4 - | 2 | 3 | two | 5 | -5 - | 2 | 3 | two | 5 | -5 - | 2 | 3 | two | 0 | - | 2 | 3 | two | | - | 2 | 3 | two | | 0 | 0 | | zero | 1 | -1 + | 1 | 4 | one | 2 | 2 | 0 | | zero | 2 | 2 + | 1 | 4 | one | 3 | -3 | 0 | | zero | 3 | -3 + | 1 | 4 | one | 2 | 4 | 0 | | zero | 2 | 4 + | 1 | 4 | one | 5 | -5 | 0 | | zero | 5 | -5 + | 1 | 4 | one | 5 | -5 | 0 | | zero | 5 | -5 + | 1 | 4 | one | 0 | | 0 | | zero | 0 | + | 1 | 4 | one | | | 0 | | zero | | + | 1 | 4 | one | | 0 | 0 | | zero | | 0 + | 2 | 3 | two | 1 | -1 | 3 | 2 | three | 1 | -1 - | 3 | 2 | three | 2 | 2 - | 3 | 2 | three | 3 | -3 - | 3 | 2 | three | 2 | 4 - | 3 | 2 | three | 5 | -5 - | 3 | 2 | three | 5 | -5 - | 3 | 2 | three | 0 | - | 3 | 2 | three | | - | 3 | 2 | three | | 0 | 4 | 1 | four | 1 | -1 - | 4 | 1 | four | 2 | 2 - | 4 | 1 | four | 3 | -3 - | 4 | 1 | four | 2 | 4 - | 4 | 1 | four | 5 | -5 - | 4 | 1 | four | 5 | -5 - | 4 | 1 | four | 0 | - | 4 | 1 | four | | - | 4 | 1 | four | | 0 - | 5 | 0 | five | 1 | -1 - | 5 | 0 | five | 2 | 2 - | 5 | 0 | five | 3 | -3 - | 5 | 0 | five | 2 | 4 - | 5 | 0 | five | 5 | -5 - | 5 | 0 | five | 5 | -5 - | 5 | 0 | five | 0 | - | 5 | 0 | five | | - | 5 | 0 | five | | 0 - | 6 | 6 | six | 1 | -1 - | 6 | 6 | six | 2 | 2 - | 6 | 6 | six | 3 | -3 - | 6 | 6 | six | 2 | 4 - | 6 | 6 | six | 5 | -5 - | 6 | 6 | six | 5 | -5 - | 6 | 6 | six | 0 | - | 6 | 6 | six | | - | 6 | 6 | six | | 0 | 7 | 7 | seven | 1 | -1 - | 7 | 7 | seven | 2 | 2 - | 7 | 7 | seven | 3 | -3 - | 7 | 7 | seven | 2 | 4 - | 7 | 7 | seven | 5 | -5 - | 7 | 7 | seven | 5 | -5 - | 7 | 7 | seven | 0 | - | 7 | 7 | seven | | - | 7 | 7 | seven | | 0 + | 8 | 8 | eight | 1 | -1 | | | null | 1 | -1 - | | | null | 2 | 2 - | | | null | 3 | -3 - | | | null | 2 | 4 - | | | null | 5 | -5 - | | | null | 5 | -5 - | | | null | 0 | - | | | null | | - | | | null | | 0 | | 0 | zero | 1 | -1 + | 2 | 3 | two | 2 | 2 + | 3 | 2 | three | 2 | 2 + | 4 | 1 | four | 2 | 2 + | 7 | 7 | seven | 2 | 2 + | 8 | 8 | eight | 2 | 2 + | | | null | 2 | 2 | | 0 | zero | 2 | 2 + | 2 | 3 | two | 3 | -3 + | 3 | 2 | three | 3 | -3 + | 4 | 1 | four | 3 | -3 + | 7 | 7 | seven | 3 | -3 + | 8 | 8 | eight | 3 | -3 + | | | null | 3 | -3 | | 0 | zero | 3 | -3 + | 2 | 3 | two | 2 | 4 + | 3 | 2 | three | 2 | 4 + | 4 | 1 | four | 2 | 4 + | 7 | 7 | seven | 2 | 4 + | 8 | 8 | eight | 2 | 4 + | | | null | 2 | 4 | | 0 | zero | 2 | 4 + | 2 | 3 | two | 5 | -5 + | 3 | 2 | three | 5 | -5 + | 4 | 1 | four | 5 | -5 + | 7 | 7 | seven | 5 | -5 + | 8 | 8 | eight | 5 | -5 + | | | null | 5 | -5 | | 0 | zero | 5 | -5 + | 2 | 3 | two | 5 | -5 + | 3 | 2 | three | 5 | -5 + | 4 | 1 | four | 5 | -5 + | 7 | 7 | seven | 5 | -5 + | 8 | 8 | eight | 5 | -5 + | | | null | 5 | -5 | | 0 | zero | 5 | -5 + | 2 | 3 | two | 0 | + | 3 | 2 | three | 0 | + | 4 | 1 | four | 0 | + | 7 | 7 | seven | 0 | + | 8 | 8 | eight | 0 | + | | | null | 0 | | | 0 | zero | 0 | + | 2 | 3 | two | | + | 3 | 2 | three | | + | 4 | 1 | four | | + | 7 | 7 | seven | | + | 8 | 8 | eight | | + | | | null | | | | 0 | zero | | + | 2 | 3 | two | | 0 + | 3 | 2 | three | | 0 + | 4 | 1 | four | | 0 + | 7 | 7 | seven | | 0 + | 8 | 8 | eight | | 0 + | | | null | | 0 | | 0 | zero | | 0 (99 rows) @@ -159,104 +163,104 @@ SELECT '' AS "xxx", t1.i, k, t xxx | i | k | t -----+---+----+------- | 1 | -1 | one - | 1 | 2 | one - | 1 | -3 | one - | 1 | 4 | one - | 1 | -5 | one - | 1 | -5 | one - | 1 | | one - | 1 | | one - | 1 | 0 | one - | 2 | -1 | two - | 2 | 2 | two - | 2 | -3 | two - | 2 | 4 | two - | 2 | -5 | two - | 2 | -5 | two - | 2 | | two - | 2 | | two - | 2 | 0 | two | 0 | -1 | zero + | 1 | 2 | one | 0 | 2 | zero + | 1 | -3 | one | 0 | -3 | zero + | 1 | 4 | one | 0 | 4 | zero + | 1 | -5 | one | 0 | -5 | zero + | 1 | -5 | one | 0 | -5 | zero + | 1 | | one | 0 | | zero + | 1 | | one | 0 | | zero + | 1 | 0 | one | 0 | 0 | zero - | 3 | -1 | three - | 3 | 2 | three - | 3 | -3 | three - | 3 | 4 | three - | 3 | -5 | three - | 3 | -5 | three - | 3 | | three - | 3 | | three - | 3 | 0 | three - | 4 | -1 | four - | 4 | 2 | four - | 4 | -3 | four - | 4 | 4 | four - | 4 | -5 | four - | 4 | -5 | four - | 4 | | four - | 4 | | four - | 4 | 0 | four | 5 | -1 | five - | 5 | 2 | five - | 5 | -3 | five - | 5 | 4 | five - | 5 | -5 | five - | 5 | -5 | five - | 5 | | five - | 5 | | five - | 5 | 0 | five | 6 | -1 | six + | 5 | 2 | five | 6 | 2 | six + | 5 | -3 | five | 6 | -3 | six + | 5 | 4 | five | 6 | 4 | six + | 5 | -5 | five | 6 | -5 | six + | 5 | -5 | five | 6 | -5 | six + | 5 | | five | 6 | | six + | 5 | | five | 6 | | six + | 5 | 0 | five | 6 | 0 | six + | 2 | -1 | two + | 3 | -1 | three + | 4 | -1 | four | 7 | -1 | seven + | 8 | -1 | eight + | | -1 | null + | | -1 | zero + | 2 | 2 | two + | 3 | 2 | three + | 4 | 2 | four | 7 | 2 | seven + | 8 | 2 | eight + | | 2 | null + | | 2 | zero + | 2 | -3 | two + | 3 | -3 | three + | 4 | -3 | four | 7 | -3 | seven + | 8 | -3 | eight + | | -3 | null + | | -3 | zero + | 2 | 4 | two + | 3 | 4 | three + | 4 | 4 | four | 7 | 4 | seven + | 8 | 4 | eight + | | 4 | null + | | 4 | zero + | 2 | -5 | two + | 3 | -5 | three + | 4 | -5 | four | 7 | -5 | seven + | 8 | -5 | eight + | | -5 | null + | | -5 | zero + | 2 | -5 | two + | 3 | -5 | three + | 4 | -5 | four | 7 | -5 | seven + | 8 | -5 | eight + | | -5 | null + | | -5 | zero + | 2 | | two + | 3 | | three + | 4 | | four | 7 | | seven + | 8 | | eight + | | | null + | | | zero + | 2 | | two + | 3 | | three + | 4 | | four | 7 | | seven - | 7 | 0 | seven - | | -1 | null - | | 2 | null - | | -3 | null - | | 4 | null - | | -5 | null - | | -5 | null - | | | null + | 8 | | eight | | | null - | | 0 | null - | | -1 | zero - | | 2 | zero - | | -3 | zero - | | 4 | zero - | | -5 | zero - | | -5 | zero | | | zero - | | | zero - | | 0 | zero - | 8 | -1 | eight - | 8 | 2 | eight - | 8 | -3 | eight - | 8 | 4 | eight - | 8 | -5 | eight - | 8 | -5 | eight - | 8 | | eight - | 8 | | eight + | 2 | 0 | two + | 3 | 0 | three + | 4 | 0 | four + | 7 | 0 | seven | 8 | 0 | eight + | | 0 | null + | | 0 | zero (99 rows) SELECT '' AS "xxx", ii, tt, kk @@ -264,105 +268,105 @@ SELECT '' AS "xxx", ii, tt, kk AS tx (ii, jj, tt, ii2, kk); xxx | ii | tt | kk -----+----+-------+---- - | 1 | one | -1 - | 1 | one | 2 - | 1 | one | -3 - | 1 | one | 4 - | 1 | one | -5 - | 1 | one | -5 - | 1 | one | - | 1 | one | - | 1 | one | 0 | 2 | two | -1 - | 2 | two | 2 - | 2 | two | -3 - | 2 | two | 4 - | 2 | two | -5 - | 2 | two | -5 - | 2 | two | - | 2 | two | - | 2 | two | 0 - | 0 | zero | -1 - | 0 | zero | 2 - | 0 | zero | -3 - | 0 | zero | 4 - | 0 | zero | -5 - | 0 | zero | -5 - | 0 | zero | - | 0 | zero | - | 0 | zero | 0 - | 8 | eight | -1 - | 8 | eight | 2 - | 8 | eight | -3 - | 8 | eight | 4 - | 8 | eight | -5 - | 8 | eight | -5 - | 8 | eight | - | 8 | eight | - | 8 | eight | 0 | 3 | three | -1 - | 3 | three | 2 - | 3 | three | -3 - | 3 | three | 4 - | 3 | three | -5 - | 3 | three | -5 - | 3 | three | - | 3 | three | - | 3 | three | 0 | 4 | four | -1 + | 7 | seven | -1 + | 8 | eight | -1 + | | null | -1 + | | zero | -1 + | 2 | two | 2 + | 3 | three | 2 | 4 | four | 2 + | 7 | seven | 2 + | 8 | eight | 2 + | | null | 2 + | | zero | 2 + | 2 | two | -3 + | 3 | three | -3 | 4 | four | -3 + | 7 | seven | -3 + | 8 | eight | -3 + | | null | -3 + | | zero | -3 + | 2 | two | 4 + | 3 | three | 4 | 4 | four | 4 + | 7 | seven | 4 + | 8 | eight | 4 + | | null | 4 + | | zero | 4 + | 2 | two | -5 + | 3 | three | -5 | 4 | four | -5 + | 7 | seven | -5 + | 8 | eight | -5 + | | null | -5 + | | zero | -5 + | 2 | two | -5 + | 3 | three | -5 | 4 | four | -5 + | 7 | seven | -5 + | 8 | eight | -5 + | | null | -5 + | | zero | -5 + | 2 | two | + | 3 | three | | 4 | four | + | 7 | seven | + | 8 | eight | + | | null | + | | zero | + | 2 | two | + | 3 | three | | 4 | four | + | 7 | seven | + | 8 | eight | + | | null | + | | zero | + | 2 | two | 0 + | 3 | three | 0 | 4 | four | 0 + | 7 | seven | 0 + | 8 | eight | 0 + | | null | 0 + | | zero | 0 | 5 | five | -1 - | 5 | five | 2 - | 5 | five | -3 - | 5 | five | 4 - | 5 | five | -5 - | 5 | five | -5 - | 5 | five | - | 5 | five | - | 5 | five | 0 | 6 | six | -1 + | 5 | five | 2 | 6 | six | 2 + | 5 | five | -3 | 6 | six | -3 + | 5 | five | 4 | 6 | six | 4 + | 5 | five | -5 | 6 | six | -5 + | 5 | five | -5 | 6 | six | -5 + | 5 | five | | 6 | six | + | 5 | five | | 6 | six | + | 5 | five | 0 | 6 | six | 0 - | 7 | seven | -1 - | 7 | seven | 2 - | 7 | seven | -3 - | 7 | seven | 4 - | 7 | seven | -5 - | 7 | seven | -5 - | 7 | seven | - | 7 | seven | - | 7 | seven | 0 - | | null | -1 - | | null | 2 - | | null | -3 - | | null | 4 - | | null | -5 - | | null | -5 - | | null | - | | null | - | | null | 0 - | | zero | -1 - | | zero | 2 - | | zero | -3 - | | zero | 4 - | | zero | -5 - | | zero | -5 - | | zero | - | | zero | - | | zero | 0 + | 1 | one | -1 + | 0 | zero | -1 + | 1 | one | 2 + | 0 | zero | 2 + | 1 | one | -3 + | 0 | zero | -3 + | 1 | one | 4 + | 0 | zero | 4 + | 1 | one | -5 + | 0 | zero | -5 + | 1 | one | -5 + | 0 | zero | -5 + | 1 | one | + | 0 | zero | + | 1 | one | + | 0 | zero | + | 1 | one | 0 + | 0 | zero | 0 (99 rows) SELECT '' AS "xxx", tx.ii, tx.jj, tx.kk @@ -371,377 +375,119 @@ SELECT '' AS "xxx", tx.ii, tx.jj, tx.kk xxx | ii | jj | kk -----+----+----+---- | 1 | 4 | -1 - | 1 | 4 | 2 - | 1 | 4 | -3 - | 1 | 4 | 4 - | 1 | 4 | -5 - | 1 | 4 | -5 - | 1 | 4 | - | 1 | 4 | - | 1 | 4 | 0 - | 2 | 3 | -1 - | 2 | 3 | 2 - | 2 | 3 | -3 - | 2 | 3 | 4 - | 2 | 3 | -5 - | 2 | 3 | -5 - | 2 | 3 | - | 2 | 3 | - | 2 | 3 | 0 | 0 | | -1 + | 1 | 4 | 2 | 0 | | 2 + | 1 | 4 | -3 | 0 | | -3 + | 1 | 4 | 4 | 0 | | 4 + | 1 | 4 | -5 | 0 | | -5 + | 1 | 4 | -5 | 0 | | -5 + | 1 | 4 | | 0 | | + | 1 | 4 | | 0 | | + | 1 | 4 | 0 | 0 | | 0 - | 3 | 2 | -1 - | 3 | 2 | 2 - | 3 | 2 | -3 - | 3 | 2 | 4 - | 3 | 2 | -5 - | 3 | 2 | -5 - | 3 | 2 | - | 3 | 2 | - | 3 | 2 | 0 - | 4 | 1 | -1 - | 4 | 1 | 2 - | 4 | 1 | -3 - | 4 | 1 | 4 - | 4 | 1 | -5 - | 4 | 1 | -5 - | 4 | 1 | - | 4 | 1 | - | 4 | 1 | 0 | 5 | 0 | -1 - | 5 | 0 | 2 - | 5 | 0 | -3 - | 5 | 0 | 4 - | 5 | 0 | -5 - | 5 | 0 | -5 - | 5 | 0 | - | 5 | 0 | - | 5 | 0 | 0 | 6 | 6 | -1 + | 5 | 0 | 2 | 6 | 6 | 2 + | 5 | 0 | -3 | 6 | 6 | -3 + | 5 | 0 | 4 | 6 | 6 | 4 + | 5 | 0 | -5 | 6 | 6 | -5 + | 5 | 0 | -5 | 6 | 6 | -5 + | 5 | 0 | | 6 | 6 | + | 5 | 0 | | 6 | 6 | + | 5 | 0 | 0 | 6 | 6 | 0 + | 2 | 3 | -1 + | 3 | 2 | -1 + | 4 | 1 | -1 | 7 | 7 | -1 + | 8 | 8 | -1 + | | | -1 + | | 0 | -1 + | 2 | 3 | 2 + | 3 | 2 | 2 + | 4 | 1 | 2 | 7 | 7 | 2 - | 7 | 7 | -3 - | 7 | 7 | 4 - | 7 | 7 | -5 - | 7 | 7 | -5 - | 7 | 7 | - | 7 | 7 | - | 7 | 7 | 0 - | | | -1 + | 8 | 8 | 2 | | | 2 - | | | -3 - | | | 4 - | | | -5 - | | | -5 - | | | - | | | - | | | 0 - | | 0 | -1 | | 0 | 2 - | | 0 | -3 - | | 0 | 4 - | | 0 | -5 - | | 0 | -5 - | | 0 | - | | 0 | - | | 0 | 0 - | 8 | 8 | -1 - | 8 | 8 | 2 + | 2 | 3 | -3 + | 3 | 2 | -3 + | 4 | 1 | -3 + | 7 | 7 | -3 | 8 | 8 | -3 + | | | -3 + | | 0 | -3 + | 2 | 3 | 4 + | 3 | 2 | 4 + | 4 | 1 | 4 + | 7 | 7 | 4 | 8 | 8 | 4 - | 8 | 8 | -5 - | 8 | 8 | -5 - | 8 | 8 | - | 8 | 8 | - | 8 | 8 | 0 -(99 rows) - -SELECT '' AS "xxx", * - FROM J1_TBL CROSS JOIN J2_TBL a CROSS JOIN J2_TBL b; - xxx | i | j | t | i | k | i | k ------+---+---+-------+---+----+---+---- - | 8 | 8 | eight | 1 | -1 | 1 | -1 - | 8 | 8 | eight | 1 | -1 | 2 | 2 - | 8 | 8 | eight | 1 | -1 | 3 | -3 - | 8 | 8 | eight | 1 | -1 | 2 | 4 - | 8 | 8 | eight | 1 | -1 | 5 | -5 - | 8 | 8 | eight | 1 | -1 | 5 | -5 - | 8 | 8 | eight | 1 | -1 | 0 | - | 8 | 8 | eight | 1 | -1 | | - | 8 | 8 | eight | 1 | -1 | | 0 - | 8 | 8 | eight | 2 | 2 | 1 | -1 - | 8 | 8 | eight | 2 | 2 | 2 | 2 - | 8 | 8 | eight | 2 | 2 | 3 | -3 - | 8 | 8 | eight | 2 | 2 | 2 | 4 - | 8 | 8 | eight | 2 | 2 | 5 | -5 - | 8 | 8 | eight | 2 | 2 | 5 | -5 - | 8 | 8 | eight | 2 | 2 | 0 | - | 8 | 8 | eight | 2 | 2 | | - | 8 | 8 | eight | 2 | 2 | | 0 - | 8 | 8 | eight | 3 | -3 | 1 | -1 - | 8 | 8 | eight | 3 | -3 | 2 | 2 - | 8 | 8 | eight | 3 | -3 | 3 | -3 - | 8 | 8 | eight | 3 | -3 | 2 | 4 - | 8 | 8 | eight | 3 | -3 | 5 | -5 - | 8 | 8 | eight | 3 | -3 | 5 | -5 - | 8 | 8 | eight | 3 | -3 | 0 | - | 8 | 8 | eight | 3 | -3 | | - | 8 | 8 | eight | 3 | -3 | | 0 - | 8 | 8 | eight | 2 | 4 | 1 | -1 - | 8 | 8 | eight | 2 | 4 | 2 | 2 - | 8 | 8 | eight | 2 | 4 | 3 | -3 - | 8 | 8 | eight | 2 | 4 | 2 | 4 - | 8 | 8 | eight | 2 | 4 | 5 | -5 - | 8 | 8 | eight | 2 | 4 | 5 | -5 - | 8 | 8 | eight | 2 | 4 | 0 | - | 8 | 8 | eight | 2 | 4 | | - | 8 | 8 | eight | 2 | 4 | | 0 - | 8 | 8 | eight | 5 | -5 | 1 | -1 - | 8 | 8 | eight | 5 | -5 | 2 | 2 - | 8 | 8 | eight | 5 | -5 | 3 | -3 - | 8 | 8 | eight | 5 | -5 | 2 | 4 - | 8 | 8 | eight | 5 | -5 | 5 | -5 - | 8 | 8 | eight | 5 | -5 | 5 | -5 - | 8 | 8 | eight | 5 | -5 | 0 | - | 8 | 8 | eight | 5 | -5 | | - | 8 | 8 | eight | 5 | -5 | | 0 - | 8 | 8 | eight | 5 | -5 | 1 | -1 - | 8 | 8 | eight | 5 | -5 | 2 | 2 - | 8 | 8 | eight | 5 | -5 | 3 | -3 - | 8 | 8 | eight | 5 | -5 | 2 | 4 - | 8 | 8 | eight | 5 | -5 | 5 | -5 - | 8 | 8 | eight | 5 | -5 | 5 | -5 - | 8 | 8 | eight | 5 | -5 | 0 | - | 8 | 8 | eight | 5 | -5 | | - | 8 | 8 | eight | 5 | -5 | | 0 - | 8 | 8 | eight | 0 | | 1 | -1 - | 8 | 8 | eight | 0 | | 2 | 2 - | 8 | 8 | eight | 0 | | 3 | -3 - | 8 | 8 | eight | 0 | | 2 | 4 - | 8 | 8 | eight | 0 | | 5 | -5 - | 8 | 8 | eight | 0 | | 5 | -5 - | 8 | 8 | eight | 0 | | 0 | - | 8 | 8 | eight | 0 | | | - | 8 | 8 | eight | 0 | | | 0 - | 8 | 8 | eight | | | 1 | -1 - | 8 | 8 | eight | | | 2 | 2 - | 8 | 8 | eight | | | 3 | -3 - | 8 | 8 | eight | | | 2 | 4 - | 8 | 8 | eight | | | 5 | -5 - | 8 | 8 | eight | | | 5 | -5 - | 8 | 8 | eight | | | 0 | - | 8 | 8 | eight | | | | - | 8 | 8 | eight | | | | 0 - | 8 | 8 | eight | | 0 | 1 | -1 - | 8 | 8 | eight | | 0 | 2 | 2 - | 8 | 8 | eight | | 0 | 3 | -3 - | 8 | 8 | eight | | 0 | 2 | 4 - | 8 | 8 | eight | | 0 | 5 | -5 - | 8 | 8 | eight | | 0 | 5 | -5 - | 8 | 8 | eight | | 0 | 0 | - | 8 | 8 | eight | | 0 | | - | 8 | 8 | eight | | 0 | | 0 - | 1 | 4 | one | 1 | -1 | 1 | -1 - | 1 | 4 | one | 1 | -1 | 2 | 2 - | 1 | 4 | one | 1 | -1 | 3 | -3 - | 1 | 4 | one | 1 | -1 | 2 | 4 - | 1 | 4 | one | 1 | -1 | 5 | -5 - | 1 | 4 | one | 1 | -1 | 5 | -5 - | 1 | 4 | one | 1 | -1 | 0 | - | 1 | 4 | one | 1 | -1 | | - | 1 | 4 | one | 1 | -1 | | 0 - | 2 | 3 | two | 1 | -1 | 1 | -1 - | 2 | 3 | two | 1 | -1 | 2 | 2 - | 2 | 3 | two | 1 | -1 | 3 | -3 - | 2 | 3 | two | 1 | -1 | 2 | 4 - | 2 | 3 | two | 1 | -1 | 5 | -5 - | 2 | 3 | two | 1 | -1 | 5 | -5 - | 2 | 3 | two | 1 | -1 | 0 | - | 2 | 3 | two | 1 | -1 | | - | 2 | 3 | two | 1 | -1 | | 0 - | 0 | | zero | 1 | -1 | 1 | -1 - | 0 | | zero | 1 | -1 | 2 | 2 - | 0 | | zero | 1 | -1 | 3 | -3 - | 0 | | zero | 1 | -1 | 2 | 4 - | 0 | | zero | 1 | -1 | 5 | -5 - | 0 | | zero | 1 | -1 | 5 | -5 - | 0 | | zero | 1 | -1 | 0 | - | 0 | | zero | 1 | -1 | | - | 0 | | zero | 1 | -1 | | 0 - | 1 | 4 | one | 2 | 2 | 1 | -1 - | 1 | 4 | one | 2 | 2 | 2 | 2 - | 1 | 4 | one | 2 | 2 | 3 | -3 - | 1 | 4 | one | 2 | 2 | 2 | 4 - | 1 | 4 | one | 2 | 2 | 5 | -5 - | 1 | 4 | one | 2 | 2 | 5 | -5 - | 1 | 4 | one | 2 | 2 | 0 | - | 1 | 4 | one | 2 | 2 | | - | 1 | 4 | one | 2 | 2 | | 0 - | 2 | 3 | two | 2 | 2 | 1 | -1 - | 2 | 3 | two | 2 | 2 | 2 | 2 - | 2 | 3 | two | 2 | 2 | 3 | -3 - | 2 | 3 | two | 2 | 2 | 2 | 4 - | 2 | 3 | two | 2 | 2 | 5 | -5 - | 2 | 3 | two | 2 | 2 | 5 | -5 - | 2 | 3 | two | 2 | 2 | 0 | - | 2 | 3 | two | 2 | 2 | | - | 2 | 3 | two | 2 | 2 | | 0 - | 0 | | zero | 2 | 2 | 1 | -1 - | 0 | | zero | 2 | 2 | 2 | 2 - | 0 | | zero | 2 | 2 | 3 | -3 - | 0 | | zero | 2 | 2 | 2 | 4 - | 0 | | zero | 2 | 2 | 5 | -5 - | 0 | | zero | 2 | 2 | 5 | -5 - | 0 | | zero | 2 | 2 | 0 | - | 0 | | zero | 2 | 2 | | - | 0 | | zero | 2 | 2 | | 0 - | 1 | 4 | one | 3 | -3 | 1 | -1 - | 1 | 4 | one | 3 | -3 | 2 | 2 - | 1 | 4 | one | 3 | -3 | 3 | -3 - | 1 | 4 | one | 3 | -3 | 2 | 4 - | 1 | 4 | one | 3 | -3 | 5 | -5 - | 1 | 4 | one | 3 | -3 | 5 | -5 - | 1 | 4 | one | 3 | -3 | 0 | - | 1 | 4 | one | 3 | -3 | | - | 1 | 4 | one | 3 | -3 | | 0 - | 2 | 3 | two | 3 | -3 | 1 | -1 - | 2 | 3 | two | 3 | -3 | 2 | 2 - | 2 | 3 | two | 3 | -3 | 3 | -3 - | 2 | 3 | two | 3 | -3 | 2 | 4 - | 2 | 3 | two | 3 | -3 | 5 | -5 - | 2 | 3 | two | 3 | -3 | 5 | -5 - | 2 | 3 | two | 3 | -3 | 0 | - | 2 | 3 | two | 3 | -3 | | - | 2 | 3 | two | 3 | -3 | | 0 - | 0 | | zero | 3 | -3 | 1 | -1 - | 0 | | zero | 3 | -3 | 2 | 2 - | 0 | | zero | 3 | -3 | 3 | -3 - | 0 | | zero | 3 | -3 | 2 | 4 - | 0 | | zero | 3 | -3 | 5 | -5 - | 0 | | zero | 3 | -3 | 5 | -5 - | 0 | | zero | 3 | -3 | 0 | - | 0 | | zero | 3 | -3 | | - | 0 | | zero | 3 | -3 | | 0 - | 1 | 4 | one | 2 | 4 | 1 | -1 - | 1 | 4 | one | 2 | 4 | 2 | 2 - | 1 | 4 | one | 2 | 4 | 3 | -3 - | 1 | 4 | one | 2 | 4 | 2 | 4 - | 1 | 4 | one | 2 | 4 | 5 | -5 - | 1 | 4 | one | 2 | 4 | 5 | -5 - | 1 | 4 | one | 2 | 4 | 0 | - | 1 | 4 | one | 2 | 4 | | - | 1 | 4 | one | 2 | 4 | | 0 - | 2 | 3 | two | 2 | 4 | 1 | -1 - | 2 | 3 | two | 2 | 4 | 2 | 2 - | 2 | 3 | two | 2 | 4 | 3 | -3 - | 2 | 3 | two | 2 | 4 | 2 | 4 - | 2 | 3 | two | 2 | 4 | 5 | -5 - | 2 | 3 | two | 2 | 4 | 5 | -5 - | 2 | 3 | two | 2 | 4 | 0 | - | 2 | 3 | two | 2 | 4 | | - | 2 | 3 | two | 2 | 4 | | 0 - | 0 | | zero | 2 | 4 | 1 | -1 - | 0 | | zero | 2 | 4 | 2 | 2 - | 0 | | zero | 2 | 4 | 3 | -3 - | 0 | | zero | 2 | 4 | 2 | 4 - | 0 | | zero | 2 | 4 | 5 | -5 - | 0 | | zero | 2 | 4 | 5 | -5 - | 0 | | zero | 2 | 4 | 0 | - | 0 | | zero | 2 | 4 | | - | 0 | | zero | 2 | 4 | | 0 - | 1 | 4 | one | 5 | -5 | 1 | -1 - | 1 | 4 | one | 5 | -5 | 2 | 2 - | 1 | 4 | one | 5 | -5 | 3 | -3 - | 1 | 4 | one | 5 | -5 | 2 | 4 - | 1 | 4 | one | 5 | -5 | 5 | -5 - | 1 | 4 | one | 5 | -5 | 5 | -5 - | 1 | 4 | one | 5 | -5 | 0 | - | 1 | 4 | one | 5 | -5 | | - | 1 | 4 | one | 5 | -5 | | 0 - | 2 | 3 | two | 5 | -5 | 1 | -1 - | 2 | 3 | two | 5 | -5 | 2 | 2 - | 2 | 3 | two | 5 | -5 | 3 | -3 - | 2 | 3 | two | 5 | -5 | 2 | 4 - | 2 | 3 | two | 5 | -5 | 5 | -5 - | 2 | 3 | two | 5 | -5 | 5 | -5 - | 2 | 3 | two | 5 | -5 | 0 | - | 2 | 3 | two | 5 | -5 | | - | 2 | 3 | two | 5 | -5 | | 0 - | 0 | | zero | 5 | -5 | 1 | -1 - | 0 | | zero | 5 | -5 | 2 | 2 - | 0 | | zero | 5 | -5 | 3 | -3 - | 0 | | zero | 5 | -5 | 2 | 4 - | 0 | | zero | 5 | -5 | 5 | -5 - | 0 | | zero | 5 | -5 | 5 | -5 - | 0 | | zero | 5 | -5 | 0 | - | 0 | | zero | 5 | -5 | | - | 0 | | zero | 5 | -5 | | 0 - | 1 | 4 | one | 5 | -5 | 1 | -1 - | 1 | 4 | one | 5 | -5 | 2 | 2 - | 1 | 4 | one | 5 | -5 | 3 | -3 - | 1 | 4 | one | 5 | -5 | 2 | 4 - | 1 | 4 | one | 5 | -5 | 5 | -5 - | 1 | 4 | one | 5 | -5 | 5 | -5 - | 1 | 4 | one | 5 | -5 | 0 | - | 1 | 4 | one | 5 | -5 | | - | 1 | 4 | one | 5 | -5 | | 0 - | 2 | 3 | two | 5 | -5 | 1 | -1 - | 2 | 3 | two | 5 | -5 | 2 | 2 - | 2 | 3 | two | 5 | -5 | 3 | -3 - | 2 | 3 | two | 5 | -5 | 2 | 4 - | 2 | 3 | two | 5 | -5 | 5 | -5 - | 2 | 3 | two | 5 | -5 | 5 | -5 - | 2 | 3 | two | 5 | -5 | 0 | - | 2 | 3 | two | 5 | -5 | | - | 2 | 3 | two | 5 | -5 | | 0 - | 0 | | zero | 5 | -5 | 1 | -1 - | 0 | | zero | 5 | -5 | 2 | 2 - | 0 | | zero | 5 | -5 | 3 | -3 - | 0 | | zero | 5 | -5 | 2 | 4 - | 0 | | zero | 5 | -5 | 5 | -5 - | 0 | | zero | 5 | -5 | 5 | -5 - | 0 | | zero | 5 | -5 | 0 | - | 0 | | zero | 5 | -5 | | - | 0 | | zero | 5 | -5 | | 0 - | 1 | 4 | one | 0 | | 1 | -1 - | 1 | 4 | one | 0 | | 2 | 2 - | 1 | 4 | one | 0 | | 3 | -3 - | 1 | 4 | one | 0 | | 2 | 4 - | 1 | 4 | one | 0 | | 5 | -5 - | 1 | 4 | one | 0 | | 5 | -5 - | 1 | 4 | one | 0 | | 0 | - | 1 | 4 | one | 0 | | | - | 1 | 4 | one | 0 | | | 0 - | 2 | 3 | two | 0 | | 1 | -1 - | 2 | 3 | two | 0 | | 2 | 2 - | 2 | 3 | two | 0 | | 3 | -3 - | 2 | 3 | two | 0 | | 2 | 4 - | 2 | 3 | two | 0 | | 5 | -5 - | 2 | 3 | two | 0 | | 5 | -5 - | 2 | 3 | two | 0 | | 0 | - | 2 | 3 | two | 0 | | | - | 2 | 3 | two | 0 | | | 0 - | 0 | | zero | 0 | | 1 | -1 - | 0 | | zero | 0 | | 2 | 2 - | 0 | | zero | 0 | | 3 | -3 - | 0 | | zero | 0 | | 2 | 4 - | 0 | | zero | 0 | | 5 | -5 - | 0 | | zero | 0 | | 5 | -5 + | | | 4 + | | 0 | 4 + | 2 | 3 | -5 + | 3 | 2 | -5 + | 4 | 1 | -5 + | 7 | 7 | -5 + | 8 | 8 | -5 + | | | -5 + | | 0 | -5 + | 2 | 3 | -5 + | 3 | 2 | -5 + | 4 | 1 | -5 + | 7 | 7 | -5 + | 8 | 8 | -5 + | | | -5 + | | 0 | -5 + | 2 | 3 | + | 3 | 2 | + | 4 | 1 | + | 7 | 7 | + | 8 | 8 | + | | | + | | 0 | + | 2 | 3 | + | 3 | 2 | + | 4 | 1 | + | 7 | 7 | + | 8 | 8 | + | | | + | | 0 | + | 2 | 3 | 0 + | 3 | 2 | 0 + | 4 | 1 | 0 + | 7 | 7 | 0 + | 8 | 8 | 0 + | | | 0 + | | 0 | 0 +(99 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL CROSS JOIN J2_TBL a CROSS JOIN J2_TBL b; + xxx | i | j | t | i | k | i | k +-----+---+---+-------+---+----+---+---- + | 2 | 3 | two | 1 | -1 | 1 | -1 + | 2 | 3 | two | 1 | -1 | 2 | 2 + | 2 | 3 | two | 1 | -1 | 3 | -3 + | 2 | 3 | two | 1 | -1 | 2 | 4 + | 2 | 3 | two | 1 | -1 | 5 | -5 + | 2 | 3 | two | 1 | -1 | 5 | -5 + | 2 | 3 | two | 1 | -1 | 0 | + | 2 | 3 | two | 1 | -1 | | + | 2 | 3 | two | 1 | -1 | | 0 | 3 | 2 | three | 1 | -1 | 1 | -1 | 3 | 2 | three | 1 | -1 | 2 | 2 | 3 | 2 | three | 1 | -1 | 3 | -3 @@ -760,24 +506,6 @@ SELECT '' AS "xxx", * | 4 | 1 | four | 1 | -1 | 0 | | 4 | 1 | four | 1 | -1 | | | 4 | 1 | four | 1 | -1 | | 0 - | 5 | 0 | five | 1 | -1 | 1 | -1 - | 5 | 0 | five | 1 | -1 | 2 | 2 - | 5 | 0 | five | 1 | -1 | 3 | -3 - | 5 | 0 | five | 1 | -1 | 2 | 4 - | 5 | 0 | five | 1 | -1 | 5 | -5 - | 5 | 0 | five | 1 | -1 | 5 | -5 - | 5 | 0 | five | 1 | -1 | 0 | - | 5 | 0 | five | 1 | -1 | | - | 5 | 0 | five | 1 | -1 | | 0 - | 6 | 6 | six | 1 | -1 | 1 | -1 - | 6 | 6 | six | 1 | -1 | 2 | 2 - | 6 | 6 | six | 1 | -1 | 3 | -3 - | 6 | 6 | six | 1 | -1 | 2 | 4 - | 6 | 6 | six | 1 | -1 | 5 | -5 - | 6 | 6 | six | 1 | -1 | 5 | -5 - | 6 | 6 | six | 1 | -1 | 0 | - | 6 | 6 | six | 1 | -1 | | - | 6 | 6 | six | 1 | -1 | | 0 | 7 | 7 | seven | 1 | -1 | 1 | -1 | 7 | 7 | seven | 1 | -1 | 2 | 2 | 7 | 7 | seven | 1 | -1 | 3 | -3 @@ -787,6 +515,15 @@ SELECT '' AS "xxx", * | 7 | 7 | seven | 1 | -1 | 0 | | 7 | 7 | seven | 1 | -1 | | | 7 | 7 | seven | 1 | -1 | | 0 + | 8 | 8 | eight | 1 | -1 | 1 | -1 + | 8 | 8 | eight | 1 | -1 | 2 | 2 + | 8 | 8 | eight | 1 | -1 | 3 | -3 + | 8 | 8 | eight | 1 | -1 | 2 | 4 + | 8 | 8 | eight | 1 | -1 | 5 | -5 + | 8 | 8 | eight | 1 | -1 | 5 | -5 + | 8 | 8 | eight | 1 | -1 | 0 | + | 8 | 8 | eight | 1 | -1 | | + | 8 | 8 | eight | 1 | -1 | | 0 | | | null | 1 | -1 | 1 | -1 | | | null | 1 | -1 | 2 | 2 | | | null | 1 | -1 | 3 | -3 @@ -805,6 +542,15 @@ SELECT '' AS "xxx", * | | 0 | zero | 1 | -1 | 0 | | | 0 | zero | 1 | -1 | | | | 0 | zero | 1 | -1 | | 0 + | 2 | 3 | two | 2 | 2 | 1 | -1 + | 2 | 3 | two | 2 | 2 | 2 | 2 + | 2 | 3 | two | 2 | 2 | 3 | -3 + | 2 | 3 | two | 2 | 2 | 2 | 4 + | 2 | 3 | two | 2 | 2 | 5 | -5 + | 2 | 3 | two | 2 | 2 | 5 | -5 + | 2 | 3 | two | 2 | 2 | 0 | + | 2 | 3 | two | 2 | 2 | | + | 2 | 3 | two | 2 | 2 | | 0 | 3 | 2 | three | 2 | 2 | 1 | -1 | 3 | 2 | three | 2 | 2 | 2 | 2 | 3 | 2 | three | 2 | 2 | 3 | -3 @@ -823,24 +569,6 @@ SELECT '' AS "xxx", * | 4 | 1 | four | 2 | 2 | 0 | | 4 | 1 | four | 2 | 2 | | | 4 | 1 | four | 2 | 2 | | 0 - | 5 | 0 | five | 2 | 2 | 1 | -1 - | 5 | 0 | five | 2 | 2 | 2 | 2 - | 5 | 0 | five | 2 | 2 | 3 | -3 - | 5 | 0 | five | 2 | 2 | 2 | 4 - | 5 | 0 | five | 2 | 2 | 5 | -5 - | 5 | 0 | five | 2 | 2 | 5 | -5 - | 5 | 0 | five | 2 | 2 | 0 | - | 5 | 0 | five | 2 | 2 | | - | 5 | 0 | five | 2 | 2 | | 0 - | 6 | 6 | six | 2 | 2 | 1 | -1 - | 6 | 6 | six | 2 | 2 | 2 | 2 - | 6 | 6 | six | 2 | 2 | 3 | -3 - | 6 | 6 | six | 2 | 2 | 2 | 4 - | 6 | 6 | six | 2 | 2 | 5 | -5 - | 6 | 6 | six | 2 | 2 | 5 | -5 - | 6 | 6 | six | 2 | 2 | 0 | - | 6 | 6 | six | 2 | 2 | | - | 6 | 6 | six | 2 | 2 | | 0 | 7 | 7 | seven | 2 | 2 | 1 | -1 | 7 | 7 | seven | 2 | 2 | 2 | 2 | 7 | 7 | seven | 2 | 2 | 3 | -3 @@ -850,6 +578,15 @@ SELECT '' AS "xxx", * | 7 | 7 | seven | 2 | 2 | 0 | | 7 | 7 | seven | 2 | 2 | | | 7 | 7 | seven | 2 | 2 | | 0 + | 8 | 8 | eight | 2 | 2 | 1 | -1 + | 8 | 8 | eight | 2 | 2 | 2 | 2 + | 8 | 8 | eight | 2 | 2 | 3 | -3 + | 8 | 8 | eight | 2 | 2 | 2 | 4 + | 8 | 8 | eight | 2 | 2 | 5 | -5 + | 8 | 8 | eight | 2 | 2 | 5 | -5 + | 8 | 8 | eight | 2 | 2 | 0 | + | 8 | 8 | eight | 2 | 2 | | + | 8 | 8 | eight | 2 | 2 | | 0 | | | null | 2 | 2 | 1 | -1 | | | null | 2 | 2 | 2 | 2 | | | null | 2 | 2 | 3 | -3 @@ -868,6 +605,15 @@ SELECT '' AS "xxx", * | | 0 | zero | 2 | 2 | 0 | | | 0 | zero | 2 | 2 | | | | 0 | zero | 2 | 2 | | 0 + | 2 | 3 | two | 3 | -3 | 1 | -1 + | 2 | 3 | two | 3 | -3 | 2 | 2 + | 2 | 3 | two | 3 | -3 | 3 | -3 + | 2 | 3 | two | 3 | -3 | 2 | 4 + | 2 | 3 | two | 3 | -3 | 5 | -5 + | 2 | 3 | two | 3 | -3 | 5 | -5 + | 2 | 3 | two | 3 | -3 | 0 | + | 2 | 3 | two | 3 | -3 | | + | 2 | 3 | two | 3 | -3 | | 0 | 3 | 2 | three | 3 | -3 | 1 | -1 | 3 | 2 | three | 3 | -3 | 2 | 2 | 3 | 2 | three | 3 | -3 | 3 | -3 @@ -886,6 +632,66 @@ SELECT '' AS "xxx", * | 4 | 1 | four | 3 | -3 | 0 | | 4 | 1 | four | 3 | -3 | | | 4 | 1 | four | 3 | -3 | | 0 + | 7 | 7 | seven | 3 | -3 | 1 | -1 + | 7 | 7 | seven | 3 | -3 | 2 | 2 + | 7 | 7 | seven | 3 | -3 | 3 | -3 + | 7 | 7 | seven | 3 | -3 | 2 | 4 + | 7 | 7 | seven | 3 | -3 | 5 | -5 + | 7 | 7 | seven | 3 | -3 | 5 | -5 + | 7 | 7 | seven | 3 | -3 | 0 | + | 7 | 7 | seven | 3 | -3 | | + | 7 | 7 | seven | 3 | -3 | | 0 + | 8 | 8 | eight | 3 | -3 | 1 | -1 + | 8 | 8 | eight | 3 | -3 | 2 | 2 + | 8 | 8 | eight | 3 | -3 | 3 | -3 + | 8 | 8 | eight | 3 | -3 | 2 | 4 + | 8 | 8 | eight | 3 | -3 | 5 | -5 + | 8 | 8 | eight | 3 | -3 | 5 | -5 + | 8 | 8 | eight | 3 | -3 | 0 | + | 8 | 8 | eight | 3 | -3 | | + | 8 | 8 | eight | 3 | -3 | | 0 + | | | null | 3 | -3 | 1 | -1 + | | | null | 3 | -3 | 2 | 2 + | | | null | 3 | -3 | 3 | -3 + | | | null | 3 | -3 | 2 | 4 + | | | null | 3 | -3 | 5 | -5 + | | | null | 3 | -3 | 5 | -5 + | 5 | 0 | five | 1 | -1 | 1 | -1 + | 5 | 0 | five | 1 | -1 | 2 | 2 + | 5 | 0 | five | 1 | -1 | 3 | -3 + | 5 | 0 | five | 1 | -1 | 2 | 4 + | 5 | 0 | five | 1 | -1 | 5 | -5 + | 5 | 0 | five | 1 | -1 | 5 | -5 + | 5 | 0 | five | 1 | -1 | 0 | + | 5 | 0 | five | 1 | -1 | | + | 5 | 0 | five | 1 | -1 | | 0 + | 6 | 6 | six | 1 | -1 | 1 | -1 + | 6 | 6 | six | 1 | -1 | 2 | 2 + | 6 | 6 | six | 1 | -1 | 3 | -3 + | 6 | 6 | six | 1 | -1 | 2 | 4 + | 6 | 6 | six | 1 | -1 | 5 | -5 + | 6 | 6 | six | 1 | -1 | 5 | -5 + | 6 | 6 | six | 1 | -1 | 0 | + | 6 | 6 | six | 1 | -1 | | + | 6 | 6 | six | 1 | -1 | | 0 + | 5 | 0 | five | 2 | 2 | 1 | -1 + | 5 | 0 | five | 2 | 2 | 2 | 2 + | 5 | 0 | five | 2 | 2 | 3 | -3 + | 5 | 0 | five | 2 | 2 | 2 | 4 + | 5 | 0 | five | 2 | 2 | 5 | -5 + | 5 | 0 | five | 2 | 2 | 5 | -5 + | 5 | 0 | five | 2 | 2 | 0 | + | 5 | 0 | five | 2 | 2 | | + | 5 | 0 | five | 2 | 2 | | 0 + | 6 | 6 | six | 2 | 2 | 1 | -1 + | 6 | 6 | six | 2 | 2 | 2 | 2 + | 6 | 6 | six | 2 | 2 | 3 | -3 + | 6 | 6 | six | 2 | 2 | 2 | 4 + | 6 | 6 | six | 2 | 2 | 5 | -5 + | 6 | 6 | six | 2 | 2 | 5 | -5 + | 6 | 6 | six | 2 | 2 | 0 | + | 6 | 6 | six | 2 | 2 | | + | 6 | 6 | six | 2 | 2 | | 0 | 5 | 0 | five | 3 | -3 | 1 | -1 | 5 | 0 | five | 3 | -3 | 2 | 2 | 5 | 0 | five | 3 | -3 | 3 | -3 @@ -904,21 +710,114 @@ SELECT '' AS "xxx", * | 6 | 6 | six | 3 | -3 | 0 | | 6 | 6 | six | 3 | -3 | | | 6 | 6 | six | 3 | -3 | | 0 - | 7 | 7 | seven | 3 | -3 | 1 | -1 - | 7 | 7 | seven | 3 | -3 | 2 | 2 - | 7 | 7 | seven | 3 | -3 | 3 | -3 - | 7 | 7 | seven | 3 | -3 | 2 | 4 - | 7 | 7 | seven | 3 | -3 | 5 | -5 - | 7 | 7 | seven | 3 | -3 | 5 | -5 - | 7 | 7 | seven | 3 | -3 | 0 | - | 7 | 7 | seven | 3 | -3 | | - | 7 | 7 | seven | 3 | -3 | | 0 - | | | null | 3 | -3 | 1 | -1 - | | | null | 3 | -3 | 2 | 2 - | | | null | 3 | -3 | 3 | -3 - | | | null | 3 | -3 | 2 | 4 - | | | null | 3 | -3 | 5 | -5 - | | | null | 3 | -3 | 5 | -5 + | 5 | 0 | five | 2 | 4 | 1 | -1 + | 5 | 0 | five | 2 | 4 | 2 | 2 + | 5 | 0 | five | 2 | 4 | 3 | -3 + | 5 | 0 | five | 2 | 4 | 2 | 4 + | 5 | 0 | five | 2 | 4 | 5 | -5 + | 5 | 0 | five | 2 | 4 | 5 | -5 + | 5 | 0 | five | 2 | 4 | 0 | + | 5 | 0 | five | 2 | 4 | | + | 5 | 0 | five | 2 | 4 | | 0 + | 6 | 6 | six | 2 | 4 | 1 | -1 + | 6 | 6 | six | 2 | 4 | 2 | 2 + | 6 | 6 | six | 2 | 4 | 3 | -3 + | 6 | 6 | six | 2 | 4 | 2 | 4 + | 6 | 6 | six | 2 | 4 | 5 | -5 + | 6 | 6 | six | 2 | 4 | 5 | -5 + | 6 | 6 | six | 2 | 4 | 0 | + | 6 | 6 | six | 2 | 4 | | + | 6 | 6 | six | 2 | 4 | | 0 + | 5 | 0 | five | 5 | -5 | 1 | -1 + | 5 | 0 | five | 5 | -5 | 2 | 2 + | 5 | 0 | five | 5 | -5 | 3 | -3 + | 5 | 0 | five | 5 | -5 | 2 | 4 + | 5 | 0 | five | 5 | -5 | 5 | -5 + | 5 | 0 | five | 5 | -5 | 5 | -5 + | 5 | 0 | five | 5 | -5 | 0 | + | 5 | 0 | five | 5 | -5 | | + | 5 | 0 | five | 5 | -5 | | 0 + | 6 | 6 | six | 5 | -5 | 1 | -1 + | 6 | 6 | six | 5 | -5 | 2 | 2 + | 6 | 6 | six | 5 | -5 | 3 | -3 + | 6 | 6 | six | 5 | -5 | 2 | 4 + | 6 | 6 | six | 5 | -5 | 5 | -5 + | 6 | 6 | six | 5 | -5 | 5 | -5 + | 6 | 6 | six | 5 | -5 | 0 | + | 6 | 6 | six | 5 | -5 | | + | 6 | 6 | six | 5 | -5 | | 0 + | 5 | 0 | five | 5 | -5 | 1 | -1 + | 5 | 0 | five | 5 | -5 | 2 | 2 + | 5 | 0 | five | 5 | -5 | 3 | -3 + | 5 | 0 | five | 5 | -5 | 2 | 4 + | 5 | 0 | five | 5 | -5 | 5 | -5 + | 5 | 0 | five | 5 | -5 | 5 | -5 + | 5 | 0 | five | 5 | -5 | 0 | + | 5 | 0 | five | 5 | -5 | | + | 5 | 0 | five | 5 | -5 | | 0 + | 6 | 6 | six | 5 | -5 | 1 | -1 + | 6 | 6 | six | 5 | -5 | 2 | 2 + | 6 | 6 | six | 5 | -5 | 3 | -3 + | 6 | 6 | six | 5 | -5 | 2 | 4 + | 6 | 6 | six | 5 | -5 | 5 | -5 + | 6 | 6 | six | 5 | -5 | 5 | -5 + | 6 | 6 | six | 5 | -5 | 0 | + | 6 | 6 | six | 5 | -5 | | + | 6 | 6 | six | 5 | -5 | | 0 + | 5 | 0 | five | 0 | | 1 | -1 + | 5 | 0 | five | 0 | | 2 | 2 + | 5 | 0 | five | 0 | | 3 | -3 + | 5 | 0 | five | 0 | | 2 | 4 + | 5 | 0 | five | 0 | | 5 | -5 + | 5 | 0 | five | 0 | | 5 | -5 + | 5 | 0 | five | 0 | | 0 | + | 5 | 0 | five | 0 | | | + | 5 | 0 | five | 0 | | | 0 + | 6 | 6 | six | 0 | | 1 | -1 + | 6 | 6 | six | 0 | | 2 | 2 + | 6 | 6 | six | 0 | | 3 | -3 + | 6 | 6 | six | 0 | | 2 | 4 + | 6 | 6 | six | 0 | | 5 | -5 + | 6 | 6 | six | 0 | | 5 | -5 + | 6 | 6 | six | 0 | | 0 | + | 6 | 6 | six | 0 | | | + | 6 | 6 | six | 0 | | | 0 + | 5 | 0 | five | | | 1 | -1 + | 5 | 0 | five | | | 2 | 2 + | 5 | 0 | five | | | 3 | -3 + | 5 | 0 | five | | | 2 | 4 + | 5 | 0 | five | | | 5 | -5 + | 5 | 0 | five | | | 5 | -5 + | 5 | 0 | five | | | 0 | + | 5 | 0 | five | | | | + | 5 | 0 | five | | | | 0 + | 6 | 6 | six | | | 1 | -1 + | 6 | 6 | six | | | 2 | 2 + | 6 | 6 | six | | | 3 | -3 + | 6 | 6 | six | | | 2 | 4 + | 6 | 6 | six | | | 5 | -5 + | 6 | 6 | six | | | 5 | -5 + | 6 | 6 | six | | | 0 | + | 6 | 6 | six | | | | + | 6 | 6 | six | | | | 0 + | 5 | 0 | five | | 0 | 1 | -1 + | 5 | 0 | five | | 0 | 2 | 2 + | 5 | 0 | five | | 0 | 3 | -3 + | 5 | 0 | five | | 0 | 2 | 4 + | 5 | 0 | five | | 0 | 5 | -5 + | 5 | 0 | five | | 0 | 5 | -5 + | 5 | 0 | five | | 0 | 0 | + | 5 | 0 | five | | 0 | | + | 5 | 0 | five | | 0 | | 0 + | 6 | 6 | six | | 0 | 1 | -1 + | 6 | 6 | six | | 0 | 2 | 2 + | 6 | 6 | six | | 0 | 3 | -3 + | 6 | 6 | six | | 0 | 2 | 4 + | 6 | 6 | six | | 0 | 5 | -5 + | 6 | 6 | six | | 0 | 5 | -5 + | 6 | 6 | six | | 0 | 0 | + | 6 | 6 | six | | 0 | | + | 6 | 6 | six | | 0 | | 0 | | | null | 3 | -3 | 0 | | | | null | 3 | -3 | | | | | null | 3 | -3 | | 0 @@ -931,6 +830,15 @@ SELECT '' AS "xxx", * | | 0 | zero | 3 | -3 | 0 | | | 0 | zero | 3 | -3 | | | | 0 | zero | 3 | -3 | | 0 + | 2 | 3 | two | 2 | 4 | 1 | -1 + | 2 | 3 | two | 2 | 4 | 2 | 2 + | 2 | 3 | two | 2 | 4 | 3 | -3 + | 2 | 3 | two | 2 | 4 | 2 | 4 + | 2 | 3 | two | 2 | 4 | 5 | -5 + | 2 | 3 | two | 2 | 4 | 5 | -5 + | 2 | 3 | two | 2 | 4 | 0 | + | 2 | 3 | two | 2 | 4 | | + | 2 | 3 | two | 2 | 4 | | 0 | 3 | 2 | three | 2 | 4 | 1 | -1 | 3 | 2 | three | 2 | 4 | 2 | 2 | 3 | 2 | three | 2 | 4 | 3 | -3 @@ -949,24 +857,6 @@ SELECT '' AS "xxx", * | 4 | 1 | four | 2 | 4 | 0 | | 4 | 1 | four | 2 | 4 | | | 4 | 1 | four | 2 | 4 | | 0 - | 5 | 0 | five | 2 | 4 | 1 | -1 - | 5 | 0 | five | 2 | 4 | 2 | 2 - | 5 | 0 | five | 2 | 4 | 3 | -3 - | 5 | 0 | five | 2 | 4 | 2 | 4 - | 5 | 0 | five | 2 | 4 | 5 | -5 - | 5 | 0 | five | 2 | 4 | 5 | -5 - | 5 | 0 | five | 2 | 4 | 0 | - | 5 | 0 | five | 2 | 4 | | - | 5 | 0 | five | 2 | 4 | | 0 - | 6 | 6 | six | 2 | 4 | 1 | -1 - | 6 | 6 | six | 2 | 4 | 2 | 2 - | 6 | 6 | six | 2 | 4 | 3 | -3 - | 6 | 6 | six | 2 | 4 | 2 | 4 - | 6 | 6 | six | 2 | 4 | 5 | -5 - | 6 | 6 | six | 2 | 4 | 5 | -5 - | 6 | 6 | six | 2 | 4 | 0 | - | 6 | 6 | six | 2 | 4 | | - | 6 | 6 | six | 2 | 4 | | 0 | 7 | 7 | seven | 2 | 4 | 1 | -1 | 7 | 7 | seven | 2 | 4 | 2 | 2 | 7 | 7 | seven | 2 | 4 | 3 | -3 @@ -976,6 +866,15 @@ SELECT '' AS "xxx", * | 7 | 7 | seven | 2 | 4 | 0 | | 7 | 7 | seven | 2 | 4 | | | 7 | 7 | seven | 2 | 4 | | 0 + | 8 | 8 | eight | 2 | 4 | 1 | -1 + | 8 | 8 | eight | 2 | 4 | 2 | 2 + | 8 | 8 | eight | 2 | 4 | 3 | -3 + | 8 | 8 | eight | 2 | 4 | 2 | 4 + | 8 | 8 | eight | 2 | 4 | 5 | -5 + | 8 | 8 | eight | 2 | 4 | 5 | -5 + | 8 | 8 | eight | 2 | 4 | 0 | + | 8 | 8 | eight | 2 | 4 | | + | 8 | 8 | eight | 2 | 4 | | 0 | | | null | 2 | 4 | 1 | -1 | | | null | 2 | 4 | 2 | 2 | | | null | 2 | 4 | 3 | -3 @@ -994,6 +893,15 @@ SELECT '' AS "xxx", * | | 0 | zero | 2 | 4 | 0 | | | 0 | zero | 2 | 4 | | | | 0 | zero | 2 | 4 | | 0 + | 2 | 3 | two | 5 | -5 | 1 | -1 + | 2 | 3 | two | 5 | -5 | 2 | 2 + | 2 | 3 | two | 5 | -5 | 3 | -3 + | 2 | 3 | two | 5 | -5 | 2 | 4 + | 2 | 3 | two | 5 | -5 | 5 | -5 + | 2 | 3 | two | 5 | -5 | 5 | -5 + | 2 | 3 | two | 5 | -5 | 0 | + | 2 | 3 | two | 5 | -5 | | + | 2 | 3 | two | 5 | -5 | | 0 | 3 | 2 | three | 5 | -5 | 1 | -1 | 3 | 2 | three | 5 | -5 | 2 | 2 | 3 | 2 | three | 5 | -5 | 3 | -3 @@ -1012,24 +920,6 @@ SELECT '' AS "xxx", * | 4 | 1 | four | 5 | -5 | 0 | | 4 | 1 | four | 5 | -5 | | | 4 | 1 | four | 5 | -5 | | 0 - | 5 | 0 | five | 5 | -5 | 1 | -1 - | 5 | 0 | five | 5 | -5 | 2 | 2 - | 5 | 0 | five | 5 | -5 | 3 | -3 - | 5 | 0 | five | 5 | -5 | 2 | 4 - | 5 | 0 | five | 5 | -5 | 5 | -5 - | 5 | 0 | five | 5 | -5 | 5 | -5 - | 5 | 0 | five | 5 | -5 | 0 | - | 5 | 0 | five | 5 | -5 | | - | 5 | 0 | five | 5 | -5 | | 0 - | 6 | 6 | six | 5 | -5 | 1 | -1 - | 6 | 6 | six | 5 | -5 | 2 | 2 - | 6 | 6 | six | 5 | -5 | 3 | -3 - | 6 | 6 | six | 5 | -5 | 2 | 4 - | 6 | 6 | six | 5 | -5 | 5 | -5 - | 6 | 6 | six | 5 | -5 | 5 | -5 - | 6 | 6 | six | 5 | -5 | 0 | - | 6 | 6 | six | 5 | -5 | | - | 6 | 6 | six | 5 | -5 | | 0 | 7 | 7 | seven | 5 | -5 | 1 | -1 | 7 | 7 | seven | 5 | -5 | 2 | 2 | 7 | 7 | seven | 5 | -5 | 3 | -3 @@ -1039,6 +929,15 @@ SELECT '' AS "xxx", * | 7 | 7 | seven | 5 | -5 | 0 | | 7 | 7 | seven | 5 | -5 | | | 7 | 7 | seven | 5 | -5 | | 0 + | 8 | 8 | eight | 5 | -5 | 1 | -1 + | 8 | 8 | eight | 5 | -5 | 2 | 2 + | 8 | 8 | eight | 5 | -5 | 3 | -3 + | 8 | 8 | eight | 5 | -5 | 2 | 4 + | 8 | 8 | eight | 5 | -5 | 5 | -5 + | 8 | 8 | eight | 5 | -5 | 5 | -5 + | 8 | 8 | eight | 5 | -5 | 0 | + | 8 | 8 | eight | 5 | -5 | | + | 8 | 8 | eight | 5 | -5 | | 0 | | | null | 5 | -5 | 1 | -1 | | | null | 5 | -5 | 2 | 2 | | | null | 5 | -5 | 3 | -3 @@ -1057,6 +956,15 @@ SELECT '' AS "xxx", * | | 0 | zero | 5 | -5 | 0 | | | 0 | zero | 5 | -5 | | | | 0 | zero | 5 | -5 | | 0 + | 2 | 3 | two | 5 | -5 | 1 | -1 + | 2 | 3 | two | 5 | -5 | 2 | 2 + | 2 | 3 | two | 5 | -5 | 3 | -3 + | 2 | 3 | two | 5 | -5 | 2 | 4 + | 2 | 3 | two | 5 | -5 | 5 | -5 + | 2 | 3 | two | 5 | -5 | 5 | -5 + | 2 | 3 | two | 5 | -5 | 0 | + | 2 | 3 | two | 5 | -5 | | + | 2 | 3 | two | 5 | -5 | | 0 | 3 | 2 | three | 5 | -5 | 1 | -1 | 3 | 2 | three | 5 | -5 | 2 | 2 | 3 | 2 | three | 5 | -5 | 3 | -3 @@ -1075,24 +983,6 @@ SELECT '' AS "xxx", * | 4 | 1 | four | 5 | -5 | 0 | | 4 | 1 | four | 5 | -5 | | | 4 | 1 | four | 5 | -5 | | 0 - | 5 | 0 | five | 5 | -5 | 1 | -1 - | 5 | 0 | five | 5 | -5 | 2 | 2 - | 5 | 0 | five | 5 | -5 | 3 | -3 - | 5 | 0 | five | 5 | -5 | 2 | 4 - | 5 | 0 | five | 5 | -5 | 5 | -5 - | 5 | 0 | five | 5 | -5 | 5 | -5 - | 5 | 0 | five | 5 | -5 | 0 | - | 5 | 0 | five | 5 | -5 | | - | 5 | 0 | five | 5 | -5 | | 0 - | 6 | 6 | six | 5 | -5 | 1 | -1 - | 6 | 6 | six | 5 | -5 | 2 | 2 - | 6 | 6 | six | 5 | -5 | 3 | -3 - | 6 | 6 | six | 5 | -5 | 2 | 4 - | 6 | 6 | six | 5 | -5 | 5 | -5 - | 6 | 6 | six | 5 | -5 | 5 | -5 - | 6 | 6 | six | 5 | -5 | 0 | - | 6 | 6 | six | 5 | -5 | | - | 6 | 6 | six | 5 | -5 | | 0 | 7 | 7 | seven | 5 | -5 | 1 | -1 | 7 | 7 | seven | 5 | -5 | 2 | 2 | 7 | 7 | seven | 5 | -5 | 3 | -3 @@ -1102,6 +992,15 @@ SELECT '' AS "xxx", * | 7 | 7 | seven | 5 | -5 | 0 | | 7 | 7 | seven | 5 | -5 | | | 7 | 7 | seven | 5 | -5 | | 0 + | 8 | 8 | eight | 5 | -5 | 1 | -1 + | 8 | 8 | eight | 5 | -5 | 2 | 2 + | 8 | 8 | eight | 5 | -5 | 3 | -3 + | 8 | 8 | eight | 5 | -5 | 2 | 4 + | 8 | 8 | eight | 5 | -5 | 5 | -5 + | 8 | 8 | eight | 5 | -5 | 5 | -5 + | 8 | 8 | eight | 5 | -5 | 0 | + | 8 | 8 | eight | 5 | -5 | | + | 8 | 8 | eight | 5 | -5 | | 0 | | | null | 5 | -5 | 1 | -1 | | | null | 5 | -5 | 2 | 2 | | | null | 5 | -5 | 3 | -3 @@ -1120,6 +1019,15 @@ SELECT '' AS "xxx", * | | 0 | zero | 5 | -5 | 0 | | | 0 | zero | 5 | -5 | | | | 0 | zero | 5 | -5 | | 0 + | 2 | 3 | two | 0 | | 1 | -1 + | 2 | 3 | two | 0 | | 2 | 2 + | 2 | 3 | two | 0 | | 3 | -3 + | 2 | 3 | two | 0 | | 2 | 4 + | 2 | 3 | two | 0 | | 5 | -5 + | 2 | 3 | two | 0 | | 5 | -5 + | 2 | 3 | two | 0 | | 0 | + | 2 | 3 | two | 0 | | | + | 2 | 3 | two | 0 | | | 0 | 3 | 2 | three | 0 | | 1 | -1 | 3 | 2 | three | 0 | | 2 | 2 | 3 | 2 | three | 0 | | 3 | -3 @@ -1138,24 +1046,6 @@ SELECT '' AS "xxx", * | 4 | 1 | four | 0 | | 0 | | 4 | 1 | four | 0 | | | | 4 | 1 | four | 0 | | | 0 - | 5 | 0 | five | 0 | | 1 | -1 - | 5 | 0 | five | 0 | | 2 | 2 - | 5 | 0 | five | 0 | | 3 | -3 - | 5 | 0 | five | 0 | | 2 | 4 - | 5 | 0 | five | 0 | | 5 | -5 - | 5 | 0 | five | 0 | | 5 | -5 - | 5 | 0 | five | 0 | | 0 | - | 5 | 0 | five | 0 | | | - | 5 | 0 | five | 0 | | | 0 - | 6 | 6 | six | 0 | | 1 | -1 - | 6 | 6 | six | 0 | | 2 | 2 - | 6 | 6 | six | 0 | | 3 | -3 - | 6 | 6 | six | 0 | | 2 | 4 - | 6 | 6 | six | 0 | | 5 | -5 - | 6 | 6 | six | 0 | | 5 | -5 - | 6 | 6 | six | 0 | | 0 | - | 6 | 6 | six | 0 | | | - | 6 | 6 | six | 0 | | | 0 | 7 | 7 | seven | 0 | | 1 | -1 | 7 | 7 | seven | 0 | | 2 | 2 | 7 | 7 | seven | 0 | | 3 | -3 @@ -1165,6 +1055,15 @@ SELECT '' AS "xxx", * | 7 | 7 | seven | 0 | | 0 | | 7 | 7 | seven | 0 | | | | 7 | 7 | seven | 0 | | | 0 + | 8 | 8 | eight | 0 | | 1 | -1 + | 8 | 8 | eight | 0 | | 2 | 2 + | 8 | 8 | eight | 0 | | 3 | -3 + | 8 | 8 | eight | 0 | | 2 | 4 + | 8 | 8 | eight | 0 | | 5 | -5 + | 8 | 8 | eight | 0 | | 5 | -5 + | 8 | 8 | eight | 0 | | 0 | + | 8 | 8 | eight | 0 | | | + | 8 | 8 | eight | 0 | | | 0 | | | null | 0 | | 1 | -1 | | | null | 0 | | 2 | 2 | | | null | 0 | | 3 | -3 @@ -1183,6 +1082,15 @@ SELECT '' AS "xxx", * | | 0 | zero | 0 | | 0 | | | 0 | zero | 0 | | | | | 0 | zero | 0 | | | 0 + | 2 | 3 | two | | | 1 | -1 + | 2 | 3 | two | | | 2 | 2 + | 2 | 3 | two | | | 3 | -3 + | 2 | 3 | two | | | 2 | 4 + | 2 | 3 | two | | | 5 | -5 + | 2 | 3 | two | | | 5 | -5 + | 2 | 3 | two | | | 0 | + | 2 | 3 | two | | | | + | 2 | 3 | two | | | | 0 | 3 | 2 | three | | | 1 | -1 | 3 | 2 | three | | | 2 | 2 | 3 | 2 | three | | | 3 | -3 @@ -1201,24 +1109,6 @@ SELECT '' AS "xxx", * | 4 | 1 | four | | | 0 | | 4 | 1 | four | | | | | 4 | 1 | four | | | | 0 - | 5 | 0 | five | | | 1 | -1 - | 5 | 0 | five | | | 2 | 2 - | 5 | 0 | five | | | 3 | -3 - | 5 | 0 | five | | | 2 | 4 - | 5 | 0 | five | | | 5 | -5 - | 5 | 0 | five | | | 5 | -5 - | 5 | 0 | five | | | 0 | - | 5 | 0 | five | | | | - | 5 | 0 | five | | | | 0 - | 6 | 6 | six | | | 1 | -1 - | 6 | 6 | six | | | 2 | 2 - | 6 | 6 | six | | | 3 | -3 - | 6 | 6 | six | | | 2 | 4 - | 6 | 6 | six | | | 5 | -5 - | 6 | 6 | six | | | 5 | -5 - | 6 | 6 | six | | | 0 | - | 6 | 6 | six | | | | - | 6 | 6 | six | | | | 0 | 7 | 7 | seven | | | 1 | -1 | 7 | 7 | seven | | | 2 | 2 | 7 | 7 | seven | | | 3 | -3 @@ -1228,6 +1118,15 @@ SELECT '' AS "xxx", * | 7 | 7 | seven | | | 0 | | 7 | 7 | seven | | | | | 7 | 7 | seven | | | | 0 + | 8 | 8 | eight | | | 1 | -1 + | 8 | 8 | eight | | | 2 | 2 + | 8 | 8 | eight | | | 3 | -3 + | 8 | 8 | eight | | | 2 | 4 + | 8 | 8 | eight | | | 5 | -5 + | 8 | 8 | eight | | | 5 | -5 + | 8 | 8 | eight | | | 0 | + | 8 | 8 | eight | | | | + | 8 | 8 | eight | | | | 0 | | | null | | | 1 | -1 | | | null | | | 2 | 2 | | | null | | | 3 | -3 @@ -1246,6 +1145,15 @@ SELECT '' AS "xxx", * | | 0 | zero | | | 0 | | | 0 | zero | | | | | | 0 | zero | | | | 0 + | 2 | 3 | two | | 0 | 1 | -1 + | 2 | 3 | two | | 0 | 2 | 2 + | 2 | 3 | two | | 0 | 3 | -3 + | 2 | 3 | two | | 0 | 2 | 4 + | 2 | 3 | two | | 0 | 5 | -5 + | 2 | 3 | two | | 0 | 5 | -5 + | 2 | 3 | two | | 0 | 0 | + | 2 | 3 | two | | 0 | | + | 2 | 3 | two | | 0 | | 0 | 3 | 2 | three | | 0 | 1 | -1 | 3 | 2 | three | | 0 | 2 | 2 | 3 | 2 | three | | 0 | 3 | -3 @@ -1264,24 +1172,6 @@ SELECT '' AS "xxx", * | 4 | 1 | four | | 0 | 0 | | 4 | 1 | four | | 0 | | | 4 | 1 | four | | 0 | | 0 - | 5 | 0 | five | | 0 | 1 | -1 - | 5 | 0 | five | | 0 | 2 | 2 - | 5 | 0 | five | | 0 | 3 | -3 - | 5 | 0 | five | | 0 | 2 | 4 - | 5 | 0 | five | | 0 | 5 | -5 - | 5 | 0 | five | | 0 | 5 | -5 - | 5 | 0 | five | | 0 | 0 | - | 5 | 0 | five | | 0 | | - | 5 | 0 | five | | 0 | | 0 - | 6 | 6 | six | | 0 | 1 | -1 - | 6 | 6 | six | | 0 | 2 | 2 - | 6 | 6 | six | | 0 | 3 | -3 - | 6 | 6 | six | | 0 | 2 | 4 - | 6 | 6 | six | | 0 | 5 | -5 - | 6 | 6 | six | | 0 | 5 | -5 - | 6 | 6 | six | | 0 | 0 | - | 6 | 6 | six | | 0 | | - | 6 | 6 | six | | 0 | | 0 | 7 | 7 | seven | | 0 | 1 | -1 | 7 | 7 | seven | | 0 | 2 | 2 | 7 | 7 | seven | | 0 | 3 | -3 @@ -1291,6 +1181,15 @@ SELECT '' AS "xxx", * | 7 | 7 | seven | | 0 | 0 | | 7 | 7 | seven | | 0 | | | 7 | 7 | seven | | 0 | | 0 + | 8 | 8 | eight | | 0 | 1 | -1 + | 8 | 8 | eight | | 0 | 2 | 2 + | 8 | 8 | eight | | 0 | 3 | -3 + | 8 | 8 | eight | | 0 | 2 | 4 + | 8 | 8 | eight | | 0 | 5 | -5 + | 8 | 8 | eight | | 0 | 5 | -5 + | 8 | 8 | eight | | 0 | 0 | + | 8 | 8 | eight | | 0 | | + | 8 | 8 | eight | | 0 | | 0 | | | null | | 0 | 1 | -1 | | | null | | 0 | 2 | 2 | | | null | | 0 | 3 | -3 @@ -1309,6 +1208,129 @@ SELECT '' AS "xxx", * | | 0 | zero | | 0 | 0 | | | 0 | zero | | 0 | | | | 0 | zero | | 0 | | 0 + | 1 | 4 | one | 1 | -1 | 1 | -1 + | 1 | 4 | one | 1 | -1 | 2 | 2 + | 1 | 4 | one | 1 | -1 | 3 | -3 + | 1 | 4 | one | 1 | -1 | 2 | 4 + | 1 | 4 | one | 1 | -1 | 5 | -5 + | 1 | 4 | one | 1 | -1 | 5 | -5 + | 1 | 4 | one | 1 | -1 | 0 | + | 1 | 4 | one | 1 | -1 | | + | 1 | 4 | one | 1 | -1 | | 0 + | 0 | | zero | 1 | -1 | 1 | -1 + | 0 | | zero | 1 | -1 | 2 | 2 + | 0 | | zero | 1 | -1 | 3 | -3 + | 0 | | zero | 1 | -1 | 2 | 4 + | 0 | | zero | 1 | -1 | 5 | -5 + | 0 | | zero | 1 | -1 | 5 | -5 + | 0 | | zero | 1 | -1 | 0 | + | 0 | | zero | 1 | -1 | | + | 0 | | zero | 1 | -1 | | 0 + | 1 | 4 | one | 2 | 2 | 1 | -1 + | 1 | 4 | one | 2 | 2 | 2 | 2 + | 1 | 4 | one | 2 | 2 | 3 | -3 + | 1 | 4 | one | 2 | 2 | 2 | 4 + | 1 | 4 | one | 2 | 2 | 5 | -5 + | 1 | 4 | one | 2 | 2 | 5 | -5 + | 1 | 4 | one | 2 | 2 | 0 | + | 1 | 4 | one | 2 | 2 | | + | 1 | 4 | one | 2 | 2 | | 0 + | 0 | | zero | 2 | 2 | 1 | -1 + | 0 | | zero | 2 | 2 | 2 | 2 + | 0 | | zero | 2 | 2 | 3 | -3 + | 0 | | zero | 2 | 2 | 2 | 4 + | 0 | | zero | 2 | 2 | 5 | -5 + | 0 | | zero | 2 | 2 | 5 | -5 + | 0 | | zero | 2 | 2 | 0 | + | 0 | | zero | 2 | 2 | | + | 0 | | zero | 2 | 2 | | 0 + | 1 | 4 | one | 3 | -3 | 1 | -1 + | 1 | 4 | one | 3 | -3 | 2 | 2 + | 1 | 4 | one | 3 | -3 | 3 | -3 + | 1 | 4 | one | 3 | -3 | 2 | 4 + | 1 | 4 | one | 3 | -3 | 5 | -5 + | 1 | 4 | one | 3 | -3 | 5 | -5 + | 1 | 4 | one | 3 | -3 | 0 | + | 1 | 4 | one | 3 | -3 | | + | 1 | 4 | one | 3 | -3 | | 0 + | 0 | | zero | 3 | -3 | 1 | -1 + | 0 | | zero | 3 | -3 | 2 | 2 + | 0 | | zero | 3 | -3 | 3 | -3 + | 0 | | zero | 3 | -3 | 2 | 4 + | 0 | | zero | 3 | -3 | 5 | -5 + | 0 | | zero | 3 | -3 | 5 | -5 + | 0 | | zero | 3 | -3 | 0 | + | 0 | | zero | 3 | -3 | | + | 0 | | zero | 3 | -3 | | 0 + | 1 | 4 | one | 2 | 4 | 1 | -1 + | 1 | 4 | one | 2 | 4 | 2 | 2 + | 1 | 4 | one | 2 | 4 | 3 | -3 + | 1 | 4 | one | 2 | 4 | 2 | 4 + | 1 | 4 | one | 2 | 4 | 5 | -5 + | 1 | 4 | one | 2 | 4 | 5 | -5 + | 1 | 4 | one | 2 | 4 | 0 | + | 1 | 4 | one | 2 | 4 | | + | 1 | 4 | one | 2 | 4 | | 0 + | 0 | | zero | 2 | 4 | 1 | -1 + | 0 | | zero | 2 | 4 | 2 | 2 + | 0 | | zero | 2 | 4 | 3 | -3 + | 0 | | zero | 2 | 4 | 2 | 4 + | 0 | | zero | 2 | 4 | 5 | -5 + | 0 | | zero | 2 | 4 | 5 | -5 + | 0 | | zero | 2 | 4 | 0 | + | 0 | | zero | 2 | 4 | | + | 0 | | zero | 2 | 4 | | 0 + | 1 | 4 | one | 5 | -5 | 1 | -1 + | 1 | 4 | one | 5 | -5 | 2 | 2 + | 1 | 4 | one | 5 | -5 | 3 | -3 + | 1 | 4 | one | 5 | -5 | 2 | 4 + | 1 | 4 | one | 5 | -5 | 5 | -5 + | 1 | 4 | one | 5 | -5 | 5 | -5 + | 1 | 4 | one | 5 | -5 | 0 | + | 1 | 4 | one | 5 | -5 | | + | 1 | 4 | one | 5 | -5 | | 0 + | 0 | | zero | 5 | -5 | 1 | -1 + | 0 | | zero | 5 | -5 | 2 | 2 + | 0 | | zero | 5 | -5 | 3 | -3 + | 0 | | zero | 5 | -5 | 2 | 4 + | 0 | | zero | 5 | -5 | 5 | -5 + | 0 | | zero | 5 | -5 | 5 | -5 + | 0 | | zero | 5 | -5 | 0 | + | 0 | | zero | 5 | -5 | | + | 0 | | zero | 5 | -5 | | 0 + | 1 | 4 | one | 5 | -5 | 1 | -1 + | 1 | 4 | one | 5 | -5 | 2 | 2 + | 1 | 4 | one | 5 | -5 | 3 | -3 + | 1 | 4 | one | 5 | -5 | 2 | 4 + | 1 | 4 | one | 5 | -5 | 5 | -5 + | 1 | 4 | one | 5 | -5 | 5 | -5 + | 1 | 4 | one | 5 | -5 | 0 | + | 1 | 4 | one | 5 | -5 | | + | 1 | 4 | one | 5 | -5 | | 0 + | 0 | | zero | 5 | -5 | 1 | -1 + | 0 | | zero | 5 | -5 | 2 | 2 + | 0 | | zero | 5 | -5 | 3 | -3 + | 0 | | zero | 5 | -5 | 2 | 4 + | 0 | | zero | 5 | -5 | 5 | -5 + | 0 | | zero | 5 | -5 | 5 | -5 + | 0 | | zero | 5 | -5 | 0 | + | 0 | | zero | 5 | -5 | | + | 0 | | zero | 5 | -5 | | 0 + | 1 | 4 | one | 0 | | 1 | -1 + | 1 | 4 | one | 0 | | 2 | 2 + | 1 | 4 | one | 0 | | 3 | -3 + | 1 | 4 | one | 0 | | 2 | 4 + | 1 | 4 | one | 0 | | 5 | -5 + | 1 | 4 | one | 0 | | 5 | -5 + | 1 | 4 | one | 0 | | 0 | + | 1 | 4 | one | 0 | | | + | 1 | 4 | one | 0 | | | 0 + | 0 | | zero | 0 | | 1 | -1 + | 0 | | zero | 0 | | 2 | 2 + | 0 | | zero | 0 | | 3 | -3 + | 0 | | zero | 0 | | 2 | 4 + | 0 | | zero | 0 | | 5 | -5 + | 0 | | zero | 0 | | 5 | -5 | 0 | | zero | 0 | | 0 | | 0 | | zero | 0 | | | | 0 | | zero | 0 | | | 0 @@ -1321,15 +1343,6 @@ SELECT '' AS "xxx", * | 1 | 4 | one | | | 0 | | 1 | 4 | one | | | | | 1 | 4 | one | | | | 0 - | 2 | 3 | two | | | 1 | -1 - | 2 | 3 | two | | | 2 | 2 - | 2 | 3 | two | | | 3 | -3 - | 2 | 3 | two | | | 2 | 4 - | 2 | 3 | two | | | 5 | -5 - | 2 | 3 | two | | | 5 | -5 - | 2 | 3 | two | | | 0 | - | 2 | 3 | two | | | | - | 2 | 3 | two | | | | 0 | 0 | | zero | | | 1 | -1 | 0 | | zero | | | 2 | 2 | 0 | | zero | | | 3 | -3 @@ -1348,15 +1361,6 @@ SELECT '' AS "xxx", * | 1 | 4 | one | | 0 | 0 | | 1 | 4 | one | | 0 | | | 1 | 4 | one | | 0 | | 0 - | 2 | 3 | two | | 0 | 1 | -1 - | 2 | 3 | two | | 0 | 2 | 2 - | 2 | 3 | two | | 0 | 3 | -3 - | 2 | 3 | two | | 0 | 2 | 4 - | 2 | 3 | two | | 0 | 5 | -5 - | 2 | 3 | two | | 0 | 5 | -5 - | 2 | 3 | two | | 0 | 0 | - | 2 | 3 | two | | 0 | | - | 2 | 3 | two | | 0 | | 0 | 0 | | zero | | 0 | 1 | -1 | 0 | | zero | | 0 | 2 | 2 | 0 | | zero | | 0 | 3 | -3 @@ -1383,12 +1387,12 @@ SELECT '' AS "xxx", * FROM J1_TBL INNER JOIN J2_TBL USING (i); xxx | i | j | t | k -----+---+---+-------+---- - | 3 | 2 | three | -3 | 5 | 0 | five | -5 | 5 | 0 | five | -5 - | 1 | 4 | one | -1 - | 2 | 3 | two | 4 | 2 | 3 | two | 2 + | 3 | 2 | three | -3 + | 2 | 3 | two | 4 + | 1 | 4 | one | -1 | 0 | | zero | (7 rows) @@ -1397,13 +1401,13 @@ SELECT '' AS "xxx", * FROM J1_TBL JOIN J2_TBL USING (i); xxx | i | j | t | k -----+---+---+-------+---- - | 1 | 4 | one | -1 - | 2 | 3 | two | 4 - | 2 | 3 | two | 2 - | 0 | | zero | - | 3 | 2 | three | -3 | 5 | 0 | five | -5 | 5 | 0 | five | -5 + | 2 | 3 | two | 2 + | 3 | 2 | three | -3 + | 2 | 3 | two | 4 + | 1 | 4 | one | -1 + | 0 | | zero | (7 rows) SELECT '' AS "xxx", * @@ -1439,13 +1443,13 @@ SELECT '' AS "xxx", * FROM J1_TBL NATURAL JOIN J2_TBL; xxx | i | j | t | k -----+---+---+-------+---- - | 1 | 4 | one | -1 - | 2 | 3 | two | 4 | 2 | 3 | two | 2 - | 0 | | zero | | 3 | 2 | three | -3 + | 2 | 3 | two | 4 | 5 | 0 | five | -5 | 5 | 0 | five | -5 + | 1 | 4 | one | -1 + | 0 | | zero | (7 rows) SELECT '' AS "xxx", * @@ -1453,20 +1457,20 @@ SELECT '' AS "xxx", * xxx | a | b | c | d -----+---+---+-------+---- | 1 | 4 | one | -1 - | 2 | 3 | two | 4 - | 2 | 3 | two | 2 | 0 | | zero | - | 3 | 2 | three | -3 | 5 | 0 | five | -5 | 5 | 0 | five | -5 + | 2 | 3 | two | 2 + | 3 | 2 | three | -3 + | 2 | 3 | two | 4 (7 rows) SELECT '' AS "xxx", * FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a); xxx | a | b | c | d -----+---+---+------+--- - | 2 | 3 | two | 2 | 0 | | zero | + | 2 | 3 | two | 2 | 4 | 1 | four | 2 (3 rows) @@ -1477,10 +1481,10 @@ SELECT '' AS "xxx", * xxx | a | b | t | k -----+---+---+-------+---- | 1 | 4 | one | -1 - | 2 | 3 | two | 4 - | 2 | 3 | two | 2 | 0 | | zero | + | 2 | 3 | two | 2 | 3 | 2 | three | -3 + | 2 | 3 | two | 4 | 5 | 0 | five | -5 | 5 | 0 | five | -5 (7 rows) @@ -1493,10 +1497,10 @@ SELECT '' AS "xxx", * xxx | i | j | t | i | k -----+---+---+-------+---+---- | 1 | 4 | one | 1 | -1 - | 2 | 3 | two | 2 | 4 - | 2 | 3 | two | 2 | 2 | 0 | | zero | 0 | + | 2 | 3 | two | 2 | 2 | 3 | 2 | three | 3 | -3 + | 2 | 3 | two | 2 | 4 | 5 | 0 | five | 5 | -5 | 5 | 0 | five | 5 | -5 (7 rows) @@ -1505,8 +1509,8 @@ SELECT '' AS "xxx", * FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.k); xxx | i | j | t | i | k -----+---+---+------+---+--- - | 2 | 3 | two | 2 | 2 | 0 | | zero | | 0 + | 2 | 3 | two | 2 | 2 | 4 | 1 | four | 2 | 4 (3 rows) @@ -1518,12 +1522,12 @@ SELECT '' AS "xxx", * xxx | i | j | t | i | k -----+---+---+-------+---+--- | 1 | 4 | one | 2 | 2 - | 1 | 4 | one | 2 | 4 - | 2 | 3 | two | 2 | 2 - | 2 | 3 | two | 2 | 4 | 0 | | zero | 2 | 2 + | 1 | 4 | one | 2 | 4 | 0 | | zero | 2 | 4 | 0 | | zero | | 0 + | 2 | 3 | two | 2 | 2 + | 2 | 3 | two | 2 | 4 | 3 | 2 | three | 2 | 4 | 4 | 1 | four | 2 | 4 (9 rows) @@ -1576,15 +1580,15 @@ SELECT '' AS "xxx", * FROM J1_TBL RIGHT OUTER JOIN J2_TBL USING (i); xxx | i | j | t | k -----+---+---+-------+---- - | 1 | 4 | one | -1 | 2 | 3 | two | 2 | 3 | 2 | three | -3 | 2 | 3 | two | 4 - | 5 | 0 | five | -5 - | 5 | 0 | five | -5 - | 0 | | zero | | | | | | | | | 0 + | 1 | 4 | one | -1 + | 0 | | zero | + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 (9 rows) SELECT '' AS "xxx", * @@ -1592,12 +1596,12 @@ SELECT '' AS "xxx", * xxx | i | j | t | k -----+---+---+-------+---- | 1 | 4 | one | -1 + | 0 | | zero | + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 | 2 | 3 | two | 2 | 3 | 2 | three | -3 | 2 | 3 | two | 4 - | 5 | 0 | five | -5 - | 5 | 0 | five | -5 - | 0 | | zero | | | | | | | | | 0 (9 rows) @@ -1681,8 +1685,8 @@ SELECT * FROM t1 FULL JOIN t2 USING (name) FULL JOIN t3 USING (name); ------+----+----+---- bb | 11 | 12 | 13 dd | | | 33 - cc | | 22 | 23 ee | | 42 | + cc | | 22 | 23 (4 rows) -- @@ -1696,8 +1700,8 @@ INNER JOIN USING (name); name | n | n ------+----+---- - bb | 12 | 13 cc | 22 | 23 + bb | 12 | 13 (2 rows) SELECT * FROM @@ -1720,8 +1724,8 @@ USING (name); name | n | n ------+----+---- bb | 12 | 13 - cc | 22 | 23 dd | | 33 + cc | 22 | 23 ee | 42 | (4 rows) @@ -1733,8 +1737,8 @@ NATURAL INNER JOIN (SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; name | s2_n | s2_2 | s3_n | s3_2 ------+------+------+------+------ - bb | 12 | 2 | 13 | 3 cc | 22 | 2 | 23 | 3 + bb | 12 | 2 | 13 | 3 (2 rows) SELECT * FROM @@ -1744,8 +1748,8 @@ NATURAL LEFT JOIN name | s2_n | s2_2 | s3_n | s3_2 ------+------+------+------+------ bb | 12 | 2 | 13 | 3 - cc | 22 | 2 | 23 | 3 ee | 42 | 2 | | + cc | 22 | 2 | 23 | 3 (3 rows) SELECT * FROM @@ -1754,10 +1758,10 @@ NATURAL FULL JOIN (SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; name | s2_n | s2_2 | s3_n | s3_2 ------+------+------+------+------ + ee | 42 | 2 | | bb | 12 | 2 | 13 | 3 - cc | 22 | 2 | 23 | 3 dd | | | 33 | 3 - ee | 42 | 2 | | + cc | 22 | 2 | 23 | 3 (4 rows) SELECT * FROM @@ -1779,9 +1783,9 @@ NATURAL FULL JOIN (SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; name | s1_n | s1_1 | s2_n | s2_2 | s3_n | s3_2 ------+------+------+------+------+------+------ + cc | | | 22 | 2 | 23 | 3 bb | 11 | 1 | 12 | 2 | 13 | 3 dd | | | | | 33 | 3 - cc | | | 22 | 2 | 23 | 3 ee | | | 42 | 2 | | (4 rows) @@ -1795,10 +1799,10 @@ NATURAL FULL JOIN ) ss2; name | s1_n | s2_n | s3_n ------+------+------+------ - cc | | 22 | 23 - ee | | 42 | bb | 11 | 12 | 13 dd | | | 33 + ee | | 42 | + cc | | 22 | 23 (4 rows) SELECT * FROM @@ -1811,9 +1815,9 @@ NATURAL FULL JOIN ) ss2; name | s1_n | s2_n | s2_2 | s3_n ------+------+------+------+------ + cc | | 22 | 2 | 23 bb | 11 | 12 | 2 | 13 dd | | | | 33 - cc | | 22 | 2 | 23 ee | | 42 | 2 | (4 rows) @@ -1844,19 +1848,19 @@ select * from x; select * from y; y1 | y2 ----+----- + 2 | 222 3 | 333 4 | 1 | 111 - 2 | 222 (4 rows) select * from x left join y on (x1 = y1 and x2 is not null); x1 | x2 | y1 | y2 ----+----+----+----- - 1 | 11 | 1 | 111 2 | 22 | 2 | 222 3 | | | 4 | 44 | 4 | + 1 | 11 | 1 | 111 5 | | | (5 rows) @@ -1864,10 +1868,10 @@ select * from x left join y on (x1 = y1 and y2 is not null); x1 | x2 | y1 | y2 ----+----+----+----- 1 | 11 | 1 | 111 + 5 | | | 2 | 22 | 2 | 222 3 | | 3 | 333 4 | 44 | | - 5 | | | (5 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) @@ -1885,21 +1889,21 @@ select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1 and x2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 + 5 | | | | | 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | | 4 | 44 | 4 | | 4 | 44 - 5 | | | | | + 1 | 11 | 1 | 111 | 1 | 11 (5 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1 and y2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | 3 | 4 | 44 | 4 | | | + 1 | 11 | 1 | 111 | 1 | 11 5 | | | | | (5 rows) @@ -1907,11 +1911,11 @@ select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1 and xx2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | | 4 | 44 | 4 | | 4 | 44 5 | | | | | + 1 | 11 | 1 | 111 | 1 | 11 (5 rows) -- these should NOT give the same answers as above @@ -1919,9 +1923,9 @@ select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1) where (x2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 4 | 44 | 4 | | 4 | 44 + 1 | 11 | 1 | 111 | 1 | 11 (3 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) @@ -1990,9 +1994,9 @@ DELETE FROM t4 USING t1 JOIN t2 USING (a) WHERE t4.x > t1.a; SELECT * FROM t4; x | y ---+---- + 7 | 8 5 | 20 6 | 7 - 7 | 8 (3 rows) DELETE FROM t3 USING t3 t3_other WHERE t3.x = t3_other.x AND t3.y = t3_other.y; @@ -2018,9 +2022,9 @@ set enable_nestloop to off; select tt1.*, tt2.* from tt1 left join tt2 on tt1.joincol = tt2.joincol; tt1_id | joincol | tt2_id | joincol --------+---------+--------+--------- - 1 | 11 | 21 | 11 - 1 | 11 | 22 | 11 2 | | | + 1 | 11 | 22 | 11 + 1 | 11 | 21 | 11 (3 rows) select tt1.*, tt2.* from tt2 right join tt1 on tt1.joincol = tt2.joincol; @@ -2509,7 +2513,7 @@ explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) retur -- CBDB_FIXME: How to derive a plan? -- Replicates join OuterQuery explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select ( select foo.c1 from (select * from strewn_issue_15860) foo join cte1 using(c2) where foo.c1 = hash_issue_15860.c1) from hash_issue_15860; -ERROR: could not devise a query plan for the given query (pathnode.c:281) +ERROR: could not devise a query plan for the given query (pathnode.c:285) -- Test case for Github Issue 17460 create table t_17460 (a int ) distributed replicated; create table foo_17460 (a int); @@ -2522,15 +2526,15 @@ analyze foo_17460; -- update|delete on replicated table should not use unique rowid skill -- to plan semi join. explain (costs off) delete from t_17460 where a in (select a from foo_17460); - QUERY PLAN ---------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------- Delete on t_17460 - -> Hash Semi Join - Hash Cond: (t_17460.a = foo_17460.a) - -> Seq Scan on t_17460 + -> Hash Right Semi Join + Hash Cond: (foo_17460.a = t_17460.a) + -> Broadcast Motion 3:3 (slice1; segments: 3) + -> Seq Scan on foo_17460 -> Hash - -> Broadcast Motion 3:3 (slice1; segments: 3) - -> Seq Scan on foo_17460 + -> Seq Scan on t_17460 Optimizer: Postgres query optimizer (8 rows) diff --git a/contrib/pax_storage/src/test/regress/expected/rpt_joins_optimizer.out b/contrib/pax_storage/src/test/regress/expected/rpt_joins_optimizer.out new file mode 100644 index 00000000000..63129b6bfd7 --- /dev/null +++ b/contrib/pax_storage/src/test/regress/expected/rpt_joins_optimizer.out @@ -0,0 +1,2556 @@ +-- +-- Tests for joins between replicated tables +-- +-- start_ignore +create extension if not exists gp_debug_numsegments; +NOTICE: extension "gp_debug_numsegments" already exists, skipping +-- end_ignore +create schema rpt_joins; +set search_path to rpt_joins, public; +-- +-- Test JOIN clauses, bellow tests are copy from tests for partitioned table +-- +CREATE TABLE J1_TBL ( + i integer, + j integer, + t text +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE J2_TBL ( + i integer, + k integer +) distributed replicated; +INSERT INTO J1_TBL VALUES (1, 4, 'one'); +INSERT INTO J1_TBL VALUES (2, 3, 'two'); +INSERT INTO J1_TBL VALUES (3, 2, 'three'); +INSERT INTO J1_TBL VALUES (4, 1, 'four'); +INSERT INTO J1_TBL VALUES (5, 0, 'five'); +INSERT INTO J1_TBL VALUES (6, 6, 'six'); +INSERT INTO J1_TBL VALUES (7, 7, 'seven'); +INSERT INTO J1_TBL VALUES (8, 8, 'eight'); +INSERT INTO J1_TBL VALUES (0, NULL, 'zero'); +INSERT INTO J1_TBL VALUES (NULL, NULL, 'null'); +INSERT INTO J1_TBL VALUES (NULL, 0, 'zero'); +INSERT INTO J2_TBL VALUES (1, -1); +INSERT INTO J2_TBL VALUES (2, 2); +INSERT INTO J2_TBL VALUES (3, -3); +INSERT INTO J2_TBL VALUES (2, 4); +INSERT INTO J2_TBL VALUES (5, -5); +INSERT INTO J2_TBL VALUES (5, -5); +INSERT INTO J2_TBL VALUES (0, NULL); +INSERT INTO J2_TBL VALUES (NULL, NULL); +INSERT INTO J2_TBL VALUES (NULL, 0); +-- +-- CROSS JOIN +-- Qualifications are not allowed on cross joins, +-- which degenerate into a standard unqualified inner join. +-- +SELECT '' AS "xxx", * + FROM J1_TBL CROSS JOIN J2_TBL; + xxx | i | j | t | i | k +-----+---+---+-------+---+---- + | 5 | 0 | five | 1 | -1 + | 5 | 0 | five | 2 | 2 + | 5 | 0 | five | 3 | -3 + | 5 | 0 | five | 2 | 4 + | 5 | 0 | five | 5 | -5 + | 5 | 0 | five | 5 | -5 + | 5 | 0 | five | 0 | + | 5 | 0 | five | | + | 5 | 0 | five | | 0 + | 6 | 6 | six | 1 | -1 + | 6 | 6 | six | 2 | 2 + | 6 | 6 | six | 3 | -3 + | 6 | 6 | six | 2 | 4 + | 6 | 6 | six | 5 | -5 + | 6 | 6 | six | 5 | -5 + | 6 | 6 | six | 0 | + | 6 | 6 | six | | + | 6 | 6 | six | | 0 + | 1 | 4 | one | 1 | -1 + | 1 | 4 | one | 2 | 2 + | 1 | 4 | one | 3 | -3 + | 1 | 4 | one | 2 | 4 + | 1 | 4 | one | 5 | -5 + | 1 | 4 | one | 5 | -5 + | 1 | 4 | one | 0 | + | 1 | 4 | one | | + | 1 | 4 | one | | 0 + | 0 | | zero | 1 | -1 + | 0 | | zero | 2 | 2 + | 0 | | zero | 3 | -3 + | 0 | | zero | 2 | 4 + | 0 | | zero | 5 | -5 + | 0 | | zero | 5 | -5 + | 0 | | zero | 0 | + | 0 | | zero | | + | 0 | | zero | | 0 + | 2 | 3 | two | 1 | -1 + | 2 | 3 | two | 2 | 2 + | 2 | 3 | two | 3 | -3 + | 2 | 3 | two | 2 | 4 + | 2 | 3 | two | 5 | -5 + | 2 | 3 | two | 5 | -5 + | 2 | 3 | two | 0 | + | 2 | 3 | two | | + | 2 | 3 | two | | 0 + | 3 | 2 | three | 1 | -1 + | 3 | 2 | three | 2 | 2 + | 3 | 2 | three | 3 | -3 + | 3 | 2 | three | 2 | 4 + | 3 | 2 | three | 5 | -5 + | 3 | 2 | three | 5 | -5 + | 3 | 2 | three | 0 | + | 3 | 2 | three | | + | 3 | 2 | three | | 0 + | 4 | 1 | four | 1 | -1 + | 4 | 1 | four | 2 | 2 + | 4 | 1 | four | 3 | -3 + | 4 | 1 | four | 2 | 4 + | 4 | 1 | four | 5 | -5 + | 4 | 1 | four | 5 | -5 + | 4 | 1 | four | 0 | + | 4 | 1 | four | | + | 4 | 1 | four | | 0 + | 7 | 7 | seven | 1 | -1 + | 7 | 7 | seven | 2 | 2 + | 7 | 7 | seven | 3 | -3 + | 7 | 7 | seven | 2 | 4 + | 7 | 7 | seven | 5 | -5 + | 7 | 7 | seven | 5 | -5 + | 7 | 7 | seven | 0 | + | 7 | 7 | seven | | + | 7 | 7 | seven | | 0 + | 8 | 8 | eight | 1 | -1 + | 8 | 8 | eight | 2 | 2 + | 8 | 8 | eight | 3 | -3 + | 8 | 8 | eight | 2 | 4 + | 8 | 8 | eight | 5 | -5 + | 8 | 8 | eight | 5 | -5 + | 8 | 8 | eight | 0 | + | 8 | 8 | eight | | + | 8 | 8 | eight | | 0 + | | | null | 1 | -1 + | | | null | 2 | 2 + | | | null | 3 | -3 + | | | null | 2 | 4 + | | | null | 5 | -5 + | | | null | 5 | -5 + | | | null | 0 | + | | | null | | + | | | null | | 0 + | | 0 | zero | 1 | -1 + | | 0 | zero | 2 | 2 + | | 0 | zero | 3 | -3 + | | 0 | zero | 2 | 4 + | | 0 | zero | 5 | -5 + | | 0 | zero | 5 | -5 + | | 0 | zero | 0 | + | | 0 | zero | | + | | 0 | zero | | 0 +(99 rows) + +-- ambiguous column +SELECT '' AS "xxx", i, k, t + FROM J1_TBL CROSS JOIN J2_TBL; +ERROR: column reference "i" is ambiguous +LINE 1: SELECT '' AS "xxx", i, k, t + ^ +-- resolve previous ambiguity by specifying the table name +SELECT '' AS "xxx", t1.i, k, t + FROM J1_TBL t1 CROSS JOIN J2_TBL t2; + xxx | i | k | t +-----+---+----+------- + | 5 | -1 | five + | 5 | 2 | five + | 5 | -3 | five + | 5 | 4 | five + | 5 | -5 | five + | 5 | -5 | five + | 5 | | five + | 5 | | five + | 5 | 0 | five + | 6 | -1 | six + | 6 | 2 | six + | 6 | -3 | six + | 6 | 4 | six + | 6 | -5 | six + | 6 | -5 | six + | 6 | | six + | 6 | | six + | 6 | 0 | six + | 1 | -1 | one + | 1 | 2 | one + | 1 | -3 | one + | 1 | 4 | one + | 1 | -5 | one + | 1 | -5 | one + | 1 | | one + | 1 | | one + | 1 | 0 | one + | 0 | -1 | zero + | 0 | 2 | zero + | 0 | -3 | zero + | 0 | 4 | zero + | 0 | -5 | zero + | 0 | -5 | zero + | 0 | | zero + | 0 | | zero + | 0 | 0 | zero + | 2 | -1 | two + | 2 | 2 | two + | 2 | -3 | two + | 2 | 4 | two + | 2 | -5 | two + | 2 | -5 | two + | 2 | | two + | 2 | | two + | 2 | 0 | two + | 3 | -1 | three + | 3 | 2 | three + | 3 | -3 | three + | 3 | 4 | three + | 3 | -5 | three + | 3 | -5 | three + | 3 | | three + | 3 | | three + | 3 | 0 | three + | 4 | -1 | four + | 4 | 2 | four + | 4 | -3 | four + | 4 | 4 | four + | 4 | -5 | four + | 4 | -5 | four + | 4 | | four + | 4 | | four + | 4 | 0 | four + | 7 | -1 | seven + | 7 | 2 | seven + | 7 | -3 | seven + | 7 | 4 | seven + | 7 | -5 | seven + | 7 | -5 | seven + | 7 | | seven + | 7 | | seven + | 7 | 0 | seven + | 8 | -1 | eight + | 8 | 2 | eight + | 8 | -3 | eight + | 8 | 4 | eight + | 8 | -5 | eight + | 8 | -5 | eight + | 8 | | eight + | 8 | | eight + | 8 | 0 | eight + | | -1 | null + | | 2 | null + | | -3 | null + | | 4 | null + | | -5 | null + | | -5 | null + | | | null + | | | null + | | 0 | null + | | -1 | zero + | | 2 | zero + | | -3 | zero + | | 4 | zero + | | -5 | zero + | | -5 | zero + | | | zero + | | | zero + | | 0 | zero +(99 rows) + +SELECT '' AS "xxx", ii, tt, kk + FROM (J1_TBL CROSS JOIN J2_TBL) + AS tx (ii, jj, tt, ii2, kk); + xxx | ii | tt | kk +-----+----+-------+---- + | 1 | one | -1 + | 1 | one | 2 + | 1 | one | -3 + | 1 | one | 4 + | 1 | one | -5 + | 1 | one | -5 + | 1 | one | + | 1 | one | + | 1 | one | 0 + | 0 | zero | -1 + | 0 | zero | 2 + | 0 | zero | -3 + | 0 | zero | 4 + | 0 | zero | -5 + | 0 | zero | -5 + | 0 | zero | + | 0 | zero | + | 0 | zero | 0 + | 5 | five | -1 + | 5 | five | 2 + | 5 | five | -3 + | 5 | five | 4 + | 5 | five | -5 + | 5 | five | -5 + | 5 | five | + | 5 | five | + | 5 | five | 0 + | 6 | six | -1 + | 6 | six | 2 + | 6 | six | -3 + | 6 | six | 4 + | 6 | six | -5 + | 6 | six | -5 + | 6 | six | + | 6 | six | + | 6 | six | 0 + | 2 | two | -1 + | 2 | two | 2 + | 2 | two | -3 + | 2 | two | 4 + | 2 | two | -5 + | 2 | two | -5 + | 2 | two | + | 2 | two | + | 2 | two | 0 + | 3 | three | -1 + | 3 | three | 2 + | 3 | three | -3 + | 3 | three | 4 + | 3 | three | -5 + | 3 | three | -5 + | 3 | three | + | 3 | three | + | 3 | three | 0 + | 4 | four | -1 + | 4 | four | 2 + | 4 | four | -3 + | 4 | four | 4 + | 4 | four | -5 + | 4 | four | -5 + | 4 | four | + | 4 | four | + | 4 | four | 0 + | 7 | seven | -1 + | 7 | seven | 2 + | 7 | seven | -3 + | 7 | seven | 4 + | 7 | seven | -5 + | 7 | seven | -5 + | 7 | seven | + | 7 | seven | + | 7 | seven | 0 + | 8 | eight | -1 + | 8 | eight | 2 + | 8 | eight | -3 + | 8 | eight | 4 + | 8 | eight | -5 + | 8 | eight | -5 + | 8 | eight | + | 8 | eight | + | 8 | eight | 0 + | | null | -1 + | | null | 2 + | | null | -3 + | | null | 4 + | | null | -5 + | | null | -5 + | | null | + | | null | + | | null | 0 + | | zero | -1 + | | zero | 2 + | | zero | -3 + | | zero | 4 + | | zero | -5 + | | zero | -5 + | | zero | + | | zero | + | | zero | 0 +(99 rows) + +SELECT '' AS "xxx", tx.ii, tx.jj, tx.kk + FROM (J1_TBL t1 (a, b, c) CROSS JOIN J2_TBL t2 (d, e)) + AS tx (ii, jj, tt, ii2, kk); + xxx | ii | jj | kk +-----+----+----+---- + | 5 | 0 | -1 + | 5 | 0 | 2 + | 5 | 0 | -3 + | 5 | 0 | 4 + | 5 | 0 | -5 + | 5 | 0 | -5 + | 5 | 0 | + | 5 | 0 | + | 5 | 0 | 0 + | 6 | 6 | -1 + | 6 | 6 | 2 + | 6 | 6 | -3 + | 6 | 6 | 4 + | 6 | 6 | -5 + | 6 | 6 | -5 + | 6 | 6 | + | 6 | 6 | + | 6 | 6 | 0 + | 1 | 4 | -1 + | 1 | 4 | 2 + | 1 | 4 | -3 + | 1 | 4 | 4 + | 1 | 4 | -5 + | 1 | 4 | -5 + | 1 | 4 | + | 1 | 4 | + | 1 | 4 | 0 + | 0 | | -1 + | 0 | | 2 + | 0 | | -3 + | 0 | | 4 + | 0 | | -5 + | 0 | | -5 + | 0 | | + | 0 | | + | 0 | | 0 + | 2 | 3 | -1 + | 2 | 3 | 2 + | 2 | 3 | -3 + | 2 | 3 | 4 + | 2 | 3 | -5 + | 2 | 3 | -5 + | 2 | 3 | + | 2 | 3 | + | 2 | 3 | 0 + | 3 | 2 | -1 + | 3 | 2 | 2 + | 3 | 2 | -3 + | 3 | 2 | 4 + | 3 | 2 | -5 + | 3 | 2 | -5 + | 3 | 2 | + | 3 | 2 | + | 3 | 2 | 0 + | 4 | 1 | -1 + | 4 | 1 | 2 + | 4 | 1 | -3 + | 4 | 1 | 4 + | 4 | 1 | -5 + | 4 | 1 | -5 + | 4 | 1 | + | 4 | 1 | + | 4 | 1 | 0 + | 7 | 7 | -1 + | 7 | 7 | 2 + | 7 | 7 | -3 + | 7 | 7 | 4 + | 7 | 7 | -5 + | 7 | 7 | -5 + | 7 | 7 | + | 7 | 7 | + | 7 | 7 | 0 + | 8 | 8 | -1 + | 8 | 8 | 2 + | 8 | 8 | -3 + | 8 | 8 | 4 + | 8 | 8 | -5 + | 8 | 8 | -5 + | 8 | 8 | + | 8 | 8 | + | 8 | 8 | 0 + | | | -1 + | | | 2 + | | | -3 + | | | 4 + | | | -5 + | | | -5 + | | | + | | | + | | | 0 + | | 0 | -1 + | | 0 | 2 + | | 0 | -3 + | | 0 | 4 + | | 0 | -5 + | | 0 | -5 + | | 0 | + | | 0 | + | | 0 | 0 +(99 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL CROSS JOIN J2_TBL a CROSS JOIN J2_TBL b; + xxx | i | j | t | i | k | i | k +-----+---+---+-------+---+----+---+---- + | 5 | 0 | five | 1 | -1 | 1 | -1 + | 5 | 0 | five | 2 | 2 | 1 | -1 + | 5 | 0 | five | 3 | -3 | 1 | -1 + | 5 | 0 | five | 2 | 4 | 1 | -1 + | 5 | 0 | five | 5 | -5 | 1 | -1 + | 5 | 0 | five | 5 | -5 | 1 | -1 + | 5 | 0 | five | 0 | | 1 | -1 + | 5 | 0 | five | | | 1 | -1 + | 5 | 0 | five | | 0 | 1 | -1 + | 5 | 0 | five | 1 | -1 | 2 | 2 + | 5 | 0 | five | 2 | 2 | 2 | 2 + | 5 | 0 | five | 3 | -3 | 2 | 2 + | 5 | 0 | five | 2 | 4 | 2 | 2 + | 5 | 0 | five | 5 | -5 | 2 | 2 + | 5 | 0 | five | 5 | -5 | 2 | 2 + | 5 | 0 | five | 0 | | 2 | 2 + | 5 | 0 | five | | | 2 | 2 + | 5 | 0 | five | | 0 | 2 | 2 + | 5 | 0 | five | 1 | -1 | 3 | -3 + | 5 | 0 | five | 2 | 2 | 3 | -3 + | 5 | 0 | five | 3 | -3 | 3 | -3 + | 5 | 0 | five | 2 | 4 | 3 | -3 + | 5 | 0 | five | 5 | -5 | 3 | -3 + | 5 | 0 | five | 5 | -5 | 3 | -3 + | 5 | 0 | five | 0 | | 3 | -3 + | 5 | 0 | five | | | 3 | -3 + | 5 | 0 | five | | 0 | 3 | -3 + | 5 | 0 | five | 1 | -1 | 2 | 4 + | 5 | 0 | five | 2 | 2 | 2 | 4 + | 5 | 0 | five | 3 | -3 | 2 | 4 + | 5 | 0 | five | 2 | 4 | 2 | 4 + | 5 | 0 | five | 5 | -5 | 2 | 4 + | 5 | 0 | five | 5 | -5 | 2 | 4 + | 5 | 0 | five | 0 | | 2 | 4 + | 5 | 0 | five | | | 2 | 4 + | 5 | 0 | five | | 0 | 2 | 4 + | 5 | 0 | five | 1 | -1 | 5 | -5 + | 5 | 0 | five | 2 | 2 | 5 | -5 + | 5 | 0 | five | 3 | -3 | 5 | -5 + | 5 | 0 | five | 2 | 4 | 5 | -5 + | 5 | 0 | five | 5 | -5 | 5 | -5 + | 5 | 0 | five | 5 | -5 | 5 | -5 + | 5 | 0 | five | 0 | | 5 | -5 + | 5 | 0 | five | | | 5 | -5 + | 5 | 0 | five | | 0 | 5 | -5 + | 5 | 0 | five | 1 | -1 | 5 | -5 + | 5 | 0 | five | 2 | 2 | 5 | -5 + | 5 | 0 | five | 3 | -3 | 5 | -5 + | 5 | 0 | five | 2 | 4 | 5 | -5 + | 5 | 0 | five | 5 | -5 | 5 | -5 + | 5 | 0 | five | 5 | -5 | 5 | -5 + | 5 | 0 | five | 0 | | 5 | -5 + | 5 | 0 | five | | | 5 | -5 + | 5 | 0 | five | | 0 | 5 | -5 + | 5 | 0 | five | 1 | -1 | 0 | + | 5 | 0 | five | 2 | 2 | 0 | + | 5 | 0 | five | 3 | -3 | 0 | + | 5 | 0 | five | 2 | 4 | 0 | + | 5 | 0 | five | 5 | -5 | 0 | + | 5 | 0 | five | 5 | -5 | 0 | + | 5 | 0 | five | 0 | | 0 | + | 5 | 0 | five | | | 0 | + | 5 | 0 | five | | 0 | 0 | + | 5 | 0 | five | 1 | -1 | | + | 5 | 0 | five | 2 | 2 | | + | 5 | 0 | five | 3 | -3 | | + | 5 | 0 | five | 2 | 4 | | + | 5 | 0 | five | 5 | -5 | | + | 5 | 0 | five | 5 | -5 | | + | 5 | 0 | five | 0 | | | + | 5 | 0 | five | | | | + | 5 | 0 | five | | 0 | | + | 5 | 0 | five | 1 | -1 | | 0 + | 5 | 0 | five | 2 | 2 | | 0 + | 5 | 0 | five | 3 | -3 | | 0 + | 5 | 0 | five | 2 | 4 | | 0 + | 5 | 0 | five | 5 | -5 | | 0 + | 5 | 0 | five | 5 | -5 | | 0 + | 5 | 0 | five | 0 | | | 0 + | 5 | 0 | five | | | | 0 + | 5 | 0 | five | | 0 | | 0 + | 6 | 6 | six | 1 | -1 | 1 | -1 + | 6 | 6 | six | 2 | 2 | 1 | -1 + | 6 | 6 | six | 3 | -3 | 1 | -1 + | 6 | 6 | six | 2 | 4 | 1 | -1 + | 6 | 6 | six | 5 | -5 | 1 | -1 + | 6 | 6 | six | 5 | -5 | 1 | -1 + | 6 | 6 | six | 0 | | 1 | -1 + | 6 | 6 | six | | | 1 | -1 + | 6 | 6 | six | | 0 | 1 | -1 + | 6 | 6 | six | 1 | -1 | 2 | 2 + | 6 | 6 | six | 2 | 2 | 2 | 2 + | 6 | 6 | six | 3 | -3 | 2 | 2 + | 6 | 6 | six | 2 | 4 | 2 | 2 + | 6 | 6 | six | 5 | -5 | 2 | 2 + | 6 | 6 | six | 5 | -5 | 2 | 2 + | 6 | 6 | six | 0 | | 2 | 2 + | 6 | 6 | six | | | 2 | 2 + | 6 | 6 | six | | 0 | 2 | 2 + | 6 | 6 | six | 1 | -1 | 3 | -3 + | 6 | 6 | six | 2 | 2 | 3 | -3 + | 6 | 6 | six | 3 | -3 | 3 | -3 + | 6 | 6 | six | 2 | 4 | 3 | -3 + | 6 | 6 | six | 5 | -5 | 3 | -3 + | 6 | 6 | six | 5 | -5 | 3 | -3 + | 6 | 6 | six | 0 | | 3 | -3 + | 6 | 6 | six | | | 3 | -3 + | 6 | 6 | six | | 0 | 3 | -3 + | 6 | 6 | six | 1 | -1 | 2 | 4 + | 6 | 6 | six | 2 | 2 | 2 | 4 + | 6 | 6 | six | 3 | -3 | 2 | 4 + | 6 | 6 | six | 2 | 4 | 2 | 4 + | 6 | 6 | six | 5 | -5 | 2 | 4 + | 6 | 6 | six | 5 | -5 | 2 | 4 + | 6 | 6 | six | 0 | | 2 | 4 + | 6 | 6 | six | | | 2 | 4 + | 6 | 6 | six | | 0 | 2 | 4 + | 6 | 6 | six | 1 | -1 | 5 | -5 + | 6 | 6 | six | 2 | 2 | 5 | -5 + | 6 | 6 | six | 3 | -3 | 5 | -5 + | 6 | 6 | six | 2 | 4 | 5 | -5 + | 6 | 6 | six | 5 | -5 | 5 | -5 + | 6 | 6 | six | 5 | -5 | 5 | -5 + | 6 | 6 | six | 0 | | 5 | -5 + | 6 | 6 | six | | | 5 | -5 + | 6 | 6 | six | | 0 | 5 | -5 + | 6 | 6 | six | 1 | -1 | 5 | -5 + | 6 | 6 | six | 2 | 2 | 5 | -5 + | 6 | 6 | six | 3 | -3 | 5 | -5 + | 6 | 6 | six | 2 | 4 | 5 | -5 + | 6 | 6 | six | 5 | -5 | 5 | -5 + | 6 | 6 | six | 5 | -5 | 5 | -5 + | 6 | 6 | six | 0 | | 5 | -5 + | 6 | 6 | six | | | 5 | -5 + | 6 | 6 | six | | 0 | 5 | -5 + | 6 | 6 | six | 1 | -1 | 0 | + | 6 | 6 | six | 2 | 2 | 0 | + | 6 | 6 | six | 3 | -3 | 0 | + | 6 | 6 | six | 2 | 4 | 0 | + | 6 | 6 | six | 5 | -5 | 0 | + | 6 | 6 | six | 5 | -5 | 0 | + | 6 | 6 | six | 0 | | 0 | + | 6 | 6 | six | | | 0 | + | 6 | 6 | six | | 0 | 0 | + | 6 | 6 | six | 1 | -1 | | + | 6 | 6 | six | 2 | 2 | | + | 6 | 6 | six | 3 | -3 | | + | 6 | 6 | six | 2 | 4 | | + | 6 | 6 | six | 5 | -5 | | + | 6 | 6 | six | 5 | -5 | | + | 6 | 6 | six | 0 | | | + | 6 | 6 | six | | | | + | 6 | 6 | six | | 0 | | + | 6 | 6 | six | 1 | -1 | | 0 + | 6 | 6 | six | 2 | 2 | | 0 + | 6 | 6 | six | 3 | -3 | | 0 + | 6 | 6 | six | 2 | 4 | | 0 + | 6 | 6 | six | 5 | -5 | | 0 + | 6 | 6 | six | 5 | -5 | | 0 + | 6 | 6 | six | 0 | | | 0 + | 6 | 6 | six | | | | 0 + | 6 | 6 | six | | 0 | | 0 + | 1 | 4 | one | 1 | -1 | 1 | -1 + | 1 | 4 | one | 2 | 2 | 1 | -1 + | 1 | 4 | one | 3 | -3 | 1 | -1 + | 1 | 4 | one | 2 | 4 | 1 | -1 + | 1 | 4 | one | 5 | -5 | 1 | -1 + | 1 | 4 | one | 5 | -5 | 1 | -1 + | 1 | 4 | one | 0 | | 1 | -1 + | 1 | 4 | one | | | 1 | -1 + | 1 | 4 | one | | 0 | 1 | -1 + | 1 | 4 | one | 1 | -1 | 2 | 2 + | 1 | 4 | one | 2 | 2 | 2 | 2 + | 1 | 4 | one | 3 | -3 | 2 | 2 + | 1 | 4 | one | 2 | 4 | 2 | 2 + | 1 | 4 | one | 5 | -5 | 2 | 2 + | 1 | 4 | one | 5 | -5 | 2 | 2 + | 1 | 4 | one | 0 | | 2 | 2 + | 1 | 4 | one | | | 2 | 2 + | 1 | 4 | one | | 0 | 2 | 2 + | 1 | 4 | one | 1 | -1 | 3 | -3 + | 1 | 4 | one | 2 | 2 | 3 | -3 + | 1 | 4 | one | 3 | -3 | 3 | -3 + | 1 | 4 | one | 2 | 4 | 3 | -3 + | 1 | 4 | one | 5 | -5 | 3 | -3 + | 1 | 4 | one | 5 | -5 | 3 | -3 + | 1 | 4 | one | 0 | | 3 | -3 + | 1 | 4 | one | | | 3 | -3 + | 1 | 4 | one | | 0 | 3 | -3 + | 1 | 4 | one | 1 | -1 | 2 | 4 + | 1 | 4 | one | 2 | 2 | 2 | 4 + | 1 | 4 | one | 3 | -3 | 2 | 4 + | 1 | 4 | one | 2 | 4 | 2 | 4 + | 1 | 4 | one | 5 | -5 | 2 | 4 + | 1 | 4 | one | 5 | -5 | 2 | 4 + | 1 | 4 | one | 0 | | 2 | 4 + | 1 | 4 | one | | | 2 | 4 + | 1 | 4 | one | | 0 | 2 | 4 + | 1 | 4 | one | 1 | -1 | 5 | -5 + | 1 | 4 | one | 2 | 2 | 5 | -5 + | 1 | 4 | one | 3 | -3 | 5 | -5 + | 1 | 4 | one | 2 | 4 | 5 | -5 + | 1 | 4 | one | 5 | -5 | 5 | -5 + | 1 | 4 | one | 5 | -5 | 5 | -5 + | 1 | 4 | one | 0 | | 5 | -5 + | 1 | 4 | one | | | 5 | -5 + | 1 | 4 | one | | 0 | 5 | -5 + | 1 | 4 | one | 1 | -1 | 5 | -5 + | 1 | 4 | one | 2 | 2 | 5 | -5 + | 1 | 4 | one | 3 | -3 | 5 | -5 + | 1 | 4 | one | 2 | 4 | 5 | -5 + | 1 | 4 | one | 5 | -5 | 5 | -5 + | 1 | 4 | one | 5 | -5 | 5 | -5 + | 1 | 4 | one | 0 | | 5 | -5 + | 1 | 4 | one | | | 5 | -5 + | 1 | 4 | one | | 0 | 5 | -5 + | 1 | 4 | one | 1 | -1 | 0 | + | 1 | 4 | one | 2 | 2 | 0 | + | 1 | 4 | one | 3 | -3 | 0 | + | 1 | 4 | one | 2 | 4 | 0 | + | 1 | 4 | one | 5 | -5 | 0 | + | 1 | 4 | one | 5 | -5 | 0 | + | 1 | 4 | one | 0 | | 0 | + | 1 | 4 | one | | | 0 | + | 1 | 4 | one | | 0 | 0 | + | 1 | 4 | one | 1 | -1 | | + | 1 | 4 | one | 2 | 2 | | + | 1 | 4 | one | 3 | -3 | | + | 1 | 4 | one | 2 | 4 | | + | 1 | 4 | one | 5 | -5 | | + | 1 | 4 | one | 5 | -5 | | + | 1 | 4 | one | 0 | | | + | 1 | 4 | one | | | | + | 1 | 4 | one | | 0 | | + | 1 | 4 | one | 1 | -1 | | 0 + | 1 | 4 | one | 2 | 2 | | 0 + | 1 | 4 | one | 3 | -3 | | 0 + | 1 | 4 | one | 2 | 4 | | 0 + | 1 | 4 | one | 5 | -5 | | 0 + | 1 | 4 | one | 5 | -5 | | 0 + | 1 | 4 | one | 0 | | | 0 + | 1 | 4 | one | | | | 0 + | 1 | 4 | one | | 0 | | 0 + | 0 | | zero | 1 | -1 | 1 | -1 + | 0 | | zero | 2 | 2 | 1 | -1 + | 0 | | zero | 3 | -3 | 1 | -1 + | 0 | | zero | 2 | 4 | 1 | -1 + | 0 | | zero | 5 | -5 | 1 | -1 + | 0 | | zero | 5 | -5 | 1 | -1 + | 0 | | zero | 0 | | 1 | -1 + | 0 | | zero | | | 1 | -1 + | 0 | | zero | | 0 | 1 | -1 + | 0 | | zero | 1 | -1 | 2 | 2 + | 0 | | zero | 2 | 2 | 2 | 2 + | 0 | | zero | 3 | -3 | 2 | 2 + | 0 | | zero | 2 | 4 | 2 | 2 + | 0 | | zero | 5 | -5 | 2 | 2 + | 0 | | zero | 5 | -5 | 2 | 2 + | 0 | | zero | 0 | | 2 | 2 + | 0 | | zero | | | 2 | 2 + | 0 | | zero | | 0 | 2 | 2 + | 0 | | zero | 1 | -1 | 3 | -3 + | 0 | | zero | 2 | 2 | 3 | -3 + | 0 | | zero | 3 | -3 | 3 | -3 + | 0 | | zero | 2 | 4 | 3 | -3 + | 0 | | zero | 5 | -5 | 3 | -3 + | 0 | | zero | 5 | -5 | 3 | -3 + | 0 | | zero | 0 | | 3 | -3 + | 0 | | zero | | | 3 | -3 + | 0 | | zero | | 0 | 3 | -3 + | 0 | | zero | 1 | -1 | 2 | 4 + | 0 | | zero | 2 | 2 | 2 | 4 + | 0 | | zero | 3 | -3 | 2 | 4 + | 0 | | zero | 2 | 4 | 2 | 4 + | 0 | | zero | 5 | -5 | 2 | 4 + | 0 | | zero | 5 | -5 | 2 | 4 + | 0 | | zero | 0 | | 2 | 4 + | 0 | | zero | | | 2 | 4 + | 0 | | zero | | 0 | 2 | 4 + | 0 | | zero | 1 | -1 | 5 | -5 + | 0 | | zero | 2 | 2 | 5 | -5 + | 0 | | zero | 3 | -3 | 5 | -5 + | 0 | | zero | 2 | 4 | 5 | -5 + | 0 | | zero | 5 | -5 | 5 | -5 + | 0 | | zero | 5 | -5 | 5 | -5 + | 0 | | zero | 0 | | 5 | -5 + | 0 | | zero | | | 5 | -5 + | 0 | | zero | | 0 | 5 | -5 + | 0 | | zero | 1 | -1 | 5 | -5 + | 0 | | zero | 2 | 2 | 5 | -5 + | 0 | | zero | 3 | -3 | 5 | -5 + | 0 | | zero | 2 | 4 | 5 | -5 + | 0 | | zero | 5 | -5 | 5 | -5 + | 0 | | zero | 5 | -5 | 5 | -5 + | 0 | | zero | 0 | | 5 | -5 + | 0 | | zero | | | 5 | -5 + | 0 | | zero | | 0 | 5 | -5 + | 0 | | zero | 1 | -1 | 0 | + | 0 | | zero | 2 | 2 | 0 | + | 0 | | zero | 3 | -3 | 0 | + | 0 | | zero | 2 | 4 | 0 | + | 0 | | zero | 5 | -5 | 0 | + | 0 | | zero | 5 | -5 | 0 | + | 0 | | zero | 0 | | 0 | + | 0 | | zero | | | 0 | + | 0 | | zero | | 0 | 0 | + | 0 | | zero | 1 | -1 | | + | 0 | | zero | 2 | 2 | | + | 0 | | zero | 3 | -3 | | + | 0 | | zero | 2 | 4 | | + | 0 | | zero | 5 | -5 | | + | 0 | | zero | 5 | -5 | | + | 0 | | zero | 0 | | | + | 0 | | zero | | | | + | 0 | | zero | | 0 | | + | 0 | | zero | 1 | -1 | | 0 + | 0 | | zero | 2 | 2 | | 0 + | 0 | | zero | 3 | -3 | | 0 + | 0 | | zero | 2 | 4 | | 0 + | 0 | | zero | 5 | -5 | | 0 + | 0 | | zero | 5 | -5 | | 0 + | 0 | | zero | 0 | | | 0 + | 0 | | zero | | | | 0 + | 0 | | zero | | 0 | | 0 + | 2 | 3 | two | 1 | -1 | 1 | -1 + | 2 | 3 | two | 2 | 2 | 1 | -1 + | 2 | 3 | two | 3 | -3 | 1 | -1 + | 2 | 3 | two | 2 | 4 | 1 | -1 + | 2 | 3 | two | 5 | -5 | 1 | -1 + | 2 | 3 | two | 5 | -5 | 1 | -1 + | 2 | 3 | two | 0 | | 1 | -1 + | 2 | 3 | two | | | 1 | -1 + | 2 | 3 | two | | 0 | 1 | -1 + | 2 | 3 | two | 1 | -1 | 2 | 2 + | 2 | 3 | two | 2 | 2 | 2 | 2 + | 2 | 3 | two | 3 | -3 | 2 | 2 + | 2 | 3 | two | 2 | 4 | 2 | 2 + | 2 | 3 | two | 5 | -5 | 2 | 2 + | 2 | 3 | two | 5 | -5 | 2 | 2 + | 2 | 3 | two | 0 | | 2 | 2 + | 2 | 3 | two | | | 2 | 2 + | 2 | 3 | two | | 0 | 2 | 2 + | 2 | 3 | two | 1 | -1 | 3 | -3 + | 2 | 3 | two | 2 | 2 | 3 | -3 + | 2 | 3 | two | 3 | -3 | 3 | -3 + | 2 | 3 | two | 2 | 4 | 3 | -3 + | 2 | 3 | two | 5 | -5 | 3 | -3 + | 2 | 3 | two | 5 | -5 | 3 | -3 + | 2 | 3 | two | 0 | | 3 | -3 + | 2 | 3 | two | | | 3 | -3 + | 2 | 3 | two | | 0 | 3 | -3 + | 2 | 3 | two | 1 | -1 | 2 | 4 + | 2 | 3 | two | 2 | 2 | 2 | 4 + | 2 | 3 | two | 3 | -3 | 2 | 4 + | 2 | 3 | two | 2 | 4 | 2 | 4 + | 2 | 3 | two | 5 | -5 | 2 | 4 + | 2 | 3 | two | 5 | -5 | 2 | 4 + | 2 | 3 | two | 0 | | 2 | 4 + | 2 | 3 | two | | | 2 | 4 + | 2 | 3 | two | | 0 | 2 | 4 + | 2 | 3 | two | 1 | -1 | 5 | -5 + | 2 | 3 | two | 2 | 2 | 5 | -5 + | 2 | 3 | two | 3 | -3 | 5 | -5 + | 2 | 3 | two | 2 | 4 | 5 | -5 + | 2 | 3 | two | 5 | -5 | 5 | -5 + | 2 | 3 | two | 5 | -5 | 5 | -5 + | 2 | 3 | two | 0 | | 5 | -5 + | 2 | 3 | two | | | 5 | -5 + | 2 | 3 | two | | 0 | 5 | -5 + | 2 | 3 | two | 1 | -1 | 5 | -5 + | 2 | 3 | two | 2 | 2 | 5 | -5 + | 2 | 3 | two | 3 | -3 | 5 | -5 + | 2 | 3 | two | 2 | 4 | 5 | -5 + | 2 | 3 | two | 5 | -5 | 5 | -5 + | 2 | 3 | two | 5 | -5 | 5 | -5 + | 2 | 3 | two | 0 | | 5 | -5 + | 2 | 3 | two | | | 5 | -5 + | 2 | 3 | two | | 0 | 5 | -5 + | 2 | 3 | two | 1 | -1 | 0 | + | 2 | 3 | two | 2 | 2 | 0 | + | 2 | 3 | two | 3 | -3 | 0 | + | 2 | 3 | two | 2 | 4 | 0 | + | 2 | 3 | two | 5 | -5 | 0 | + | 2 | 3 | two | 5 | -5 | 0 | + | 2 | 3 | two | 0 | | 0 | + | 2 | 3 | two | | | 0 | + | 2 | 3 | two | | 0 | 0 | + | 2 | 3 | two | 1 | -1 | | + | 2 | 3 | two | 2 | 2 | | + | 2 | 3 | two | 3 | -3 | | + | 2 | 3 | two | 2 | 4 | | + | 2 | 3 | two | 5 | -5 | | + | 2 | 3 | two | 5 | -5 | | + | 2 | 3 | two | 0 | | | + | 2 | 3 | two | | | | + | 2 | 3 | two | | 0 | | + | 2 | 3 | two | 1 | -1 | | 0 + | 2 | 3 | two | 2 | 2 | | 0 + | 2 | 3 | two | 3 | -3 | | 0 + | 2 | 3 | two | 2 | 4 | | 0 + | 2 | 3 | two | 5 | -5 | | 0 + | 2 | 3 | two | 5 | -5 | | 0 + | 2 | 3 | two | 0 | | | 0 + | 2 | 3 | two | | | | 0 + | 2 | 3 | two | | 0 | | 0 + | 3 | 2 | three | 1 | -1 | 1 | -1 + | 3 | 2 | three | 2 | 2 | 1 | -1 + | 3 | 2 | three | 3 | -3 | 1 | -1 + | 3 | 2 | three | 2 | 4 | 1 | -1 + | 3 | 2 | three | 5 | -5 | 1 | -1 + | 3 | 2 | three | 5 | -5 | 1 | -1 + | 3 | 2 | three | 0 | | 1 | -1 + | 3 | 2 | three | | | 1 | -1 + | 3 | 2 | three | | 0 | 1 | -1 + | 3 | 2 | three | 1 | -1 | 2 | 2 + | 3 | 2 | three | 2 | 2 | 2 | 2 + | 3 | 2 | three | 3 | -3 | 2 | 2 + | 3 | 2 | three | 2 | 4 | 2 | 2 + | 3 | 2 | three | 5 | -5 | 2 | 2 + | 3 | 2 | three | 5 | -5 | 2 | 2 + | 3 | 2 | three | 0 | | 2 | 2 + | 3 | 2 | three | | | 2 | 2 + | 3 | 2 | three | | 0 | 2 | 2 + | 3 | 2 | three | 1 | -1 | 3 | -3 + | 3 | 2 | three | 2 | 2 | 3 | -3 + | 3 | 2 | three | 3 | -3 | 3 | -3 + | 3 | 2 | three | 2 | 4 | 3 | -3 + | 3 | 2 | three | 5 | -5 | 3 | -3 + | 3 | 2 | three | 5 | -5 | 3 | -3 + | 3 | 2 | three | 0 | | 3 | -3 + | 3 | 2 | three | | | 3 | -3 + | 3 | 2 | three | | 0 | 3 | -3 + | 3 | 2 | three | 1 | -1 | 2 | 4 + | 3 | 2 | three | 2 | 2 | 2 | 4 + | 3 | 2 | three | 3 | -3 | 2 | 4 + | 3 | 2 | three | 2 | 4 | 2 | 4 + | 3 | 2 | three | 5 | -5 | 2 | 4 + | 3 | 2 | three | 5 | -5 | 2 | 4 + | 3 | 2 | three | 0 | | 2 | 4 + | 3 | 2 | three | | | 2 | 4 + | 3 | 2 | three | | 0 | 2 | 4 + | 3 | 2 | three | 1 | -1 | 5 | -5 + | 3 | 2 | three | 2 | 2 | 5 | -5 + | 3 | 2 | three | 3 | -3 | 5 | -5 + | 3 | 2 | three | 2 | 4 | 5 | -5 + | 3 | 2 | three | 5 | -5 | 5 | -5 + | 3 | 2 | three | 5 | -5 | 5 | -5 + | 3 | 2 | three | 0 | | 5 | -5 + | 3 | 2 | three | | | 5 | -5 + | 3 | 2 | three | | 0 | 5 | -5 + | 3 | 2 | three | 1 | -1 | 5 | -5 + | 3 | 2 | three | 2 | 2 | 5 | -5 + | 3 | 2 | three | 3 | -3 | 5 | -5 + | 3 | 2 | three | 2 | 4 | 5 | -5 + | 3 | 2 | three | 5 | -5 | 5 | -5 + | 3 | 2 | three | 5 | -5 | 5 | -5 + | 3 | 2 | three | 0 | | 5 | -5 + | 3 | 2 | three | | | 5 | -5 + | 3 | 2 | three | | 0 | 5 | -5 + | 3 | 2 | three | 1 | -1 | 0 | + | 3 | 2 | three | 2 | 2 | 0 | + | 3 | 2 | three | 3 | -3 | 0 | + | 3 | 2 | three | 2 | 4 | 0 | + | 3 | 2 | three | 5 | -5 | 0 | + | 3 | 2 | three | 5 | -5 | 0 | + | 3 | 2 | three | 0 | | 0 | + | 3 | 2 | three | | | 0 | + | 3 | 2 | three | | 0 | 0 | + | 3 | 2 | three | 1 | -1 | | + | 3 | 2 | three | 2 | 2 | | + | 3 | 2 | three | 3 | -3 | | + | 3 | 2 | three | 2 | 4 | | + | 3 | 2 | three | 5 | -5 | | + | 3 | 2 | three | 5 | -5 | | + | 3 | 2 | three | 0 | | | + | 3 | 2 | three | | | | + | 3 | 2 | three | | 0 | | + | 3 | 2 | three | 1 | -1 | | 0 + | 3 | 2 | three | 2 | 2 | | 0 + | 3 | 2 | three | 3 | -3 | | 0 + | 3 | 2 | three | 2 | 4 | | 0 + | 3 | 2 | three | 5 | -5 | | 0 + | 3 | 2 | three | 5 | -5 | | 0 + | 3 | 2 | three | 0 | | | 0 + | 3 | 2 | three | | | | 0 + | 3 | 2 | three | | 0 | | 0 + | 4 | 1 | four | 1 | -1 | 1 | -1 + | 4 | 1 | four | 2 | 2 | 1 | -1 + | 4 | 1 | four | 3 | -3 | 1 | -1 + | 4 | 1 | four | 2 | 4 | 1 | -1 + | 4 | 1 | four | 5 | -5 | 1 | -1 + | 4 | 1 | four | 5 | -5 | 1 | -1 + | 4 | 1 | four | 0 | | 1 | -1 + | 4 | 1 | four | | | 1 | -1 + | 4 | 1 | four | | 0 | 1 | -1 + | 4 | 1 | four | 1 | -1 | 2 | 2 + | 4 | 1 | four | 2 | 2 | 2 | 2 + | 4 | 1 | four | 3 | -3 | 2 | 2 + | 4 | 1 | four | 2 | 4 | 2 | 2 + | 4 | 1 | four | 5 | -5 | 2 | 2 + | 4 | 1 | four | 5 | -5 | 2 | 2 + | 4 | 1 | four | 0 | | 2 | 2 + | 4 | 1 | four | | | 2 | 2 + | 4 | 1 | four | | 0 | 2 | 2 + | 4 | 1 | four | 1 | -1 | 3 | -3 + | 4 | 1 | four | 2 | 2 | 3 | -3 + | 4 | 1 | four | 3 | -3 | 3 | -3 + | 4 | 1 | four | 2 | 4 | 3 | -3 + | 4 | 1 | four | 5 | -5 | 3 | -3 + | 4 | 1 | four | 5 | -5 | 3 | -3 + | 4 | 1 | four | 0 | | 3 | -3 + | 4 | 1 | four | | | 3 | -3 + | 4 | 1 | four | | 0 | 3 | -3 + | 4 | 1 | four | 1 | -1 | 2 | 4 + | 4 | 1 | four | 2 | 2 | 2 | 4 + | 4 | 1 | four | 3 | -3 | 2 | 4 + | 4 | 1 | four | 2 | 4 | 2 | 4 + | 4 | 1 | four | 5 | -5 | 2 | 4 + | 4 | 1 | four | 5 | -5 | 2 | 4 + | 4 | 1 | four | 0 | | 2 | 4 + | 4 | 1 | four | | | 2 | 4 + | 4 | 1 | four | | 0 | 2 | 4 + | 4 | 1 | four | 1 | -1 | 5 | -5 + | 4 | 1 | four | 2 | 2 | 5 | -5 + | 4 | 1 | four | 3 | -3 | 5 | -5 + | 4 | 1 | four | 2 | 4 | 5 | -5 + | 4 | 1 | four | 5 | -5 | 5 | -5 + | 4 | 1 | four | 5 | -5 | 5 | -5 + | 4 | 1 | four | 0 | | 5 | -5 + | 4 | 1 | four | | | 5 | -5 + | 4 | 1 | four | | 0 | 5 | -5 + | 4 | 1 | four | 1 | -1 | 5 | -5 + | 4 | 1 | four | 2 | 2 | 5 | -5 + | 4 | 1 | four | 3 | -3 | 5 | -5 + | 4 | 1 | four | 2 | 4 | 5 | -5 + | 4 | 1 | four | 5 | -5 | 5 | -5 + | 4 | 1 | four | 5 | -5 | 5 | -5 + | 4 | 1 | four | 0 | | 5 | -5 + | 4 | 1 | four | | | 5 | -5 + | 4 | 1 | four | | 0 | 5 | -5 + | 4 | 1 | four | 1 | -1 | 0 | + | 4 | 1 | four | 2 | 2 | 0 | + | 4 | 1 | four | 3 | -3 | 0 | + | 4 | 1 | four | 2 | 4 | 0 | + | 4 | 1 | four | 5 | -5 | 0 | + | 4 | 1 | four | 5 | -5 | 0 | + | 4 | 1 | four | 0 | | 0 | + | 4 | 1 | four | | | 0 | + | 4 | 1 | four | | 0 | 0 | + | 4 | 1 | four | 1 | -1 | | + | 4 | 1 | four | 2 | 2 | | + | 4 | 1 | four | 3 | -3 | | + | 4 | 1 | four | 2 | 4 | | + | 4 | 1 | four | 5 | -5 | | + | 4 | 1 | four | 5 | -5 | | + | 4 | 1 | four | 0 | | | + | 4 | 1 | four | | | | + | 4 | 1 | four | | 0 | | + | 4 | 1 | four | 1 | -1 | | 0 + | 4 | 1 | four | 2 | 2 | | 0 + | 4 | 1 | four | 3 | -3 | | 0 + | 4 | 1 | four | 2 | 4 | | 0 + | 4 | 1 | four | 5 | -5 | | 0 + | 4 | 1 | four | 5 | -5 | | 0 + | 4 | 1 | four | 0 | | | 0 + | 4 | 1 | four | | | | 0 + | 4 | 1 | four | | 0 | | 0 + | 7 | 7 | seven | 1 | -1 | 1 | -1 + | 7 | 7 | seven | 2 | 2 | 1 | -1 + | 7 | 7 | seven | 3 | -3 | 1 | -1 + | 7 | 7 | seven | 2 | 4 | 1 | -1 + | 7 | 7 | seven | 5 | -5 | 1 | -1 + | 7 | 7 | seven | 5 | -5 | 1 | -1 + | 7 | 7 | seven | 0 | | 1 | -1 + | 7 | 7 | seven | | | 1 | -1 + | 7 | 7 | seven | | 0 | 1 | -1 + | 7 | 7 | seven | 1 | -1 | 2 | 2 + | 7 | 7 | seven | 2 | 2 | 2 | 2 + | 7 | 7 | seven | 3 | -3 | 2 | 2 + | 7 | 7 | seven | 2 | 4 | 2 | 2 + | 7 | 7 | seven | 5 | -5 | 2 | 2 + | 7 | 7 | seven | 5 | -5 | 2 | 2 + | 7 | 7 | seven | 0 | | 2 | 2 + | 7 | 7 | seven | | | 2 | 2 + | 7 | 7 | seven | | 0 | 2 | 2 + | 7 | 7 | seven | 1 | -1 | 3 | -3 + | 7 | 7 | seven | 2 | 2 | 3 | -3 + | 7 | 7 | seven | 3 | -3 | 3 | -3 + | 7 | 7 | seven | 2 | 4 | 3 | -3 + | 7 | 7 | seven | 5 | -5 | 3 | -3 + | 7 | 7 | seven | 5 | -5 | 3 | -3 + | 7 | 7 | seven | 0 | | 3 | -3 + | 7 | 7 | seven | | | 3 | -3 + | 7 | 7 | seven | | 0 | 3 | -3 + | 7 | 7 | seven | 1 | -1 | 2 | 4 + | 7 | 7 | seven | 2 | 2 | 2 | 4 + | 7 | 7 | seven | 3 | -3 | 2 | 4 + | 7 | 7 | seven | 2 | 4 | 2 | 4 + | 7 | 7 | seven | 5 | -5 | 2 | 4 + | 7 | 7 | seven | 5 | -5 | 2 | 4 + | 7 | 7 | seven | 0 | | 2 | 4 + | 7 | 7 | seven | | | 2 | 4 + | 7 | 7 | seven | | 0 | 2 | 4 + | 7 | 7 | seven | 1 | -1 | 5 | -5 + | 7 | 7 | seven | 2 | 2 | 5 | -5 + | 7 | 7 | seven | 3 | -3 | 5 | -5 + | 7 | 7 | seven | 2 | 4 | 5 | -5 + | 7 | 7 | seven | 5 | -5 | 5 | -5 + | 7 | 7 | seven | 5 | -5 | 5 | -5 + | 7 | 7 | seven | 0 | | 5 | -5 + | 7 | 7 | seven | | | 5 | -5 + | 7 | 7 | seven | | 0 | 5 | -5 + | 7 | 7 | seven | 1 | -1 | 5 | -5 + | 7 | 7 | seven | 2 | 2 | 5 | -5 + | 7 | 7 | seven | 3 | -3 | 5 | -5 + | 7 | 7 | seven | 2 | 4 | 5 | -5 + | 7 | 7 | seven | 5 | -5 | 5 | -5 + | 7 | 7 | seven | 5 | -5 | 5 | -5 + | 7 | 7 | seven | 0 | | 5 | -5 + | 7 | 7 | seven | | | 5 | -5 + | 7 | 7 | seven | | 0 | 5 | -5 + | 7 | 7 | seven | 1 | -1 | 0 | + | 7 | 7 | seven | 2 | 2 | 0 | + | 7 | 7 | seven | 3 | -3 | 0 | + | 7 | 7 | seven | 2 | 4 | 0 | + | 7 | 7 | seven | 5 | -5 | 0 | + | 7 | 7 | seven | 5 | -5 | 0 | + | 7 | 7 | seven | 0 | | 0 | + | 7 | 7 | seven | | | 0 | + | 7 | 7 | seven | | 0 | 0 | + | 7 | 7 | seven | 1 | -1 | | + | 7 | 7 | seven | 2 | 2 | | + | 7 | 7 | seven | 3 | -3 | | + | 7 | 7 | seven | 2 | 4 | | + | 7 | 7 | seven | 5 | -5 | | + | 7 | 7 | seven | 5 | -5 | | + | 7 | 7 | seven | 0 | | | + | 7 | 7 | seven | | | | + | 7 | 7 | seven | | 0 | | + | 7 | 7 | seven | 1 | -1 | | 0 + | 7 | 7 | seven | 2 | 2 | | 0 + | 7 | 7 | seven | 3 | -3 | | 0 + | 7 | 7 | seven | 2 | 4 | | 0 + | 7 | 7 | seven | 5 | -5 | | 0 + | 7 | 7 | seven | 5 | -5 | | 0 + | 7 | 7 | seven | 0 | | | 0 + | 7 | 7 | seven | | | | 0 + | 7 | 7 | seven | | 0 | | 0 + | 8 | 8 | eight | 1 | -1 | 1 | -1 + | 8 | 8 | eight | 2 | 2 | 1 | -1 + | 8 | 8 | eight | 3 | -3 | 1 | -1 + | 8 | 8 | eight | 2 | 4 | 1 | -1 + | 8 | 8 | eight | 5 | -5 | 1 | -1 + | 8 | 8 | eight | 5 | -5 | 1 | -1 + | 8 | 8 | eight | 0 | | 1 | -1 + | 8 | 8 | eight | | | 1 | -1 + | 8 | 8 | eight | | 0 | 1 | -1 + | 8 | 8 | eight | 1 | -1 | 2 | 2 + | 8 | 8 | eight | 2 | 2 | 2 | 2 + | 8 | 8 | eight | 3 | -3 | 2 | 2 + | 8 | 8 | eight | 2 | 4 | 2 | 2 + | 8 | 8 | eight | 5 | -5 | 2 | 2 + | 8 | 8 | eight | 5 | -5 | 2 | 2 + | 8 | 8 | eight | 0 | | 2 | 2 + | 8 | 8 | eight | | | 2 | 2 + | 8 | 8 | eight | | 0 | 2 | 2 + | 8 | 8 | eight | 1 | -1 | 3 | -3 + | 8 | 8 | eight | 2 | 2 | 3 | -3 + | 8 | 8 | eight | 3 | -3 | 3 | -3 + | 8 | 8 | eight | 2 | 4 | 3 | -3 + | 8 | 8 | eight | 5 | -5 | 3 | -3 + | 8 | 8 | eight | 5 | -5 | 3 | -3 + | 8 | 8 | eight | 0 | | 3 | -3 + | 8 | 8 | eight | | | 3 | -3 + | 8 | 8 | eight | | 0 | 3 | -3 + | 8 | 8 | eight | 1 | -1 | 2 | 4 + | 8 | 8 | eight | 2 | 2 | 2 | 4 + | 8 | 8 | eight | 3 | -3 | 2 | 4 + | 8 | 8 | eight | 2 | 4 | 2 | 4 + | 8 | 8 | eight | 5 | -5 | 2 | 4 + | 8 | 8 | eight | 5 | -5 | 2 | 4 + | 8 | 8 | eight | 0 | | 2 | 4 + | 8 | 8 | eight | | | 2 | 4 + | 8 | 8 | eight | | 0 | 2 | 4 + | 8 | 8 | eight | 1 | -1 | 5 | -5 + | 8 | 8 | eight | 2 | 2 | 5 | -5 + | 8 | 8 | eight | 3 | -3 | 5 | -5 + | 8 | 8 | eight | 2 | 4 | 5 | -5 + | 8 | 8 | eight | 5 | -5 | 5 | -5 + | 8 | 8 | eight | 5 | -5 | 5 | -5 + | 8 | 8 | eight | 0 | | 5 | -5 + | 8 | 8 | eight | | | 5 | -5 + | 8 | 8 | eight | | 0 | 5 | -5 + | 8 | 8 | eight | 1 | -1 | 5 | -5 + | 8 | 8 | eight | 2 | 2 | 5 | -5 + | 8 | 8 | eight | 3 | -3 | 5 | -5 + | 8 | 8 | eight | 2 | 4 | 5 | -5 + | 8 | 8 | eight | 5 | -5 | 5 | -5 + | 8 | 8 | eight | 5 | -5 | 5 | -5 + | 8 | 8 | eight | 0 | | 5 | -5 + | 8 | 8 | eight | | | 5 | -5 + | 8 | 8 | eight | | 0 | 5 | -5 + | 8 | 8 | eight | 1 | -1 | 0 | + | 8 | 8 | eight | 2 | 2 | 0 | + | 8 | 8 | eight | 3 | -3 | 0 | + | 8 | 8 | eight | 2 | 4 | 0 | + | 8 | 8 | eight | 5 | -5 | 0 | + | 8 | 8 | eight | 5 | -5 | 0 | + | 8 | 8 | eight | 0 | | 0 | + | 8 | 8 | eight | | | 0 | + | 8 | 8 | eight | | 0 | 0 | + | 8 | 8 | eight | 1 | -1 | | + | 8 | 8 | eight | 2 | 2 | | + | 8 | 8 | eight | 3 | -3 | | + | 8 | 8 | eight | 2 | 4 | | + | 8 | 8 | eight | 5 | -5 | | + | 8 | 8 | eight | 5 | -5 | | + | 8 | 8 | eight | 0 | | | + | 8 | 8 | eight | | | | + | 8 | 8 | eight | | 0 | | + | 8 | 8 | eight | 1 | -1 | | 0 + | 8 | 8 | eight | 2 | 2 | | 0 + | 8 | 8 | eight | 3 | -3 | | 0 + | 8 | 8 | eight | 2 | 4 | | 0 + | 8 | 8 | eight | 5 | -5 | | 0 + | 8 | 8 | eight | 5 | -5 | | 0 + | 8 | 8 | eight | 0 | | | 0 + | 8 | 8 | eight | | | | 0 + | 8 | 8 | eight | | 0 | | 0 + | | | null | 1 | -1 | 1 | -1 + | | | null | 2 | 2 | 1 | -1 + | | | null | 3 | -3 | 1 | -1 + | | | null | 2 | 4 | 1 | -1 + | | | null | 5 | -5 | 1 | -1 + | | | null | 5 | -5 | 1 | -1 + | | | null | 0 | | 1 | -1 + | | | null | | | 1 | -1 + | | | null | | 0 | 1 | -1 + | | | null | 1 | -1 | 2 | 2 + | | | null | 2 | 2 | 2 | 2 + | | | null | 3 | -3 | 2 | 2 + | | | null | 2 | 4 | 2 | 2 + | | | null | 5 | -5 | 2 | 2 + | | | null | 5 | -5 | 2 | 2 + | | | null | 0 | | 2 | 2 + | | | null | | | 2 | 2 + | | | null | | 0 | 2 | 2 + | | | null | 1 | -1 | 3 | -3 + | | | null | 2 | 2 | 3 | -3 + | | | null | 3 | -3 | 3 | -3 + | | | null | 2 | 4 | 3 | -3 + | | | null | 5 | -5 | 3 | -3 + | | | null | 5 | -5 | 3 | -3 + | | | null | 0 | | 3 | -3 + | | | null | | | 3 | -3 + | | | null | | 0 | 3 | -3 + | | | null | 1 | -1 | 2 | 4 + | | | null | 2 | 2 | 2 | 4 + | | | null | 3 | -3 | 2 | 4 + | | | null | 2 | 4 | 2 | 4 + | | | null | 5 | -5 | 2 | 4 + | | | null | 5 | -5 | 2 | 4 + | | | null | 0 | | 2 | 4 + | | | null | | | 2 | 4 + | | | null | | 0 | 2 | 4 + | | | null | 1 | -1 | 5 | -5 + | | | null | 2 | 2 | 5 | -5 + | | | null | 3 | -3 | 5 | -5 + | | | null | 2 | 4 | 5 | -5 + | | | null | 5 | -5 | 5 | -5 + | | | null | 5 | -5 | 5 | -5 + | | | null | 0 | | 5 | -5 + | | | null | | | 5 | -5 + | | | null | | 0 | 5 | -5 + | | | null | 1 | -1 | 5 | -5 + | | | null | 2 | 2 | 5 | -5 + | | | null | 3 | -3 | 5 | -5 + | | | null | 2 | 4 | 5 | -5 + | | | null | 5 | -5 | 5 | -5 + | | | null | 5 | -5 | 5 | -5 + | | | null | 0 | | 5 | -5 + | | | null | | | 5 | -5 + | | | null | | 0 | 5 | -5 + | | | null | 1 | -1 | 0 | + | | | null | 2 | 2 | 0 | + | | | null | 3 | -3 | 0 | + | | | null | 2 | 4 | 0 | + | | | null | 5 | -5 | 0 | + | | | null | 5 | -5 | 0 | + | | | null | 0 | | 0 | + | | | null | | | 0 | + | | | null | | 0 | 0 | + | | | null | 1 | -1 | | + | | | null | 2 | 2 | | + | | | null | 3 | -3 | | + | | | null | 2 | 4 | | + | | | null | 5 | -5 | | + | | | null | 5 | -5 | | + | | | null | 0 | | | + | | | null | | | | + | | | null | | 0 | | + | | | null | 1 | -1 | | 0 + | | | null | 2 | 2 | | 0 + | | | null | 3 | -3 | | 0 + | | | null | 2 | 4 | | 0 + | | | null | 5 | -5 | | 0 + | | | null | 5 | -5 | | 0 + | | | null | 0 | | | 0 + | | | null | | | | 0 + | | | null | | 0 | | 0 + | | 0 | zero | 1 | -1 | 1 | -1 + | | 0 | zero | 2 | 2 | 1 | -1 + | | 0 | zero | 3 | -3 | 1 | -1 + | | 0 | zero | 2 | 4 | 1 | -1 + | | 0 | zero | 5 | -5 | 1 | -1 + | | 0 | zero | 5 | -5 | 1 | -1 + | | 0 | zero | 0 | | 1 | -1 + | | 0 | zero | | | 1 | -1 + | | 0 | zero | | 0 | 1 | -1 + | | 0 | zero | 1 | -1 | 2 | 2 + | | 0 | zero | 2 | 2 | 2 | 2 + | | 0 | zero | 3 | -3 | 2 | 2 + | | 0 | zero | 2 | 4 | 2 | 2 + | | 0 | zero | 5 | -5 | 2 | 2 + | | 0 | zero | 5 | -5 | 2 | 2 + | | 0 | zero | 0 | | 2 | 2 + | | 0 | zero | | | 2 | 2 + | | 0 | zero | | 0 | 2 | 2 + | | 0 | zero | 1 | -1 | 3 | -3 + | | 0 | zero | 2 | 2 | 3 | -3 + | | 0 | zero | 3 | -3 | 3 | -3 + | | 0 | zero | 2 | 4 | 3 | -3 + | | 0 | zero | 5 | -5 | 3 | -3 + | | 0 | zero | 5 | -5 | 3 | -3 + | | 0 | zero | 0 | | 3 | -3 + | | 0 | zero | | | 3 | -3 + | | 0 | zero | | 0 | 3 | -3 + | | 0 | zero | 1 | -1 | 2 | 4 + | | 0 | zero | 2 | 2 | 2 | 4 + | | 0 | zero | 3 | -3 | 2 | 4 + | | 0 | zero | 2 | 4 | 2 | 4 + | | 0 | zero | 5 | -5 | 2 | 4 + | | 0 | zero | 5 | -5 | 2 | 4 + | | 0 | zero | 0 | | 2 | 4 + | | 0 | zero | | | 2 | 4 + | | 0 | zero | | 0 | 2 | 4 + | | 0 | zero | 1 | -1 | 5 | -5 + | | 0 | zero | 2 | 2 | 5 | -5 + | | 0 | zero | 3 | -3 | 5 | -5 + | | 0 | zero | 2 | 4 | 5 | -5 + | | 0 | zero | 5 | -5 | 5 | -5 + | | 0 | zero | 5 | -5 | 5 | -5 + | | 0 | zero | 0 | | 5 | -5 + | | 0 | zero | | | 5 | -5 + | | 0 | zero | | 0 | 5 | -5 + | | 0 | zero | 1 | -1 | 5 | -5 + | | 0 | zero | 2 | 2 | 5 | -5 + | | 0 | zero | 3 | -3 | 5 | -5 + | | 0 | zero | 2 | 4 | 5 | -5 + | | 0 | zero | 5 | -5 | 5 | -5 + | | 0 | zero | 5 | -5 | 5 | -5 + | | 0 | zero | 0 | | 5 | -5 + | | 0 | zero | | | 5 | -5 + | | 0 | zero | | 0 | 5 | -5 + | | 0 | zero | 1 | -1 | 0 | + | | 0 | zero | 2 | 2 | 0 | + | | 0 | zero | 3 | -3 | 0 | + | | 0 | zero | 2 | 4 | 0 | + | | 0 | zero | 5 | -5 | 0 | + | | 0 | zero | 5 | -5 | 0 | + | | 0 | zero | 0 | | 0 | + | | 0 | zero | | | 0 | + | | 0 | zero | | 0 | 0 | + | | 0 | zero | 1 | -1 | | + | | 0 | zero | 2 | 2 | | + | | 0 | zero | 3 | -3 | | + | | 0 | zero | 2 | 4 | | + | | 0 | zero | 5 | -5 | | + | | 0 | zero | 5 | -5 | | + | | 0 | zero | 0 | | | + | | 0 | zero | | | | + | | 0 | zero | | 0 | | + | | 0 | zero | 1 | -1 | | 0 + | | 0 | zero | 2 | 2 | | 0 + | | 0 | zero | 3 | -3 | | 0 + | | 0 | zero | 2 | 4 | | 0 + | | 0 | zero | 5 | -5 | | 0 + | | 0 | zero | 5 | -5 | | 0 + | | 0 | zero | 0 | | | 0 + | | 0 | zero | | | | 0 + | | 0 | zero | | 0 | | 0 +(891 rows) + +-- +-- +-- Inner joins (equi-joins) +-- +-- +-- +-- Inner joins (equi-joins) with USING clause +-- The USING syntax changes the shape of the resulting table +-- by including a column in the USING clause only once in the result. +-- +-- Inner equi-join on specified column +SELECT '' AS "xxx", * + FROM J1_TBL INNER JOIN J2_TBL USING (i); + xxx | i | j | t | k +-----+---+---+-------+---- + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 + | 1 | 4 | one | -1 + | 0 | | zero | + | 2 | 3 | two | 4 + | 2 | 3 | two | 2 + | 3 | 2 | three | -3 +(7 rows) + +-- Same as above, slightly different syntax +SELECT '' AS "xxx", * + FROM J1_TBL JOIN J2_TBL USING (i); + xxx | i | j | t | k +-----+---+---+-------+---- + | 2 | 3 | two | 4 + | 2 | 3 | two | 2 + | 3 | 2 | three | -3 + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 + | 1 | 4 | one | -1 + | 0 | | zero | +(7 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL t1 (a, b, c) JOIN J2_TBL t2 (a, d) USING (a) + ORDER BY a, d; + xxx | a | b | c | d +-----+---+---+-------+---- + | 0 | | zero | + | 1 | 4 | one | -1 + | 2 | 3 | two | 2 + | 2 | 3 | two | 4 + | 3 | 2 | three | -3 + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 +(7 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL t1 (a, b, c) JOIN J2_TBL t2 (a, b) USING (b) + ORDER BY b, t1.a; + xxx | b | a | c | a +-----+---+---+-------+--- + | 0 | 5 | five | + | 0 | | zero | + | 2 | 3 | three | 2 + | 4 | 1 | one | 2 +(4 rows) + +-- +-- NATURAL JOIN +-- Inner equi-join on all columns with the same name +-- +SELECT '' AS "xxx", * + FROM J1_TBL NATURAL JOIN J2_TBL; + xxx | i | j | t | k +-----+---+---+-------+---- + | 1 | 4 | one | -1 + | 0 | | zero | + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 + | 2 | 3 | two | 4 + | 2 | 3 | two | 2 + | 3 | 2 | three | -3 +(7 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (a, d); + xxx | a | b | c | d +-----+---+---+-------+---- + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 + | 1 | 4 | one | -1 + | 0 | | zero | + | 2 | 3 | two | 4 + | 2 | 3 | two | 2 + | 3 | 2 | three | -3 +(7 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a); + xxx | a | b | c | d +-----+---+---+------+--- + | 0 | | zero | + | 2 | 3 | two | 2 + | 4 | 1 | four | 2 +(3 rows) + +-- mismatch number of columns +-- currently, Postgres will fill in with underlying names +SELECT '' AS "xxx", * + FROM J1_TBL t1 (a, b) NATURAL JOIN J2_TBL t2 (a); + xxx | a | b | t | k +-----+---+---+-------+---- + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 + | 2 | 3 | two | 4 + | 2 | 3 | two | 2 + | 3 | 2 | three | -3 + | 1 | 4 | one | -1 + | 0 | | zero | +(7 rows) + +-- +-- Inner joins (equi-joins) +-- +SELECT '' AS "xxx", * + FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.i); + xxx | i | j | t | i | k +-----+---+---+-------+---+---- + | 1 | 4 | one | 1 | -1 + | 0 | | zero | 0 | + | 2 | 3 | two | 2 | 4 + | 2 | 3 | two | 2 | 2 + | 3 | 2 | three | 3 | -3 + | 5 | 0 | five | 5 | -5 + | 5 | 0 | five | 5 | -5 +(7 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.k); + xxx | i | j | t | i | k +-----+---+---+------+---+--- + | 0 | | zero | | 0 + | 2 | 3 | two | 2 | 2 + | 4 | 1 | four | 2 | 4 +(3 rows) + +-- +-- Non-equi-joins +-- +SELECT '' AS "xxx", * + FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i <= J2_TBL.k); + xxx | i | j | t | i | k +-----+---+---+-------+---+--- + | 1 | 4 | one | 2 | 2 + | 1 | 4 | one | 2 | 4 + | 0 | | zero | 2 | 2 + | 0 | | zero | 2 | 4 + | 0 | | zero | | 0 + | 2 | 3 | two | 2 | 2 + | 2 | 3 | two | 2 | 4 + | 3 | 2 | three | 2 | 4 + | 4 | 1 | four | 2 | 4 +(9 rows) + +-- +-- Outer joins +-- Note that OUTER is a noise word +-- +SELECT '' AS "xxx", * + FROM J1_TBL LEFT OUTER JOIN J2_TBL USING (i) + ORDER BY i, k, t; + xxx | i | j | t | k +-----+---+---+-------+---- + | 0 | | zero | + | 1 | 4 | one | -1 + | 2 | 3 | two | 2 + | 2 | 3 | two | 4 + | 3 | 2 | three | -3 + | 4 | 1 | four | + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 + | 6 | 6 | six | + | 7 | 7 | seven | + | 8 | 8 | eight | + | | | null | + | | 0 | zero | +(13 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL LEFT JOIN J2_TBL USING (i) + ORDER BY i, k, t; + xxx | i | j | t | k +-----+---+---+-------+---- + | 0 | | zero | + | 1 | 4 | one | -1 + | 2 | 3 | two | 2 + | 2 | 3 | two | 4 + | 3 | 2 | three | -3 + | 4 | 1 | four | + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 + | 6 | 6 | six | + | 7 | 7 | seven | + | 8 | 8 | eight | + | | | null | + | | 0 | zero | +(13 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL RIGHT OUTER JOIN J2_TBL USING (i); + xxx | i | j | t | k +-----+---+---+-------+---- + | 2 | 3 | two | 2 + | 3 | 2 | three | -3 + | 2 | 3 | two | 4 + | | | | + | | | | 0 + | 1 | 4 | one | -1 + | 0 | | zero | + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 +(9 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL RIGHT JOIN J2_TBL USING (i); + xxx | i | j | t | k +-----+---+---+-------+---- + | 2 | 3 | two | 2 + | 3 | 2 | three | -3 + | 2 | 3 | two | 4 + | | | | + | | | | 0 + | 1 | 4 | one | -1 + | 0 | | zero | + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 +(9 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL FULL OUTER JOIN J2_TBL USING (i) + ORDER BY i, k, t; + xxx | i | j | t | k +-----+---+---+-------+---- + | 0 | | zero | + | 1 | 4 | one | -1 + | 2 | 3 | two | 2 + | 2 | 3 | two | 4 + | 3 | 2 | three | -3 + | 4 | 1 | four | + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 + | 6 | 6 | six | + | 7 | 7 | seven | + | 8 | 8 | eight | + | | | | 0 + | | | null | + | | 0 | zero | + | | | | +(15 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL FULL JOIN J2_TBL USING (i) + ORDER BY i, k, t; + xxx | i | j | t | k +-----+---+---+-------+---- + | 0 | | zero | + | 1 | 4 | one | -1 + | 2 | 3 | two | 2 + | 2 | 3 | two | 4 + | 3 | 2 | three | -3 + | 4 | 1 | four | + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 + | 6 | 6 | six | + | 7 | 7 | seven | + | 8 | 8 | eight | + | | | | 0 + | | | null | + | | 0 | zero | + | | | | +(15 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL LEFT JOIN J2_TBL USING (i) WHERE (k = 1); + xxx | i | j | t | k +-----+---+---+---+--- +(0 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL LEFT JOIN J2_TBL USING (i) WHERE (i = 1); + xxx | i | j | t | k +-----+---+---+-----+---- + | 1 | 4 | one | -1 +(1 row) + +-- +-- Multiway full join +-- +CREATE TABLE t1 (name TEXT, n INTEGER); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'name' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE t2 (name TEXT, n INTEGER) distributed replicated; +CREATE TABLE t3 (name TEXT, n INTEGER); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'name' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +INSERT INTO t1 VALUES ( 'bb', 11 ); +INSERT INTO t2 VALUES ( 'bb', 12 ); +INSERT INTO t2 VALUES ( 'cc', 22 ); +INSERT INTO t2 VALUES ( 'ee', 42 ); +INSERT INTO t3 VALUES ( 'bb', 13 ); +INSERT INTO t3 VALUES ( 'cc', 23 ); +INSERT INTO t3 VALUES ( 'dd', 33 ); +SELECT * FROM t1 FULL JOIN t2 USING (name) FULL JOIN t3 USING (name); + name | n | n | n +------+----+----+---- + bb | 11 | 12 | 13 + cc | | 22 | 23 + ee | | 42 | + dd | | | 33 +(4 rows) + +-- +-- Test interactions of join syntax and subqueries +-- +-- Basic cases (we expect planner to pull up the subquery here) +SELECT * FROM +(SELECT * FROM t2) as s2 +INNER JOIN +(SELECT * FROM t3) s3 +USING (name); + name | n | n +------+----+---- + bb | 12 | 13 + cc | 22 | 23 +(2 rows) + +SELECT * FROM +(SELECT * FROM t2) as s2 +LEFT JOIN +(SELECT * FROM t3) s3 +USING (name); + name | n | n +------+----+---- + ee | 42 | + cc | 22 | 23 + bb | 12 | 13 +(3 rows) + +SELECT * FROM +(SELECT * FROM t2) as s2 +FULL JOIN +(SELECT * FROM t3) s3 +USING (name); + name | n | n +------+----+---- + ee | 42 | + bb | 12 | 13 + dd | | 33 + cc | 22 | 23 +(4 rows) + +-- Cases with non-nullable expressions in subquery results; +-- make sure these go to null as expected +SELECT * FROM +(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 +NATURAL INNER JOIN +(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; + name | s2_n | s2_2 | s3_n | s3_2 +------+------+------+------+------ + bb | 12 | 2 | 13 | 3 + cc | 22 | 2 | 23 | 3 +(2 rows) + +SELECT * FROM +(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 +NATURAL LEFT JOIN +(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; + name | s2_n | s2_2 | s3_n | s3_2 +------+------+------+------+------ + bb | 12 | 2 | 13 | 3 + ee | 42 | 2 | | + cc | 22 | 2 | 23 | 3 +(3 rows) + +SELECT * FROM +(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 +NATURAL FULL JOIN +(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; + name | s2_n | s2_2 | s3_n | s3_2 +------+------+------+------+------ + bb | 12 | 2 | 13 | 3 + cc | 22 | 2 | 23 | 3 + ee | 42 | 2 | | + dd | | | 33 | 3 +(4 rows) + +SELECT * FROM +(SELECT name, n as s1_n, 1 as s1_1 FROM t1) as s1 +NATURAL INNER JOIN +(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 +NATURAL INNER JOIN +(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; + name | s1_n | s1_1 | s2_n | s2_2 | s3_n | s3_2 +------+------+------+------+------+------+------ + bb | 11 | 1 | 12 | 2 | 13 | 3 +(1 row) + +SELECT * FROM +(SELECT name, n as s1_n, 1 as s1_1 FROM t1) as s1 +NATURAL FULL JOIN +(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 +NATURAL FULL JOIN +(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; + name | s1_n | s1_1 | s2_n | s2_2 | s3_n | s3_2 +------+------+------+------+------+------+------ + bb | 11 | 1 | 12 | 2 | 13 | 3 + cc | | | 22 | 2 | 23 | 3 + ee | | | 42 | 2 | | + dd | | | | | 33 | 3 +(4 rows) + +SELECT * FROM +(SELECT name, n as s1_n FROM t1) as s1 +NATURAL FULL JOIN + (SELECT * FROM + (SELECT name, n as s2_n FROM t2) as s2 + NATURAL FULL JOIN + (SELECT name, n as s3_n FROM t3) as s3 + ) ss2; + name | s1_n | s2_n | s3_n +------+------+------+------ + ee | | 42 | + cc | | 22 | 23 + bb | 11 | 12 | 13 + dd | | | 33 +(4 rows) + +SELECT * FROM +(SELECT name, n as s1_n FROM t1) as s1 +NATURAL FULL JOIN + (SELECT * FROM + (SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 + NATURAL FULL JOIN + (SELECT name, n as s3_n FROM t3) as s3 + ) ss2; + name | s1_n | s2_n | s2_2 | s3_n +------+------+------+------+------ + bb | 11 | 12 | 2 | 13 + dd | | | | 33 + cc | | 22 | 2 | 23 + ee | | 42 | 2 | +(4 rows) + +-- Test for propagation of nullability constraints into sub-joins +create temp table x (x1 int, x2 int) distributed replicated; +insert into x values (1,11); +insert into x values (2,22); +insert into x values (3,null); +insert into x values (4,44); +insert into x values (5,null); +create temp table y (y1 int, y2 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'y1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into y values (1,111); +insert into y values (2,222); +insert into y values (3,333); +insert into y values (4,null); +select * from x; + x1 | x2 +----+---- + 1 | 11 + 2 | 22 + 3 | + 4 | 44 + 5 | +(5 rows) + +select * from y; + y1 | y2 +----+----- + 1 | 111 + 2 | 222 + 3 | 333 + 4 | +(4 rows) + +select * from x left join y on (x1 = y1 and x2 is not null); + x1 | x2 | y1 | y2 +----+----+----+----- + 1 | 11 | 1 | 111 + 5 | | | + 2 | 22 | 2 | 222 + 3 | | | + 4 | 44 | 4 | +(5 rows) + +select * from x left join y on (x1 = y1 and y2 is not null); + x1 | x2 | y1 | y2 +----+----+----+----- + 1 | 11 | 1 | 111 + 2 | 22 | 2 | 222 + 3 | | 3 | 333 + 4 | 44 | | + 5 | | | +(5 rows) + +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1); + x1 | x2 | y1 | y2 | xx1 | xx2 +----+----+----+-----+-----+----- + 2 | 22 | 2 | 222 | 2 | 22 + 3 | | 3 | 333 | 3 | + 4 | 44 | 4 | | 4 | 44 + 5 | | | | 5 | + 1 | 11 | 1 | 111 | 1 | 11 +(5 rows) + +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1 and x2 is not null); + x1 | x2 | y1 | y2 | xx1 | xx2 +----+----+----+-----+-----+----- + 2 | 22 | 2 | 222 | 2 | 22 + 3 | | 3 | 333 | | + 4 | 44 | 4 | | 4 | 44 + 5 | | | | | + 1 | 11 | 1 | 111 | 1 | 11 +(5 rows) + +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1 and y2 is not null); + x1 | x2 | y1 | y2 | xx1 | xx2 +----+----+----+-----+-----+----- + 2 | 22 | 2 | 222 | 2 | 22 + 3 | | 3 | 333 | 3 | + 4 | 44 | 4 | | | + 1 | 11 | 1 | 111 | 1 | 11 + 5 | | | | | +(5 rows) + +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1 and xx2 is not null); + x1 | x2 | y1 | y2 | xx1 | xx2 +----+----+----+-----+-----+----- + 2 | 22 | 2 | 222 | 2 | 22 + 3 | | 3 | 333 | | + 4 | 44 | 4 | | 4 | 44 + 1 | 11 | 1 | 111 | 1 | 11 + 5 | | | | | +(5 rows) + +-- these should NOT give the same answers as above +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1) where (x2 is not null); + x1 | x2 | y1 | y2 | xx1 | xx2 +----+----+----+-----+-----+----- + 1 | 11 | 1 | 111 | 1 | 11 + 2 | 22 | 2 | 222 | 2 | 22 + 4 | 44 | 4 | | 4 | 44 +(3 rows) + +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1) where (y2 is not null); + x1 | x2 | y1 | y2 | xx1 | xx2 +----+----+----+-----+-----+----- + 2 | 22 | 2 | 222 | 2 | 22 + 3 | | 3 | 333 | 3 | + 1 | 11 | 1 | 111 | 1 | 11 +(3 rows) + +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1) where (xx2 is not null); + x1 | x2 | y1 | y2 | xx1 | xx2 +----+----+----+-----+-----+----- + 1 | 11 | 1 | 111 | 1 | 11 + 2 | 22 | 2 | 222 | 2 | 22 + 4 | 44 | 4 | | 4 | 44 +(3 rows) + +-- +-- regression test: check for bug with propagation of implied equality +-- to outside an IN +-- +create table foo (unique1 int, unique2 int) distributed replicated; +insert into foo values (1, 2), (2, 42); +select count(*) from foo a where unique1 in + (select unique1 from foo b join foo c using (unique1) + where b.unique2 = 42); + count +------- + 1 +(1 row) + +drop table if exists foo; +-- Both DELETE and UPDATE allow the specification of additional tables +-- to "join" against to determine which rows should be modified. +CREATE TEMP TABLE t1 (a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TEMP TABLE t2 (a int, b int) distributed replicated; +CREATE TEMP TABLE t3 (x int, y int) distributed replicated; +CREATE TEMP TABLE t4 (x int, y int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'x' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +INSERT INTO t1 VALUES (5, 10); +INSERT INTO t1 VALUES (15, 20); +INSERT INTO t1 VALUES (100, 100); +INSERT INTO t1 VALUES (200, 1000); +INSERT INTO t2 VALUES (200, 2000); +INSERT INTO t3 VALUES (5, 20); +INSERT INTO t3 VALUES (6, 7); +INSERT INTO t3 VALUES (7, 8); +INSERT INTO t3 VALUES (500, 100); +INSERT INTO t4 SELECT * FROM t3; +DELETE FROM t3 USING t1 table1 WHERE t3.x = table1.a; +SELECT * FROM t3; + x | y +-----+----- + 6 | 7 + 7 | 8 + 500 | 100 +(3 rows) + +DELETE FROM t4 USING t1 JOIN t2 USING (a) WHERE t4.x > t1.a; +SELECT * FROM t4; + x | y +---+---- + 5 | 20 + 6 | 7 + 7 | 8 +(3 rows) + +DELETE FROM t3 USING t3 t3_other WHERE t3.x = t3_other.x AND t3.y = t3_other.y; +SELECT * FROM t3; + x | y +---+--- +(0 rows) + +-- +-- regression test for 8.1 merge right join bug +-- +CREATE TEMP TABLE tt1 ( tt1_id int4, joincol int4 ) distributed replicated; +INSERT INTO tt1 VALUES (1, 11); +INSERT INTO tt1 VALUES (2, NULL); +CREATE TEMP TABLE tt2 ( tt2_id int4, joincol int4 ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'tt2_id' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +INSERT INTO tt2 VALUES (21, 11); +INSERT INTO tt2 VALUES (22, 11); +set enable_hashjoin to off; +set enable_nestloop to off; +-- these should give the same results +select tt1.*, tt2.* from tt1 left join tt2 on tt1.joincol = tt2.joincol; + tt1_id | joincol | tt2_id | joincol +--------+---------+--------+--------- + 2 | | | + 1 | 11 | 21 | 11 + 1 | 11 | 22 | 11 +(3 rows) + +select tt1.*, tt2.* from tt2 right join tt1 on tt1.joincol = tt2.joincol; + tt1_id | joincol | tt2_id | joincol +--------+---------+--------+--------- + 1 | 11 | 21 | 11 + 1 | 11 | 22 | 11 + 2 | | | +(3 rows) + +reset enable_hashjoin; +reset enable_nestloop; +-- +-- regression test for 8.2 bug with improper re-ordering of left joins +-- +create temp table tt3(f1 int, f2 text) distributed replicated; +insert into tt3 select x, repeat('xyzzy', 100) from generate_series(1,10000) x; +create index tt3i on tt3(f1); +analyze tt3; +create temp table tt4(f1 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into tt4 values (0),(1),(9999); +analyze tt4; +SELECT a.f1 +FROM tt4 a +LEFT JOIN ( + SELECT b.f1 + FROM tt3 b LEFT JOIN tt3 c ON (b.f1 = c.f1) + WHERE c.f1 IS NULL +) AS d ON (a.f1 = d.f1) +WHERE d.f1 IS NULL; + f1 +------ + 9999 + 0 + 1 +(3 rows) + +-- +-- regression test for problems of the sort depicted in bug #3494 +-- +create temp table tt5(f1 int, f2 int) distributed replicated; +create temp table tt6(f1 int, f2 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into tt5 values(1, 10); +insert into tt5 values(1, 11); +insert into tt6 values(1, 9); +insert into tt6 values(1, 2); +insert into tt6 values(2, 9); +select * from tt5,tt6 where tt5.f1 = tt6.f1 and tt5.f1 = tt5.f2 - tt6.f2; + f1 | f2 | f1 | f2 +----+----+----+---- + 1 | 10 | 1 | 9 +(1 row) + +-- +-- regression test for problems of the sort depicted in bug #3588 +-- +create temp table xx (pkxx int) distributed replicated; +create temp table yy (pkyy int, pkxx int) distributed replicated; +insert into xx values (1); +insert into xx values (2); +insert into xx values (3); +insert into yy values (101, 1); +insert into yy values (201, 2); +insert into yy values (301, NULL); +select yy.pkyy as yy_pkyy, yy.pkxx as yy_pkxx, yya.pkyy as yya_pkyy, + xxa.pkxx as xxa_pkxx, xxb.pkxx as xxb_pkxx +from yy + left join (SELECT * FROM yy where pkyy = 101) as yya ON yy.pkyy = yya.pkyy + left join xx xxa on yya.pkxx = xxa.pkxx + left join xx xxb on coalesce (xxa.pkxx, 1) = xxb.pkxx; + yy_pkyy | yy_pkxx | yya_pkyy | xxa_pkxx | xxb_pkxx +---------+---------+----------+----------+---------- + 101 | 1 | 101 | 1 | 1 + 201 | 2 | | | 1 + 301 | | | | 1 +(3 rows) + +-- +-- regression test for improper pushing of constants across outer-join clauses +-- (as seen in early 8.2.x releases) +-- +create temp table zt1 (f1 int primary key); +create temp table zt2 (f2 int primary key); +create temp table zt3 (f3 int primary key) distributed replicated; +insert into zt1 values(53); +insert into zt2 values(53); +select * from + zt2 left join zt3 on (f2 = f3) + left join zt1 on (f3 = f1) +where f2 = 53; + f2 | f3 | f1 +----+----+---- + 53 | | +(1 row) + +create temp view zv1 as select *,'dummy'::text AS junk from zt1; +select * from + zt2 left join zt3 on (f2 = f3) + left join zv1 on (f3 = f1) +where f2 = 53; + f2 | f3 | f1 | junk +----+----+----+------ + 53 | | | +(1 row) + +-- +-- regression test for nest loop join of rpt and entry +-- +create temp table t_5628 (c1 int, c2 int) distributed replicated; +insert into t_5628 values (1,1), (2,2); +set enable_indexscan to off; +set enable_bitmapscan to off; +explain (costs off) select max(c1) from pg_class left join t_5628 on true; + QUERY PLAN +------------------------------------------------------------ + Aggregate + -> Nested Loop Left Join + -> Seq Scan on pg_class + -> Materialize + -> Gather Motion 1:1 (slice1; segments: 1) + -> Seq Scan on t_5628 + Optimizer: Postgres query optimizer +(7 rows) + +select max(c1) from pg_class left join t_5628 on true; + max +----- + 2 +(1 row) + +-- +-- Writeable CTE on replicated table join with other tables. +-- See issue https://github.com/greenplum-db/gpdb/issues/15860 +-- +select gp_debug_set_create_table_default_numsegments(2); + gp_debug_set_create_table_default_numsegments +----------------------------------------------- + 2 +(1 row) + +create table rpt_issue_15860_2_segments(c1 int, c2 int) distributed replicated; +create table hash_issue_15860_2_segments(c1 int, c2 int) distributed by (c1); +select gp_debug_reset_create_table_default_numsegments(); + gp_debug_reset_create_table_default_numsegments +------------------------------------------------- + +(1 row) + +create table rpt_issue_15860 (c1 int, c2 int) distributed replicated; +create table rpt2_issue_15860 (c1 int, c2 int) distributed replicated; +create table hash_issue_15860(c1 int, c2 int) distributed by (c1); +create table strewn_issue_15860(c1 int, c2 int) distributed randomly; +insert into rpt2_issue_15860 values (1, 2), (2, 3); +insert into rpt_issue_15860_2_segments values (1, 2), (2, 3); +analyze rpt_issue_15860; +analyze rpt2_issue_15860; +analyze hash_issue_15860; +analyze strewn_issue_15860; +analyze rpt_issue_15860_2_segments; +-- Replicated join SegmentGeneral. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 join rpt2_issue_15860 using(c1); + QUERY PLAN +--------------------------------------------------------------- + Explicit Gather Motion 3:1 (slice1; segments: 3) + -> Hash Join + Hash Cond: (rpt2_issue_15860.c1 = rpt_issue_15860.c1) + -> Seq Scan on rpt2_issue_15860 + -> Hash + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(8 rows) + +-- Replicated join SegmentGeneral, Replicated is not ok to replicate. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 left join rpt2_issue_15860 using(c1); + QUERY PLAN +--------------------------------------------------------------- + Hash Right Join + Hash Cond: (rpt2_issue_15860.c1 = rpt_issue_15860.c1) + -> Gather Motion 1:1 (slice1; segments: 1) + -> Seq Scan on rpt2_issue_15860 + -> Hash + -> Explicit Gather Motion 3:1 (slice2; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(9 rows) + +-- Replicated join SegmentGeneral, SegmentGeneral is not ok to replicate. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 right join rpt2_issue_15860 using(c1); + QUERY PLAN +--------------------------------------------------------------- + Hash Left Join + Hash Cond: (rpt2_issue_15860.c1 = cte1.c1) + -> Gather Motion 1:1 (slice1; segments: 1) + -> Seq Scan on rpt2_issue_15860 + -> Hash + -> Explicit Gather Motion 3:1 (slice2; segments: 3) + -> Subquery Scan on cte1 + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(10 rows) + +-- Replicated join SegmentGeneral, both are not ok to replicate. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 full join rpt2_issue_15860 using(c1); + QUERY PLAN +--------------------------------------------------------------- + Hash Full Join + Hash Cond: (rpt2_issue_15860.c1 = rpt_issue_15860.c1) + -> Gather Motion 1:1 (slice1; segments: 1) + -> Seq Scan on rpt2_issue_15860 + -> Hash + -> Explicit Gather Motion 3:1 (slice2; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(9 rows) + +-- Replicated join SegmentGeneral, num segments are not matched. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 join rpt_issue_15860_2_segments using(c1); + QUERY PLAN +------------------------------------------------------------------- + Hash Join + Hash Cond: (rpt_issue_15860_2_segments.c1 = rpt_issue_15860.c1) + -> Gather Motion 1:1 (slice1; segments: 1) + -> Seq Scan on rpt_issue_15860_2_segments + -> Hash + -> Explicit Gather Motion 3:1 (slice2; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(9 rows) + +-- Replicated join General. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 join generate_series(1, 5) i on i= cte1.c1 ; + QUERY PLAN +--------------------------------------------------- + Explicit Gather Motion 3:1 (slice1; segments: 3) + -> Hash Join + Hash Cond: (i.i = rpt_issue_15860.c1) + -> Function Scan on generate_series i + -> Hash + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(8 rows) + +-- Replicated join General, Replicated is not ok to replicate. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 left join generate_series(1, 5) i on i= cte1.c1 ; + QUERY PLAN +--------------------------------------------------------------- + Hash Right Join + Hash Cond: (i.i = rpt_issue_15860.c1) + -> Function Scan on generate_series i + -> Hash + -> Explicit Gather Motion 3:1 (slice1; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(8 rows) + +-- Replicated join General, General is not ok to replicate. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 right join generate_series(1, 5) i on i= cte1.c1 ; + QUERY PLAN +--------------------------------------------------------------- + Hash Left Join + Hash Cond: (i.i = rpt_issue_15860.c1) + -> Function Scan on generate_series i + -> Hash + -> Explicit Gather Motion 3:1 (slice1; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(8 rows) + +-- Replicated join General, both are not not ok to replicate. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 full join generate_series(1, 5) i on i= cte1.c1 ; + QUERY PLAN +--------------------------------------------------------------- + Hash Full Join + Hash Cond: (i.i = rpt_issue_15860.c1) + -> Function Scan on generate_series i + -> Hash + -> Explicit Gather Motion 3:1 (slice1; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(8 rows) + +-- Replicate join SingleQE. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 join (select count(*) as c from hash_issue_15860) a on a.c = cte1.c1; + QUERY PLAN +--------------------------------------------------------------- + Hash Join + Hash Cond: ((count(*)) = rpt_issue_15860.c1) + -> Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Seq Scan on hash_issue_15860 + -> Hash + -> Explicit Gather Motion 3:1 (slice2; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(10 rows) + +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 left join (select count(*) as c from hash_issue_15860) a on a.c = cte1.c1; + QUERY PLAN +--------------------------------------------------------------- + Hash Right Join + Hash Cond: ((count(*)) = rpt_issue_15860.c1) + -> Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Seq Scan on hash_issue_15860 + -> Hash + -> Explicit Gather Motion 3:1 (slice2; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(10 rows) + +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 right join (select count(*) as c from hash_issue_15860) a on a.c = cte1.c1; + QUERY PLAN +--------------------------------------------------------------- + Hash Left Join + Hash Cond: ((count(*)) = rpt_issue_15860.c1) + -> Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Seq Scan on hash_issue_15860 + -> Hash + -> Explicit Gather Motion 3:1 (slice2; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(10 rows) + +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 full join (select count(*) as c from hash_issue_15860) a on a.c = cte1.c1; + QUERY PLAN +--------------------------------------------------------------- + Hash Full Join + Hash Cond: ((count(*)) = rpt_issue_15860.c1) + -> Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Seq Scan on hash_issue_15860 + -> Hash + -> Explicit Gather Motion 3:1 (slice2; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(10 rows) + +-- When external_fts is on +-- Seq scan on gp_segment_configuration would be replaced by +-- Function Scan on gp_get_segment_configuration +-- Inconsistence between CIs will cause such cases to fail. +-- Use other catalog to test Entry. +-- Replicate join Entry. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 join pg_class c on c.oid = cte1.c1; + QUERY PLAN +--------------------------------------------------------------- + Hash Join + Hash Cond: (c.oid = (rpt_issue_15860.c1)::oid) + -> Seq Scan on pg_class c + -> Hash + -> Explicit Gather Motion 3:1 (slice1; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(8 rows) + +-- +-- Begin of Replicated join Partitioned. +-- +-- Replicated join Hashed. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 join hash_issue_15860 using(c1); + QUERY PLAN +--------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Join + Hash Cond: (hash_issue_15860.c1 = rpt_issue_15860.c1) + -> Seq Scan on hash_issue_15860 + -> Hash + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(8 rows) + +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 right join hash_issue_15860 using(c1); + QUERY PLAN +---------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Left Join + Hash Cond: (hash_issue_15860.c1 = cte1.c1) + -> Seq Scan on hash_issue_15860 + -> Hash + -> Subquery Scan on cte1 + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(9 rows) + +-- Replicated join Hashed, Replicated is not ok to replicate +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 left join hash_issue_15860 using(c1); + QUERY PLAN +--------------------------------------------------------------- + Hash Right Join + Hash Cond: (hash_issue_15860.c1 = rpt_issue_15860.c1) + -> Gather Motion 3:1 (slice1; segments: 3) + -> Seq Scan on hash_issue_15860 + -> Hash + -> Explicit Gather Motion 3:1 (slice2; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(9 rows) + +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 full join hash_issue_15860 using(c1); + QUERY PLAN +--------------------------------------------------------------- + Hash Full Join + Hash Cond: (hash_issue_15860.c1 = rpt_issue_15860.c1) + -> Gather Motion 3:1 (slice1; segments: 3) + -> Seq Scan on hash_issue_15860 + -> Hash + -> Explicit Gather Motion 3:1 (slice2; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(9 rows) + +-- Replicated join Hashed, num segments are not match. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 join hash_issue_15860_2_segments using(c1); + QUERY PLAN +-------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Join + Hash Cond: (hash_issue_15860_2_segments.c1 = rpt_issue_15860.c1) + -> Redistribute Motion 2:3 (slice2; segments: 2) + Hash Key: hash_issue_15860_2_segments.c1 + -> Seq Scan on hash_issue_15860_2_segments + -> Hash + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(10 rows) + +-- Replicated join Strewn = Strewn. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 join strewn_issue_15860 using(c1); + QUERY PLAN +----------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Join + Hash Cond: (strewn_issue_15860.c1 = rpt_issue_15860.c1) + -> Seq Scan on strewn_issue_15860 + -> Hash + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(8 rows) + +-- Replicated join HashedOJ = HashedOJ +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 join (select * from hash_issue_15860 a full join hash_issue_15860 b using(c1)) c using(c1); + QUERY PLAN +------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Join + Hash Cond: ((COALESCE(a.c1, b.c1)) = rpt_issue_15860.c1) + -> Hash Full Join + Hash Cond: (a.c1 = b.c1) + -> Seq Scan on hash_issue_15860 a + -> Hash + -> Seq Scan on hash_issue_15860 b + -> Hash + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(12 rows) + +-- +-- End of Replicated join Partitioned. +-- +-- CBDB_FIXME: How to derive a plan? +-- Replicates join OuterQuery +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select ( select foo.c1 from (select * from strewn_issue_15860) foo join cte1 using(c2) where foo.c1 = hash_issue_15860.c1) from hash_issue_15860; +ERROR: could not devise a query plan for the given query (pathnode.c:285) +-- Test case for Github Issue 17460 +create table t_17460 (a int ) distributed replicated; +create table foo_17460 (a int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into t_17460 values(1); +insert into foo_17460 select i from generate_series(1, 10000) i; +analyze t_17460; +analyze foo_17460; +-- update|delete on replicated table should not use unique rowid skill +-- to plan semi join. +explain (costs off) delete from t_17460 where a in (select a from foo_17460); + QUERY PLAN +--------------------------------------------------------- + Delete on t_17460 + -> Hash Right Semi Join + Hash Cond: (foo_17460.a = t_17460.a) + -> Broadcast Motion 3:3 (slice1; segments: 3) + -> Seq Scan on foo_17460 + -> Hash + -> Seq Scan on t_17460 + Optimizer: Postgres query optimizer +(8 rows) + +delete from t_17460 where a in (select a from foo_17460); +drop schema rpt_joins cascade; +NOTICE: drop cascades to 13 other objects +DETAIL: drop cascades to table j1_tbl +drop cascades to table j2_tbl +drop cascades to table rpt_joins.t1 +drop cascades to table rpt_joins.t2 +drop cascades to table rpt_joins.t3 +drop cascades to table rpt_issue_15860_2_segments +drop cascades to table hash_issue_15860_2_segments +drop cascades to table rpt_issue_15860 +drop cascades to table rpt2_issue_15860 +drop cascades to table hash_issue_15860 +drop cascades to table strewn_issue_15860 +drop cascades to table t_17460 +drop cascades to table foo_17460 diff --git a/contrib/pax_storage/src/test/regress/expected/rpt_optimizer.out b/contrib/pax_storage/src/test/regress/expected/rpt_optimizer.out index 8a6fe7788d1..e12ab248f01 100644 --- a/contrib/pax_storage/src/test/regress/expected/rpt_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/rpt_optimizer.out @@ -129,10 +129,10 @@ insert into foo values (1,'aaa'); insert into foo values (2,'bbb'); -- fail insert into foo values (1,'ccc'); -ERROR: duplicate key value violates unique constraint "foo_pkey" (seg0 192.168.99.102:25432 pid=22681) +ERROR: duplicate key value violates unique constraint "foo_pkey" (seg0 172.18.0.2:7002 pid=63342) DETAIL: Key (id)=(1) already exists. insert into foo values (3,'aaa'); -ERROR: duplicate key value violates unique constraint "foo_name_key" (seg2 192.168.99.102:25434 pid=22683) +ERROR: duplicate key value violates unique constraint "foo_name_key" (seg1 172.18.0.2:7003 pid=63343) DETAIL: Key (name)=(aaa) already exists. drop table if exists foo; -- @@ -232,15 +232,14 @@ drop table if exists bar; -- CTAS from partition table table create table foo as select i as c1, i as c2 from generate_series(1,3) i; -NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'c1' as the Apache Cloudberry data distribution key for this table. -HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause. Creating a NULL policy entry. create table bar as select * from foo distributed replicated; select * from bar; c1 | c2 ----+---- - 1 | 1 2 | 2 3 | 3 + 1 | 1 (3 rows) drop table if exists foo; @@ -248,8 +247,7 @@ drop table if exists bar; -- CTAS from singleQE create table foo as select i as c1, i as c2 from generate_series(1,3) i; -NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'c1' as the Apache Cloudberry data distribution key for this table. -HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause. Creating a NULL policy entry. select * from foo; c1 | c2 ----+---- @@ -354,10 +352,10 @@ select * from foo; 2 | 2 3 | 3 4 | 4 - 5 | 5 - 6 | 6 7 | 7 8 | 8 + 5 | 5 + 6 | 6 9 | 9 10 | 10 (10 rows) @@ -365,14 +363,14 @@ select * from foo; select * from foo1; x | y ----+---- + 4 | 4 1 | 1 2 | 2 - 3 | 3 - 4 | 4 5 | 5 6 | 6 - 7 | 7 8 | 8 + 3 | 3 + 7 | 7 9 | 9 10 | 10 (10 rows) @@ -380,14 +378,14 @@ select * from foo1; select * from bar; x | y ----+---- - 1 | 1 2 | 2 3 | 3 4 | 4 - 5 | 5 - 6 | 6 7 | 7 8 | 8 + 1 | 1 + 5 | 5 + 6 | 6 9 | 9 10 | 10 (10 rows) @@ -395,16 +393,16 @@ select * from bar; select * from bar1; x | y ----+---- - 1 | 1 2 | 2 3 | 3 + 7 | 7 + 8 | 8 + 10 | 10 + 1 | 1 4 | 4 5 | 5 6 | 6 - 7 | 7 - 8 | 8 9 | 9 - 10 | 10 (10 rows) -- alter back @@ -449,14 +447,14 @@ Distributed randomly select * from foo; x | y ----+---- - 1 | 1 2 | 2 3 | 3 4 | 4 - 5 | 5 - 6 | 6 7 | 7 8 | 8 + 1 | 1 + 5 | 5 + 6 | 6 9 | 9 10 | 10 (10 rows) @@ -464,14 +462,14 @@ select * from foo; select * from foo1; x | y ----+---- + 4 | 4 1 | 1 2 | 2 - 3 | 3 - 4 | 4 5 | 5 6 | 6 - 7 | 7 8 | 8 + 3 | 3 + 7 | 7 9 | 9 10 | 10 (10 rows) @@ -480,30 +478,30 @@ select * from bar; x | y ----+---- 1 | 1 + 5 | 5 + 6 | 6 + 9 | 9 + 10 | 10 2 | 2 3 | 3 4 | 4 - 5 | 5 - 6 | 6 7 | 7 8 | 8 - 9 | 9 - 10 | 10 (10 rows) select * from bar1; x | y ----+---- - 1 | 1 - 2 | 2 + 8 | 8 + 10 | 10 + 6 | 6 3 | 3 + 1 | 1 4 | 4 - 5 | 5 - 6 | 6 - 7 | 7 - 8 | 8 9 | 9 - 10 | 10 + 2 | 2 + 7 | 7 + 5 | 5 (10 rows) drop table if exists foo; @@ -531,8 +529,8 @@ update foo set y = 1 from bar where bar.y = foo.y; select * from foo; x | y ---+--- - 1 | 1 2 | 1 + 1 | 1 (2 rows) delete from foo where y = 1; @@ -692,13 +690,12 @@ ERROR: PARTITION BY clause cannot be used with DISTRIBUTED REPLICATED clause CREATE TABLE foopart (a int4, b int4) PARTITION BY RANGE (a) (START (1) END (10)) ; NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. -NOTICE: CREATE TABLE will create partition "foopart_1_prt_1" for table "foopart" -- should fail ALTER TABLE foopart SET DISTRIBUTED REPLICATED; ERROR: can't set the distribution policy of a partition table to REPLICATED ALTER TABLE foopart_1_prt_1 SET DISTRIBUTED REPLICATED; ERROR: can't set the distribution policy of "foopart_1_prt_1" -HINT: Distribution policy can be set for an entire partitioned table, not for one of its leaf parts or an interior branch. +HINT: Distribution policy of a partition can only be the same as its parent's. DROP TABLE foopart; -- Test that replicated table can't inherit a parent table, and it also -- can't be inherited by a child table. @@ -780,7 +777,7 @@ explain (costs off) select * from t_hashdist where a > All (select random() from Filter: ((CASE WHEN (sum((CASE WHEN ((t_hashdist.a)::double precision <= random()) THEN 1 ELSE 0 END)) IS NULL) THEN true WHEN (sum((CASE WHEN (random() IS NULL) THEN 1 ELSE 0 END)) > '0'::bigint) THEN NULL::boolean WHEN ((t_hashdist.a)::double precision IS NULL) THEN NULL::boolean WHEN (sum((CASE WHEN ((t_hashdist.a)::double precision <= random()) THEN 1 ELSE 0 END)) = '0'::bigint) THEN true ELSE false END) = true) -> Aggregate -> Seq Scan on t_replicate_volatile - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) explain (costs off) select * from t_hashdist where a in (select random()::int from t_replicate_volatile); @@ -794,7 +791,7 @@ explain (costs off) select * from t_hashdist where a in (select random()::int fr -> Redistribute Motion 1:3 (slice2; segments: 1) Hash Key: ((random())::integer) -> Seq Scan on t_replicate_volatile - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) -- subplan @@ -819,8 +816,8 @@ explain (costs off, verbose) select * from t_hashdist left join t_replicate_vola Output: t_replicate_volatile.a, t_replicate_volatile.b, t_replicate_volatile.c -> Seq Scan on rpt.t_replicate_volatile Output: t_replicate_volatile.a, t_replicate_volatile.b, t_replicate_volatile.c + Settings: optimizer = 'on', enable_seqscan = 'off' Optimizer: Postgres query optimizer - Settings: enable_seqscan=off, optimizer=on (20 rows) -- targetlist @@ -833,7 +830,7 @@ explain (costs off) select * from t_hashdist cross join (select random () from t -> Seq Scan on t_hashdist -> Materialize -> Seq Scan on t_replicate_volatile - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) explain (costs off) select * from t_hashdist cross join (select a, sum(random()) from t_replicate_volatile group by a) x; @@ -848,7 +845,7 @@ explain (costs off) select * from t_hashdist cross join (select a, sum(random()) -> Sort Sort Key: t_replicate_volatile.a -> Seq Scan on t_replicate_volatile - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) explain (costs off) select * from t_hashdist cross join (select random() as k, sum(a) from t_replicate_volatile group by k) x; @@ -894,7 +891,7 @@ explain (costs off) insert into t_replicate_volatile select random() from t_repl -> Result -> Broadcast Motion 1:3 (slice1; segments: 1) -> Seq Scan on t_replicate_volatile t_replicate_volatile_1 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) explain (costs off) insert into t_replicate_volatile select random(), a, a from generate_series(1, 10) a; @@ -904,7 +901,7 @@ explain (costs off) insert into t_replicate_volatile select random(), a, a from -> Result -> Broadcast Motion 1:3 (slice1) -> Function Scan on generate_series - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) create sequence seq_for_insert_replicated_table; @@ -915,7 +912,7 @@ explain (costs off) insert into t_replicate_volatile select nextval('seq_for_ins -> Result -> Broadcast Motion 1:3 (slice1) -> Result - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) explain (costs off) select a from t_replicate_volatile union all select * from nextval('seq_for_insert_replicated_table'); @@ -928,21 +925,22 @@ explain (costs off) select a from t_replicate_volatile union all select * from n -> Seq Scan on t_replicate_volatile -> Redistribute Motion 1:3 (slice2) -> Function Scan on nextval - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) -- CTAS explain (costs off) create table rpt_ctas as select random() from generate_series(1, 10) distributed replicated; -QUERY PLAN -___________ + QUERY PLAN +---------------------------------------------- Result -> Broadcast Motion 1:3 (slice1) -> Function Scan on generate_series -GP_IGNORE:(4 rows) + Optimizer: GPORCA +(4 rows) 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; -QUERY PLAN -___________ + QUERY PLAN +------------------------------------------------------------------------------- Result -> Broadcast Motion 3:3 (slice1; segments: 3) -> Result @@ -951,24 +949,25 @@ ___________ Group Key: generate_series -> Result -> Function Scan on generate_series -GP_IGNORE:(9 rows) + Optimizer: GPORCA +(9 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) +ERROR: could not devise a plan (cdbpath.c:2907) 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) +ERROR: could not devise a plan (cdbpath.c:2907) 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) +ERROR: could not devise a plan (cdbpath.c:2907) explain (costs off) delete from t_replicate_volatile where a < random(); -ERROR: could not devise a plan (cdbpath.c:2578) +ERROR: could not devise a plan (cdbpath.c:2907) 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) +ERROR: could not devise a plan (cdbpath.c:2907) explain (costs off) update t_replicate_volatile set a = random(); -ERROR: could not devise a plan. (cdbpath.c:2441) +ERROR: could not devise a plan. (cdbpath.c:2697) -- limit explain (costs off) insert into t_replicate_volatile select * from t_replicate_volatile limit random(); - QUERY PLAN + QUERY PLAN --------------------------------------------------------------------------------------- Insert on t_replicate_volatile -> Result @@ -976,7 +975,7 @@ explain (costs off) insert into t_replicate_volatile select * from t_replicate_v -> Limit -> Gather Motion 1:1 (slice2; segments: 1) -> Seq Scan on t_replicate_volatile t_replicate_volatile_1 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) explain (costs off) select * from t_hashdist cross join (select * from t_replicate_volatile limit random()) x; @@ -990,7 +989,7 @@ explain (costs off) select * from t_hashdist cross join (select * from t_replica -> Materialize -> Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on t_hashdist - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) -- ORCA @@ -1059,8 +1058,8 @@ explain select c from rep_tab where c in (select distinct c from rep_tab); select c from rep_tab where c in (select distinct c from rep_tab); c --- - 2 1 + 2 (2 rows) -- Table Side Derives @@ -1077,16 +1076,16 @@ explain select a from dist_tab where a in (select distinct c from rep_tab); -> Seq Scan on dist_tab (cost=0.00..431.00 rows=2 width=4) -> Hash (cost=431.00..431.00 rows=2 width=4) -> Seq Scan on rep_tab (cost=0.00..431.00 rows=2 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) select a from dist_tab where a in (select distinct c from rep_tab); a --- - 1 - 1 2 2 + 1 + 1 (4 rows) -- Table Side Derives @@ -1098,19 +1097,19 @@ explain select d from rand_tab where d in (select distinct c from rep_tab); QUERY PLAN ------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=2 width=4) - -> Hash Semi Join (cost=0.00..862.00 rows=1 width=4) + -> Hash Right Semi Join (cost=0.00..862.00 rows=1 width=4) Hash Cond: (rand_tab.d = rep_tab.c) - -> Seq Scan on rand_tab (cost=0.00..431.00 rows=1 width=4) - -> Hash (cost=431.00..431.00 rows=2 width=4) - -> Seq Scan on rep_tab (cost=0.00..431.00 rows=2 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + -> Seq Scan on rep_tab (cost=0.00..431.00 rows=2 width=4) + -> Hash (cost=431.00..431.00 rows=1 width=4) + -> Seq Scan on rand_tab (cost=0.00..431.00 rows=1 width=4) + Optimizer: GPORCA (7 rows) select d from rand_tab where d in (select distinct c from rep_tab); d --- - 1 2 + 1 (2 rows) -- Table Side Derives @@ -1122,23 +1121,24 @@ explain select c from rep_tab where c in (select distinct a from dist_tab); QUERY PLAN ---------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=2 width=4) - -> Hash Join (cost=0.00..862.00 rows=1 width=4) - Hash Cond: (dist_tab.a = rep_tab.c) + -> Hash Right Semi Join (cost=0.00..862.00 rows=1 width=4) + Hash Cond: (rep_tab.c = dist_tab.a) -> GroupAggregate (cost=0.00..431.00 rows=1 width=4) Group Key: dist_tab.a -> Sort (cost=0.00..431.00 rows=2 width=4) Sort Key: dist_tab.a -> Seq Scan on dist_tab (cost=0.00..431.00 rows=2 width=4) - -> Hash (cost=431.00..431.00 rows=2 width=4) - -> Seq Scan on rep_tab (cost=0.00..431.00 rows=2 width=4) - Optimizer: Pivotal Optimizer (GPORCA) -(11 rows) + -> Hash (cost=431.00..431.00 rows=1 width=4) + -> Result (cost=0.00..431.00 rows=1 width=4) + -> Seq Scan on rep_tab (cost=0.00..431.00 rows=2 width=4) + Optimizer: GPORCA +(12 rows) select c from rep_tab where c in (select distinct a from dist_tab); c --- - 1 2 + 1 (2 rows) -- Table Side Derives @@ -1147,17 +1147,17 @@ select c from rep_tab where c in (select distinct a from dist_tab); -- -- join derives EdtHashed explain select c from rep_tab where c in (select distinct d from rand_tab); - QUERY PLAN ------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=2 width=4) - -> Hash Semi Join (cost=0.00..862.00 rows=1 width=4) + -> Hash Right Semi Join (cost=0.00..862.00 rows=1 width=4) Hash Cond: (rep_tab.c = rand_tab.d) - -> Result (cost=0.00..431.00 rows=1 width=4) - -> Seq Scan on rep_tab (cost=0.00..431.00 rows=2 width=4) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) + Hash Key: rand_tab.d + -> Seq Scan on rand_tab (cost=0.00..431.00 rows=1 width=4) -> Hash (cost=431.00..431.00 rows=1 width=4) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) - Hash Key: rand_tab.d - -> Seq Scan on rand_tab (cost=0.00..431.00 rows=1 width=4) + -> Result (cost=0.00..431.00 rows=1 width=4) + -> Seq Scan on rep_tab (cost=0.00..431.00 rows=2 width=4) Optimizer: GPORCA (10 rows) @@ -1203,11 +1203,11 @@ explain (costs off) select * from t1_13532 x, t2_13532 y where y.a < random() an -- test for optimizer_enable_replicated_table explain (costs off) select * from rep_tab; - QUERY PLAN + QUERY PLAN ------------------------------------------ Gather Motion 1:1 (slice1; segments: 1) -> Seq Scan on rep_tab - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) set optimizer_enable_replicated_table=off; @@ -1215,7 +1215,7 @@ set optimizer_trace_fallback=on; explain (costs off) select * from rep_tab; INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Use optimizer_enable_replicated_table to enable replicated tables - QUERY PLAN + QUERY PLAN ------------------------------------------ Gather Motion 1:1 (slice1; segments: 1) -> Seq Scan on rep_tab diff --git a/contrib/pax_storage/src/test/regress/expected/subselect.out b/contrib/pax_storage/src/test/regress/expected/subselect.out index f8d0c3d4e07..7f5b7210704 100644 --- a/contrib/pax_storage/src/test/regress/expected/subselect.out +++ b/contrib/pax_storage/src/test/regress/expected/subselect.out @@ -84,6 +84,8 @@ CREATE TABLE SUBSELECT_TBL ( f2 integer, f3 float ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO SUBSELECT_TBL VALUES (1, 2, 3); INSERT INTO SUBSELECT_TBL VALUES (2, 3, 4); INSERT INTO SUBSELECT_TBL VALUES (3, 4, 5); @@ -95,13 +97,13 @@ INSERT INTO SUBSELECT_TBL VALUES (8, 9, NULL); SELECT * FROM SUBSELECT_TBL; f1 | f2 | f3 ----+----+---- + 6 | 7 | 8 1 | 2 | 3 + 1 | 1 | 1 2 | 3 | 4 3 | 4 | 5 - 1 | 1 | 1 2 | 2 | 2 3 | 3 | 3 - 6 | 7 | 8 8 | 9 | (8 rows) @@ -118,12 +120,12 @@ SELECT f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL); Uncorrelated Field -------------------- - 1 2 3 - 1 2 3 + 1 + 1 (6 rows) SELECT f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL @@ -131,12 +133,12 @@ SELECT f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL f2 IN (SELECT f1 FROM SUBSELECT_TBL)); Uncorrelated Field -------------------- - 1 2 3 - 1 2 3 + 1 + 1 (6 rows) SELECT f1, f2 @@ -145,8 +147,8 @@ SELECT f1, f2 WHERE f3 IS NOT NULL); f1 | f2 ----+---- - 1 | 2 6 | 7 + 1 | 2 8 | 9 (3 rows) @@ -157,9 +159,9 @@ SELECT f1 AS "Correlated Field", f2 AS "Second Field" Correlated Field | Second Field ------------------+-------------- 1 | 2 + 1 | 1 2 | 3 3 | 4 - 1 | 1 2 | 2 3 | 3 (6 rows) @@ -170,9 +172,9 @@ SELECT f1 AS "Correlated Field", f3 AS "Second Field" (SELECT f2 FROM SUBSELECT_TBL WHERE CAST(upper.f2 AS float) = f3); Correlated Field | Second Field ------------------+-------------- + 1 | 1 2 | 4 3 | 5 - 1 | 1 2 | 2 3 | 3 (5 rows) @@ -183,10 +185,10 @@ SELECT f1 AS "Correlated Field", f3 AS "Second Field" WHERE f2 = CAST(f3 AS integer)); Correlated Field | Second Field ------------------+-------------- - 1 | 3 2 | 4 3 | 5 6 | 8 + 1 | 3 (4 rows) SELECT f1 AS "Correlated Field" @@ -197,9 +199,9 @@ SELECT f1 AS "Correlated Field" ------------------ 2 3 - 1 2 3 + 1 (5 rows) -- Subselects without aliases @@ -278,8 +280,8 @@ SELECT ss.f1 AS "Correlated Field", ss.f3 AS "Second Field" 3 | 5 2 | 2 3 | 3 - 6 | 8 8 | + 6 | 8 (6 rows) select q1, float8(count(*)) / (select count(*) from int8_tbl) @@ -302,30 +304,34 @@ SELECT *, pg_typeof(f1) FROM -- ... unless there's context to suggest differently explain (verbose, costs off) select '42' union all select '43'; - QUERY PLAN ----------------------------- + QUERY PLAN +------------------------------------- Append -> Result Output: '42'::text -> Result Output: '43'::text -(5 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(7 rows) explain (verbose, costs off) select '42' union all select 43; - QUERY PLAN --------------------- + QUERY PLAN +------------------------------------- Append -> Result Output: 42 -> Result Output: 43 -(5 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(7 rows) -- check materialization of an initplan reference (bug #14524) explain (verbose, costs off) select 1 = all (select (select 1)); - QUERY PLAN ------------------------------------ + QUERY PLAN +------------------------------------- Result Output: (SubPlan 2) SubPlan 2 @@ -336,7 +342,9 @@ select 1 = all (select (select 1)); Output: 1 -> Result Output: $0 -(10 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(12 rows) select 1 = all (select (select 1)); ?column? @@ -429,7 +437,11 @@ select count(distinct ss.ten) from -- Luca Pireddu and Michael Fuhr. -- CREATE TEMP TABLE foo (id integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TEMP TABLE bar (id1 integer, id2 integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO foo VALUES (1); INSERT INTO bar VALUES (1, 1); INSERT INTO bar VALUES (2, 2); @@ -489,6 +501,8 @@ CREATE TABLE orderstest ( po_ref integer, ordercanceled boolean ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'approver_ref' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO orderstest VALUES (1, 1, false); INSERT INTO orderstest VALUES (66, 5, false); INSERT INTO orderstest VALUES (66, 6, false); @@ -539,7 +553,6 @@ FROM orderstest ord; SELECT * FROM orders_view; approver_ref | po_ref | ordercanceled | Approved | Status | Status_OK --------------+--------+---------------+----------+----------+----------- - 1 | 1 | f | --- | --- | --- 66 | 5 | f | Approved | PO | PO 66 | 6 | f | Approved | PO | PO 66 | 7 | f | Approved | PO | PO @@ -547,9 +560,10 @@ SELECT * FROM orders_view; 66 | 8 | f | Approved | PO | PO 66 | 1 | f | Approved | Approved | Approved 77 | 1 | f | Approved | Approved | Approved - 1 | 1 | f | --- | --- | --- 66 | 1 | f | Approved | Approved | Approved 1 | 1 | f | --- | --- | --- + 1 | 1 | f | --- | --- | --- + 1 | 1 | f | --- | --- | --- (11 rows) DROP TABLE orderstest cascade; @@ -562,12 +576,16 @@ create temp table parts ( partnum text, cost float8 ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'partnum' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp table shipped ( ttype char(2), ordnum int4, partnum text, value float8 ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'ttype' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp view shipped_view as select * from shipped where ttype = 'wt'; create rule shipped_view_insert as on insert to shipped_view do instead @@ -600,10 +618,10 @@ select f1, ss1 as relabel from f1 | relabel -------------+------------ 0 | 2147607103 - 123456 | 2147607103 - -123456 | 2147483647 2147483647 | 2147483647 -2147483647 | 0 + 123456 | 2147607103 + -123456 | 2147483647 (5 rows) -- @@ -637,15 +655,19 @@ select * from ( -- pointless.) -- create temp table numeric_table (num_col numeric); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'num_col' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into numeric_table values (1), (1.000000000000000000001), (2), (3); create temp table float_table (float_col float8); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'float_col' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into float_table values (1), (2), (3); select * from float_table where float_col in (select num_col from numeric_table); float_col ----------- - 1 2 + 1 3 (3 rows) @@ -653,9 +675,9 @@ select * from numeric_table where num_col in (select float_col from float_table); num_col ------------------------- + 2 1 1.000000000000000000001 - 2 3 (4 rows) @@ -682,6 +704,8 @@ ERROR: correlated subquery with skip-level correlations is not supported -- Test case for 8.3 "failed to locate grouping columns" bug -- create temp table t1 (f1 numeric(14,0), f2 varchar(30)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. select * from (select distinct f1, f2, (select f2 from t1 x where x.f1 = up.f1) as fs from t1 up) ss @@ -694,6 +718,8 @@ group by f1,f2,fs; -- Test case for bug #5514 (mishandling of whole-row Vars in subselects) -- create temp table table_a(id integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into table_a values (42); create temp view view_a as select * from table_a; select view_a from view_a; @@ -741,10 +767,10 @@ with q as (select max(f1) from int4_tbl group by f1 order by f1) select q from q; -- order none q --------------- - (-2147483647) (-123456) - (0) (123456) + (-2147483647) + (0) (2147483647) (5 rows) @@ -782,9 +808,9 @@ ERROR: correlated subquery with skip-level correlations is not supported -- create temp table upsert(key int4 primary key, val text); insert into upsert values(1, 'val') on conflict (key) do update set val = 'not seen'; -ERROR: not implemented yet on pax relations: TupleInsertSpeculative (seg1 127.0.1.1:7003 pid=1171493) +ERROR: not implemented yet on pax relations: TupleInsertSpeculative (seg1 172.18.0.2:7003 pid=13652) insert into upsert values(1, 'val') on conflict (key) do update set val = 'seen with subselect ' || (select f1 from int4_tbl where f1 != 0 order by f1 limit 1)::text; -ERROR: not implemented yet on pax relations: TupleInsertSpeculative (seg1 127.0.1.1:7003 pid=1171493) +ERROR: not implemented yet on pax relations: TupleInsertSpeculative (seg1 172.18.0.2:7003 pid=13652) select * from upsert; key | val -----+----- @@ -794,16 +820,20 @@ with aa as (select 'int4_tbl' u from int4_tbl limit 1) insert into upsert values (1, 'x'), (999, 'y') on conflict (key) do update set val = (select u from aa) returning *; -ERROR: not implemented yet on pax relations: TupleInsertSpeculative (seg0 slice1 127.0.1.1:7002 pid=1171488) +ERROR: not implemented yet on pax relations: TupleInsertSpeculative (seg0 slice1 172.18.0.2:7002 pid=13654) -- -- Test case for cross-type partial matching in hashed subplan (bug #7597) -- create temp table outer_7597 (f1 int4, f2 int4); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into outer_7597 values (0, 0); insert into outer_7597 values (1, 0); insert into outer_7597 values (0, null); insert into outer_7597 values (1, null); create temp table inner_7597(c1 int8, c2 int8); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into inner_7597 values(0, null); select * from outer_7597 where (f1, f2) not in (select * from inner_7597); f1 | f2 @@ -818,11 +848,15 @@ select * from outer_7597 where (f1, f2) not in (select * from inner_7597); -- (otherwise it would error in texteq()) -- create temp table outer_text (f1 text, f2 text); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into outer_text values ('a', 'a'); insert into outer_text values ('b', 'a'); insert into outer_text values ('a', null); insert into outer_text values ('b', null); create temp table inner_text (c1 text, c2 text); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into inner_text values ('a', null); insert into inner_text values ('123', '456'); select * from outer_text where (f1, f2) not in (select * from inner_text); @@ -848,7 +882,9 @@ select 'foo'::text in (select 'bar'::name union all select 'bar'::name); Output: 'bar'::name -> Result Output: 'bar'::name -(8 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(10 rows) select 'foo'::text in (select 'bar'::name union all select 'bar'::name); ?column? @@ -871,8 +907,9 @@ select row(row(row(1))) = any (select row(row(1))); Output: (ROW(ROW(1))) -> Result Output: ROW(ROW(1)) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(8 rows) +(9 rows) select row(row(row(1))) = any (select row(row(1))); ?column? @@ -914,6 +951,7 @@ select * from int8_tbl where q1 in (select c1 from inner_text); SubPlan 1 -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on inner_text + Optimizer: Postgres query optimizer (7 rows) select * from int8_tbl where q1 in (select c1 from inner_text); @@ -937,6 +975,7 @@ select * from int8_tbl where q1 in (select c1 from inner_text); SubPlan 1 -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on inner_text + Optimizer: Postgres query optimizer (7 rows) select * from int8_tbl where q1 in (select c1 from inner_text); @@ -988,6 +1027,7 @@ where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0); SubPlan 2 -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on tenk1 k + Optimizer: Postgres query optimizer (9 rows) select count(*) from tenk1 t @@ -1017,7 +1057,8 @@ where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0) -> Materialize -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on tenk1 k -(14 rows) + Optimizer: Postgres query optimizer +(15 rows) select count(*) from tenk1 t where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0) @@ -1029,8 +1070,12 @@ where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0) -- It's possible for the same EXISTS to get resolved both ways create temp table exists_tbl (c1 int, c2 int, c3 int) partition by list (c1); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp table exists_tbl_null partition of exists_tbl for values in (null); +NOTICE: table has parent, setting distribution columns to match parent table create temp table exists_tbl_def partition of exists_tbl default; +NOTICE: table has parent, setting distribution columns to match parent table insert into exists_tbl select x, x/2, x+1 from generate_series(0,10) x; analyze exists_tbl; explain (costs off) @@ -1067,12 +1112,12 @@ select * from exists_tbl t1 where (exists(select 1 from exists_tbl t2 where t1.c1 = t2.c2) or c3 < 0); c1 | c2 | c3 ----+----+---- - 0 | 0 | 1 - 1 | 0 | 2 2 | 1 | 3 3 | 1 | 4 4 | 2 | 5 5 | 2 | 6 + 0 | 0 | 1 + 1 | 0 | 2 (6 rows) -- @@ -1108,14 +1153,15 @@ explain (verbose, costs off) InitPlan 2 (returns $1) -> Result Output: 'regression'::name + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(9 rows) +(10 rows) explain (verbose, costs off) select x, x from (select (select random()) as x from (values(1),(2)) v(y)) ss; - QUERY PLAN ------------------------------------ + QUERY PLAN +------------------------------------- Subquery Scan on ss Output: ss.x, ss.x -> Values Scan on "*VALUES*" @@ -1123,8 +1169,9 @@ explain (verbose, costs off) InitPlan 1 (returns $0) -> Result Output: random() + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(8 rows) +(9 rows) explain (verbose, costs off) select x, x from @@ -1141,8 +1188,9 @@ explain (verbose, costs off) -> Result Output: 'regression'::name One-Time Filter: ("*VALUES*".column1 = "*VALUES*".column1) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(11 rows) +(12 rows) explain (verbose, costs off) select x, x from @@ -1157,8 +1205,9 @@ explain (verbose, costs off) -> Result Output: random() One-Time Filter: ("*VALUES*".column1 = "*VALUES*".column1) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(9 rows) +(10 rows) -- -- Test rescan of a hashed subplan (the use of random() is to prevent the @@ -1280,13 +1329,17 @@ where o.ten = 1; -- Check we don't misoptimize a NOT IN where the subquery returns no rows. -- create temp table notinouter (a int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp table notininner (b int not null); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'b' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into notinouter values (null), (1); select * from notinouter where a not in (select b from notininner); a --- - 1 + (2 rows) -- @@ -1344,7 +1397,9 @@ select * from SubPlan 1 -> Values Scan on "*VALUES*_1" Output: "*VALUES*_1".column1 -(5 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(7 rows) select * from (values @@ -1392,8 +1447,9 @@ select * from int4_tbl where Hash Key: b.ten -> Seq Scan on public.tenk1 b Output: b.ten + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(26 rows) +(27 rows) select * from int4_tbl where (case when f1 in (select unique1 from tenk1 a) then f1 else null end) in @@ -1409,28 +1465,29 @@ select * from int4_tbl where explain (verbose, costs off) select * from int4_tbl o where (f1, f1) in (select f1, generate_series(1,50) / 10 g from int4_tbl i group by f1); - QUERY PLAN -------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: o.f1 - -> Hash Semi Join + -> Hash Right Semi Join Output: o.f1 - Hash Cond: (o.f1 = "ANY_subquery".f1) - -> Seq Scan on public.int4_tbl o - Output: o.f1 - -> Hash + Hash Cond: ("ANY_subquery".f1 = o.f1) + -> Subquery Scan on "ANY_subquery" Output: "ANY_subquery".f1, "ANY_subquery".g - -> Subquery Scan on "ANY_subquery" - Output: "ANY_subquery".f1, "ANY_subquery".g - Filter: ("ANY_subquery".f1 = "ANY_subquery".g) - -> Result - Output: i.f1, ((generate_series(1, 50)) / 10) - -> ProjectSet - Output: generate_series(1, 50), i.f1 - -> Seq Scan on public.int4_tbl i - Output: i.f1 + Filter: ("ANY_subquery".f1 = "ANY_subquery".g) + -> Result + Output: i.f1, ((generate_series(1, 50)) / 10) + -> ProjectSet + Output: generate_series(1, 50), i.f1 + -> Seq Scan on public.int4_tbl i + Output: i.f1 + -> Hash + Output: o.f1 + -> Seq Scan on public.int4_tbl o + Output: o.f1 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(19 rows) +(20 rows) select * from int4_tbl o where (f1, f1) in (select f1, generate_series(1,50) / 10 g from int4_tbl i group by f1); @@ -1450,9 +1507,9 @@ select (select q from from int4_tbl; q ----------- - (4,5,6.0) (1,2,3) (4,5,6.0) + (4,5,6.0) (1,2,3) (4,5,6.0) (5 rows) @@ -1494,7 +1551,9 @@ where b and f1 >= 0; Output: random() -> Result Output: true, 2 -(21 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(22 rows) select * from int4_tbl i4, @@ -1507,9 +1566,9 @@ select * from where b and f1 >= 0; f1 | b | id ------------+---+---- - 0 | t | 2 123456 | t | 1 123456 | t | 2 + 0 | t | 2 2147483647 | t | 1 2147483647 | t | 2 (5 rows) @@ -1565,7 +1624,9 @@ select * from -> ProjectSet Output: 9, unnest('{1,2,3,11,12,13}'::integer[]) -> Result -(6 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(8 rows) select * from (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss @@ -1598,7 +1659,9 @@ NOTICE: x = 9, y = 8 ProjectSet Output: 9, unnest('{1,2,3,11,12,13}'::integer[]) -> Result -(4 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(5 rows) select * from (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss @@ -1627,7 +1690,9 @@ select * from -> ProjectSet Output: 9, unnest('{1,2,3,11,12,13}'::integer[]) -> Result -(6 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(8 rows) select * from (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss @@ -1792,8 +1857,9 @@ order by t1.ten; Output: t1.ten, t1.unique1 -> Seq Scan on public.tenk1 t1 Output: t1.ten, t1.unique1 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(28 rows) +(29 rows) select t1.ten, sum(x) from tenk1 t1 left join lateral ( @@ -1855,8 +1921,9 @@ order by 1, 2; Hash Key: t1.q2 -> Seq Scan on public.int8_tbl t1 Output: t1.q1, t1.q2 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(32 rows) +(33 rows) select t1.q1, x from int8_tbl t1 left join @@ -1887,15 +1954,15 @@ set gp_cte_sharing to on; explain (verbose, costs off) with x as (select * from (select f1 from subselect_tbl) ss) select * from x where f1 = 1; - QUERY PLAN ------------------------------------------- + QUERY PLAN +---------------------------------------------------- Gather Motion 1:1 (slice1; segments: 1) Output: subselect_tbl.f1 -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1 Filter: (subselect_tbl.f1 = 1) + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer - Settings: optimizer=off (7 rows) -- Explicitly request materialization @@ -1913,8 +1980,8 @@ select * from x where f1 = 1; Output: share0_ref1.f1 -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1 + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer - Settings: gp_cte_sharing=on (11 rows) -- Stable functions are safe to inline @@ -1928,8 +1995,8 @@ select * from x where f1 = 1; -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1, 'regression'::name Filter: (subselect_tbl.f1 = 1) + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer - Settings: gp_cte_sharing=on (7 rows) -- Volatile functions prevent inlining @@ -1949,12 +2016,13 @@ select * from x where f1 = 1; Output: share0_ref1.f1, share0_ref1.random -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1, random() + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(10 rows) +(11 rows) create temporary sequence ts; create table vol_test(a int, b int); -NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table. +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. explain (verbose, costs off) with x as (select * from (select a, nextval('ts') from vol_test) ss) @@ -1970,8 +2038,9 @@ select * from x where a = 1; Output: share0_ref1.a, share0_ref1.nextval -> Seq Scan on public.vol_test Output: vol_test.a, nextval('ts'::regclass) + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(10 rows) +(11 rows) drop sequence ts; drop table vol_test; @@ -1992,8 +2061,8 @@ select * from x where f1 = 1; -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1, subselect_tbl.ctid Filter: (subselect_tbl.f1 = 1) + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer - Settings: gp_cte_sharing=on, optimizer=off (9 rows) -- Multiply-referenced CTEs are inlined only when requested @@ -2021,7 +2090,7 @@ select * from x, x x2 where x.n = x2.n; Output: share0_ref1.f1, share0_ref1.n -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1, 'regression'::name - Settings: gp_cte_sharing=on + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer (21 rows) @@ -2047,8 +2116,8 @@ select * from x, x x2 where x.n = x2.n; Hash Key: ('regression'::name) -> Seq Scan on public.subselect_tbl subselect_tbl_1 Output: subselect_tbl_1.f1, 'regression'::name + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer - Settings: gp_cte_sharing=on (19 rows) -- Multiply-referenced CTEs can't be inlined if they contain outer self-refs @@ -2060,8 +2129,8 @@ with recursive x(a) as select z.a || z1.a as a from z cross join z as z1 where length(z.a || z1.a) < 5)) select * from x; - QUERY PLAN ---------------------------------------------------- + QUERY PLAN +---------------------------------------------------- Recursive Union -> Values Scan on "*VALUES*" Output: "*VALUES*".column1 @@ -2072,7 +2141,7 @@ select * from x; Output: x.a -> WorkTable Scan on x x_1 Output: x_1.a - Settings: optimizer = 'off' + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer (12 rows) @@ -2117,8 +2186,8 @@ with recursive x(a) as select z.a || z.a as a from z where length(z.a || z.a) < 5)) select * from x; - QUERY PLAN --------------------------------------------------- + QUERY PLAN +---------------------------------------------------- Recursive Union -> Values Scan on "*VALUES*" Output: "*VALUES*".column1 @@ -2127,7 +2196,7 @@ select * from x; -> WorkTable Scan on x Output: x.a Filter: (length((x.a || x.a)) < 5) - Settings: optimizer = 'off' + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer (10 rows) @@ -2152,28 +2221,29 @@ select * from x; explain (verbose, costs off) with x as (select * from int4_tbl) select * from (with y as (select * from x) select * from y) ss; - QUERY PLAN ------------------------------------------- + QUERY PLAN +---------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: int4_tbl.f1 -> Seq Scan on public.int4_tbl Output: int4_tbl.f1 + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(5 rows) +(6 rows) explain (verbose, costs off) with x as materialized (select * from int4_tbl) select * from (with y as (select * from x) select * from y) ss; - QUERY PLAN --------------------------------------------- + QUERY PLAN +---------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: share0_ref1.f1 -> Shared Scan (share slice:id 1:0) Output: share0_ref1.f1 -> Seq Scan on public.int4_tbl Output: int4_tbl.f1 + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer - Settings: gp_cte_sharing=on, optimizer=off (8 rows) -- Ensure that we inline the currect CTE when there are @@ -2181,11 +2251,13 @@ select * from (with y as (select * from x) select * from y) ss; explain (verbose, costs off) with x as (select 1 as y) select * from (with x as (select 2 as y) select * from x) ss; - QUERY PLAN -------------- + QUERY PLAN +---------------------------------------------------- Result Output: 2 -(2 rows) + Settings: optimizer = 'off', gp_cte_sharing = 'on' + Optimizer: Postgres query optimizer +(4 rows) -- Row marks are not pushed into CTEs explain (verbose, costs off) @@ -2197,8 +2269,9 @@ select * from x for update; Output: subselect_tbl.f1, subselect_tbl.f2, subselect_tbl.f3 -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1, subselect_tbl.f2, subselect_tbl.f3 + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(5 rows) +(6 rows) set gp_cte_sharing to off; -- Ensure that both planners produce valid plans for the query with the nested @@ -2219,8 +2292,8 @@ select j, (select j from (select j) q2) from t group by i, j; - QUERY PLAN ------------------------------------------- + QUERY PLAN +----------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: t.j, ((SubPlan 1)), t.i -> HashAggregate @@ -2231,8 +2304,9 @@ group by i, j; SubPlan 1 -> Result Output: t.j - Optimizer: Postgres-based planner -(11 rows) + Settings: optimizer = 'off', gp_cte_sharing = 'off' + Optimizer: Postgres query optimizer +(12 rows) select j, (select j from (select j) q2) @@ -2274,8 +2348,9 @@ group by j, q1; SubPlan 1 -> Result Output: t.j - Optimizer: Postgres-based planner -(17 rows) + Settings: optimizer = 'off', gp_cte_sharing = 'off' + Optimizer: Postgres query optimizer +(18 rows) select j, 1 as c, (select j from (select j) q2) q1 @@ -2292,8 +2367,8 @@ group by j, q1; -- should correctly process args of the aggregation during normalization. explain (verbose, costs off) select (select max((select t.i))) from t; - QUERY PLAN ------------------------------------------------- + QUERY PLAN +----------------------------------------------------- Finalize Aggregate Output: (SubPlan 2) -> Gather Motion 3:1 (slice1; segments: 3) @@ -2308,8 +2383,9 @@ select (select max((select t.i))) from t; SubPlan 2 -> Result Output: max((SubPlan 1)) - Optimizer: Postgres-based planner -(15 rows) + Settings: optimizer = 'off', gp_cte_sharing = 'off' + Optimizer: Postgres query optimizer +(16 rows) select (select max((select t.i))) from t; max diff --git a/contrib/pax_storage/src/test/regress/expected/subselect_gp.out b/contrib/pax_storage/src/test/regress/expected/subselect_gp.out index 8a2863ae734..c0f9b8c3e38 100644 --- a/contrib/pax_storage/src/test/regress/expected/subselect_gp.out +++ b/contrib/pax_storage/src/test/regress/expected/subselect_gp.out @@ -1,3 +1,7 @@ +-- start_ignore +create schema subselect_gp; +set search_path to subselect_gp, public; +-- end_ignore set optimizer_enable_master_only_queries = on; set optimizer_segments = 3; set optimizer_nestloop_factor = 1.0; @@ -196,14 +200,14 @@ analyze mrs_t1; explain select * from mrs_t1 where exists (select x from mrs_t1 where x < -1); QUERY PLAN ------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=3.27..6.87 rows=20 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.10..2.44 rows=20 width=4) InitPlan 1 (returns $0) (slice2) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..3.27 rows=1 width=0) - -> Seq Scan on mrs_t1 mrs_t1_1 (cost=0.00..3.25 rows=1 width=0) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..1.10 rows=1 width=4) + -> Seq Scan on mrs_t1 mrs_t1_1 (cost=0.00..1.08 rows=1 width=4) Filter: (x < '-1'::integer) - -> Result (cost=3.27..6.47 rows=7 width=4) + -> Result (cost=0.00..1.07 rows=7 width=4) One-Time Filter: $0 - -> Seq Scan on mrs_t1 (cost=3.27..6.47 rows=7 width=4) + -> Seq Scan on mrs_t1 (cost=0.00..1.07 rows=7 width=4) Optimizer: Postgres query optimizer (9 rows) @@ -215,14 +219,14 @@ select * from mrs_t1 where exists (select x from mrs_t1 where x < -1) order by 1 explain select * from mrs_t1 where exists (select x from mrs_t1 where x = 1); QUERY PLAN ------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=3.27..6.87 rows=20 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.10..2.44 rows=20 width=4) InitPlan 1 (returns $0) (slice2) - -> Gather Motion 1:1 (slice3; segments: 1) (cost=0.00..3.27 rows=1 width=0) - -> Seq Scan on mrs_t1 mrs_t1_1 (cost=0.00..3.25 rows=1 width=0) + -> Gather Motion 1:1 (slice3; segments: 1) (cost=0.00..1.10 rows=1 width=4) + -> Seq Scan on mrs_t1 mrs_t1_1 (cost=0.00..1.08 rows=1 width=4) Filter: (x = 1) - -> Result (cost=3.27..6.47 rows=7 width=4) + -> Result (cost=0.00..1.07 rows=7 width=4) One-Time Filter: $0 - -> Seq Scan on mrs_t1 (cost=3.27..6.47 rows=7 width=4) + -> Seq Scan on mrs_t1 (cost=0.00..1.07 rows=7 width=4) Optimizer: Postgres query optimizer (9 rows) @@ -254,12 +258,12 @@ select * from mrs_t1 where exists (select x from mrs_t1 where x = 1) order by 1; explain select * from mrs_t1 where x in (select x-95 from mrs_t1) or x < 5; QUERY PLAN --------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice2; segments: 3) (cost=3.30..6.60 rows=13 width=4) - -> Seq Scan on mrs_t1 (cost=3.30..6.60 rows=5 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.24 rows=12 width=4) + -> Seq Scan on mrs_t1 (cost=0.00..1.08 rows=4 width=4) Filter: ((hashed SubPlan 1) OR (x < 5)) SubPlan 1 - -> Broadcast Motion 3:3 (slice1; segments: 3) (cost=0.00..3.25 rows=7 width=4) - -> Seq Scan on mrs_t1 mrs_t1_1 (cost=0.00..3.25 rows=7 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.08 rows=7 width=4) + -> Seq Scan on mrs_t1 mrs_t1_1 (cost=0.00..1.08 rows=7 width=4) Optimizer: Postgres query optimizer (7 rows) @@ -363,12 +367,11 @@ analyze csq_d1; explain select array(select x from csq_m1); -- no initplan QUERY PLAN -------------------------------------------------------------- - Result (cost=1.01..1.02 rows=1 width=0) + Result (cost=1.01..1.02 rows=1 width=32) InitPlan 1 (returns $0) -> Seq Scan on csq_m1 (cost=0.00..1.01 rows=1 width=4) - Settings: optimizer_segments=3 - Optimizer status: Postgres query optimizer -(5 rows) + Optimizer: Postgres query optimizer +(4 rows) select array(select x from csq_m1); -- {1} array @@ -379,13 +382,12 @@ select array(select x from csq_m1); -- {1} explain select array(select x from csq_d1); -- initplan QUERY PLAN ------------------------------------------------------------------------------------ - Result (cost=1.01..1.02 rows=1 width=0) + Result (cost=1.03..1.04 rows=1 width=32) InitPlan 1 (returns $0) (slice1) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.01 rows=1 width=4) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=4) -> Seq Scan on csq_d1 (cost=0.00..1.01 rows=1 width=4) - Settings: optimizer_segments=3 - Optimizer status: Postgres query optimizer -(6 rows) + Optimizer: Postgres query optimizer +(5 rows) select array(select x from csq_d1); -- {1} array @@ -456,9 +458,9 @@ select * from csq_m1; select * from csq_d1; x --- - 1 2 4 + 1 (3 rows) -- @@ -467,11 +469,11 @@ select * from csq_d1; explain select * from csq_m1 where x not in (select x from csq_d1) or x < -100; -- gather motion QUERY PLAN ------------------------------------------------------------------------------------ - Seq Scan on csq_m1 (cost=2.02..3.07 rows=2 width=4) + Seq Scan on csq_m1 (cost=0.00..1.04 rows=2 width=4) Filter: ((NOT (hashed SubPlan 1)) OR (x < '-100'::integer)) SubPlan 1 - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.02 rows=2 width=4) - -> Seq Scan on csq_d1 (cost=0.00..2.02 rows=1 width=4) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.05 rows=3 width=4) + -> Seq Scan on csq_d1 (cost=0.00..1.01 rows=1 width=4) Optimizer: Postgres query optimizer (6 rows) @@ -487,11 +489,11 @@ select * from csq_m1 where x not in (select x from csq_d1) or x < -100; -- (3) explain select * from csq_d1 where x not in (select x from csq_m1) or x < -100; -- broadcast motion QUERY PLAN -------------------------------------------------------------------------------- - Gather Motion 3:1 (slice2; segments: 3) (cost=1.04..3.07 rows=2 width=4) - -> Seq Scan on csq_d1 (cost=1.04..3.07 rows=1 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.04 rows=2 width=4) + -> Seq Scan on csq_d1 (cost=0.00..1.01 rows=1 width=4) Filter: ((NOT (hashed SubPlan 1)) OR (x < '-100'::integer)) SubPlan 1 - -> Broadcast Motion 1:3 (slice1) (cost=0.00..1.03 rows=3 width=4) + -> Broadcast Motion 1:3 (slice2) (cost=0.00..1.03 rows=3 width=4) -> Seq Scan on csq_m1 (cost=0.00..1.03 rows=3 width=4) Optimizer: Postgres query optimizer (7 rows) @@ -535,10 +537,10 @@ INSERT INTO csq_r VALUES (1); -- with a correlated argument -- force_explain explain SELECT * FROM csq_r WHERE a IN (SELECT * FROM csq_f(csq_r.a)); - QUERY PLAN ----------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.02 rows=1 width=4) - -> Seq Scan on csq_r (cost=0.00..1.02 rows=1 width=4) + QUERY PLAN +---------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..997.00 rows=48150 width=4) + -> Seq Scan on csq_r (cost=0.00..355.00 rows=16050 width=4) Filter: (SubPlan 1) SubPlan 1 -> Function Scan on csq_f (cost=0.00..0.01 rows=1 width=4) @@ -553,10 +555,10 @@ SELECT * FROM csq_r WHERE a IN (SELECT * FROM csq_f(csq_r.a)); -- force_explain explain SELECT * FROM csq_r WHERE a not IN (SELECT * FROM csq_f(csq_r.a)); - QUERY PLAN ----------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.02 rows=1 width=4) - -> Seq Scan on csq_r (cost=0.00..1.02 rows=1 width=4) + QUERY PLAN +---------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..997.00 rows=48150 width=4) + -> Seq Scan on csq_r (cost=0.00..355.00 rows=16050 width=4) Filter: (SubPlan 1) SubPlan 1 -> Function Scan on csq_f (cost=0.00..0.01 rows=1 width=4) @@ -570,10 +572,10 @@ SELECT * FROM csq_r WHERE a not IN (SELECT * FROM csq_f(csq_r.a)); -- force_explain explain SELECT * FROM csq_r WHERE exists (SELECT * FROM csq_f(csq_r.a)); - QUERY PLAN ----------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.02 rows=1 width=4) - -> Seq Scan on csq_r (cost=0.00..1.02 rows=1 width=4) + QUERY PLAN +---------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..997.00 rows=48150 width=4) + -> Seq Scan on csq_r (cost=0.00..355.00 rows=16050 width=4) Filter: (SubPlan 1) SubPlan 1 -> Function Scan on csq_f (cost=0.00..0.01 rows=1 width=0) @@ -588,10 +590,10 @@ SELECT * FROM csq_r WHERE exists (SELECT * FROM csq_f(csq_r.a)); -- force_explain explain SELECT * FROM csq_r WHERE not exists (SELECT * FROM csq_f(csq_r.a)); - QUERY PLAN ----------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.02 rows=1 width=4) - -> Seq Scan on csq_r (cost=0.00..1.02 rows=1 width=4) + QUERY PLAN +---------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..997.00 rows=48150 width=4) + -> Seq Scan on csq_r (cost=0.00..355.00 rows=16050 width=4) Filter: (NOT (SubPlan 1)) SubPlan 1 -> Function Scan on csq_f (cost=0.00..0.01 rows=1 width=0) @@ -605,10 +607,10 @@ SELECT * FROM csq_r WHERE not exists (SELECT * FROM csq_f(csq_r.a)); -- force_explain explain SELECT * FROM csq_r WHERE a > (SELECT csq_f FROM csq_f(csq_r.a) limit 1); - QUERY PLAN ------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.02 rows=1 width=4) - -> Seq Scan on csq_r (cost=0.00..1.02 rows=1 width=4) + QUERY PLAN +---------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..863.25 rows=32100 width=4) + -> Seq Scan on csq_r (cost=0.00..435.25 rows=10700 width=4) Filter: (a > (SubPlan 1)) SubPlan 1 -> Limit (cost=0.00..0.01 rows=1 width=4) @@ -623,10 +625,10 @@ SELECT * FROM csq_r WHERE a > (SELECT csq_f FROM csq_f(csq_r.a) limit 1); -- force_explain explain SELECT * FROM csq_r WHERE a < ANY (SELECT csq_f FROM csq_f(csq_r.a)); - QUERY PLAN ----------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.02 rows=1 width=4) - -> Seq Scan on csq_r (cost=0.00..1.02 rows=1 width=4) + QUERY PLAN +---------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..997.00 rows=48150 width=4) + -> Seq Scan on csq_r (cost=0.00..355.00 rows=16050 width=4) Filter: (SubPlan 1) SubPlan 1 -> Function Scan on csq_f (cost=0.00..0.01 rows=1 width=4) @@ -640,10 +642,10 @@ SELECT * FROM csq_r WHERE a < ANY (SELECT csq_f FROM csq_f(csq_r.a)); -- force_explain explain SELECT * FROM csq_r WHERE a <= ALL (SELECT csq_f FROM csq_f(csq_r.a)); - QUERY PLAN ----------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.02 rows=1 width=4) - -> Seq Scan on csq_r (cost=0.00..1.02 rows=1 width=4) + QUERY PLAN +---------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..997.00 rows=48150 width=4) + -> Seq Scan on csq_r (cost=0.00..355.00 rows=16050 width=4) Filter: (SubPlan 1) SubPlan 1 -> Function Scan on csq_f (cost=0.00..0.01 rows=1 width=4) @@ -658,17 +660,17 @@ SELECT * FROM csq_r WHERE a <= ALL (SELECT csq_f FROM csq_f(csq_r.a)); -- force_explain explain SELECT * FROM csq_r WHERE a IN (SELECT csq_f FROM csq_f(csq_r.a),csq_r); - QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..10000000001.54 rows=1 width=4) - -> Seq Scan on csq_r (cost=0.00..10000000001.54 rows=1 width=4) + QUERY PLAN +---------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..997.00 rows=48150 width=4) + -> Seq Scan on csq_r (cost=0.00..355.00 rows=16050 width=4) Filter: (SubPlan 1) SubPlan 1 - -> Nested Loop (cost=10000000000.00..10000000001.06 rows=4 width=4) + -> Nested Loop (cost=10000000000.00..10000003083.51 rows=96300 width=4) -> Function Scan on csq_f (cost=0.00..0.01 rows=1 width=4) - -> Materialize (cost=0.00..1.03 rows=1 width=0) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=0) - -> Seq Scan on csq_r csq_r_1 (cost=0.00..1.01 rows=1 width=0) + -> Materialize (cost=0.00..2120.50 rows=96300 width=0) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1639.00 rows=96300 width=0) + -> Seq Scan on csq_r csq_r_1 (cost=0.00..355.00 rows=32100 width=0) Optimizer: Postgres query optimizer (10 rows) @@ -700,19 +702,18 @@ insert into csq_pullup values ('def',3, 1, 'abc'); explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.t); QUERY PLAN ------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..2.11 rows=4 width=19) - -> Hash Join (cost=1.06..2.11 rows=2 width=19) - Hash Cond: t0.t = "Expr_SUBQUERY".csq_c0 - -> Seq Scan on csq_pullup t0 (cost=0.00..1.01 rows=1 width=19) - -> Hash (cost=1.04..1.04 rows=1 width=32) - -> Subquery Scan on "Expr_SUBQUERY" (cost=1.02..1.04 rows=1 width=32) - -> HashAggregate (cost=1.02..1.03 rows=1 width=40) - Filter: count(*) = 1 - Group By: t1.t + Gather Motion 3:1 (slice1; segments: 3) (cost=1.05..2.12 rows=3 width=17) + -> Hash Join (cost=1.05..2.07 rows=1 width=17) + Hash Cond: (t0.t = "Expr_SUBQUERY".csq_c0) + -> Seq Scan on csq_pullup t0 (cost=0.00..1.01 rows=1 width=17) + -> Hash (cost=1.04..1.04 rows=1 width=4) + -> Subquery Scan on "Expr_SUBQUERY" (cost=1.01..1.04 rows=1 width=4) + -> HashAggregate (cost=1.01..1.03 rows=1 width=12) + Group Key: t1.t + Filter: (1 = count(*)) -> Seq Scan on csq_pullup t1 (cost=0.00..1.01 rows=1 width=4) - Settings: optimizer_segments=3 - Optimizer status: Postgres query optimizer -(12 rows) + Optimizer: Postgres query optimizer +(11 rows) select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.t); t | n | i | v @@ -728,16 +729,16 @@ select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.v); QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice2; segments: 3) (cost=1.06..2.11 rows=4 width=17) - -> Hash Join (cost=1.06..2.11 rows=2 width=17) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.07..2.14 rows=3 width=17) + -> Hash Join (cost=1.07..2.09 rows=1 width=17) Hash Cond: (t0.t = "Expr_SUBQUERY".csq_c0) -> Seq Scan on csq_pullup t0 (cost=0.00..1.01 rows=1 width=17) - -> Hash (cost=1.05..1.05 rows=1 width=32) - -> Subquery Scan on "Expr_SUBQUERY" (cost=1.03..1.05 rows=1 width=32) - -> HashAggregate (cost=1.03..1.04 rows=1 width=40) + -> Hash (cost=1.06..1.06 rows=1 width=32) + -> Subquery Scan on "Expr_SUBQUERY" (cost=1.03..1.06 rows=1 width=32) + -> HashAggregate (cost=1.03..1.05 rows=1 width=40) Group Key: ((t1.v)::text) Filter: (1 = count(*)) - -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=32) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=32) Hash Key: ((t1.v)::text) -> Seq Scan on csq_pullup t1 (cost=0.00..1.01 rows=1 width=32) Optimizer: Postgres query optimizer @@ -757,17 +758,17 @@ select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.n=t1.n); QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice3; segments: 3) (cost=1.13..2.17 rows=4 width=17) - -> Hash Join (cost=1.13..2.17 rows=2 width=17) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.14..2.20 rows=3 width=17) + -> Hash Join (cost=1.14..2.16 rows=1 width=17) Hash Cond: (t0.n = "Expr_SUBQUERY".csq_c0) -> Seq Scan on csq_pullup t0 (cost=0.00..1.01 rows=1 width=17) - -> Hash (cost=1.09..1.09 rows=1 width=5) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=1.03..1.09 rows=1 width=5) - -> Subquery Scan on "Expr_SUBQUERY" (cost=1.03..1.05 rows=1 width=5) - -> HashAggregate (cost=1.03..1.04 rows=1 width=13) + -> Hash (cost=1.10..1.10 rows=3 width=5) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=1.03..1.10 rows=3 width=5) + -> Subquery Scan on "Expr_SUBQUERY" (cost=1.03..1.06 rows=1 width=5) + -> HashAggregate (cost=1.03..1.05 rows=1 width=13) Group Key: t1.n Filter: (1 = count(*)) - -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=5) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.03 rows=1 width=5) Hash Key: t1.n -> Seq Scan on csq_pullup t1 (cost=0.00..1.01 rows=1 width=5) Optimizer: Postgres query optimizer @@ -777,8 +778,8 @@ select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t t | n | i | v -----+---+---+----- def | 3 | 1 | abc - xyz | 2 | 3 | def abc | 1 | 2 | xyz + xyz | 2 | 3 | def (3 rows) -- @@ -787,18 +788,18 @@ select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.n + 1=t1.n + 1); QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice3; segments: 3) (cost=1.07..2.13 rows=4 width=17) - -> Hash Join (cost=1.07..2.13 rows=2 width=17) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.07..2.16 rows=3 width=17) + -> Hash Join (cost=1.07..2.12 rows=1 width=17) Hash Cond: ((t0.n + '1'::numeric) = "Expr_SUBQUERY".csq_c0) - -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=17) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=17) Hash Key: (t0.n + '1'::numeric) -> Seq Scan on csq_pullup t0 (cost=0.00..1.01 rows=1 width=17) - -> Hash (cost=1.05..1.05 rows=1 width=32) - -> Subquery Scan on "Expr_SUBQUERY" (cost=1.03..1.05 rows=1 width=32) - -> HashAggregate (cost=1.03..1.04 rows=1 width=40) + -> Hash (cost=1.06..1.06 rows=1 width=32) + -> Subquery Scan on "Expr_SUBQUERY" (cost=1.04..1.06 rows=1 width=32) + -> HashAggregate (cost=1.04..1.05 rows=1 width=40) Group Key: ((t1.n + '1'::numeric)) Filter: (1 = count(*)) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=32) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.03 rows=1 width=32) Hash Key: ((t1.n + '1'::numeric)) -> Seq Scan on csq_pullup t1 (cost=0.00..1.01 rows=1 width=32) Optimizer: Postgres query optimizer @@ -807,8 +808,8 @@ explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.n + 1=t1.n + 1); t | n | i | v -----+---+---+----- - def | 3 | 1 | abc xyz | 2 | 3 | def + def | 3 | 1 | abc abc | 1 | 2 | xyz (3 rows) @@ -818,18 +819,18 @@ select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.n + 1=t1.i + 1); QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice3; segments: 3) (cost=1.07..2.14 rows=4 width=17) - -> Hash Join (cost=1.07..2.14 rows=2 width=17) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.08..2.17 rows=3 width=17) + -> Hash Join (cost=1.08..2.12 rows=1 width=17) Hash Cond: ((t0.n + '1'::numeric) = "Expr_SUBQUERY".csq_c0) - -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=17) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=17) Hash Key: (t0.n + '1'::numeric) -> Seq Scan on csq_pullup t0 (cost=0.00..1.01 rows=1 width=17) - -> Hash (cost=1.06..1.06 rows=1 width=32) - -> Subquery Scan on "Expr_SUBQUERY" (cost=1.03..1.06 rows=1 width=32) - -> HashAggregate (cost=1.03..1.05 rows=1 width=40) + -> Hash (cost=1.07..1.07 rows=1 width=32) + -> Subquery Scan on "Expr_SUBQUERY" (cost=1.04..1.07 rows=1 width=32) + -> HashAggregate (cost=1.04..1.06 rows=1 width=40) Group Key: (((t1.i + 1))::numeric) Filter: (1 = count(*)) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=32) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.03 rows=1 width=32) Hash Key: (((t1.i + 1))::numeric) -> Seq Scan on csq_pullup t1 (cost=0.00..1.01 rows=1 width=32) Optimizer: Postgres query optimizer @@ -838,9 +839,9 @@ explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.n + 1=t1.i + 1); t | n | i | v -----+---+---+----- + abc | 1 | 2 | xyz xyz | 2 | 3 | def def | 3 | 1 | abc - abc | 1 | 2 | xyz (3 rows) -- @@ -867,9 +868,9 @@ explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.t LIMIT 1); t | n | i | v -----+---+---+----- + abc | 1 | 2 | xyz xyz | 2 | 3 | def def | 3 | 1 | abc - abc | 1 | 2 | xyz (3 rows) -- subquery contains a HAVING clause @@ -893,9 +894,9 @@ explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.t HAVING count(*) < 10); t | n | i | v -----+---+---+----- - xyz | 2 | 3 | def def | 3 | 1 | abc abc | 1 | 2 | xyz + xyz | 2 | 3 | def (3 rows) -- subquery contains quals of form 'function(outervar, innervar1) = innvervar2' @@ -942,8 +943,8 @@ explain select * from csq_pullup t0 where not exists (select 1 from csq_pullup t select * from csq_pullup t0 where not exists (select 1 from csq_pullup t1 where t0.t=t1.t and t1.i = 1); t | n | i | v -----+---+---+----- - abc | 1 | 2 | xyz xyz | 2 | 3 | def + abc | 1 | 2 | xyz (2 rows) -- @@ -972,9 +973,7 @@ select * from csq_pullup t0 where not exists (select 1 from csq_pullup t1 where -- wrong results bug MPP-16477 -- drop table if exists subselect_t1; -NOTICE: table "subselect_t1" does not exist, skipping drop table if exists subselect_t2; -NOTICE: table "subselect_t2" does not exist, skipping create table subselect_t1(x int) distributed by (x); insert into subselect_t1 values(1),(2); create table subselect_t2(y int) distributed by (y); @@ -1004,16 +1003,16 @@ select * from subselect_t1 where x in (select y from subselect_t2); -- Known_opt_diff: MPP-21351 -- end_ignore explain select * from subselect_t1 where x in (select y from subselect_t2 union all select y from subselect_t2); - QUERY PLAN ---------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.05..3.12 rows=3 width=4) - -> Hash Semi Join (cost=2.05..3.08 rows=1 width=4) - Hash Cond: (subselect_t1.x = subselect_t2.y) - -> Seq Scan on subselect_t1 (cost=0.00..1.01 rows=1 width=4) - -> Hash (cost=2.03..2.03 rows=2 width=4) - -> Append (cost=0.00..2.03 rows=2 width=4) - -> Seq Scan on subselect_t2 (cost=0.00..1.01 rows=1 width=4) - -> Seq Scan on subselect_t2 subselect_t2_1 (cost=0.00..1.01 rows=1 width=4) + QUERY PLAN +--------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=1.02..3.11 rows=3 width=4) + -> Hash Right Semi Join (cost=1.02..3.07 rows=1 width=4) + Hash Cond: (subselect_t2.y = subselect_t1.x) + -> Append (cost=0.00..2.03 rows=2 width=4) + -> Seq Scan on subselect_t2 (cost=0.00..1.01 rows=1 width=4) + -> Seq Scan on subselect_t2 subselect_t2_1 (cost=0.00..1.01 rows=1 width=4) + -> Hash (cost=1.01..1.01 rows=1 width=4) + -> Seq Scan on subselect_t1 (cost=0.00..1.01 rows=1 width=4) Optimizer: Postgres query optimizer (9 rows) @@ -1047,17 +1046,17 @@ select count(*) from subselect_t1 where x in (select y from subselect_t2); -- Known_opt_diff: MPP-21351 -- end_ignore explain select count(*) from subselect_t1 where x in (select y from subselect_t2 union all select y from subselect_t2); - QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Aggregate (cost=3.14..3.15 rows=1 width=8) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=2.06..3.13 rows=3 width=0) - -> Hash Semi Join (cost=2.06..3.09 rows=1 width=0) - Hash Cond: (subselect_t1.x = subselect_t2.y) - -> Seq Scan on subselect_t1 (cost=0.00..1.01 rows=1 width=4) - -> Hash (cost=2.04..2.04 rows=2 width=4) - -> Append (cost=0.00..2.02 rows=2 width=4) - -> Seq Scan on subselect_t2 (cost=0.00..1.01 rows=1 width=4) - -> Seq Scan on subselect_t2 subselect_t2_1 (cost=0.00..1.01 rows=1 width=4) + QUERY PLAN +--------------------------------------------------------------------------------------------------- + Aggregate (cost=3.12..3.13 rows=1 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=1.02..3.11 rows=3 width=0) + -> Hash Right Semi Join (cost=1.02..3.07 rows=1 width=0) + Hash Cond: (subselect_t2.y = subselect_t1.x) + -> Append (cost=0.00..2.03 rows=2 width=4) + -> Seq Scan on subselect_t2 (cost=0.00..1.01 rows=1 width=4) + -> Seq Scan on subselect_t2 subselect_t2_1 (cost=0.00..1.01 rows=1 width=4) + -> Hash (cost=1.01..1.01 rows=1 width=4) + -> Seq Scan on subselect_t1 (cost=0.00..1.01 rows=1 width=4) Optimizer: Postgres query optimizer (10 rows) @@ -1080,9 +1079,13 @@ select count(*) from -- Query was deadlocking because of not squelching subplans (MPP-18936) -- drop table if exists t1; +NOTICE: table "t1" does not exist, skipping drop table if exists t2; +NOTICE: table "t2" does not exist, skipping drop table if exists t3; +NOTICE: table "t3" does not exist, skipping drop table if exists t4; +NOTICE: table "t4" does not exist, skipping CREATE TABLE t1 AS (SELECT generate_series(1, 5000) AS i, generate_series(5001, 10000) AS j); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'i' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. @@ -1159,13 +1162,12 @@ select * from t1 where a=1 and a=2 and a > (select t2.b from t2); explain select * from t1, (select * from t1 where a=1 and a=2 and a > (select t2.b from t2)) foo where t1.a = foo.a; - QUERY PLAN ------------------------------------------------------------------------------ - Result (cost=1063.00..1063.01 rows=1 width=0) + QUERY PLAN +------------------------------------------------ + Result (cost=1639.00..1639.00 rows=0 width=8) One-Time Filter: false - Settings: optimizer=off; optimizer_nestloop_factor=1; optimizer_segments=3 - Optimizer status: Postgres query optimizer -(4 rows) + Optimizer: Postgres query optimizer +(3 rows) select * from t1, (select * from t1 where a=1 and a=2 and a > (select t2.b from t2)) foo @@ -1180,34 +1182,34 @@ where t1.a = foo.a; insert into t1 values (1); insert into t2 values (1); explain select 1 from t1 where a in (select b from t2 where a = 1 limit 1); - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.53 rows=1 width=0) - -> Seq Scan on t1 (cost=0.00..1.53 rows=1 width=0) + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..997.00 rows=48150 width=4) + -> Seq Scan on t1 (cost=0.00..355.00 rows=16050 width=4) Filter: (SubPlan 1) SubPlan 1 - -> Limit (cost=0.00..1.03 rows=1 width=4) - -> Result (cost=0.00..1.03 rows=1 width=4) + -> Limit (cost=0.00..0.03 rows=1 width=4) + -> Result (cost=0.00..3083.50 rows=96300 width=4) One-Time Filter: (t1.a = 1) - -> Materialize (cost=0.00..1.03 rows=1 width=4) - -> Broadcast Motion 3:3 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=4) - -> Seq Scan on t2 (cost=0.00..1.01 rows=1 width=4) + -> Materialize (cost=0.00..2120.50 rows=96300 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1639.00 rows=96300 width=4) + -> Seq Scan on t2 (cost=0.00..355.00 rows=32100 width=4) Optimizer: Postgres query optimizer (11 rows) explain select 1 from t1 where a in (select b from t2 where a = 1 offset 1); - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..2.05 rows=1 width=0) - -> Seq Scan on t1 (cost=0.00..2.05 rows=1 width=0) + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..997.00 rows=48150 width=4) + -> Seq Scan on t1 (cost=0.00..355.00 rows=16050 width=4) Filter: (SubPlan 1) SubPlan 1 - -> Limit (cost=1.03..1.03 rows=1 width=4) - -> Result (cost=0.00..1.03 rows=1 width=4) + -> Limit (cost=0.03..3083.50 rows=96299 width=4) + -> Result (cost=0.00..3083.50 rows=96300 width=4) One-Time Filter: (t1.a = 1) - -> Materialize (cost=0.00..1.03 rows=1 width=4) - -> Broadcast Motion 3:3 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=4) - -> Seq Scan on t2 (cost=0.00..1.01 rows=1 width=4) + -> Materialize (cost=0.00..2120.50 rows=96300 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1639.00 rows=96300 width=4) + -> Seq Scan on t2 (cost=0.00..355.00 rows=32100 width=4) Optimizer: Postgres query optimizer (11 rows) @@ -1279,26 +1281,25 @@ explain select row_number() over (order by seq asc) as id, foo.cnt from (select seq, (select count(*) from t1_mpp_24563 t1 where t1.id = t2.id) cnt from t2_mpp_24563 t2 where value = 7) foo; - QUERY PLAN ------------------------------------------------------------------------------------------------------- - WindowAgg (cost=1.02..2.12 rows=1 width=8) + QUERY PLAN +------------------------------------------------------------------------------------------------------------- + WindowAgg (cost=359.19..232173.17 rows=78 width=20) Order By: t2.seq - -> Gather Motion 3:1 (slice2; segments: 3) (cost=1.02..1.05 rows=1 width=8) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=359.19..360.30 rows=78 width=8) Merge Key: t2.seq - -> Sort (cost=1.02..1.03 rows=1 width=8) + -> Sort (cost=359.19..359.26 rows=26 width=8) Sort Key: t2.seq - -> Seq Scan on t2_mpp_24563 t2 (cost=0.00..1.01 rows=1 width=8) - Filter: value = 7 + -> Seq Scan on t2_mpp_24563 t2 (cost=0.00..358.58 rows=26 width=8) + Filter: (value = 7) SubPlan 1 - -> Aggregate (cost=1.06..1.07 rows=1 width=8) - -> Result (cost=1.01..1.02 rows=1 width=0) - Filter: t1.id = $0 - -> Materialize (cost=1.01..1.02 rows=1 width=0) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.01 rows=1 width=0) - -> Seq Scan on t1_mpp_24563 t1 (cost=0.00..1.01 rows=1 width=0) - Settings: optimizer_segments=3 - Optimizer status: Postgres query optimizer -(17 rows) + -> Aggregate (cost=2975.75..2975.76 rows=1 width=8) + -> Result (cost=0.00..2760.50 rows=86100 width=0) + Filter: (t1.id = t2.id) + -> Materialize (cost=0.00..1899.50 rows=86100 width=4) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1469.00 rows=86100 width=4) + -> Seq Scan on t1_mpp_24563 t1 (cost=0.00..321.00 rows=28700 width=4) + Optimizer: Postgres query optimizer +(16 rows) drop table t1_mpp_24563; drop table t2_mpp_24563; @@ -1532,42 +1533,42 @@ ANALYZE SUBSELECT_TBL; -- Uncorrelated subselects EXPLAIN SELECT '' AS six, f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL) ORDER BY 2; - QUERY PLAN ------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice2; segments: 3) (cost=6.66..6.84 rows=8 width=36) + QUERY PLAN +----------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=2.20..2.31 rows=8 width=36) Merge Key: subselect_tbl.f1 - -> Sort (cost=6.66..6.68 rows=3 width=36) + -> Sort (cost=2.20..2.20 rows=3 width=36) Sort Key: subselect_tbl.f1 - -> Hash Semi Join (cost=3.34..6.54 rows=3 width=36) - Hash Cond: (subselect_tbl.f1 = subselect_tbl_1.f2) - -> Seq Scan on subselect_tbl (cost=0.00..3.08 rows=3 width=4) - -> Hash (cost=3.24..3.24 rows=3 width=4) - -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..3.24 rows=3 width=4) - Hash Key: subselect_tbl_1.f2 - -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..3.08 rows=3 width=4) + -> Hash Right Semi Join (cost=1.06..2.18 rows=3 width=36) + Hash Cond: (subselect_tbl_1.f2 = subselect_tbl.f1) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.08 rows=3 width=4) + Hash Key: subselect_tbl_1.f2 + -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.03..1.03 rows=3 width=4) + -> Seq Scan on subselect_tbl (cost=0.00..1.03 rows=3 width=4) Optimizer: Postgres query optimizer (12 rows) EXPLAIN SELECT '' AS six, f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE f2 IN (SELECT f1 FROM SUBSELECT_TBL)) ORDER BY 2; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=3.28..3.40 rows=8 width=36) + QUERY PLAN +----------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=3.29..3.40 rows=8 width=36) Merge Key: subselect_tbl.f1 - -> Sort (cost=3.28..3.29 rows=3 width=36) + -> Sort (cost=3.29..3.29 rows=3 width=36) Sort Key: subselect_tbl.f1 - -> Hash Semi Join (cost=2.20..3.27 rows=3 width=36) - Hash Cond: (subselect_tbl.f1 = subselect_tbl_1.f2) - -> Seq Scan on subselect_tbl (cost=0.00..1.03 rows=3 width=4) - -> Hash (cost=2.17..2.17 rows=2 width=8) - -> Hash Semi Join (cost=1.06..2.17 rows=2 width=8) - Hash Cond: (subselect_tbl_1.f2 = subselect_tbl_2.f1) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.08 rows=3 width=4) - Hash Key: subselect_tbl_1.f2 - -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..1.03 rows=3 width=4) - -> Hash (cost=1.03..1.03 rows=3 width=4) - -> Seq Scan on subselect_tbl subselect_tbl_2 (cost=0.00..1.03 rows=3 width=4) + -> Hash Right Semi Join (cost=2.12..3.27 rows=3 width=36) + Hash Cond: (subselect_tbl_1.f2 = subselect_tbl.f1) + -> Hash Semi Join (cost=1.06..2.17 rows=2 width=8) + Hash Cond: (subselect_tbl_1.f2 = subselect_tbl_2.f1) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.08 rows=3 width=4) + Hash Key: subselect_tbl_1.f2 + -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.03..1.03 rows=3 width=4) + -> Seq Scan on subselect_tbl subselect_tbl_2 (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.03..1.03 rows=3 width=4) + -> Seq Scan on subselect_tbl (cost=0.00..1.03 rows=3 width=4) Optimizer: Postgres query optimizer (16 rows) @@ -1596,22 +1597,22 @@ EXPLAIN SELECT * FROM tenk1 a, tenk1 b WHERE (a.unique1,b.unique2) IN (SELECT unique1,unique2 FROM tenk1 c); QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=356.67..706.67 rows=10000 width=488) - -> Hash Join (cost=356.67..573.33 rows=3333 width=488) + Gather Motion 3:1 (slice1; segments: 3) (cost=284.67..634.67 rows=10000 width=488) + -> Hash Join (cost=284.67..501.33 rows=3333 width=488) Hash Cond: (c.unique2 = b.unique2) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=185.00..355.83 rows=3333 width=248) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=137.00..307.83 rows=3333 width=248) Hash Key: c.unique2 - -> Hash Join (cost=185.00..289.17 rows=3333 width=248) + -> Hash Join (cost=137.00..241.17 rows=3333 width=248) Hash Cond: (c.unique1 = a.unique1) - -> HashAggregate (cost=80.00..113.33 rows=10000 width=8) + -> HashAggregate (cost=56.00..89.33 rows=10000 width=8) Group Key: c.unique1, c.unique2 - -> Seq Scan on tenk1 c (cost=0.00..63.33 rows=3333 width=8) - -> Hash (cost=63.33..63.33 rows=3333 width=244) - -> Seq Scan on tenk1 a (cost=0.00..63.33 rows=3333 width=244) - -> Hash (cost=130.00..130.00 rows=3333 width=244) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..130.00 rows=3333 width=244) + -> Seq Scan on tenk1 c (cost=0.00..39.33 rows=3333 width=8) + -> Hash (cost=39.33..39.33 rows=3333 width=244) + -> Seq Scan on tenk1 a (cost=0.00..39.33 rows=3333 width=244) + -> Hash (cost=106.00..106.00 rows=3333 width=244) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..106.00 rows=3333 width=244) Hash Key: b.unique2 - -> Seq Scan on tenk1 b (cost=0.00..63.33 rows=3333 width=244) + -> Seq Scan on tenk1 b (cost=0.00..39.33 rows=3333 width=244) Optimizer: Postgres query optimizer (17 rows) @@ -1621,9 +1622,9 @@ EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f2 AS "Second Field" WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE f1 = upper.f1) ORDER BY 2,3; QUERY PLAN ------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.10..2.11 rows=4 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=2.10..2.15 rows=3 width=40) Merge Key: upper.f1, upper.f2 - -> Sort (cost=2.10..2.11 rows=2 width=8) + -> Sort (cost=2.10..2.11 rows=1 width=40) Sort Key: upper.f1, upper.f2 -> Hash Semi Join (cost=1.05..2.09 rows=1 width=40) Hash Cond: (upper.f1 = subselect_tbl.f1) @@ -1638,22 +1639,21 @@ EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f3 AS "Second Field" FROM SUBSELECT_TBL upper WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE CAST(upper.f2 AS float) = f3) ORDER BY 2,3; - QUERY PLAN ------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice2; segments: 3) (cost=2.13..2.14 rows=4 width=12) + QUERY PLAN +---------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=2.20..2.28 rows=6 width=44) Merge Key: upper.f1, upper.f3 - -> Sort (cost=2.13..2.14 rows=2 width=12) + -> Sort (cost=2.20..2.20 rows=2 width=44) Sort Key: upper.f1, upper.f3 - -> Hash Semi Join (cost=1.12..2.19 rows=2 width=44) - Hash Cond: (((upper.f2)::double precision = subselect_tbl.f3) AND (upper.f1 = subselect_tbl.f2)) - -> Seq Scan on subselect_tbl upper (cost=0.00..1.03 rows=3 width=16) - -> Hash (cost=1.08..1.08 rows=3 width=12) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.08 rows=3 width=12) - Hash Key: subselect_tbl.f2 - -> Seq Scan on subselect_tbl (cost=0.00..1.01 rows=1 width=12) - Settings: optimizer=off - Optimizer status: Postgres query optimizer -(13 rows) + -> Hash Right Semi Join (cost=1.07..2.19 rows=2 width=44) + Hash Cond: ((subselect_tbl.f3 = (upper.f2)::double precision) AND (subselect_tbl.f2 = upper.f1)) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.08 rows=3 width=12) + Hash Key: subselect_tbl.f2 + -> Seq Scan on subselect_tbl (cost=0.00..1.03 rows=3 width=12) + -> Hash (cost=1.03..1.03 rows=3 width=16) + -> Seq Scan on subselect_tbl upper (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer +(12 rows) EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f3 AS "Second Field" FROM SUBSELECT_TBL upper @@ -1684,20 +1684,20 @@ EXPLAIN SELECT '' AS five, f1 AS "Correlated Field" FROM SUBSELECT_TBL WHERE (f1, f2) IN (SELECT f2, CAST(f3 AS int4) FROM SUBSELECT_TBL WHERE f3 IS NOT NULL) ORDER BY 2; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice2; segments: 3) (cost=6.67..6.69 rows=8 width=4) + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=2.20..2.30 rows=7 width=36) Merge Key: subselect_tbl.f1 - -> Sort (cost=6.67..6.69 rows=3 width=4) + -> Sort (cost=2.20..2.20 rows=2 width=36) Sort Key: subselect_tbl.f1 - -> Hash Semi Join (cost=1.11..2.18 rows=2 width=36) - Hash Cond: ((subselect_tbl.f1 = subselect_tbl_1.f2) AND (subselect_tbl.f2 = (subselect_tbl_1.f3)::integer)) - -> Seq Scan on subselect_tbl (cost=0.00..1.03 rows=3 width=8) - -> Hash (cost=1.07..1.07 rows=2 width=12) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.07 rows=2 width=12) - Hash Key: subselect_tbl_1.f2 - -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..1.03 rows=2 width=12) - Filter: (f3 IS NOT NULL) + -> Hash Right Semi Join (cost=1.07..2.18 rows=2 width=36) + Hash Cond: ((subselect_tbl_1.f2 = subselect_tbl.f1) AND ((subselect_tbl_1.f3)::integer = subselect_tbl.f2)) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.07 rows=2 width=12) + Hash Key: subselect_tbl_1.f2 + -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..1.03 rows=2 width=12) + Filter: (f3 IS NOT NULL) + -> Hash (cost=1.03..1.03 rows=3 width=8) + -> Seq Scan on subselect_tbl (cost=0.00..1.03 rows=3 width=8) Optimizer: Postgres query optimizer (13 rows) @@ -1781,18 +1781,18 @@ EXPLAIN select count(*) from where unique1 IN (select hundred from tenk1 b)) ss; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------- - Finalize Aggregate (cost=643.26..643.27 rows=1 width=8) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=643.23..643.26 rows=1 width=8) - -> Partial Aggregate (cost=643.23..643.24 rows=1 width=8) - -> Hash Join (cost=415.48..642.98 rows=34 width=0) + Finalize Aggregate (cost=164.51..164.52 rows=1 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=164.45..164.50 rows=3 width=8) + -> Partial Aggregate (cost=164.45..164.46 rows=1 width=8) + -> Hash Join (cost=115.92..164.37 rows=33 width=0) Hash Cond: (a.unique1 = b.hundred) - -> Seq Scan on tenk1 a (cost=0.00..189.00 rows=3334 width=4) - -> Hash (cost=414.23..414.23 rows=34 width=4) - -> HashAggregate (cost=413.90..414.23 rows=34 width=4) + -> Seq Scan on tenk1 a (cost=0.00..39.33 rows=3333 width=4) + -> Hash (cost=114.67..114.67 rows=100 width=4) + -> HashAggregate (cost=114.33..114.67 rows=100 width=4) Group Key: b.hundred - -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..389.00 rows=3334 width=4) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..106.00 rows=3333 width=4) Hash Key: b.hundred - -> Seq Scan on tenk1 b (cost=0.00..189.00 rows=3334 width=4) + -> Seq Scan on tenk1 b (cost=0.00..39.33 rows=3333 width=4) Optimizer: Postgres query optimizer (13 rows) @@ -1801,24 +1801,24 @@ EXPLAIN select count(distinct ss.ten) from where unique1 IN (select hundred from tenk1 b)) ss; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------- - Finalize Aggregate (cost=643.64..643.65 rows=1 width=8) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=643.61..643.64 rows=1 width=8) - -> Partial Aggregate (cost=643.61..643.62 rows=1 width=8) - -> HashAggregate (cost=643.57..643.60 rows=1 width=4) + Finalize Aggregate (cost=164.98..164.99 rows=1 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=164.92..164.97 rows=3 width=8) + -> Partial Aggregate (cost=164.92..164.93 rows=1 width=8) + -> HashAggregate (cost=164.88..164.91 rows=3 width=4) Group Key: a.ten - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=643.48..643.57 rows=1 width=4) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=164.54..164.83 rows=10 width=4) Hash Key: a.ten - -> Streaming HashAggregate (cost=643.48..643.51 rows=1 width=4) + -> Streaming HashAggregate (cost=164.54..164.64 rows=10 width=4) Group Key: a.ten - -> Hash Join (cost=415.48..642.98 rows=34 width=4) + -> Hash Join (cost=115.92..164.37 rows=33 width=4) Hash Cond: (a.unique1 = b.hundred) - -> Seq Scan on tenk1 a (cost=0.00..189.00 rows=3334 width=8) - -> Hash (cost=414.23..414.23 rows=34 width=4) - -> HashAggregate (cost=413.90..414.23 rows=34 width=4) + -> Seq Scan on tenk1 a (cost=0.00..39.33 rows=3333 width=8) + -> Hash (cost=114.67..114.67 rows=100 width=4) + -> HashAggregate (cost=114.33..114.67 rows=100 width=4) Group Key: b.hundred - -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..389.00 rows=3334 width=4) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..106.00 rows=3333 width=4) Hash Key: b.hundred - -> Seq Scan on tenk1 b (cost=0.00..189.00 rows=3334 width=4) + -> Seq Scan on tenk1 b (cost=0.00..39.33 rows=3333 width=4) Optimizer: Postgres query optimizer (19 rows) @@ -1827,18 +1827,18 @@ EXPLAIN select count(*) from where unique1 IN (select distinct hundred from tenk1 b)) ss; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------- - Finalize Aggregate (cost=643.26..643.27 rows=1 width=8) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=643.23..643.26 rows=1 width=8) - -> Partial Aggregate (cost=643.23..643.24 rows=1 width=8) - -> Hash Join (cost=415.48..642.98 rows=34 width=0) + Finalize Aggregate (cost=164.51..164.52 rows=1 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=164.45..164.50 rows=3 width=8) + -> Partial Aggregate (cost=164.45..164.46 rows=1 width=8) + -> Hash Join (cost=115.92..164.37 rows=33 width=0) Hash Cond: (a.unique1 = b.hundred) - -> Seq Scan on tenk1 a (cost=0.00..189.00 rows=3334 width=4) - -> Hash (cost=414.23..414.23 rows=34 width=4) - -> HashAggregate (cost=413.90..414.23 rows=34 width=4) + -> Seq Scan on tenk1 a (cost=0.00..39.33 rows=3333 width=4) + -> Hash (cost=114.67..114.67 rows=100 width=4) + -> HashAggregate (cost=114.33..114.67 rows=100 width=4) Group Key: b.hundred - -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..389.00 rows=3334 width=4) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..106.00 rows=3333 width=4) Hash Key: b.hundred - -> Seq Scan on tenk1 b (cost=0.00..62.33 rows=3333 width=4) + -> Seq Scan on tenk1 b (cost=0.00..39.33 rows=3333 width=4) Optimizer: Postgres query optimizer (13 rows) @@ -1847,24 +1847,24 @@ EXPLAIN select count(distinct ss.ten) from where unique1 IN (select distinct hundred from tenk1 b)) ss; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------- - Finalize Aggregate (cost=643.64..643.65 rows=1 width=8) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=643.61..643.64 rows=1 width=8) - -> Partial Aggregate (cost=643.61..643.62 rows=1 width=8) - -> HashAggregate (cost=643.57..643.60 rows=1 width=4) + Finalize Aggregate (cost=164.98..164.99 rows=1 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=164.92..164.97 rows=3 width=8) + -> Partial Aggregate (cost=164.92..164.93 rows=1 width=8) + -> HashAggregate (cost=164.88..164.91 rows=3 width=4) Group Key: a.ten - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=643.48..643.57 rows=1 width=4) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=164.54..164.83 rows=10 width=4) Hash Key: a.ten - -> Streaming HashAggregate (cost=643.48..643.51 rows=1 width=4) + -> Streaming HashAggregate (cost=164.54..164.64 rows=10 width=4) Group Key: a.ten - -> Hash Join (cost=415.48..642.98 rows=34 width=4) + -> Hash Join (cost=115.92..164.37 rows=33 width=4) Hash Cond: (a.unique1 = b.hundred) - -> Seq Scan on tenk1 a (cost=0.00..189.00 rows=3334 width=8) - -> Hash (cost=414.23..414.23 rows=34 width=4) - -> HashAggregate (cost=413.90..414.23 rows=34 width=4) + -> Seq Scan on tenk1 a (cost=0.00..39.33 rows=3333 width=8) + -> Hash (cost=114.67..114.67 rows=100 width=4) + -> HashAggregate (cost=114.33..114.67 rows=100 width=4) Group Key: b.hundred - -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..389.00 rows=3334 width=4) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..106.00 rows=3333 width=4) Hash Key: b.hundred - -> Seq Scan on tenk1 b (cost=0.00..62.33 rows=3333 width=4) + -> Seq Scan on tenk1 b (cost=0.00..39.33 rows=3333 width=4) Optimizer: Postgres query optimizer (19 rows) @@ -1877,13 +1877,13 @@ EXPLAIN select count(distinct ss.ten) from EXPLAIN SELECT EXISTS(SELECT * FROM tenk1 WHERE tenk1.unique1 = tenk2.unique1) FROM tenk2 LIMIT 1; QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Limit (cost=17.76..17.79 rows=1 width=1) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=17.76..17.85 rows=3 width=1) - -> Limit (cost=17.76..17.81 rows=1 width=1) - -> Seq Scan on tenk2 (cost=0.00..177.56 rows=3333 width=1) + Limit (cost=0.00..0.03 rows=1 width=1) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..0.08 rows=3 width=1) + -> Limit (cost=0.00..0.04 rows=1 width=1) + -> Seq Scan on tenk2 (cost=0.00..146.89 rows=3333 width=1) SubPlan 2 - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..62.33 rows=3333 width=4) - -> Seq Scan on tenk1 (cost=0.00..62.33 rows=3333 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..39.33 rows=3333 width=4) + -> Seq Scan on tenk1 (cost=0.00..39.33 rows=3333 width=4) Optimizer: Postgres query optimizer (8 rows) @@ -1922,22 +1922,20 @@ ANALYZE dedup_test1; ANALYZE dedup_test2; ANALYZE dedup_test3; EXPLAIN SELECT * FROM dedup_test1 INNER JOIN dedup_test2 ON dedup_test1.a= dedup_test2.e WHERE (a) IN (SELECT a FROM dedup_test3); - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.11..3.18 rows=3 width=16) - -> Hash Join (cost=2.11..3.14 rows=1 width=16) - Hash Cond: (dedup_test2.e = dedup_test1.a) - -> Seq Scan on dedup_test2 (cost=0.00..1.01 rows=1 width=8) - -> Hash (cost=2.09..2.09 rows=1 width=12) - -> Hash Join (cost=1.06..2.09 rows=1 width=12) - Hash Cond: (dedup_test1.a = dedup_test3.a) + QUERY PLAN +------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=2.06..3.18 rows=3 width=16) + -> Hash Join (cost=2.06..3.13 rows=1 width=16) + Hash Cond: (dedup_test1.a = dedup_test2.e) + -> Hash Right Semi Join (cost=1.03..2.09 rows=1 width=12) + Hash Cond: (dedup_test3.a = dedup_test1.a) + -> Seq Scan on dedup_test3_1_prt_1 dedup_test3 (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.01..1.01 rows=1 width=8) -> Seq Scan on dedup_test1 (cost=0.00..1.01 rows=1 width=8) - -> Hash (cost=1.05..1.05 rows=1 width=4) - -> HashAggregate (cost=1.04..1.05 rows=1 width=4) - Group Key: dedup_test3.a - -> Seq Scan on dedup_test3_1_prt_1 dedup_test3 (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.01..1.01 rows=1 width=8) + -> Seq Scan on dedup_test2 (cost=0.00..1.01 rows=1 width=8) Optimizer: Postgres query optimizer -(13 rows) +(11 rows) SELECT * FROM dedup_test1 INNER JOIN dedup_test2 ON dedup_test1.a= dedup_test2.e WHERE (a) IN (SELECT a FROM dedup_test3); a | b | e | f @@ -1949,7 +1947,7 @@ SELECT * FROM dedup_test1 INNER JOIN dedup_test2 ON dedup_test1.a= dedup_test2.e EXPLAIN SELECT * FROM dedup_test3, dedup_test1 WHERE c = 7 AND dedup_test3.b IN (SELECT b FROM dedup_test1); QUERY PLAN ------------------------------------------ - Result (cost=0.00..0.01 rows=1 width=0) + Result (cost=0.00..0.00 rows=0 width=8) One-Time Filter: false Optimizer: Postgres query optimizer (3 rows) @@ -1957,7 +1955,7 @@ EXPLAIN SELECT * FROM dedup_test3, dedup_test1 WHERE c = 7 AND dedup_test3.b IN EXPLAIN SELECT * FROM dedup_test3, dedup_test1 WHERE c = 7 AND dedup_test3.b IN (SELECT a FROM dedup_test1); QUERY PLAN ------------------------------------------ - Result (cost=0.00..0.01 rows=1 width=0) + Result (cost=0.00..0.00 rows=0 width=8) One-Time Filter: false Optimizer: Postgres query optimizer (3 rows) @@ -1965,7 +1963,7 @@ EXPLAIN SELECT * FROM dedup_test3, dedup_test1 WHERE c = 7 AND dedup_test3.b IN EXPLAIN SELECT * FROM dedup_test3, dedup_test1 WHERE c = 7 AND EXISTS (SELECT b FROM dedup_test1) AND dedup_test3.b IN (SELECT b FROM dedup_test1); QUERY PLAN ------------------------------------------ - Result (cost=1.53..0.54 rows=1 width=0) + Result (cost=0.27..0.27 rows=0 width=8) One-Time Filter: false Optimizer: Postgres query optimizer (3 rows) @@ -2068,9 +2066,9 @@ select * from dedup_srf() r(a) where r.a in (select t.a/10 from dedup_tab t); select * from dedup_srf() r(a) where r.a in (select t.a/10 from dedup_tab t); a --- - 1 2 3 + 1 (3 rows) explain (costs off) @@ -2155,7 +2153,7 @@ select * from dedup_func() r(a) where r.a in (select t.a/10 from dedup_tab t); -> Seq Scan on dedup_tab t Filter: (5 = (a / 10)) Optimizer: Postgres query optimizer -(15 rows) +(7 rows) select * from dedup_func() r(a) where r.a in (select t.a/10 from dedup_tab t); a @@ -2174,7 +2172,7 @@ select * from dedup_func_stable() r(a) where r.a in (select t.a/10 from dedup_ta -> Seq Scan on dedup_tab t Filter: (5 = (a / 10)) Optimizer: Postgres query optimizer -(15 rows) +(7 rows) select * from dedup_func_stable() r(a) where r.a in (select t.a/10 from dedup_tab t); a @@ -2313,8 +2311,8 @@ select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where t1.i = t2.i limit 1); i --- - 2 1 + 2 (2 rows) explain (costs off) @@ -2381,8 +2379,8 @@ select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where t1.i = t2.i limit all); i --- - 2 1 + 2 (2 rows) explain (costs off) @@ -2419,8 +2417,8 @@ select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where t1.i = t2.i limit NULL); i --- - 2 1 + 2 (2 rows) explain (costs off) @@ -2454,8 +2452,8 @@ select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i); i --- - 2 1 + 2 (2 rows) explain (costs off) @@ -2484,8 +2482,8 @@ select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i offset 0); i --- - 2 1 + 2 (2 rows) explain (costs off) @@ -2528,8 +2526,8 @@ select * from simplify_sub t1 where not exists (select sum(t2.i) from simplify_s select * from simplify_sub t1 where not exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i offset 1); i --- - 2 1 + 2 (2 rows) explain (costs off) @@ -2544,8 +2542,8 @@ select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i offset NULL); i --- - 2 1 + 2 (2 rows) explain (costs off) @@ -2606,8 +2604,8 @@ select * from foo left outer join baz on (select bar.i from bar where bar.i = fo Output: bar.i -> Seq Scan on subselect_gp.bar Output: bar.i + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (29 rows) select * from foo left outer join baz on (select bar.i from bar where bar.i = foo.i) + 1 = baz.j; @@ -2636,48 +2634,42 @@ explain (verbose, costs off) select * from foo where (case when foo.i in (select a.i from baz a) then foo.i else null end) in (select b.i from baz b); - QUERY PLAN ------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Output: foo.i, foo.j - -> HashAggregate + -> Hash Right Semi Join Output: foo.i, foo.j - Group Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Output: foo.i, foo.j, (RowIdExpr) - Hash Key: (RowIdExpr) - -> Hash Join - Output: foo.i, foo.j, (RowIdExpr) - Hash Cond: (b.i = CASE WHEN ((hashed SubPlan 1)) THEN foo.i ELSE NULL::integer END) - -> Seq Scan on subselect_gp.baz b - Output: b.i - -> Hash - Output: foo.i, foo.j, ((hashed SubPlan 1)), (RowIdExpr) - -> Redistribute Motion 3:3 (slice3; segments: 3) - Output: foo.i, foo.j, ((hashed SubPlan 1)), (RowIdExpr) - Hash Key: CASE WHEN ((hashed SubPlan 1)) THEN foo.i ELSE NULL::integer END - -> Seq Scan on subselect_gp.foo - Output: foo.i, foo.j, (hashed SubPlan 1), RowIdExpr - SubPlan 1 - -> Broadcast Motion 3:3 (slice4; segments: 3) - Output: a.i - -> Seq Scan on subselect_gp.baz a - Output: a.i + Hash Cond: (b.i = CASE WHEN ((hashed SubPlan 1)) THEN foo.i ELSE NULL::integer END) + -> Seq Scan on subselect_gp.baz b + Output: b.i + -> Hash + Output: foo.i, foo.j, ((hashed SubPlan 1)) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Output: foo.i, foo.j, ((hashed SubPlan 1)) + Hash Key: CASE WHEN ((hashed SubPlan 1)) THEN foo.i ELSE NULL::integer END + -> Seq Scan on subselect_gp.foo + Output: foo.i, foo.j, (hashed SubPlan 1) + SubPlan 1 + -> Broadcast Motion 3:3 (slice3; segments: 3) + Output: a.i + -> Seq Scan on subselect_gp.baz a + Output: a.i + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off -(27 rows) +(21 rows) select * from foo where (case when foo.i in (select a.i from baz a) then foo.i else null end) in (select b.i from baz b); i | j ----+---- - 6 | 6 7 | 7 - 10 | 10 - 5 | 5 8 | 8 + 5 | 5 + 6 | 6 9 | 9 + 10 | 10 (6 rows) -- When creating plan with subquery and CTE, it sets the useless flow for the plan. @@ -2730,8 +2722,9 @@ where dt < '2010-01-01'::date; Output: extra_flow_dist.c, extra_flow_dist.b -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(25 rows) +(26 rows) with run_dt as ( select @@ -2744,8 +2737,8 @@ select * from run_dt, extra_flow_dist1 where dt < '2010-01-01'::date; dt | a | b ------------+----+---- - 10-01-1949 | 20 | 20 10-01-1949 | 22 | 22 + 10-01-1949 | 20 | 20 10-01-1949 | 21 | 21 (3 rows) @@ -2786,8 +2779,9 @@ where dt < '2010-01-01'::date; Output: extra_flow_dist1.a, extra_flow_dist1.b -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(24 rows) +(25 rows) with run_dt as ( select @@ -2844,8 +2838,9 @@ where dt < '2010-01-01'::date; Output: extra_flow_dist.c, extra_flow_dist.b -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(28 rows) +(29 rows) with run_dt as ( select @@ -2858,9 +2853,9 @@ select * from run_dt, extra_flow_dist1 where dt < '2010-01-01'::date; dt | a | b ------------+----+---- + 10-01-1949 | 22 | 22 10-01-1949 | 20 | 20 10-01-1949 | 21 | 21 - 10-01-1949 | 22 | 22 (3 rows) -- case 4 subplan with outer segment general locus without param in subplan (CTE and subquery) @@ -2901,8 +2896,9 @@ where dt < extra_flow_dist1.a; Output: extra_flow_dist1.a, extra_flow_dist1.b -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(28 rows) +(29 rows) -- case 5 for subplan with outer entry locus without param in subplan (CTE and subquery) explain (verbose, costs off) with run_dt as ( @@ -2944,8 +2940,9 @@ where dt < extra_flow_dist1.a; Output: extra_flow_dist1.a, extra_flow_dist1.b -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(30 rows) +(31 rows) -- case 6 without CTE, nested subquery should not add extral flow explain (verbose, costs off) select * from ( @@ -3013,8 +3010,9 @@ where dt < '2010-01-01'::date; Output: extra_flow_dist_1.c, extra_flow_dist_1.b -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(47 rows) +(48 rows) -- Check DISTINCT ON clause and ORDER BY clause in SubLink, See https://github.com/greenplum-db/gpdb/issues/12656. -- For EXISTS SubLink, we don’t need to care about the data deduplication problem, we can delete DISTINCT ON clause and @@ -3049,8 +3047,8 @@ select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issu Sort Key: issue_12656_1.i -> Seq Scan on subselect_gp.issue_12656 issue_12656_1 Output: issue_12656_1.i, issue_12656_1.j + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (20 rows) select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issue_12656); @@ -3082,8 +3080,8 @@ select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issu Sort Key: issue_12656_1.i, issue_12656_1.j -> Seq Scan on subselect_gp.issue_12656 issue_12656_1 Output: issue_12656_1.i, issue_12656_1.j + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (20 rows) select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issue_12656 order by i, j asc); @@ -3114,8 +3112,8 @@ select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issu Sort Key: issue_12656_1.i, issue_12656_1.j DESC -> Seq Scan on subselect_gp.issue_12656 issue_12656_1 Output: issue_12656_1.i, issue_12656_1.j + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (20 rows) select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issue_12656 order by i, j desc); @@ -3133,7 +3131,7 @@ explain select * from issue_12656 a where (i, j) in -> Seq Scan on issue_12656 a (cost=0.00..321.00 rows=14350 width=8) Filter: (SubPlan 1) SubPlan 1 - -> Unique (cost=9818.00..10033.25 rows=1000 width=8) + -> Unique (cost=9818.00..10033.25 rows=1 width=8) -> Sort (cost=9818.00..10033.25 rows=86100 width=8) Sort Key: b.j -> Result (cost=0.00..2760.50 rows=86100 width=8) @@ -3245,8 +3243,8 @@ with cte(table_oid, size) as select pc.relname, ts.size from pg_class pc, cte ts where pc.oid = ts.table_oid; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: pc.relname, (sum((pg_relation_size((pg_class.oid)::regclass, 'main'::text)))) -> Nested Loop @@ -3267,8 +3265,9 @@ where pc.oid = ts.table_oid; Hash Key: pg_class.oid -> Seq Scan on pg_catalog.pg_class Output: pg_class.oid, pg_relation_size((pg_class.oid)::regclass, 'main'::text) + Settings: optimizer = 'off', gp_enable_multiphase_agg = 'on', enable_hashjoin = 'off', enable_nestloop = 'on', enable_indexscan = 'off', enable_bitmapscan = 'off' Optimizer: Postgres query optimizer -(21 rows) +(22 rows) set gp_enable_multiphase_agg = off; explain (verbose on, costs off) @@ -3287,8 +3286,8 @@ with cte(table_oid, size) as select pc.relname, ts.size from pg_class pc, cte ts where pc.oid = ts.table_oid; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: pc.relname, (sum((pg_relation_size((pg_class.oid)::regclass, 'main'::text)))) -> Nested Loop @@ -3309,8 +3308,9 @@ where pc.oid = ts.table_oid; Hash Key: pg_class.oid -> Seq Scan on pg_catalog.pg_class Output: pg_class.oid, pg_relation_size((pg_class.oid)::regclass, 'main'::text) + Settings: optimizer = 'off', gp_enable_multiphase_agg = 'off', enable_hashjoin = 'off', enable_nestloop = 'on', enable_indexscan = 'off', enable_bitmapscan = 'off' Optimizer: Postgres query optimizer -(21 rows) +(22 rows) reset gp_enable_multiphase_agg; reset enable_hashjoin; @@ -3323,12 +3323,12 @@ set optimizer to off; explain select t.* from sublink_outer_table t join (select y ,10*avg(x) s from sublink_inner_table group by y) RR on RR.y = t.b and t.a > rr.s; QUERY PLAN -------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=436.00..1310.77 rows=28700 width=8) - -> Hash Join (cost=436.00..928.11 rows=9567 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=432.67..1307.44 rows=28700 width=8) + -> Hash Join (cost=432.67..924.77 rows=9567 width=8) Hash Cond: (t.b = sublink_inner_table.y) Join Filter: ((t.a)::numeric > (('10'::numeric * avg(sublink_inner_table.x)))) -> Seq Scan on sublink_outer_table t (cost=0.00..321.00 rows=28700 width=8) - -> Hash (cost=431.83..431.83 rows=333 width=40) + -> Hash (cost=428.50..428.50 rows=333 width=40) -> HashAggregate (cost=423.50..428.50 rows=333 width=40) Group Key: sublink_inner_table.y -> Seq Scan on sublink_inner_table (cost=0.00..293.67 rows=25967 width=12) @@ -3338,13 +3338,13 @@ explain select t.* from sublink_outer_table t join (select y ,10*avg(x) s from s explain select * from sublink_outer_table T where a > (select 10*avg(x) from sublink_inner_table R where T.b=R.y); QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=436.00..1310.77 rows=28700 width=8) - -> Hash Join (cost=436.00..928.11 rows=9567 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=433.78..1308.55 rows=28700 width=8) + -> Hash Join (cost=433.78..925.89 rows=9567 width=8) Hash Cond: (t.b = "Expr_SUBQUERY".csq_c0) Join Filter: ((t.a)::numeric > "Expr_SUBQUERY".csq_c1) -> Seq Scan on sublink_outer_table t (cost=0.00..321.00 rows=28700 width=8) - -> Hash (cost=431.83..431.83 rows=333 width=40) - -> Subquery Scan on "Expr_SUBQUERY" (cost=423.50..431.83 rows=333 width=40) + -> Hash (cost=429.61..429.61 rows=333 width=40) + -> Subquery Scan on "Expr_SUBQUERY" (cost=423.50..429.61 rows=333 width=40) -> HashAggregate (cost=423.50..428.50 rows=333 width=40) Group Key: r.y -> Seq Scan on sublink_inner_table r (cost=0.00..293.67 rows=25967 width=12) @@ -3355,12 +3355,12 @@ set enable_hashagg to off; explain select t.* from sublink_outer_table t join (select y ,10*avg(x) s from sublink_inner_table group by y) RR on RR.y = t.b and t.a > rr.s; QUERY PLAN -------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2404.84..3279.62 rows=28700 width=8) - -> Hash Join (cost=2404.84..2896.95 rows=9567 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=2401.51..3276.28 rows=28700 width=8) + -> Hash Join (cost=2401.51..2893.62 rows=9567 width=8) Hash Cond: (t.b = sublink_inner_table.y) Join Filter: ((t.a)::numeric > (('10'::numeric * avg(sublink_inner_table.x)))) -> Seq Scan on sublink_outer_table t (cost=0.00..321.00 rows=28700 width=8) - -> Hash (cost=2400.67..2400.67 rows=333 width=40) + -> Hash (cost=2397.34..2397.34 rows=333 width=40) -> GroupAggregate (cost=2197.59..2397.34 rows=333 width=40) Group Key: sublink_inner_table.y -> Sort (cost=2197.59..2262.51 rows=25967 width=12) @@ -3372,13 +3372,13 @@ explain select t.* from sublink_outer_table t join (select y ,10*avg(x) s from s explain select * from sublink_outer_table T where a > (select 10*avg(x) from sublink_inner_table R where T.b=R.y); QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2404.84..3279.62 rows=28700 width=8) - -> Hash Join (cost=2404.84..2896.95 rows=9567 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=2402.62..3277.39 rows=28700 width=8) + -> Hash Join (cost=2402.62..2894.73 rows=9567 width=8) Hash Cond: (t.b = "Expr_SUBQUERY".csq_c0) Join Filter: ((t.a)::numeric > "Expr_SUBQUERY".csq_c1) -> Seq Scan on sublink_outer_table t (cost=0.00..321.00 rows=28700 width=8) - -> Hash (cost=2400.67..2400.67 rows=333 width=40) - -> Subquery Scan on "Expr_SUBQUERY" (cost=2197.59..2400.67 rows=333 width=40) + -> Hash (cost=2398.45..2398.45 rows=333 width=40) + -> Subquery Scan on "Expr_SUBQUERY" (cost=2197.59..2398.45 rows=333 width=40) -> GroupAggregate (cost=2197.59..2397.34 rows=333 width=40) Group Key: r.y -> Sort (cost=2197.59..2262.51 rows=25967 width=12) @@ -3562,10 +3562,10 @@ SELECT c FROM t0; -- Test push predicate into subquery -- more details could be found at https://github.com/greenplum-db/gpdb/issues/8429 CREATE TABLE foo_predicate_pushdown (a int, b int); -NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table. +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TABLE bar_predicate_pushdown (c int, d int); -NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c' as the Greenplum Database data distribution key for this table. +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. explain (costs off) select * from ( select distinct (select bar.c from bar_predicate_pushdown bar where c = foo.b) as ss from foo_predicate_pushdown foo @@ -3629,7 +3629,7 @@ explain (costs off) select * from table_left where exists (select 1 from table_r -> Hash -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on table_left - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (12 rows) select * from table_left where exists (select 1 from table_right where l1 = r1); @@ -3652,7 +3652,7 @@ explain (costs off) select * from table_left where l1 in (select r1 from table_r -> Hash -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on table_left - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (12 rows) select * from table_left where exists (select 1 from table_right where l1 = r1); @@ -3667,15 +3667,13 @@ explain (costs off) select * from table_left where exists (select 1 from table_r QUERY PLAN ----------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) - -> Hash Join + -> Hash Right Semi Join Hash Cond: (table_right.r1 = table_left.l1) - -> HashAggregate - Group Key: table_right.r1 - -> Seq Scan on table_right + -> Seq Scan on table_right -> Hash -> Seq Scan on table_left - Optimizer: Postgres-based planner -(9 rows) + Optimizer: Postgres query optimizer +(7 rows) select * from table_left where exists (select 1 from table_right where l1 = r1); l1 | l2 @@ -3687,15 +3685,13 @@ explain (costs off) select * from table_left where l1 in (select r1 from table_r QUERY PLAN ----------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) - -> Hash Join + -> Hash Right Semi Join Hash Cond: (table_right.r1 = table_left.l1) - -> HashAggregate - Group Key: table_right.r1 - -> Seq Scan on table_right + -> Seq Scan on table_right -> Hash -> Seq Scan on table_left - Optimizer: Postgres-based planner -(9 rows) + Optimizer: Postgres query optimizer +(7 rows) select * from table_left where exists (select 1 from table_right where l1 = r1); l1 | l2 @@ -3796,7 +3792,7 @@ explain (costs off) select foo.a from foo where foo.a <= LEAST(foo.b, (SELECT 1) -> Result -> Seq Scan on foo Filter: (a <= LEAST(b, $0, NULL::integer)) - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (6 rows) select foo.a from foo where foo.a <= LEAST(foo.b, (SELECT 1), NULL); @@ -3813,7 +3809,7 @@ explain (costs off) select foo.a from foo where foo.a <= GREATEST(foo.b, (SELECT -> Result -> Seq Scan on foo Filter: (a <= GREATEST(b, $0, NULL::integer)) - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (6 rows) select foo.a from foo where foo.a <= GREATEST(foo.b, (SELECT 1), NULL); @@ -3833,15 +3829,15 @@ explain (costs off) select least((select 5), greatest(b, NULL, (select 1)), a) f InitPlan 2 (returns $1) (slice3) -> Result -> Seq Scan on foo - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (7 rows) select least((select 5), greatest(b, NULL, (select 1)), a) from foo; least ------- - 1 2 3 + 1 (3 rows) drop table foo; @@ -3858,7 +3854,7 @@ explain (costs off) select (select a from bar)[1] from bar; -> Gather Motion 3:1 (slice3; segments: 3) -> Seq Scan on bar bar_1 -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (6 rows) select (select a from bar)[1] from bar; @@ -3877,7 +3873,7 @@ explain (costs off) select (select a from bar)[(select 1)] from bar; -> Gather Motion 3:1 (slice4; segments: 3) -> Seq Scan on bar bar_1 -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (8 rows) select (select a from bar)[(select 1)] from bar; @@ -3894,7 +3890,7 @@ explain (costs off) select (select b from bar)[1][1:3] from bar; -> Gather Motion 3:1 (slice3; segments: 3) -> Seq Scan on bar bar_1 -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (6 rows) select (select b from bar)[1][1:3] from bar; @@ -3913,7 +3909,7 @@ explain (costs off) select (select b from bar)[(select 1)][1:3] from bar; -> Gather Motion 3:1 (slice4; segments: 3) -> Seq Scan on bar bar_1 -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (8 rows) select (select b from bar)[(select 1)][1:3] from bar; @@ -3943,7 +3939,7 @@ explain (costs off) select t1.a from outer_foo t1, LATERAL(SELECT distinct t2. -> Materialize -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on inner_bar t2 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (13 rows) explain (costs off) select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q; @@ -3960,7 +3956,7 @@ explain (costs off) select t1.a from outer_foo t1, LATERAL(SELECT distinct t2. -> Materialize -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on inner_bar t2 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (12 rows) select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q order by 1; @@ -4002,7 +3998,7 @@ select * from t where a > (select count(1) from cte where x > t.a + random()); -> Materialize -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on inner_bar t2 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (22 rows) with cte(x) as (select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q order by 1) diff --git a/contrib/pax_storage/src/test/regress/expected/subselect_gp_optimizer.out b/contrib/pax_storage/src/test/regress/expected/subselect_gp_optimizer.out index d70d2e1a133..c3a5bdb226a 100644 --- a/contrib/pax_storage/src/test/regress/expected/subselect_gp_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/subselect_gp_optimizer.out @@ -70,6 +70,7 @@ select csq_t1.x, (select bar.x from csq_t1 bar where bar.x = csq_t1.x) as sum fr -- Another case correlations in the targetlist: PlaceHolderVar -- drop table if exists phv_t; +NOTICE: table "phv_t" does not exist, skipping create table phv_t(a int, b int) distributed by (a); insert into phv_t values(1,1),(2,2); explain(costs off) select *, (select ss.y as z from phv_t as t3 limit 1) from phv_t t1 left join @@ -121,6 +122,8 @@ partition by range (y) ( start (0) end (4) every (1)) insert into csq_t1 select * from csq_t1_base; insert into csq_t2 select * from csq_t2_base; explain select * from csq_t1 where csq_t1.x >ALL (select csq_t2.x from csq_t2 where csq_t2.y=csq_t1.y) order by 1; +NOTICE: One or more columns in the following table(s) do not have statistics: csq_t1, csq_t2 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Result (cost=0.00..1293.00 rows=1 width=8) @@ -144,6 +147,8 @@ explain select * from csq_t1 where csq_t1.x >ALL (select csq_t2.x from csq_t2 wh (18 rows) select * from csq_t1 where csq_t1.x >ALL (select csq_t2.x from csq_t2 where csq_t2.y=csq_t1.y) order by 1; -- expected (4,2) +NOTICE: One or more columns in the following table(s) do not have statistics: csq_t1, csq_t2 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. x | y ---+--- 4 | 2 @@ -169,7 +174,7 @@ explain select * from mrs_t1 where exists (select x from mrs_t1 where x < -1); Join Filter: true -> Seq Scan on mrs_t1 mrs_t1_1 (cost=0.00..431.00 rows=7 width=4) -> Materialize (cost=0.00..431.00 rows=1 width=1) - -> Broadcast Motion 1:3 (slice2) (cost=0.00..431.00 rows=3 width=1) + -> Broadcast Motion 1:3 (slice2) (cost=0.00..431.00 rows=1 width=1) -> Limit (cost=0.00..431.00 rows=1 width=1) -> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=1) -> Seq Scan on mrs_t1 (cost=0.00..431.00 rows=1 width=1) @@ -190,7 +195,7 @@ explain select * from mrs_t1 where exists (select x from mrs_t1 where x = 1); Join Filter: true -> Seq Scan on mrs_t1 mrs_t1_1 (cost=0.00..431.00 rows=7 width=4) -> Materialize (cost=0.00..431.00 rows=1 width=1) - -> Broadcast Motion 1:3 (slice2) (cost=0.00..431.00 rows=3 width=1) + -> Broadcast Motion 1:3 (slice2) (cost=0.00..431.00 rows=1 width=1) -> Limit (cost=0.00..431.00 rows=1 width=1) -> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=1) -> Seq Scan on mrs_t1 (cost=0.00..431.00 rows=1 width=1) @@ -281,6 +286,7 @@ drop table if exists mrs_u2; -- Set right motion type to subquery -- drop table if exists gs_tab; +NOTICE: table "gs_tab" does not exist, skipping create table gs_tab(a int, b int, c int) distributed by (a); insert into gs_tab values (1,1,1),(2,2,2); explain(costs off) @@ -728,9 +734,9 @@ explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.t); t | n | i | v -----+---+---+----- + abc | 1 | 2 | xyz xyz | 2 | 3 | def def | 3 | 1 | abc - abc | 1 | 2 | xyz (3 rows) -- @@ -759,9 +765,9 @@ explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.v); t | n | i | v -----+---+---+----- + abc | 1 | 2 | xyz xyz | 2 | 3 | def def | 3 | 1 | abc - abc | 1 | 2 | xyz (3 rows) -- @@ -791,9 +797,9 @@ explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.n=t1.n); t | n | i | v -----+---+---+----- + abc | 1 | 2 | xyz xyz | 2 | 3 | def def | 3 | 1 | abc - abc | 1 | 2 | xyz (3 rows) -- @@ -877,9 +883,9 @@ explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.t LIMIT 1); t | n | i | v -----+---+---+----- - xyz | 2 | 3 | def def | 3 | 1 | abc abc | 1 | 2 | xyz + xyz | 2 | 3 | def (3 rows) -- subquery contains a HAVING clause @@ -906,9 +912,9 @@ explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.t HAVING count(*) < 10); t | n | i | v -----+---+---+----- + abc | 1 | 2 | xyz xyz | 2 | 3 | def def | 3 | 1 | abc - abc | 1 | 2 | xyz (3 rows) -- subquery contains quals of form 'function(outervar, innervar1) = innvervar2' @@ -986,9 +992,7 @@ select * from csq_pullup t0 where not exists (select 1 from csq_pullup t1 where -- wrong results bug MPP-16477 -- drop table if exists subselect_t1; -NOTICE: table "subselect_t1" does not exist, skipping drop table if exists subselect_t2; -NOTICE: table "subselect_t2" does not exist, skipping create table subselect_t1(x int) distributed by (x); insert into subselect_t1 values(1),(2); create table subselect_t2(y int) distributed by (y); @@ -1353,6 +1357,8 @@ CASE ELSE 'Q2'::text END AS cc, 1 AS nn FROM t_mpp_20470 b; explain SELECT cc, sum(nn) over() FROM v1_mpp_20470; +NOTICE: One or more columns in the following table(s) do not have statistics: t_mpp_20470 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN ------------------------------------------------------------------------------------------------------------------- WindowAgg (cost=0.00..862.00 rows=2 width=16) @@ -1452,6 +1458,8 @@ create table bar(a int, b int) distributed by (a); with CT as (select a from foo except select a from bar) select * from foo where exists (select 1 from CT where CT.a = foo.a); +NOTICE: One or more columns in the following table(s) do not have statistics: foo +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b ---+--- (0 rows) @@ -1480,6 +1488,8 @@ HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sur INSERT INTO foo_s VALUES (9,9); INSERT INTO foo_s VALUES (2,9); SELECT bar_s.c from bar_s, foo_s WHERE foo_s.a=2 AND foo_s.b = (SELECT max(b) FROM foo_s WHERE bar_s.c = 9); +NOTICE: One or more columns in the following table(s) do not have statistics: foo_s +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. c --- 9 @@ -1494,6 +1504,8 @@ ANALYZE baz_s; -- because it avoids picking SubPlans from an equivalence class, when it has -- other choices. SELECT bar_s.c FROM bar_s, foo_s WHERE foo_s.b = (SELECT max(i) FROM baz_s WHERE bar_s.c = 9) AND foo_s.b = bar_s.d::int4; +NOTICE: One or more columns in the following table(s) do not have statistics: foo_s +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. c --- 9 @@ -1503,12 +1515,14 @@ SELECT bar_s.c FROM bar_s, foo_s WHERE foo_s.b = (SELECT max(i) FROM baz_s WHERE -- Same as above, but with another subquery, so it must use a SubPlan. There -- are two references to the same SubPlan in the plan, on different slices. explain SELECT bar_s.c FROM bar_s, foo_s WHERE foo_s.b = (SELECT max(i) FROM baz_s WHERE bar_s.c = 9) AND foo_s.b = (select bar_s.d::int4); +NOTICE: One or more columns in the following table(s) do not have statistics: foo_s +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN ----------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1356273072.98 rows=1000 width=4) - -> Hash Join (cost=0.00..1356273072.97 rows=334 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1356273054.53 rows=1000 width=4) + -> Hash Join (cost=0.00..1356273054.51 rows=334 width=4) Hash Cond: ((((SubPlan 1)) = foo_s.b) AND (((SubPlan 2)) = foo_s.b)) - -> Seq Scan on bar_s (cost=0.00..1324053.98 rows=334 width=16) + -> Seq Scan on bar_s (cost=0.00..1324053.96 rows=334 width=16) SubPlan 1 -> Aggregate (cost=0.00..431.00 rows=1 width=4) -> Result (cost=0.00..431.00 rows=1 width=4) @@ -1527,6 +1541,8 @@ explain SELECT bar_s.c FROM bar_s, foo_s WHERE foo_s.b = (SELECT max(i) FROM baz (19 rows) SELECT bar_s.c FROM bar_s, foo_s WHERE foo_s.b = (SELECT max(i) FROM baz_s WHERE bar_s.c = 9) AND foo_s.b = (select bar_s.d::int4); +NOTICE: One or more columns in the following table(s) do not have statistics: foo_s +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. c --- 9 @@ -1629,22 +1645,22 @@ EXPLAIN SELECT * FROM tenk1 a, tenk1 b WHERE (a.unique1,b.unique2) IN (SELECT unique1,unique2 FROM tenk1 c); QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=287.67..637.67 rows=10000 width=488) - -> Hash Join (cost=287.67..504.33 rows=3333 width=488) + Gather Motion 3:1 (slice1; segments: 3) (cost=284.67..634.67 rows=10000 width=488) + -> Hash Join (cost=284.67..501.33 rows=3333 width=488) Hash Cond: (c.unique2 = b.unique2) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=139.00..309.83 rows=3333 width=248) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=137.00..307.83 rows=3333 width=248) Hash Key: c.unique2 - -> Hash Join (cost=139.00..243.17 rows=3333 width=248) + -> Hash Join (cost=137.00..241.17 rows=3333 width=248) Hash Cond: (c.unique1 = a.unique1) - -> HashAggregate (cost=57.00..90.33 rows=10000 width=8) + -> HashAggregate (cost=56.00..89.33 rows=10000 width=8) Group Key: c.unique1, c.unique2 - -> Seq Scan on tenk1 c (cost=0.00..40.33 rows=3333 width=8) - -> Hash (cost=40.33..40.33 rows=3333 width=244) - -> Seq Scan on tenk1 a (cost=0.00..40.33 rows=3333 width=244) - -> Hash (cost=107.00..107.00 rows=3333 width=244) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..107.00 rows=3333 width=244) + -> Seq Scan on tenk1 c (cost=0.00..39.33 rows=3333 width=8) + -> Hash (cost=39.33..39.33 rows=3333 width=244) + -> Seq Scan on tenk1 a (cost=0.00..39.33 rows=3333 width=244) + -> Hash (cost=106.00..106.00 rows=3333 width=244) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..106.00 rows=3333 width=244) Hash Key: b.unique2 - -> Seq Scan on tenk1 b (cost=0.00..40.33 rows=3333 width=244) + -> Seq Scan on tenk1 b (cost=0.00..39.33 rows=3333 width=244) Optimizer: Postgres query optimizer (17 rows) @@ -1695,12 +1711,12 @@ EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f3 AS "Second Field" WHERE f2 = CAST(f3 AS integer)) ORDER BY 2,3; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------- - Result (cost=0.00..1324033.90 rows=8 width=20) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324033.90 rows=8 width=12) + Result (cost=0.00..1324033.85 rows=8 width=20) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324033.85 rows=8 width=12) Merge Key: upper.f1, upper.f3 - -> Sort (cost=0.00..1324033.90 rows=3 width=12) + -> Sort (cost=0.00..1324033.85 rows=3 width=12) Sort Key: upper.f1, upper.f3 - -> Seq Scan on subselect_tbl upper (cost=0.00..1324033.90 rows=3 width=12) + -> Seq Scan on subselect_tbl upper (cost=0.00..1324033.85 rows=3 width=12) Filter: (SubPlan 1) SubPlan 1 -> Result (cost=0.00..431.00 rows=4 width=4) @@ -1717,18 +1733,18 @@ EXPLAIN SELECT '' AS five, f1 AS "Correlated Field" WHERE f3 IS NOT NULL) ORDER BY 2; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.19..2.29 rows=7 width=36) + Gather Motion 3:1 (slice1; segments: 3) (cost=2.20..2.30 rows=7 width=36) Merge Key: subselect_tbl.f1 - -> Sort (cost=2.19..2.20 rows=2 width=36) + -> Sort (cost=2.20..2.20 rows=2 width=36) Sort Key: subselect_tbl.f1 - -> Hash Semi Join (cost=1.11..2.18 rows=2 width=36) - Hash Cond: ((subselect_tbl.f1 = subselect_tbl_1.f2) AND (subselect_tbl.f2 = (subselect_tbl_1.f3)::integer)) - -> Seq Scan on subselect_tbl (cost=0.00..1.03 rows=3 width=8) - -> Hash (cost=1.07..1.07 rows=2 width=12) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.07 rows=2 width=12) - Hash Key: subselect_tbl_1.f2 - -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..1.03 rows=2 width=12) - Filter: (f3 IS NOT NULL) + -> Hash Right Semi Join (cost=1.07..2.18 rows=2 width=36) + Hash Cond: ((subselect_tbl_1.f2 = subselect_tbl.f1) AND ((subselect_tbl_1.f3)::integer = subselect_tbl.f2)) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.07 rows=2 width=12) + Hash Key: subselect_tbl_1.f2 + -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..1.03 rows=2 width=12) + Filter: (f3 IS NOT NULL) + -> Hash (cost=1.03..1.03 rows=3 width=8) + -> Seq Scan on subselect_tbl (cost=0.00..1.03 rows=3 width=8) Optimizer: Postgres query optimizer (13 rows) @@ -1753,9 +1769,9 @@ EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f2 AS "Second Field" WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE f1 = upper.f1 GROUP BY f2 LIMIT 3); QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Result (cost=0.00..1324038.68 rows=8 width=16) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324038.68 rows=8 width=8) - -> Seq Scan on subselect_tbl upper (cost=0.00..1324038.68 rows=3 width=8) + Result (cost=0.00..1324038.63 rows=8 width=16) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324038.63 rows=8 width=8) + -> Seq Scan on subselect_tbl upper (cost=0.00..1324038.63 rows=3 width=8) Filter: (SubPlan 1) SubPlan 1 -> Limit (cost=0.00..431.01 rows=1 width=4) @@ -1790,9 +1806,9 @@ EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f2 AS "Second Field" WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE f1 = upper.f1 ORDER BY f2 LIMIT 3); QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Result (cost=0.00..1324039.05 rows=8 width=16) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324039.05 rows=8 width=8) - -> Seq Scan on subselect_tbl upper (cost=0.00..1324039.05 rows=3 width=8) + Result (cost=0.00..1324039.00 rows=8 width=16) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324039.00 rows=8 width=8) + -> Seq Scan on subselect_tbl upper (cost=0.00..1324039.00 rows=3 width=8) Filter: ((NOT (f1 IS NULL)) AND (SubPlan 1)) SubPlan 1 -> Limit (cost=0.00..431.01 rows=1 width=4) @@ -1815,18 +1831,18 @@ EXPLAIN select count(*) from where unique1 IN (select hundred from tenk1 b)) ss; QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Finalize Aggregate (cost=0.00..826.06 rows=1 width=8) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..826.06 rows=1 width=8) - -> Partial Aggregate (cost=0.00..826.06 rows=1 width=8) - -> Nested Loop (cost=0.00..826.06 rows=34 width=1) + Finalize Aggregate (cost=0.00..826.04 rows=1 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..826.04 rows=1 width=8) + -> Partial Aggregate (cost=0.00..826.04 rows=1 width=8) + -> Nested Loop (cost=0.00..826.04 rows=34 width=1) Join Filter: true - -> HashAggregate (cost=0.00..431.95 rows=34 width=4) + -> HashAggregate (cost=0.00..431.92 rows=34 width=4) Group Key: b.hundred - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.94 rows=100 width=4) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.91 rows=100 width=4) Hash Key: b.hundred - -> Streaming HashAggregate (cost=0.00..431.94 rows=100 width=4) + -> Streaming HashAggregate (cost=0.00..431.91 rows=100 width=4) Group Key: b.hundred - -> Seq Scan on tenk1 b (cost=0.00..431.51 rows=3334 width=4) + -> Seq Scan on tenk1 b (cost=0.00..431.48 rows=3334 width=4) -> Bitmap Heap Scan on tenk1 a (cost=0.00..394.11 rows=1 width=1) Recheck Cond: (unique1 = b.hundred) -> Bitmap Index Scan on tenk1_unique1 (cost=0.00..0.00 rows=0 width=0) @@ -1839,20 +1855,20 @@ EXPLAIN select count(distinct ss.ten) from where unique1 IN (select hundred from tenk1 b)) ss; QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Finalize Aggregate (cost=0.00..826.07 rows=1 width=8) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..826.07 rows=1 width=8) - -> Partial Aggregate (cost=0.00..826.07 rows=1 width=8) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..826.07 rows=34 width=4) + Finalize Aggregate (cost=0.00..826.04 rows=1 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..826.04 rows=1 width=8) + -> Partial Aggregate (cost=0.00..826.04 rows=1 width=8) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..826.04 rows=34 width=4) Hash Key: a.ten - -> Nested Loop (cost=0.00..826.07 rows=34 width=4) + -> Nested Loop (cost=0.00..826.04 rows=34 width=4) Join Filter: true - -> HashAggregate (cost=0.00..431.95 rows=34 width=4) + -> HashAggregate (cost=0.00..431.92 rows=34 width=4) Group Key: b.hundred - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..431.94 rows=100 width=4) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..431.91 rows=100 width=4) Hash Key: b.hundred - -> Streaming HashAggregate (cost=0.00..431.94 rows=100 width=4) + -> Streaming HashAggregate (cost=0.00..431.91 rows=100 width=4) Group Key: b.hundred - -> Seq Scan on tenk1 b (cost=0.00..431.51 rows=3334 width=4) + -> Seq Scan on tenk1 b (cost=0.00..431.48 rows=3334 width=4) -> Bitmap Heap Scan on tenk1 a (cost=0.00..394.12 rows=1 width=4) Recheck Cond: (unique1 = b.hundred) -> Bitmap Index Scan on tenk1_unique1 (cost=0.00..0.00 rows=0 width=0) @@ -1865,18 +1881,18 @@ EXPLAIN select count(*) from where unique1 IN (select distinct hundred from tenk1 b)) ss; QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Finalize Aggregate (cost=0.00..826.06 rows=1 width=8) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..826.06 rows=1 width=8) - -> Partial Aggregate (cost=0.00..826.06 rows=1 width=8) - -> Nested Loop (cost=0.00..826.06 rows=34 width=1) + Finalize Aggregate (cost=0.00..826.04 rows=1 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..826.04 rows=1 width=8) + -> Partial Aggregate (cost=0.00..826.04 rows=1 width=8) + -> Nested Loop (cost=0.00..826.04 rows=34 width=1) Join Filter: true - -> HashAggregate (cost=0.00..431.95 rows=34 width=4) + -> HashAggregate (cost=0.00..431.92 rows=34 width=4) Group Key: b.hundred - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.94 rows=100 width=4) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.91 rows=100 width=4) Hash Key: b.hundred - -> Streaming HashAggregate (cost=0.00..431.94 rows=100 width=4) + -> Streaming HashAggregate (cost=0.00..431.91 rows=100 width=4) Group Key: b.hundred - -> Seq Scan on tenk1 b (cost=0.00..431.51 rows=3334 width=4) + -> Seq Scan on tenk1 b (cost=0.00..431.48 rows=3334 width=4) -> Bitmap Heap Scan on tenk1 a (cost=0.00..394.11 rows=1 width=1) Recheck Cond: (unique1 = b.hundred) -> Bitmap Index Scan on tenk1_unique1 (cost=0.00..0.00 rows=0 width=0) @@ -1889,20 +1905,20 @@ EXPLAIN select count(distinct ss.ten) from where unique1 IN (select distinct hundred from tenk1 b)) ss; QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Finalize Aggregate (cost=0.00..826.07 rows=1 width=8) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..826.07 rows=1 width=8) - -> Partial Aggregate (cost=0.00..826.07 rows=1 width=8) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..826.07 rows=34 width=4) + Finalize Aggregate (cost=0.00..826.04 rows=1 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..826.04 rows=1 width=8) + -> Partial Aggregate (cost=0.00..826.04 rows=1 width=8) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..826.04 rows=34 width=4) Hash Key: a.ten - -> Nested Loop (cost=0.00..826.07 rows=34 width=4) + -> Nested Loop (cost=0.00..826.04 rows=34 width=4) Join Filter: true - -> HashAggregate (cost=0.00..431.95 rows=34 width=4) + -> HashAggregate (cost=0.00..431.92 rows=34 width=4) Group Key: b.hundred - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..431.94 rows=100 width=4) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..431.91 rows=100 width=4) Hash Key: b.hundred - -> Streaming HashAggregate (cost=0.00..431.94 rows=100 width=4) + -> Streaming HashAggregate (cost=0.00..431.91 rows=100 width=4) Group Key: b.hundred - -> Seq Scan on tenk1 b (cost=0.00..431.51 rows=3334 width=4) + -> Seq Scan on tenk1 b (cost=0.00..431.48 rows=3334 width=4) -> Bitmap Heap Scan on tenk1 a (cost=0.00..394.12 rows=1 width=4) Recheck Cond: (unique1 = b.hundred) -> Bitmap Index Scan on tenk1_unique1 (cost=0.00..0.00 rows=0 width=0) @@ -1919,18 +1935,18 @@ EXPLAIN select count(distinct ss.ten) from EXPLAIN SELECT EXISTS(SELECT * FROM tenk1 WHERE tenk1.unique1 = tenk2.unique1) FROM tenk2 LIMIT 1; QUERY PLAN --------------------------------------------------------------------------------------------------------------- - Limit (cost=0.00..865.49 rows=1 width=1) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..865.49 rows=1 width=1) - -> Limit (cost=0.00..865.49 rows=1 width=1) - -> Hash Left Join (cost=0.00..865.46 rows=3334 width=8) + Limit (cost=0.00..865.43 rows=1 width=1) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..865.43 rows=1 width=1) + -> Limit (cost=0.00..865.43 rows=1 width=1) + -> Hash Left Join (cost=0.00..865.40 rows=3334 width=8) Hash Cond: (tenk2.unique1 = tenk1.unique1) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.58 rows=3334 width=4) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.55 rows=3334 width=4) Hash Key: tenk2.unique1 - -> Seq Scan on tenk2 (cost=0.00..431.51 rows=3334 width=4) - -> Hash (cost=431.96..431.96 rows=3334 width=12) - -> HashAggregate (cost=0.00..431.96 rows=3334 width=12) + -> Seq Scan on tenk2 (cost=0.00..431.48 rows=3334 width=4) + -> Hash (cost=431.93..431.93 rows=3334 width=12) + -> HashAggregate (cost=0.00..431.93 rows=3334 width=12) Group Key: tenk1.unique1 - -> Seq Scan on tenk1 (cost=0.00..431.51 rows=3334 width=4) + -> Seq Scan on tenk1 (cost=0.00..431.48 rows=3334 width=4) Optimizer: GPORCA (13 rows) @@ -2006,8 +2022,8 @@ SELECT * FROM dedup_test1 INNER JOIN dedup_test2 ON dedup_test1.a= dedup_test2.e EXPLAIN SELECT * FROM dedup_test3, dedup_test1 WHERE c = 7 AND dedup_test3.b IN (SELECT b FROM dedup_test1); QUERY PLAN ---------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..882688.08 rows=1 width=20) - -> Nested Loop (cost=0.00..882688.08 rows=1 width=20) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..882688.07 rows=1 width=20) + -> Nested Loop (cost=0.00..882688.07 rows=1 width=20) Join Filter: true -> Result (cost=0.00..0.00 rows=0 width=12) One-Time Filter: false @@ -2018,8 +2034,8 @@ EXPLAIN SELECT * FROM dedup_test3, dedup_test1 WHERE c = 7 AND dedup_test3.b IN EXPLAIN SELECT * FROM dedup_test3, dedup_test1 WHERE c = 7 AND dedup_test3.b IN (SELECT a FROM dedup_test1); QUERY PLAN ---------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..882688.08 rows=1 width=20) - -> Nested Loop (cost=0.00..882688.08 rows=1 width=20) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..882688.07 rows=1 width=20) + -> Nested Loop (cost=0.00..882688.07 rows=1 width=20) Join Filter: true -> Result (cost=0.00..0.00 rows=0 width=12) One-Time Filter: false @@ -2030,8 +2046,8 @@ EXPLAIN SELECT * FROM dedup_test3, dedup_test1 WHERE c = 7 AND dedup_test3.b IN EXPLAIN SELECT * FROM dedup_test3, dedup_test1 WHERE c = 7 AND EXISTS (SELECT b FROM dedup_test1) AND dedup_test3.b IN (SELECT b FROM dedup_test1); QUERY PLAN ---------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..882688.08 rows=1 width=20) - -> Nested Loop (cost=0.00..882688.08 rows=1 width=20) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..882688.07 rows=1 width=20) + -> Nested Loop (cost=0.00..882688.07 rows=1 width=20) Join Filter: true -> Result (cost=0.00..0.00 rows=0 width=12) One-Time Filter: false @@ -2053,22 +2069,19 @@ analyze dedup_reptab; -- row otherwise. explain (costs off, locus) select * from dedup_reptab r where r.a in (select t.a/10 from dedup_tab t); - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> Hash Join - Hash Cond: (((t.a / 10)) = r.a) - -> GroupAggregate - Group Key: ((t.a / 10)) - -> Sort - Sort Key: ((t.a / 10)) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: ((t.a / 10)) - -> Seq Scan on dedup_tab t + -> Hash Right Semi Join + Hash Cond: (r.a = ((t.a / 10))) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: ((t.a / 10)) + -> Seq Scan on dedup_tab t -> Hash - -> Seq Scan on dedup_reptab r + -> Result + -> Seq Scan on dedup_reptab r Optimizer: GPORCA -(13 rows) +(10 rows) select * from dedup_reptab r where r.a in (select t.a/10 from dedup_tab t); a @@ -2120,9 +2133,9 @@ select * from dedup_srf() r(a) where r.a in (select t.a/10 from dedup_tab t); select * from dedup_srf() r(a) where r.a in (select t.a/10 from dedup_tab t); a --- - 1 2 3 + 1 (3 rows) explain (costs off) @@ -2145,9 +2158,9 @@ select * from dedup_srf_stable() r(a) where r.a in (select t.a/10 from dedup_tab select * from dedup_srf_stable() r(a) where r.a in (select t.a/10 from dedup_tab t); a --- - 1 2 3 + 1 (3 rows) explain (costs off) @@ -2170,9 +2183,9 @@ select * from dedup_srf_volatile() r(a) where r.a in (select t.a/10 from dedup_t select * from dedup_srf_volatile() r(a) where r.a in (select t.a/10 from dedup_tab t); a --- - 1 2 3 + 1 (3 rows) -- Also test it with non-SRFs. In principle, since the function returns exactly @@ -2190,22 +2203,19 @@ create function dedup_func_volatile() RETURNS int AS $$ $$ LANGUAGE SQL VOLATILE; explain (costs off) select * from dedup_func() r(a) where r.a in (select t.a/10 from dedup_tab t); - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> Hash Join - Hash Cond: (((a / 10)) = (5)) - -> GroupAggregate - Group Key: ((a / 10)) - -> Sort - Sort Key: ((a / 10)) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: ((a / 10)) - -> Seq Scan on dedup_tab t + -> Hash Right Semi Join + Hash Cond: ((5) = ((a / 10))) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: ((a / 10)) + -> Seq Scan on dedup_tab t -> Hash -> Result + -> Result Optimizer: GPORCA -(13 rows) +(10 rows) select * from dedup_func() r(a) where r.a in (select t.a/10 from dedup_tab t); a @@ -2215,22 +2225,19 @@ select * from dedup_func() r(a) where r.a in (select t.a/10 from dedup_tab t); explain (costs off) select * from dedup_func_stable() r(a) where r.a in (select t.a/10 from dedup_tab t); - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> Hash Join - Hash Cond: (((a / 10)) = (5)) - -> GroupAggregate - Group Key: ((a / 10)) - -> Sort - Sort Key: ((a / 10)) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: ((a / 10)) - -> Seq Scan on dedup_tab t + -> Hash Right Semi Join + Hash Cond: ((5) = ((a / 10))) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: ((a / 10)) + -> Seq Scan on dedup_tab t -> Hash -> Result + -> Result Optimizer: GPORCA -(13 rows) +(10 rows) select * from dedup_func_stable() r(a) where r.a in (select t.a/10 from dedup_tab t); a @@ -2240,22 +2247,19 @@ select * from dedup_func_stable() r(a) where r.a in (select t.a/10 from dedup_ta explain (costs off) select * from dedup_func_volatile() r(a) where r.a in (select t.a/10 from dedup_tab t); - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> Hash Join - Hash Cond: (((a / 10)) = (5)) - -> GroupAggregate - Group Key: ((a / 10)) - -> Sort - Sort Key: ((a / 10)) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: ((a / 10)) - -> Seq Scan on dedup_tab t + -> Hash Right Semi Join + Hash Cond: ((5) = ((a / 10))) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: ((a / 10)) + -> Seq Scan on dedup_tab t -> Hash -> Result + -> Result Optimizer: GPORCA -(13 rows) +(10 rows) select * from dedup_func_volatile() r(a) where r.a in (select t.a/10 from dedup_tab t); a @@ -2285,6 +2289,7 @@ select * from init_main_plan_parallel where exists (select * from pg_class); -- hashExpr are in its targetlist, test the motion node above it also updated -- its targetlist, otherwise, a wrong answer or a crash happens. DROP TABLE IF EXISTS TEST_IN; +NOTICE: table "test_in" does not exist, skipping CREATE TABLE TEST_IN( C01 FLOAT, C02 NUMERIC(10,0) @@ -2528,8 +2533,8 @@ select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i); i --- - 1 2 + 1 (2 rows) explain (costs off) @@ -2558,8 +2563,8 @@ select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i offset 0); i --- - 2 1 + 2 (2 rows) explain (costs off) @@ -2622,8 +2627,8 @@ select * from simplify_sub t1 where not exists (select sum(t2.i) from simplify_s select * from simplify_sub t1 where not exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i offset 1); i --- - 2 1 + 2 (2 rows) explain (costs off) @@ -2727,15 +2732,15 @@ select * from foo left outer join baz on (select bar.i from bar where bar.i = fo select * from foo left outer join baz on (select bar.i from bar where bar.i = foo.i) + 1 = baz.j; i | j | i | j ----+----+---+--- - 10 | 10 | | - 9 | 9 | | - 6 | 6 | | - 5 | 5 | | 8 | 8 | | 7 | 7 | | 4 | 4 | | 3 | 3 | | 2 | 2 | | + 10 | 10 | | + 9 | 9 | | + 6 | 6 | | + 5 | 5 | | 1 | 1 | | (10 rows) @@ -2784,12 +2789,12 @@ select * from foo where (select b.i from baz b); i | j ----+---- - 6 | 6 7 | 7 - 10 | 10 - 5 | 5 8 | 8 + 5 | 5 + 6 | 6 9 | 9 + 10 | 10 (6 rows) -- When creating plan with subquery and CTE, it sets the useless flow for the plan. @@ -2859,9 +2864,9 @@ select * from run_dt, extra_flow_dist1 where dt < '2010-01-01'::date; dt | a | b ------------+----+---- - 10-01-1949 | 22 | 22 10-01-1949 | 20 | 20 10-01-1949 | 21 | 21 + 10-01-1949 | 22 | 22 (3 rows) create table extra_flow_rand(a int) distributed replicated; @@ -2918,8 +2923,8 @@ where dt < '2010-01-01'::date; dt | a | b ------------+----+---- 10-01-1949 | 22 | 22 - 10-01-1949 | 21 | 21 10-01-1949 | 20 | 20 + 10-01-1949 | 21 | 21 (3 rows) -- case 3 for subplan with outer entry locus (CTE and subquery) @@ -3289,7 +3294,10 @@ select * from issue_12656 a where (i, j) in --- Test param info is preserved when bringing a path to OuterQuery locus --- drop table if exists param_t; +NOTICE: table "param_t" does not exist, skipping create table param_t (i int, j int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into param_t select i, i from generate_series(1,10)i; analyze param_t; explain (costs off) @@ -3747,18 +3755,18 @@ analyze table_left; analyze table_right; -- two types of semi join tests explain (costs off) select * from table_left where exists (select 1 from table_right where l1 = r1); - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join + -> Hash Right Semi Join Hash Cond: (table_left.l1 = table_right.r1) - -> Seq Scan on table_left - Filter: (NOT (l1 IS NULL)) + -> Result + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: table_right.r1 + -> Seq Scan on table_right -> Hash - -> Result - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: table_right.r1 - -> Seq Scan on table_right + -> Seq Scan on table_left + Filter: (NOT (l1 IS NULL)) Optimizer: GPORCA (11 rows) @@ -3769,16 +3777,16 @@ select * from table_left where exists (select 1 from table_right where l1 = r1); (1 row) explain (costs off) select * from table_left where l1 in (select r1 from table_right); - QUERY PLAN ------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join + -> Hash Right Semi Join Hash Cond: (table_left.l1 = table_right.r1) - -> Seq Scan on table_left + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: table_right.r1 + -> Seq Scan on table_right -> Hash - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: table_right.r1 - -> Seq Scan on table_right + -> Seq Scan on table_left Optimizer: GPORCA (9 rows) @@ -3841,19 +3849,19 @@ insert into table_right select i, i from generate_series(1, 299) i; insert into table_right select 1, 1 from generate_series(1, 100) i; analyze table_right; explain (costs off) select * from table_left where exists (select 1 from table_right where l1 = r1); - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join + -> Hash Right Semi Join Hash Cond: (table_left.l1 = table_right.r1) - -> Seq Scan on table_left - Filter: (NOT (l1 IS NULL)) + -> Result + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: table_right.r1 + -> Dynamic Seq Scan on table_right + Number of partitions to scan: 3 (out of 3) -> Hash - -> Result - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: table_right.r1 - -> Dynamic Seq Scan on table_right - Number of partitions to scan: 3 (out of 3) + -> Seq Scan on table_left + Filter: (NOT (l1 IS NULL)) Optimizer: GPORCA (12 rows) @@ -3864,17 +3872,17 @@ select * from table_left where exists (select 1 from table_right where l1 = r1); (1 row) explain (costs off) select * from table_left where l1 in (select r1 from table_right); - QUERY PLAN ----------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join + -> Hash Right Semi Join Hash Cond: (table_left.l1 = table_right.r1) - -> Seq Scan on table_left + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: table_right.r1 + -> Dynamic Seq Scan on table_right + Number of partitions to scan: 3 (out of 3) -> Hash - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: table_right.r1 - -> Dynamic Seq Scan on table_right - Number of partitions to scan: 3 (out of 3) + -> Seq Scan on table_left Optimizer: GPORCA (10 rows) @@ -3961,9 +3969,9 @@ explain (costs off) select least((select 5), greatest(b, NULL, (select 1)), a) f select least((select 5), greatest(b, NULL, (select 1)), a) from foo; least ------- - 1 2 3 + 1 (3 rows) drop table foo; diff --git a/contrib/pax_storage/src/test/regress/expected/subselect_optimizer.out b/contrib/pax_storage/src/test/regress/expected/subselect_optimizer.out index 9dae344e9d9..2f1a641a2e3 100644 --- a/contrib/pax_storage/src/test/regress/expected/subselect_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/subselect_optimizer.out @@ -84,6 +84,8 @@ CREATE TABLE SUBSELECT_TBL ( f2 integer, f3 float ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO SUBSELECT_TBL VALUES (1, 2, 3); INSERT INTO SUBSELECT_TBL VALUES (2, 3, 4); INSERT INTO SUBSELECT_TBL VALUES (3, 4, 5); @@ -95,13 +97,13 @@ INSERT INTO SUBSELECT_TBL VALUES (8, 9, NULL); SELECT * FROM SUBSELECT_TBL; f1 | f2 | f3 ----+----+---- - 1 | 1 | 1 1 | 2 | 3 - 2 | 2 | 2 + 1 | 1 | 1 + 6 | 7 | 8 2 | 3 | 4 - 3 | 3 | 3 3 | 4 | 5 - 6 | 7 | 8 + 2 | 2 | 2 + 3 | 3 | 3 8 | 9 | (8 rows) @@ -118,12 +120,12 @@ SELECT f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL); Uncorrelated Field -------------------- - 1 - 1 - 2 2 3 + 2 3 + 1 + 1 (6 rows) SELECT f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL @@ -134,8 +136,8 @@ SELECT f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL 1 1 2 - 2 3 + 2 3 (6 rows) @@ -156,12 +158,12 @@ SELECT f1 AS "Correlated Field", f2 AS "Second Field" WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE f1 = upper.f1); Correlated Field | Second Field ------------------+-------------- - 1 | 1 - 1 | 2 - 2 | 2 2 | 3 - 3 | 3 3 | 4 + 2 | 2 + 3 | 3 + 1 | 2 + 1 | 1 (6 rows) SELECT f1 AS "Correlated Field", f3 AS "Second Field" @@ -170,11 +172,11 @@ SELECT f1 AS "Correlated Field", f3 AS "Second Field" (SELECT f2 FROM SUBSELECT_TBL WHERE CAST(upper.f2 AS float) = f3); Correlated Field | Second Field ------------------+-------------- - 1 | 1 - 2 | 2 2 | 4 - 3 | 3 3 | 5 + 2 | 2 + 3 | 3 + 1 | 1 (5 rows) SELECT f1 AS "Correlated Field", f3 AS "Second Field" @@ -183,10 +185,10 @@ SELECT f1 AS "Correlated Field", f3 AS "Second Field" WHERE f2 = CAST(f3 AS integer)); Correlated Field | Second Field ------------------+-------------- + 6 | 8 1 | 3 2 | 4 3 | 5 - 6 | 8 (4 rows) SELECT f1 AS "Correlated Field" @@ -195,11 +197,11 @@ SELECT f1 AS "Correlated Field" WHERE f3 IS NOT NULL); Correlated Field ------------------ - 1 - 2 2 3 + 2 3 + 1 (5 rows) -- Subselects without aliases @@ -230,9 +232,9 @@ SELECT * FROM view_unnamed_ss; ----+------------------+------------------- 0 | 123 | 456 0 | 123 | 4567890123456789 + 0 | 4567890123456789 | -4567890123456789 0 | 4567890123456789 | 123 0 | 4567890123456789 | 4567890123456789 - 0 | 4567890123456789 | -4567890123456789 (5 rows) \sv view_unnamed_ss @@ -274,11 +276,11 @@ SELECT ss.f1 AS "Correlated Field", ss.f3 AS "Second Field" WHERE f1 != ss.f1 AND f1 < 2147483647); Correlated Field | Second Field ------------------+-------------- - 2 | 2 + 6 | 8 2 | 4 - 3 | 3 3 | 5 - 6 | 8 + 2 | 2 + 3 | 3 8 | (6 rows) @@ -309,17 +311,21 @@ explain (verbose, costs off) select '42' union all select '43'; Output: '42'::text -> Result Output: '43'::text -(5 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(7 rows) explain (verbose, costs off) select '42' union all select 43; - QUERY PLAN --------------------- + QUERY PLAN +---------------------------- Append -> Result Output: 42 -> Result Output: 43 -(5 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(7 rows) -- check materialization of an initplan reference (bug #14524) explain (verbose, costs off) @@ -448,7 +454,11 @@ select count(distinct ss.ten) from -- Luca Pireddu and Michael Fuhr. -- CREATE TEMP TABLE foo (id integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TEMP TABLE bar (id1 integer, id2 integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO foo VALUES (1); INSERT INTO bar VALUES (1, 1); INSERT INTO bar VALUES (2, 2); @@ -508,6 +518,8 @@ CREATE TABLE orderstest ( po_ref integer, ordercanceled boolean ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'approver_ref' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO orderstest VALUES (1, 1, false); INSERT INTO orderstest VALUES (66, 5, false); INSERT INTO orderstest VALUES (66, 6, false); @@ -559,6 +571,8 @@ SELECT * FROM orders_view; approver_ref | po_ref | ordercanceled | Approved | Status | Status_OK --------------+--------+---------------+----------+----------+----------- 1 | 1 | f | --- | --- | --- + 1 | 1 | f | --- | --- | --- + 1 | 1 | f | --- | --- | --- 66 | 5 | f | Approved | PO | PO 66 | 6 | f | Approved | PO | PO 66 | 7 | f | Approved | PO | PO @@ -566,9 +580,7 @@ SELECT * FROM orders_view; 66 | 8 | f | Approved | PO | PO 66 | 1 | f | Approved | Approved | Approved 77 | 1 | f | Approved | Approved | Approved - 1 | 1 | f | --- | --- | --- 66 | 1 | f | Approved | Approved | Approved - 1 | 1 | f | --- | --- | --- (11 rows) DROP TABLE orderstest cascade; @@ -581,12 +593,16 @@ create temp table parts ( partnum text, cost float8 ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'partnum' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp table shipped ( ttype char(2), ordnum int4, partnum text, value float8 ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'ttype' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp view shipped_view as select * from shipped where ttype = 'wt'; create rule shipped_view_insert as on insert to shipped_view do instead @@ -618,9 +634,9 @@ select f1, ss1 as relabel from from int4_tbl a) ss; f1 | relabel -------------+------------ - 0 | 2147607103 123456 | 2147607103 -123456 | 2147483647 + 0 | 2147607103 2147483647 | 2147483647 -2147483647 | 0 (5 rows) @@ -656,15 +672,19 @@ select * from ( -- pointless.) -- create temp table numeric_table (num_col numeric); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'num_col' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into numeric_table values (1), (1.000000000000000000001), (2), (3); create temp table float_table (float_col float8); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'float_col' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into float_table values (1), (2), (3); select * from float_table where float_col in (select num_col from numeric_table); float_col ----------- - 1 2 + 1 3 (3 rows) @@ -672,8 +692,8 @@ select * from numeric_table where num_col in (select float_col from float_table); num_col ------------------------- - 1 2 + 1 1.000000000000000000001 3 (4 rows) @@ -698,14 +718,16 @@ select from tc; min_tb_id ----------- - 1 3 + 1 (2 rows) -- -- Test case for 8.3 "failed to locate grouping columns" bug -- create temp table t1 (f1 numeric(14,0), f2 varchar(30)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. select * from (select distinct f1, f2, (select f2 from t1 x where x.f1 = up.f1) as fs from t1 up) ss @@ -718,6 +740,8 @@ group by f1,f2,fs; -- Test case for bug #5514 (mishandling of whole-row Vars in subselects) -- create temp table table_a(id integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into table_a values (42); create temp view view_a as select * from table_a; select view_a from view_a; @@ -766,10 +790,10 @@ with q as (select max(f1) from int4_tbl group by f1 order by f1) q --------------- (-2147483647) - (-123456) (0) - (123456) (2147483647) + (-123456) + (123456) (5 rows) -- @@ -809,9 +833,9 @@ from -- create temp table upsert(key int4 primary key, val text); insert into upsert values(1, 'val') on conflict (key) do update set val = 'not seen'; -ERROR: not implemented yet on pax relations: TupleInsertSpeculative +ERROR: not implemented yet on pax relations: TupleInsertSpeculative (seg1 172.18.0.2:7003 pid=13481) insert into upsert values(1, 'val') on conflict (key) do update set val = 'seen with subselect ' || (select f1 from int4_tbl where f1 != 0 order by f1 limit 1)::text; -ERROR: not implemented yet on pax relations: TupleInsertSpeculative +ERROR: not implemented yet on pax relations: TupleInsertSpeculative (seg1 172.18.0.2:7003 pid=13481) select * from upsert; key | val -----+----- @@ -821,16 +845,20 @@ with aa as (select 'int4_tbl' u from int4_tbl limit 1) insert into upsert values (1, 'x'), (999, 'y') on conflict (key) do update set val = (select u from aa) returning *; -ERROR: not implemented yet on pax relations: TupleInsertSpeculative +ERROR: not implemented yet on pax relations: TupleInsertSpeculative (seg1 slice1 172.18.0.2:7003 pid=13481) -- -- Test case for cross-type partial matching in hashed subplan (bug #7597) -- create temp table outer_7597 (f1 int4, f2 int4); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into outer_7597 values (0, 0); insert into outer_7597 values (1, 0); insert into outer_7597 values (0, null); insert into outer_7597 values (1, null); create temp table inner_7597(c1 int8, c2 int8); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into inner_7597 values(0, null); select * from outer_7597 where (f1, f2) not in (select * from inner_7597); f1 | f2 @@ -845,11 +873,15 @@ select * from outer_7597 where (f1, f2) not in (select * from inner_7597); -- (otherwise it would error in texteq()) -- create temp table outer_text (f1 text, f2 text); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into outer_text values ('a', 'a'); insert into outer_text values ('b', 'a'); insert into outer_text values ('a', null); insert into outer_text values ('b', null); create temp table inner_text (c1 text, c2 text); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into inner_text values ('a', null); insert into inner_text values ('123', '456'); select * from outer_text where (f1, f2) not in (select * from inner_text); @@ -875,7 +907,9 @@ select 'foo'::text in (select 'bar'::name union all select 'bar'::name); Output: 'bar'::name -> Result Output: 'bar'::name -(8 rows) + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer +(10 rows) select 'foo'::text in (select 'bar'::name union all select 'bar'::name); ?column? @@ -898,7 +932,9 @@ select row(row(row(1))) = any (select row(row(1))); Output: (ROW(ROW(1))) -> Result Output: ROW(ROW(1)) -(8 rows) + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer +(9 rows) select row(row(row(1))) = any (select row(row(1))); ?column? @@ -932,8 +968,8 @@ language sql as 'select $1::text = $2'; create operator = (procedure=bogus_int8_text_eq, leftarg=int8, rightarg=text); explain (costs off) select * from int8_tbl where q1 in (select c1 from inner_text); - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> GroupAggregate Group Key: int8_tbl.q1, int8_tbl.q2, int8_tbl.ctid, int8_tbl.gp_segment_id @@ -946,7 +982,7 @@ select * from int8_tbl where q1 in (select c1 from inner_text); -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on inner_text -> Seq Scan on int8_tbl - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) select * from int8_tbl where q1 in (select c1 from inner_text); @@ -962,8 +998,8 @@ create or replace function bogus_int8_text_eq(int8, text) returns boolean language sql as 'select $1::text = $2 and $1::text = $2'; explain (costs off) select * from int8_tbl where q1 in (select c1 from inner_text); - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> GroupAggregate Group Key: int8_tbl.q1, int8_tbl.q2, int8_tbl.ctid, int8_tbl.gp_segment_id @@ -976,7 +1012,7 @@ select * from int8_tbl where q1 in (select c1 from inner_text); -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on inner_text -> Seq Scan on int8_tbl - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) select * from int8_tbl where q1 in (select c1 from inner_text); @@ -992,8 +1028,8 @@ create or replace function bogus_int8_text_eq(int8, text) returns boolean language sql as 'select $2 = $1::text'; explain (costs off) select * from int8_tbl where q1 in (select c1 from inner_text); - QUERY PLAN ------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> GroupAggregate Group Key: int8_tbl.q1, int8_tbl.q2, int8_tbl.ctid, int8_tbl.gp_segment_id @@ -1006,7 +1042,7 @@ select * from int8_tbl where q1 in (select c1 from inner_text); -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on inner_text -> Seq Scan on int8_tbl - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) select * from int8_tbl where q1 in (select c1 from inner_text); @@ -1023,8 +1059,8 @@ rollback; -- to get rid of the bogus operator explain (costs off) select count(*) from tenk1 t where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0); - QUERY PLAN ------------------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------------ Finalize Aggregate -> Gather Motion 3:1 (slice1; segments: 3) -> Partial Aggregate @@ -1086,8 +1122,12 @@ where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0) -- It's possible for the same EXISTS to get resolved both ways create temp table exists_tbl (c1 int, c2 int, c3 int) partition by list (c1); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp table exists_tbl_null partition of exists_tbl for values in (null); +NOTICE: table has parent, setting distribution columns to match parent table create temp table exists_tbl_def partition of exists_tbl default; +NOTICE: table has parent, setting distribution columns to match parent table insert into exists_tbl select x, x/2, x+1 from generate_series(0,10) x; analyze exists_tbl; explain (costs off) @@ -1159,15 +1199,15 @@ explain (verbose, costs off) InitPlan 2 (returns $1) -> Result Output: 'regression'::name + Settings: optimizer = 'on' Optimizer: Postgres query optimizer - Settings: optimizer=on -(9 rows) +(10 rows) explain (verbose, costs off) select x, x from (select (select random()) as x from (values(1),(2)) v(y)) ss; - QUERY PLAN ------------------------------------ + QUERY PLAN +------------------------------------- Subquery Scan on ss Output: ss.x, ss.x -> Values Scan on "*VALUES*" @@ -1175,8 +1215,9 @@ explain (verbose, costs off) InitPlan 1 (returns $0) -> Result Output: random() + Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(8 rows) +(9 rows) explain (verbose, costs off) select x, x from @@ -1193,9 +1234,9 @@ explain (verbose, costs off) -> Result Output: 'regression'::name One-Time Filter: ("*VALUES*".column1 = "*VALUES*".column1) + Settings: optimizer = 'on' Optimizer: Postgres query optimizer - Settings: optimizer=on -(9 rows) +(12 rows) explain (verbose, costs off) select x, x from @@ -1210,8 +1251,9 @@ explain (verbose, costs off) -> Result Output: random() One-Time Filter: ("*VALUES*".column1 = "*VALUES*".column1) + Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(9 rows) +(10 rows) -- -- Test rescan of a hashed subplan (the use of random() is to prevent the @@ -1295,8 +1337,8 @@ select sum(o.four), sum(ss.a) from select * from x ) ss where o.ten = 1; - QUERY PLAN ---------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------- Finalize Aggregate -> Gather Motion 3:1 (slice1; segments: 3) -> Partial Aggregate @@ -1333,7 +1375,11 @@ where o.ten = 1; -- Check we don't misoptimize a NOT IN where the subquery returns no rows. -- create temp table notinouter (a int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp table notininner (b int not null); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'b' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into notinouter values (null), (1); select * from notinouter where a not in (select b from notininner); a @@ -1472,26 +1518,26 @@ select * from int4_tbl where explain (verbose, costs off) select * from int4_tbl o where (f1, f1) in (select f1, generate_series(1,50) / 10 g from int4_tbl i group by f1); - QUERY PLAN -------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: o.f1 - -> Hash Semi Join + -> Hash Right Semi Join Output: o.f1 - Hash Cond: (o.f1 = "ANY_subquery".f1) - -> Seq Scan on public.int4_tbl o - Output: o.f1 - -> Hash + Hash Cond: ("ANY_subquery".f1 = o.f1) + -> Subquery Scan on "ANY_subquery" Output: "ANY_subquery".f1, "ANY_subquery".g - -> Subquery Scan on "ANY_subquery" - Output: "ANY_subquery".f1, "ANY_subquery".g - Filter: ("ANY_subquery".f1 = "ANY_subquery".g) - -> Result - Output: i.f1, ((generate_series(1, 50)) / 10) - -> ProjectSet - Output: generate_series(1, 50), i.f1 - -> Seq Scan on public.int4_tbl i - Output: i.f1 + Filter: ("ANY_subquery".f1 = "ANY_subquery".g) + -> Result + Output: i.f1, ((generate_series(1, 50)) / 10) + -> ProjectSet + Output: generate_series(1, 50), i.f1 + -> Seq Scan on public.int4_tbl i + Output: i.f1 + -> Hash + Output: o.f1 + -> Seq Scan on public.int4_tbl o + Output: o.f1 Settings: optimizer = 'on' Optimizer: Postgres query optimizer (20 rows) @@ -1514,10 +1560,10 @@ select (select q from from int4_tbl; q ----------- + (1,2,3) (4,5,6.0) (4,5,6.0) (1,2,3) - (1,2,3) (4,5,6.0) (5 rows) @@ -1558,7 +1604,9 @@ where b and f1 >= 0; Output: random() -> Result Output: true, 2 -(21 rows) + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer +(22 rows) select * from int4_tbl i4, @@ -1572,10 +1620,10 @@ where b and f1 >= 0; f1 | b | id ------------+---+---- 0 | t | 2 - 123456 | t | 1 - 123456 | t | 2 2147483647 | t | 1 2147483647 | t | 2 + 123456 | t | 1 + 123456 | t | 2 (5 rows) -- @@ -1630,8 +1678,8 @@ select * from Output: 9, unnest('{1,2,3,11,12,13}'::integer[]) -> Result Output: true - Optimizer: Pivotal Optimizer (GPORCA) - Settings: optimizer=on + Settings: optimizer = 'on' + Optimizer: GPORCA (9 rows) select * from @@ -1668,13 +1716,18 @@ select * from Output: 9, unnest('{1,2,3,11,12,13}'::integer[]) -> Result Output: true - Optimizer: Pivotal Optimizer (GPORCA) - Settings: optimizer=on + Settings: optimizer = 'on' + Optimizer: GPORCA (9 rows) select * from (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss where tattle(x, 8); +NOTICE: x = 9, y = 8 +NOTICE: x = 9, y = 8 +NOTICE: x = 9, y = 8 +NOTICE: x = 9, y = 8 +NOTICE: x = 9, y = 8 NOTICE: x = 9, y = 8 x | u ---+---- @@ -1700,8 +1753,8 @@ select * from Output: 9, unnest('{1,2,3,11,12,13}'::integer[]) -> Result Output: true - Optimizer: Pivotal Optimizer (GPORCA) - Settings: optimizer=on + Settings: optimizer = 'on' + Optimizer: GPORCA (9 rows) select * from @@ -1808,8 +1861,8 @@ select relname::information_schema.sql_identifier as tname, * from (select * from pg_class c) ss1) ss2 right join pg_attribute a on a.attrelid = ss2.oid where tname = 'tenk1' and attnum = 1; - QUERY PLAN ------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------- Hash Join Hash Cond: (a.attrelid = c.oid) -> Seq Scan on pg_attribute a @@ -1817,6 +1870,7 @@ where tname = 'tenk1' and attnum = 1; -> Hash -> Index Scan using pg_class_relname_nsp_index on pg_class c Index Cond: (relname = 'tenk1'::name) + Optimizer: Postgres query optimizer (8 rows) select tname, attname from ( @@ -1837,8 +1891,8 @@ select t1.ten, sum(x) from ) ss on t1.unique1 = ss.fivethous group by t1.ten order by t1.ten; - QUERY PLAN ----------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Output: t1.ten, (sum((t1.ten + t2.ten))) Merge Key: t1.ten @@ -1866,6 +1920,8 @@ order by t1.ten; Output: t1.ten, t1.unique1 -> Seq Scan on public.tenk1 t1 Output: t1.ten, t1.unique1 + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer (29 rows) select t1.ten, sum(x) from @@ -1895,8 +1951,8 @@ select t1.q1, x from lateral (select t2.q1+t3.q1 as x, * from int8_tbl t3) t3 on t2.q2 = t3.q2) on t1.q2 = t2.q2 order by 1, 2; - QUERY PLAN --------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Output: t1.q1, ((t2.q1 + t3.q1)) Merge Key: t1.q1, ((t2.q1 + t3.q1)) @@ -1928,6 +1984,8 @@ order by 1, 2; Hash Key: t1.q2 -> Seq Scan on public.int8_tbl t1 Output: t1.q1, t1.q2 + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer (33 rows) select t1.q1, x from @@ -1959,30 +2017,30 @@ set gp_cte_sharing to on; explain (verbose, costs off) with x as (select * from (select f1 from subselect_tbl) ss) select * from x where f1 = 1; - QUERY PLAN -------------------------------------------- + QUERY PLAN +--------------------------------------------------- Gather Motion 1:1 (slice1; segments: 1) Output: f1 -> Seq Scan on public.subselect_tbl Output: f1 Filter: (subselect_tbl.f1 = 1) - Optimizer: Pivotal Optimizer (GPORCA) - Settings: gp_cte_sharing=on, optimizer=on + Settings: optimizer = 'on', gp_cte_sharing = 'on' + Optimizer: GPORCA (7 rows) -- Explicitly request materialization explain (verbose, costs off) with x as materialized (select * from (select f1 from subselect_tbl) ss) select * from x where f1 = 1; - QUERY PLAN -------------------------------------------- + QUERY PLAN +--------------------------------------------------- Gather Motion 1:1 (slice1; segments: 1) Output: f1 -> Seq Scan on public.subselect_tbl Output: f1 Filter: (subselect_tbl.f1 = 1) - Optimizer: Pivotal Optimizer (GPORCA) - Settings: gp_cte_sharing=on, optimizer=on + Settings: optimizer = 'on', gp_cte_sharing = 'on' + Optimizer: GPORCA (7 rows) -- Stable functions are safe to inline @@ -1996,8 +2054,8 @@ select * from x where f1 = 1; -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1, 'regression'::name Filter: (subselect_tbl.f1 = 1) + Settings: optimizer = 'on', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer - Settings: optimizer=off (7 rows) -- Volatile functions prevent inlining @@ -2022,16 +2080,18 @@ select * from x where f1 = 1; Filter: (share0_ref2.f1 = 1) -> Shared Scan (share slice:id 1:0) Output: share0_ref2.f1, share0_ref2.random - Optimizer: Pivotal Optimizer (GPORCA) - Settings: gp_cte_sharing=on, optimizer=on + Settings: optimizer = 'on', gp_cte_sharing = 'on' + Optimizer: GPORCA (16 rows) create temporary sequence ts; create table vol_test(a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. explain (verbose, costs off) with x as (select * from (select a, nextval('ts') from vol_test) ss) select * from x where a = 1; - QUERY PLAN + QUERY PLAN ----------------------------------------------------------------- Gather Motion 1:1 (slice1; segments: 1) Output: share0_ref2.a, share0_ref2.nextval @@ -2047,8 +2107,8 @@ select * from x where a = 1; Filter: (share0_ref2.a = 1) -> Shared Scan (share slice:id 1:0) Output: share0_ref2.a, share0_ref2.nextval - Optimizer: Pivotal Optimizer (GPORCA) - Settings: gp_cte_sharing=on, optimizer=on + Settings: optimizer = 'on', gp_cte_sharing = 'on' + Optimizer: GPORCA (16 rows) drop sequence ts; @@ -2061,15 +2121,15 @@ drop table vol_test; explain (verbose, costs off) with x as (select * from (select f1 from subselect_tbl for update) ss) select * from x where f1 = 1; - QUERY PLAN -------------------------------------------- + QUERY PLAN +--------------------------------------------------- Gather Motion 1:1 (slice1; segments: 1) Output: f1 -> Seq Scan on public.subselect_tbl Output: f1 Filter: (subselect_tbl.f1 = 1) - Optimizer: Pivotal Optimizer (GPORCA) - Settings: gp_cte_sharing=on, optimizer=on + Settings: optimizer = 'on', gp_cte_sharing = 'on' + Optimizer: GPORCA (7 rows) -- Multiply-referenced CTEs are inlined only when requested @@ -2097,7 +2157,7 @@ select * from x, x x2 where x.n = x2.n; Output: share0_ref1.f1, share0_ref1.n -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1, 'regression'::name - Settings: gp_cte_sharing=on, optimizer=on + Settings: optimizer = 'on', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer (21 rows) @@ -2123,8 +2183,8 @@ select * from x, x x2 where x.n = x2.n; Hash Key: ('regression'::name) -> Seq Scan on public.subselect_tbl subselect_tbl_1 Output: subselect_tbl_1.f1, 'regression'::name + Settings: optimizer = 'on', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer - Settings: gp_cte_sharing=on, optimizer=on (19 rows) -- Multiply-referenced CTEs can't be inlined if they contain outer self-refs @@ -2162,23 +2222,23 @@ select * from x; a ------ a + b aa + ab + ba + bb aaaa aaab aaba aabb - ab abaa abab abba abbb - b - ba baaa baab baba babb - bb bbaa bbab bbba @@ -2193,8 +2253,8 @@ with recursive x(a) as select z.a || z.a as a from z where length(z.a || z.a) < 5)) select * from x; - QUERY PLAN --------------------------------------------------- + QUERY PLAN +--------------------------------------------------- Recursive Union -> Values Scan on "*VALUES*" Output: "*VALUES*".column1 @@ -2203,8 +2263,8 @@ select * from x; -> WorkTable Scan on x Output: x.a Filter: (length((x.a || x.a)) < 5) + Settings: optimizer = 'on', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer - Settings: gp_cte_sharing=on, optimizer=on (10 rows) with recursive x(a) as @@ -2228,27 +2288,27 @@ select * from x; explain (verbose, costs off) with x as (select * from int4_tbl) select * from (with y as (select * from x) select * from y) ss; - QUERY PLAN -------------------------------------------- + QUERY PLAN +--------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: f1 -> Seq Scan on public.int4_tbl Output: f1 - Optimizer: Pivotal Optimizer (GPORCA) - Settings: gp_cte_sharing=on, optimizer=on + Settings: optimizer = 'on', gp_cte_sharing = 'on' + Optimizer: GPORCA (6 rows) explain (verbose, costs off) with x as materialized (select * from int4_tbl) select * from (with y as (select * from x) select * from y) ss; - QUERY PLAN -------------------------------------------- + QUERY PLAN +--------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: f1 -> Seq Scan on public.int4_tbl Output: f1 - Optimizer: Pivotal Optimizer (GPORCA) - Settings: gp_cte_sharing=on, optimizer=on + Settings: optimizer = 'on', gp_cte_sharing = 'on' + Optimizer: GPORCA (6 rows) -- Ensure that we inline the currect CTE when there are @@ -2256,26 +2316,26 @@ select * from (with y as (select * from x) select * from y) ss; explain (verbose, costs off) with x as (select 1 as y) select * from (with x as (select 2 as y) select * from x) ss; - QUERY PLAN -------------------------------------------- + QUERY PLAN +--------------------------------------------------- Result Output: 2 - Optimizer: Pivotal Optimizer (GPORCA) - Settings: gp_cte_sharing=on, optimizer=on + Settings: optimizer = 'on', gp_cte_sharing = 'on' + Optimizer: GPORCA (4 rows) -- Row marks are not pushed into CTEs explain (verbose, costs off) with x as (select * from subselect_tbl) select * from x for update; - QUERY PLAN -------------------------------------------- + QUERY PLAN +--------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: f1, f2, f3 -> Seq Scan on public.subselect_tbl Output: f1, f2, f3 - Optimizer: Pivotal Optimizer (GPORCA) - Settings: gp_cte_sharing=on, optimizer=on + Settings: optimizer = 'on', gp_cte_sharing = 'on' + Optimizer: GPORCA (6 rows) set gp_cte_sharing to off; diff --git a/contrib/pax_storage/src/test/regress/expected/table_functions.out b/contrib/pax_storage/src/test/regress/expected/table_functions.out index 834e7c643b1..111ea23e2bf 100644 --- a/contrib/pax_storage/src/test/regress/expected/table_functions.out +++ b/contrib/pax_storage/src/test/regress/expected/table_functions.out @@ -329,59 +329,59 @@ HINT: No function matches the given name and argument types. You might need to SELECT row(a+5, b)::example from example; row ------------------- - (6," value1.1/4") - (8," value3.1/2") - (6," value1.2/4") - (8," value3.2/2") - (6," value1.3/4") - (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") + (6," value1.1/4") + (6," value1.2/4") + (6," value1.3/4") + (6," value1.4/4") (10 rows) SELECT scalar_tf_1(5); scalar_tf_1 ------------------- (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (10 rows) SELECT scalar_tf_2(5); scalar_tf_2 ------------------- - (6," value1.1/4") - (8," value3.1/2") - (6," value1.2/4") - (8," value3.2/2") - (6," value1.3/4") - (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") + (6," value1.1/4") + (6," value1.2/4") + (6," value1.3/4") + (6," value1.4/4") (10 rows) SELECT scalar_tf_3(5); scalar_tf_3 ------------------- (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (10 rows) @@ -389,44 +389,44 @@ SELECT scalar_tf_3(5); SELECT scalar_tf_4(5); scalar_tf_4 ------------------- - (7," value2.1/3") - (9," value4.1/1") - (7," value2.2/3") - (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") + (7," value2.1/3") + (8," value3.1/2") + (9," value4.1/1") + (7," value2.2/3") + (8," value3.2/2") + (7," value2.3/3") (10 rows) SELECT scalar_tf_5(5); scalar_tf_5 ------------------- - (7," value2.1/3") - (9," value4.1/1") - (7," value2.2/3") - (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") + (7," value2.1/3") + (8," value3.1/2") + (9," value4.1/1") + (7," value2.2/3") + (8," value3.2/2") + (7," value2.3/3") (10 rows) SELECT scalar_tf_6(5); scalar_tf_6 ------------------- (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (10 rows) @@ -435,13 +435,13 @@ SELECT scalar_tf_1((select 5)); scalar_tf_1 ------------------- (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (10 rows) @@ -449,29 +449,29 @@ SELECT scalar_tf_1((select 5)); SELECT scalar_tf_2((select 5)); scalar_tf_2 ------------------- - (6," value1.1/4") - (8," value3.1/2") - (6," value1.2/4") - (8," value3.2/2") - (6," value1.3/4") - (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") + (6," value1.1/4") + (6," value1.2/4") + (6," value1.3/4") + (6," value1.4/4") (10 rows) SELECT scalar_tf_3((select 5)); scalar_tf_3 ------------------- (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (10 rows) @@ -479,46 +479,46 @@ SELECT scalar_tf_3((select 5)); SELECT scalar_tf_4((select 5)); scalar_tf_4 ------------------- - (6," value1.1/4") - (8," value3.1/2") - (6," value1.2/4") - (8," value3.2/2") - (6," value1.3/4") - (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") + (6," value1.1/4") + (6," value1.2/4") + (6," value1.3/4") + (6," value1.4/4") (10 rows) SELECT scalar_tf_5((select 5)); scalar_tf_5 ------------------- - (6," value1.1/4") - (8," value3.1/2") - (6," value1.2/4") - (8," value3.2/2") - (6," value1.3/4") - (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") + (6," value1.1/4") + (6," value1.2/4") + (6," value1.3/4") + (6," value1.4/4") (10 rows) SELECT scalar_tf_6((select 5)); scalar_tf_6 ------------------- - (7," value2.1/3") - (9," value4.1/1") - (7," value2.2/3") - (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") + (7," value2.1/3") + (8," value3.1/2") + (9," value4.1/1") + (7," value2.2/3") + (8," value3.2/2") + (7," value2.3/3") (10 rows) -- end equivalent @@ -1348,9 +1348,9 @@ SELECT a from multiset_setof_value( TABLE(SELECT 1) ) as a; -- end equivalent -- ERROR: Table Functions do not currently support SFRM_Materialize SELECT * FROM multiset_materialize_good( TABLE( SELECT * from example ) ); -ERROR: set-valued function called in context that cannot accept a set (seg1 slice1 @hostname@:40041 pid=12397) +ERROR: set-valued function called in context that cannot accept a set (seg2 slice1 172.18.0.2:7004 pid=34438) SELECT * FROM multiset_materialize_bad( TABLE( SELECT * from example ) ); -ERROR: table functions must use SFRM_ValuePerCall protocol (seg1 slice1 @hostname@:40041 pid=12397) +ERROR: table functions must use SFRM_ValuePerCall protocol (seg1 slice1 172.18.0.2:7003 pid=34439) -- name resolution rules should work correctly between scalar and anytable, -- i.e. there cannot be any automatic conversion. CREATE FUNCTION nameres(int) RETURNS int @@ -1416,11 +1416,11 @@ DROP FUNCTION nameres(anyelement); explain SELECT * FROM multiset_5( TABLE( SELECT * FROM example SCATTER BY a+1) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.23 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..3.23 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.12 rows=4 width=16) - Hash Key: (example.a + 1) - -> Seq Scan on example (cost=0.00..3.12 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.61 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.21 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.11 rows=3 width=20) + Hash Key: ((example.a + 1)) + -> Seq Scan on example (cost=0.00..1.04 rows=3 width=20) Optimizer: Postgres query optimizer (6 rows) @@ -1552,254 +1552,254 @@ SELECT * FROM multiset_5( TABLE(SELECT a, b from example)) where (a,b) in (selec -- end equivalent -- Explain a couple interesting cases explain SELECT * FROM multiset_5( TABLE (SELECT dbid, gpname FROM gp_id) ); - QUERY PLAN ------------------------------------------------------------------------ - Table Function Scan on multiset_5 (cost=0.00..1.11 rows=64 width=36) - -> Seq Scan on gp_id (cost=0.00..1.01 rows=8 width=66) - Settings: gp_segments_for_planner=8 + QUERY PLAN +---------------------------------------------------------------------- + Table Function Scan on multiset_5 (cost=0.00..1.02 rows=1 width=36) + -> Seq Scan on gp_id (cost=0.00..1.01 rows=1 width=66) + Optimizer: Postgres query optimizer (3 rows) explain SELECT * FROM multiset_5( TABLE (SELECT dbid, gpname FROM gp_id SCATTER BY dbid) ); QUERY PLAN ---------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.11 rows=4 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..1.11 rows=4 width=36) - -> Redistribute Motion 1:3 (slice2) (cost=0.00..1.01 rows=8 width=66) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.18 rows=9 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.06 rows=3 width=36) + -> Redistribute Motion 1:3 (slice2) (cost=0.00..1.03 rows=1 width=66) Hash Key: gp_id.dbid - -> Seq Scan on gp_id (cost=0.00..1.01 rows=8 width=66) - Settings: gp_segments_for_planner=8 + -> Seq Scan on gp_id (cost=0.00..1.01 rows=1 width=66) + Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT dbid, gpname FROM gp_id SCATTER RANDOMLY) ); QUERY PLAN ---------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.11 rows=4 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..1.11 rows=4 width=36) - -> Redistribute Motion 1:3 (slice2) (cost=0.00..1.01 rows=8 width=66) - -> Seq Scan on gp_id (cost=0.00..1.01 rows=8 width=66) - Settings: gp_segments_for_planner=8 + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.18 rows=9 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.06 rows=3 width=36) + -> Redistribute Motion 1:3 (slice2) (cost=0.00..1.03 rows=1 width=66) + -> Seq Scan on gp_id (cost=0.00..1.01 rows=1 width=66) + Optimizer: Postgres query optimizer (5 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.53 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (4 rows) explain SELECT * from multiset_5( TABLE (SELECT * FROM example ORDER BY a limit 10 ) ); - QUERY PLAN ------------------------------------------------------------------------------------------ - Table Function Scan on multiset_5 (cost=2.27..2.62 rows=80 width=36) - -> Limit (cost=2.27..2.49 rows=10 width=16) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.49 rows=5 width=16) + QUERY PLAN +------------------------------------------------------------------------------------------ + Table Function Scan on multiset_5 (cost=1.06..1.30 rows=10 width=36) + -> Limit (cost=1.06..1.20 rows=10 width=16) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.20 rows=10 width=16) Merge Key: example.a - -> Limit (cost=2.27..2.29 rows=5 width=16) - -> Sort (cost=2.27..2.29 rows=5 width=16) - Sort Key (Limit): example.a - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Limit (cost=1.06..1.07 rows=3 width=16) + -> Sort (cost=1.06..1.07 rows=3 width=16) + Sort Key: example.a + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (9 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example SCATTER BY a) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.53 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (4 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example SCATTER BY b) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..2.10 rows=5 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.60 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.20 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=3 width=16) Hash Key: example.b - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example SCATTER RANDOMLY) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..2.10 rows=5 width=16) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.60 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.20 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=3 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (5 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY a, b) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.42 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.42 rows=5 width=36) - -> Sort (cost=2.27..2.29 rows=5 width=16) + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.57 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.17 rows=10 width=36) + -> Sort (cost=1.06..1.07 rows=3 width=16) Sort Key: example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY a, b SCATTER BY a) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.42 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.42 rows=5 width=36) - -> Sort (cost=2.27..2.29 rows=5 width=16) + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.57 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.17 rows=10 width=36) + -> Sort (cost=1.06..1.07 rows=3 width=16) Sort Key: example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY b, a SCATTER BY b) ); QUERY PLAN ----------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.42 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.42 rows=5 width=36) - -> Sort (cost=2.27..2.29 rows=5 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.13..1.64 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.13..1.24 rows=10 width=36) + -> Sort (cost=1.13..1.14 rows=3 width=16) Sort Key: example.b, example.a - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..2.10 rows=5 width=16) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=3 width=16) Hash Key: example.b - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (8 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY b, a SCATTER RANDOMLY) ); QUERY PLAN ----------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.42 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.42 rows=5 width=36) - -> Sort (cost=2.27..2.29 rows=5 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.13..1.64 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.13..1.24 rows=10 width=36) + -> Sort (cost=1.13..1.14 rows=3 width=16) Sort Key: example.b, example.a - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..2.10 rows=5 width=16) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=3 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (7 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY a, b LIMIT 10 SCATTER BY a) ); - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.62 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.62 rows=5 width=36) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=2.27..2.49 rows=10 width=16) + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.84 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.44 rows=10 width=36) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.06..1.34 rows=3 width=16) Hash Key: example.a - -> Limit (cost=2.27..2.49 rows=10 width=16) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=2.27..2.49 rows=5 width=16) + -> Limit (cost=1.06..1.20 rows=10 width=16) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.06..1.20 rows=10 width=16) Merge Key: example.a, example.b - -> Limit (cost=2.27..2.29 rows=5 width=16) - -> Sort (cost=2.27..2.29 rows=5 width=16) - Sort Key (Limit): example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Limit (cost=1.06..1.07 rows=3 width=16) + -> Sort (cost=1.06..1.07 rows=3 width=16) + Sort Key: example.a, example.b + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (12 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY b, a LIMIT 10 SCATTER BY b) ); - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.62 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.62 rows=5 width=36) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=2.27..2.49 rows=10 width=16) + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.84 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.44 rows=10 width=36) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.06..1.34 rows=3 width=16) Hash Key: example.b - -> Limit (cost=2.27..2.49 rows=10 width=16) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=2.27..2.49 rows=5 width=16) + -> Limit (cost=1.06..1.20 rows=10 width=16) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.06..1.20 rows=10 width=16) Merge Key: example.b, example.a - -> Limit (cost=2.27..2.29 rows=5 width=16) - -> Sort (cost=2.27..2.29 rows=5 width=16) - Sort Key (Limit): example.b, example.a - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Limit (cost=1.06..1.07 rows=3 width=16) + -> Sort (cost=1.06..1.07 rows=3 width=16) + Sort Key: example.b, example.a + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (12 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY b, a LIMIT 10 SCATTER RANDOMLY) ); - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.62 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.62 rows=5 width=36) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=2.27..2.49 rows=10 width=16) - -> Limit (cost=2.27..2.49 rows=10 width=16) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=2.27..2.49 rows=5 width=16) + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.84 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.44 rows=10 width=36) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.06..1.34 rows=3 width=16) + -> Limit (cost=1.06..1.20 rows=10 width=16) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.06..1.20 rows=10 width=16) Merge Key: example.b, example.a - -> Limit (cost=2.27..2.29 rows=5 width=16) - -> Sort (cost=2.27..2.29 rows=5 width=16) - Sort Key (Limit): example.b, example.a - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Limit (cost=1.06..1.07 rows=3 width=16) + -> Sort (cost=1.06..1.07 rows=3 width=16) + Sort Key: example.b, example.a + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (11 rows) explain SELECT ARRAY(SELECT a FROM multiset_5( TABLE ( SELECT a, b from example)) order by a); - QUERY PLAN ------------------------------------------------------------------------------------------ - Result (cost=2.42..2.43 rows=1 width=0) + QUERY PLAN +------------------------------------------------------------------------------------------ + Result (cost=1.72..1.73 rows=1 width=32) InitPlan 1 (returns $0) (slice1) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=2.39..2.42 rows=5 width=4) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=1.30..1.72 rows=30 width=4) Merge Key: a - -> Sort (cost=2.39..2.42 rows=5 width=4) - Sort Key: multiset_5.a - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=4) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Sort (cost=1.30..1.32 rows=10 width=4) + Sort Key: a + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=4) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (9 rows) explain SELECT ARRAY(SELECT a FROM multiset_5( TABLE ( SELECT a, b from example order by a))); - QUERY PLAN ------------------------------------------------------------------------------------- - Result (cost=2.42..2.43 rows=1 width=0) + QUERY PLAN +------------------------------------------------------------------------------------- + Result (cost=1.57..1.58 rows=1 width=32) InitPlan 1 (returns $0) (slice1) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=2.27..2.42 rows=5 width=4) - -> Table Function Scan on multiset_5 (cost=2.27..2.42 rows=5 width=4) - -> Sort (cost=2.27..2.29 rows=5 width=16) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=1.06..1.57 rows=30 width=4) + -> Table Function Scan on multiset_5 (cost=1.06..1.17 rows=10 width=4) + -> Sort (cost=1.06..1.07 rows=3 width=16) Sort Key: example.a - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (8 rows) explain SELECT * FROM example where (a,b) in (select * from multiset_5( TABLE(SELECT a, b from example) )); - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=3.55..6.83 rows=10 width=16) - -> Hash Semi Join (cost=3.55..6.83 rows=4 width=16) - Hash Cond: example.a = a AND example.b = b - -> Seq Scan on example (cost=0.00..3.10 rows=4 width=16) - -> Hash (cost=3.40..3.40 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.40 rows=4 width=36) - Hash Key: a - -> Table Function Scan on multiset_5 (cost=0.00..3.20 rows=4 width=36) - -> Seq Scan on example example_1 (cost=0.00..3.10 rows=4 width=16) + QUERY PLAN +------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.08..2.66 rows=10 width=16) + -> Hash Right Semi Join (cost=1.08..2.53 rows=3 width=16) + Hash Cond: ((a = example.a) AND (b = example.b)) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.33 rows=10 width=36) + Hash Key: a + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example example_1 (cost=0.00..1.03 rows=3 width=16) + -> Hash (cost=1.03..1.03 rows=3 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (10 rows) explain SELECT * FROM example where (a,b) in (select * from multiset_5( TABLE(SELECT a, b from example scatter by b) )); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=3.55..6.83 rows=10 width=16) - -> Hash Semi Join (cost=3.55..6.83 rows=4 width=16) - Hash Cond: example.a = a AND example.b = b - -> Seq Scan on example (cost=0.00..3.10 rows=4 width=16) - -> Hash (cost=3.40..3.40 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.40 rows=4 width=36) - Hash Key: a - -> Table Function Scan on multiset_5 (cost=0.00..3.20 rows=4 width=36) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..3.10 rows=4 width=16) - Hash Key: example_1.b - -> Seq Scan on example example_1 (cost=0.00..3.10 rows=4 width=16) + QUERY PLAN +----------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=1.08..2.73 rows=10 width=16) + -> Hash Right Semi Join (cost=1.08..2.59 rows=3 width=16) + Hash Cond: ((a = example.a) AND (b = example.b)) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.40 rows=10 width=36) + Hash Key: a + -> Table Function Scan on multiset_5 (cost=0.00..1.20 rows=10 width=36) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.10 rows=3 width=16) + Hash Key: example_1.b + -> Seq Scan on example example_1 (cost=0.00..1.03 rows=3 width=16) + -> Hash (cost=1.03..1.03 rows=3 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (12 rows) explain SELECT * FROM multiset_5( TABLE(SELECT a, b from example)) where (a,b) in (select a,b from example); - QUERY PLAN ---------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=1.32..2.58 rows=4 width=36) - -> Hash Semi Join (cost=1.32..2.52 rows=1 width=36) - Hash Cond: ((a = example.a) AND (b = example.b)) - -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) - -> Seq Scan on example example_1 (cost=0.00..1.03 rows=3 width=16) - -> Hash (cost=1.17..1.17 rows=10 width=16) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.17 rows=10 width=16) - -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + QUERY PLAN +--------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=1.28..2.59 rows=4 width=36) + -> Hash Right Semi Join (cost=1.28..2.54 rows=1 width=36) + Hash Cond: ((example.a = a) AND (example.b = b)) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.17 rows=10 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + -> Hash (cost=1.13..1.13 rows=10 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example example_1 (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (9 rows) @@ -1820,107 +1820,107 @@ explain SELECT * FROM multiset_5( TABLE(SELECT a, b from example scatter by b)) (11 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * from example_r) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Seq Scan on example_r (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.53 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example_r (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (4 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * FROM example_r SCATTER by a||b) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.28 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..3.28 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.18 rows=4 width=16) - Hash Key: (example_r.a::text || example_r.b) - -> Seq Scan on example_r (cost=0.00..3.18 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.62 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.23 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.12 rows=3 width=48) + Hash Key: (((example_r.a)::text || example_r.b)) + -> Seq Scan on example_r (cost=0.00..1.06 rows=3 width=48) Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * FROM example_r SCATTER by b, a, a||b) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.28 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..3.28 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.18 rows=4 width=16) - Hash Key: example_r.b, example_r.a, (example_r.a::text || example_r.b) - -> Seq Scan on example_r (cost=0.00..3.18 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.62 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.23 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.12 rows=3 width=48) + Hash Key: example_r.b, example_r.a, (((example_r.a)::text || example_r.b)) + -> Seq Scan on example_r (cost=0.00..1.06 rows=3 width=48) Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * FROM example_r SCATTER RANDOMLY) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..2.10 rows=5 width=16) - -> Seq Scan on example_r (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.60 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.20 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=3 width=16) + -> Seq Scan on example_r (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (5 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example) ); QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.09..2.29 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.09..2.29 rows=4 width=36) - -> HashAggregate (cost=2.09..2.19 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.05..1.58 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.05..1.18 rows=10 width=36) + -> HashAggregate (cost=1.05..1.08 rows=3 width=16) Group Key: example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example SCATTER BY a) ); QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.09..2.29 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.09..2.29 rows=4 width=36) - -> HashAggregate (cost=2.09..2.19 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.05..1.58 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.05..1.18 rows=10 width=36) + -> HashAggregate (cost=1.05..1.08 rows=3 width=16) Group Key: example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a / 2, b FROM example SCATTER BY a / 2) ); QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.38..2.80 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.38..2.80 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.38..2.70 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.12..1.73 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.12..1.33 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.12..1.23 rows=3 width=16) Hash Key: ((example.a / 2)) - -> HashAggregate (cost=2.38..2.50 rows=4 width=16) + -> HashAggregate (cost=1.12..1.17 rows=3 width=16) Group Key: ((example.a / 2)), example.b - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..2.33 rows=4 width=16) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.11 rows=3 width=16) Hash Key: ((example.a / 2)), example.b - -> Seq Scan on example (cost=0.00..2.12 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.04 rows=3 width=16) Optimizer: Postgres query optimizer (10 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example SCATTER BY b) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.09..2.49 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.09..2.49 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.09..2.39 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.05..1.65 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.05..1.25 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.05..1.15 rows=3 width=16) Hash Key: example.b - -> HashAggregate (cost=2.09..2.19 rows=4 width=16) + -> HashAggregate (cost=1.05..1.08 rows=3 width=16) Group Key: example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (8 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example ORDER BY b, a SCATTER RANDOMLY) ); QUERY PLAN ----------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.62..2.74 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.62..2.74 rows=4 width=36) - -> Sort (cost=2.62..2.64 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.18..1.69 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.18..1.29 rows=10 width=36) + -> Sort (cost=1.18..1.19 rows=3 width=16) Sort Key: example.b, example.a - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.15..2.45 rows=4 width=16) - -> HashAggregate (cost=2.15..2.25 rows=4 width=16) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.05..1.15 rows=3 width=16) + -> HashAggregate (cost=1.05..1.08 rows=3 width=16) Group Key: example.b, example.a - -> Seq Scan on example (cost=0.00..2.10 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (9 rows) @@ -1940,28 +1940,28 @@ explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example ORDER explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example ORDER BY b, a SCATTER BY b) ); QUERY PLAN ----------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.62..2.74 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.62..2.74 rows=4 width=36) - -> Sort (cost=2.62..2.64 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.18..1.69 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.18..1.29 rows=10 width=36) + -> Sort (cost=1.18..1.19 rows=3 width=16) Sort Key: example.b, example.a - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.15..2.45 rows=4 width=16) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.05..1.15 rows=3 width=16) Hash Key: example.b - -> HashAggregate (cost=2.15..2.25 rows=4 width=16) + -> HashAggregate (cost=1.05..1.08 rows=3 width=16) Group Key: example.b, example.a - -> Seq Scan on example (cost=0.00..2.10 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (10 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example ORDER BY b, a LIMIT 2 SCATTER RANDOMLY) ); QUERY PLAN -------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=1.07..1.28 rows=9 width=36) - -> Table Function Scan on multiset_5 (cost=1.07..1.16 rows=3 width=36) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.07..1.13 rows=1 width=16) - -> Limit (cost=1.07..1.10 rows=2 width=16) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.07..1.16 rows=6 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.27 rows=9 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.15 rows=3 width=36) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.06..1.12 rows=1 width=16) + -> Limit (cost=1.06..1.09 rows=2 width=16) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.06..1.16 rows=6 width=16) Merge Key: example.b, example.a - -> Limit (cost=1.07..1.08 rows=2 width=16) + -> Limit (cost=1.06..1.08 rows=2 width=16) -> Unique (cost=1.06..1.09 rows=3 width=16) Group Key: example.b, example.a -> Sort (cost=1.06..1.07 rows=3 width=16) @@ -1973,64 +1973,64 @@ explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example ORDER explain SELECT * FROM multiset_5( TABLE( SELECT count(*)::integer, 'hello'::text from example_r ) ); QUERY PLAN ---------------------------------------------------------------------------------------- - Table Function Scan on multiset_5 (cost=3.16..3.18 rows=1 width=36) - -> Finalize Aggregate (cost=3.16..3.17 rows=1 width=36) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=3.12..3.15 rows=1 width=8) - -> Partial Aggregate (cost=3.12..3.13 rows=1 width=8) - -> Seq Scan on example_r (cost=0.00..3.10 rows=4 width=0) + Table Function Scan on multiset_5 (cost=1.10..1.12 rows=1 width=36) + -> Finalize Aggregate (cost=1.10..1.11 rows=1 width=36) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=1.04..1.09 rows=3 width=8) + -> Partial Aggregate (cost=1.04..1.05 rows=1 width=8) + -> Seq Scan on example_r (cost=0.00..1.03 rows=3 width=0) Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM example_r WHERE (10, 'hello') in (SELECT * FROM multiset_5( TABLE( SELECT count(*)::integer, 'hello'::text from example_r ))); QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.10 rows=5 width=16) - -> Seq Scan on example_r (cost=0.00..3.10 rows=2 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.10 rows=5 width=16) + -> Seq Scan on example_r (cost=0.00..1.03 rows=2 width=16) Filter: (hashed SubPlan 1) SubPlan 1 - -> Broadcast Motion 1:3 (slice2) (cost=3.16..3.18 rows=1 width=36) - -> Table Function Scan on multiset_5 (cost=3.16..3.18 rows=1 width=36) - -> Finalize Aggregate (cost=3.16..3.17 rows=1 width=36) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=3.12..3.15 rows=1 width=8) - -> Partial Aggregate (cost=3.12..3.13 rows=1 width=8) - -> Seq Scan on example_r example_r_1 (cost=0.00..3.10 rows=4 width=0) + -> Broadcast Motion 1:3 (slice2) (cost=1.10..1.12 rows=1 width=36) + -> Table Function Scan on multiset_5 (cost=1.10..1.12 rows=1 width=36) + -> Finalize Aggregate (cost=1.10..1.11 rows=1 width=36) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.04..1.09 rows=3 width=8) + -> Partial Aggregate (cost=1.04..1.05 rows=1 width=8) + -> Seq Scan on example_r example_r_1 (cost=0.00..1.03 rows=3 width=0) Optimizer: Postgres query optimizer (11 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * from example_v) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.53 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (4 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * FROM example WHERE a >= (SELECT min(a) FROM example))); QUERY PLAN ------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.17..4.33 rows=4 width=36) - -> Table Function Scan on multiset_5 (cost=2.17..4.33 rows=2 width=36) - -> Seq Scan on example (cost=2.17..4.29 rows=2 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.11..2.32 rows=10 width=36) + -> Table Function Scan on multiset_5 (cost=1.11..2.18 rows=3 width=36) + -> Seq Scan on example (cost=1.11..2.15 rows=1 width=16) Filter: (a >= $0) InitPlan 1 (returns $0) (slice2) - -> Finalize Aggregate (cost=2.16..2.17 rows=1 width=4) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=2.12..2.15 rows=1 width=4) - -> Partial Aggregate (cost=2.12..2.13 rows=1 width=4) - -> Seq Scan on example example_1 (cost=0.00..2.10 rows=4 width=4) + -> Finalize Aggregate (cost=1.10..1.11 rows=1 width=4) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.04..1.09 rows=3 width=4) + -> Partial Aggregate (cost=1.04..1.05 rows=1 width=4) + -> Seq Scan on example example_1 (cost=0.00..1.03 rows=3 width=4) Optimizer: Postgres query optimizer (10 rows) explain WITH cte AS (SELECT * FROM example) SELECT * FROM multiset_5( TABLE ( SELECT * FROM cte ) ) order by a, b; - QUERY PLAN ----------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.39..2.42 rows=5 width=36) + QUERY PLAN +----------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=1.30..1.72 rows=30 width=36) Merge Key: a, b - -> Sort (cost=2.39..2.42 rows=5 width=36) - Sort Key: multiset_5.a, multiset_5.b - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Sort (cost=1.30..1.32 rows=10 width=36) + Sort Key: a, b + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (7 rows) explain WITH cte AS (SELECT * FROM example) SELECT x.* FROM multiset_5( TABLE ( SELECT * FROM cte ) ) x, (SELECT count(*) FROM cte) y order by x.a, x.b; @@ -2056,81 +2056,81 @@ explain WITH cte AS (SELECT * FROM example) SELECT x.* FROM multiset_5( TABLE ( explain select * from multiset_2( TABLE( SELECT distinct a.a, b.b from example a, example b where a.a = b.a) ) order by 1,2; QUERY PLAN ---------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=8.19..8.26 rows=30 width=36) + Gather Motion 3:1 (slice1; segments: 3) (cost=3.41..4.68 rows=90 width=36) Merge Key: a, b - -> Sort (cost=8.19..8.26 rows=10 width=36) + -> Sort (cost=3.41..3.48 rows=30 width=36) Sort Key: a, b - -> Table Function Scan on multiset_2 (cost=6.85..7.45 rows=10 width=36) - -> HashAggregate (cost=6.85..7.15 rows=10 width=36) + -> Table Function Scan on multiset_2 (cost=2.27..2.67 rows=30 width=36) + -> HashAggregate (cost=2.27..2.37 rows=10 width=16) Group Key: a.a, b.b - -> Hash Join (cost=3.23..6.70 rows=11 width=16) - Hash Cond: a.a = b.a - -> Seq Scan on example a (cost=0.00..3.10 rows=4 width=4) - -> Hash (cost=3.10..3.10 rows=4 width=16) - -> Seq Scan on example b (cost=0.00..3.10 rows=4 width=16) + -> Hash Join (cost=1.08..2.22 rows=10 width=16) + Hash Cond: (a.a = b.a) + -> Seq Scan on example a (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.03..1.03 rows=3 width=16) + -> Seq Scan on example b (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (13 rows) explain select * from multiset_2( TABLE( SELECT distinct a.a, b.b from example a join example b using (a) ) ) order by 1,2; QUERY PLAN ---------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=8.19..8.26 rows=30 width=36) + Gather Motion 3:1 (slice1; segments: 3) (cost=3.41..4.68 rows=90 width=36) Merge Key: a, b - -> Sort (cost=8.19..8.26 rows=10 width=36) + -> Sort (cost=3.41..3.48 rows=30 width=36) Sort Key: a, b - -> Table Function Scan on multiset_2 (cost=6.85..7.45 rows=10 width=36) - -> HashAggregate (cost=6.85..7.15 rows=10 width=36) + -> Table Function Scan on multiset_2 (cost=2.27..2.67 rows=30 width=36) + -> HashAggregate (cost=2.27..2.37 rows=10 width=16) Group Key: a.a, b.b - -> Hash Join (cost=3.23..6.70 rows=11 width=16) - Hash Cond: a.a = b.a - -> Seq Scan on example a (cost=0.00..3.10 rows=4 width=4) - -> Hash (cost=3.10..3.10 rows=4 width=16) - -> Seq Scan on example b (cost=0.00..3.10 rows=4 width=16) + -> Hash Join (cost=1.08..2.22 rows=10 width=16) + Hash Cond: (a.a = b.a) + -> Seq Scan on example a (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.03..1.03 rows=3 width=16) + -> Seq Scan on example b (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (13 rows) explain select * from multiset_2( TABLE ( SELECT * FROM example WHERE a = 2 ) ) WHERE a = 2; QUERY PLAN ----------------------------------------------------------------------------- - Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..2.17 rows=1 width=36) - -> Table Function Scan on multiset_2 (cost=0.00..2.17 rows=1 width=36) - Filter: a = 2 - -> Seq Scan on example (cost=0.00..2.12 rows=2 width=16) - Filter: a = 2 - Settings: gp_segments_for_planner=8 + Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..1.10 rows=1 width=36) + -> Table Function Scan on multiset_2 (cost=0.00..1.08 rows=1 width=36) + Filter: (a = 2) + -> Seq Scan on example (cost=0.00..1.04 rows=1 width=16) + Filter: (a = 2) + Optimizer: Postgres query optimizer (6 rows) -- Not rescannable, should produce materialize node explain SELECT x.* FROM multiset_5( TABLE ( SELECT 1 ) ) x right join (SELECT 1) y on (true); QUERY PLAN ------------------------------------------------------------------------------------ - Nested Loop Left Join (cost=0.03..1.33 rows=27 width=36) + Nested Loop Left Join (cost=10000000000.00..10000000000.04 rows=3 width=36) -> Result (cost=0.00..0.01 rows=1 width=0) - -> Materialize (cost=0.03..0.11 rows=4 width=36) - -> Table Function Scan on multiset_5 x (cost=0.00..0.02 rows=8 width=36) - -> Result (cost=0.00..0.01 rows=1 width=0) - Settings: gp_segments_for_planner=8 + -> Materialize (cost=0.00..0.03 rows=1 width=36) + -> Table Function Scan on multiset_5 x (cost=0.00..0.02 rows=1 width=36) + -> Result (cost=0.00..0.01 rows=1 width=4) + Optimizer: Postgres query optimizer (6 rows) -- Do an explain analyze while we are at it: explain analyze SELECT * FROM multiset_5( TABLE( SELECT count(*)::integer, 'hello'::text from example_r scatter randomly) ); QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=3.16..3.22 rows=1 width=36) (actual time=1.893..2.348 rows=1 loops=1) - -> Table Function Scan on multiset_5 (cost=3.16..3.20 rows=1 width=36) (actual time=1.553..1.557 rows=1 loops=1) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=3.16..3.19 rows=1 width=36) (actual time=1.539..1.540 rows=1 loops=1) - -> Finalize Aggregate (cost=3.16..3.17 rows=1 width=36) (actual time=1.146..1.147 rows=1 loops=1) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=3.12..3.15 rows=1 width=8) (actual time=0.872..1.133 rows=3 loops=1) - -> Partial Aggregate (cost=3.12..3.13 rows=1 width=8) (actual time=0.054..0.054 rows=1 loops=1) - -> Seq Scan on example_r (cost=0.00..3.10 rows=4 width=0) (actual time=0.044..0.046 rows=4 loops=1) - Planning time: 0.533 ms - (slice0) Executor memory: 127K bytes. - (slice1) Executor memory: 35K bytes avg x 3 workers, 40K bytes max (seg0). - (slice2) Executor memory: 63K bytes (seg0). - (slice3) Executor memory: 70K bytes avg x 3 workers, 92K bytes max (seg0). + Gather Motion 3:1 (slice1; segments: 3) (cost=1.10..1.28 rows=9 width=36) (actual time=10.061..10.063 rows=1 loops=1) + -> Table Function Scan on multiset_5 (cost=1.10..1.16 rows=3 width=36) (actual time=5.306..5.308 rows=1 loops=1) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.10..1.13 rows=1 width=36) (actual time=5.302..5.302 rows=1 loops=1) + -> Finalize Aggregate (cost=1.10..1.11 rows=1 width=36) (actual time=4.116..4.117 rows=1 loops=1) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.04..1.09 rows=3 width=8) (actual time=3.020..4.104 rows=3 loops=1) + -> Partial Aggregate (cost=1.04..1.05 rows=1 width=8) (actual time=0.296..0.296 rows=1 loops=1) + -> Seq Scan on example_r (cost=0.00..1.03 rows=3 width=0) (actual time=0.374..0.382 rows=5 loops=1) + Planning Time: 0.046 ms + (slice0) Executor memory: 37K bytes. + (slice1) Executor memory: 10K bytes avg x 3x(0) workers, 10K bytes max (seg1). + (slice2) Executor memory: 118K bytes (seg2). + (slice3) Executor memory: 120K bytes avg x 3x(0) workers, 120K bytes max (seg2). Memory used: 128000kB Optimizer: Postgres query optimizer - Execution time: 3.194 ms + Execution Time: 18.835 ms (15 rows) -- Test for an old bug in aggregate planning - this used to crash. @@ -2377,9 +2377,9 @@ explain SELECT *, generate_series(1,2) FROM multi_args( TABLE(SELECT 1::int, 'he explain SELECT * FROM multi_args( TABLE(SELECT 1::int, 'hello'::text), 2); QUERY PLAN ---------------------------------------------------------------------- - Table Function Scan on multi_args (cost=0.00..0.02 rows=8 width=36) - -> Result (cost=0.00..0.01 rows=1 width=0) - Settings: gp_segments_for_planner=8 + Table Function Scan on multi_args (cost=0.00..0.02 rows=1 width=36) + -> Result (cost=0.00..0.01 rows=1 width=36) + Optimizer: Postgres query optimizer (3 rows) -- Error: don't support sets as arguments that are not TableValueExpr @@ -2393,11 +2393,11 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'a' HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. QUERY PLAN ----------------------------------------------------------------------------------- - Redistribute Motion 1:3 (slice1; segments: 1) (cost=0.00..0.02 rows=8 width=36) - Hash Key: a - -> Table Function Scan on multi_args (cost=0.00..0.02 rows=8 width=36) - -> Result (cost=0.00..0.01 rows=1 width=0) - Settings: gp_segments_for_planner=8 + Redistribute Motion 1:3 (slice1; segments: 1) (cost=0.00..0.04 rows=1 width=36) + Hash Key: multi_args.a + -> Table Function Scan on multi_args (cost=0.00..0.02 rows=1 width=36) + -> Result (cost=0.00..0.01 rows=1 width=36) + Optimizer: Postgres query optimizer (5 rows) CREATE TABLE example_out AS SELECT * FROM multi_args( TABLE(SELECT 1::int, 'hello'::text), 2); @@ -2415,11 +2415,11 @@ DROP TABLE example_out; -- =============== DROP VIEW example_v; ALTER TABLE example DROP column a; -NOTICE: dropping a column that is part of the distribution policy forces a random distribution policy +NOTICE: dropping a column that is part of the distribution policy forces a NULL distribution policy -- ERROR: input tuple does not conform to expectations of multiset_5 SELECT * FROM multiset_5( TABLE( SELECT 'hello'::text) ) as tf; ERROR: invalid input tuple for function multiset_example -HINT: expected (integer, text) +HINT: Expected (integer, text). -- However, this should work despite the output tupdesc having a dropped column. SELECT * FROM multiset_5( TABLE( SELECT 1::integer, 'hello'::text) ) as tf; b @@ -2433,6 +2433,7 @@ SELECT * FROM multiset_5( TABLE( SELECT 1::integer, 'hello'::text) ) as tf; -- start_ignore -- These may have been created by previous test create language plpython3u; +ERROR: extension "plpython3u" already exists -- end_ignore CREATE FUNCTION tf_sql(anytable) returns int AS $$ SELECT 1 $$ language sql CONTAINS SQL; ERROR: SQL functions cannot have arguments of type anytable @@ -2987,14 +2988,14 @@ SELECT * FROM project( TABLE( SELECT * FROM pg_am WHERE amname not in ('pax') ), amname ----------- heap - ao_row - ao_column btree hash gist gin spgist brin + ao_row + ao_column bitmap heap2 (11 rows) @@ -3004,14 +3005,14 @@ SELECT * FROM project( TABLE( SELECT * FROM pg_am WHERE amname not in ('pax') ), amname ----------- heap - ao_row - ao_column btree hash gist gin spgist brin + ao_row + ao_column bitmap heap2 (11 rows) @@ -3026,7 +3027,7 @@ SELECT "time"+1 FROM project( TABLE( SELECT * FROM history ), 2); ERROR: operator does not exist: timestamp without time zone + integer LINE 1: SELECT "time"+1 FROM project( TABLE( SELECT * FROM history )... ^ -HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. +HINT: No operator matches the given name and argument types. You might need to add explicit type casts. -- ERROR: select columns projected out by the function SELECT id FROM project( TABLE( SELECT * FROM history ), 2); ERROR: column "id" does not exist @@ -3095,13 +3096,9 @@ CREATE FUNCTION noop_project(anytable) RETURNS setof RECORD SELECT * FROM noop_project( TABLE( SELECT * FROM history ) ) AS s (id integer, time timestamp); id | time ----+-------------------------- - 1 | Mon Aug 22 10:15:04 2011 - 1 | Mon Aug 22 10:16:10 2011 - 1 | Sun Aug 21 10:15:02 2011 - 1 | Sun Aug 21 10:15:30 2011 2 | Sun Aug 21 10:15:02 2011 - 2 | Sun Aug 21 10:16:02 2011 2 | Sun Aug 21 22:15:02 2011 + 2 | Sun Aug 21 10:16:02 2011 2 | Sun Aug 21 22:16:02 2011 3 | Fri Aug 19 19:05:13 2011 3 | Fri Aug 19 19:06:50 2011 @@ -3113,6 +3110,10 @@ SELECT * FROM noop_project( TABLE( SELECT * FROM history ) ) AS s (id integer, t 3 | Sat Aug 20 10:11:29 2011 3 | Sat Aug 20 10:17:10 2011 3 | Sat Aug 20 10:17:42 2011 + 1 | Sun Aug 21 10:15:02 2011 + 1 | Sun Aug 21 10:15:30 2011 + 1 | Mon Aug 22 10:15:04 2011 + 1 | Mon Aug 22 10:16:10 2011 (18 rows) -- SCATTER BY vs MEDIAN @@ -3137,6 +3138,7 @@ SELECT * FROM noop_project( TABLE( SELECT count(*) FROM history SCATTER BY media SELECT * FROM noop_project( TABLE( SELECT count(*) FROM history GROUP BY time SCATTER BY median(id) ) ) AS s (cnt bigint); cnt ----- + 2 1 1 1 @@ -3153,7 +3155,6 @@ SELECT * FROM noop_project( TABLE( SELECT count(*) FROM history GROUP BY time SC 1 1 1 - 2 (17 rows) -- ======================== diff --git a/contrib/pax_storage/src/test/regress/expected/table_functions_optimizer.out b/contrib/pax_storage/src/test/regress/expected/table_functions_optimizer.out index 7f996d5c37f..584083c8d8d 100644 --- a/contrib/pax_storage/src/test/regress/expected/table_functions_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/table_functions_optimizer.out @@ -330,59 +330,59 @@ HINT: No function matches the given name and argument types. You might need to SELECT row(a+5, b)::example from example; row ------------------- - (6," value1.1/4") - (8," value3.1/2") - (6," value1.2/4") - (8," value3.2/2") - (6," value1.3/4") - (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") + (6," value1.1/4") + (6," value1.2/4") + (6," value1.3/4") + (6," value1.4/4") (10 rows) SELECT scalar_tf_1(5); scalar_tf_1 ------------------- - (6," value1.1/4") - (8," value3.1/2") - (6," value1.2/4") - (8," value3.2/2") - (6," value1.3/4") - (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") + (6," value1.1/4") + (6," value1.2/4") + (6," value1.3/4") + (6," value1.4/4") (10 rows) SELECT scalar_tf_2(5); scalar_tf_2 ------------------- - (6," value1.1/4") - (8," value3.1/2") - (6," value1.2/4") - (8," value3.2/2") - (6," value1.3/4") - (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") + (6," value1.1/4") + (6," value1.2/4") + (6," value1.3/4") + (6," value1.4/4") (10 rows) SELECT scalar_tf_3(5); scalar_tf_3 ------------------- (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (10 rows) @@ -391,13 +391,13 @@ SELECT scalar_tf_4(5); scalar_tf_4 ------------------- (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (10 rows) @@ -406,13 +406,13 @@ SELECT scalar_tf_5(5); scalar_tf_5 ------------------- (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (10 rows) @@ -421,13 +421,13 @@ SELECT scalar_tf_6(5); scalar_tf_6 ------------------- (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (10 rows) @@ -436,13 +436,13 @@ SELECT scalar_tf_1((select 5)); scalar_tf_1 ------------------- (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (10 rows) @@ -451,75 +451,75 @@ SELECT scalar_tf_2((select 5)); scalar_tf_2 ------------------- (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (10 rows) SELECT scalar_tf_3((select 5)); scalar_tf_3 ------------------- - (7," value2.1/3") - (9," value4.1/1") - (7," value2.2/3") - (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") + (7," value2.1/3") + (8," value3.1/2") + (9," value4.1/1") + (7," value2.2/3") + (8," value3.2/2") + (7," value2.3/3") (10 rows) SELECT scalar_tf_4((select 5)); scalar_tf_4 ------------------- - (6," value1.1/4") - (8," value3.1/2") - (6," value1.2/4") - (8," value3.2/2") - (6," value1.3/4") - (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") + (6," value1.1/4") + (6," value1.2/4") + (6," value1.3/4") + (6," value1.4/4") (10 rows) SELECT scalar_tf_5((select 5)); scalar_tf_5 ------------------- - (6," value1.1/4") - (8," value3.1/2") - (6," value1.2/4") - (8," value3.2/2") - (6," value1.3/4") - (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") + (6," value1.1/4") + (6," value1.2/4") + (6," value1.3/4") + (6," value1.4/4") (10 rows) SELECT scalar_tf_6((select 5)); scalar_tf_6 ------------------- - (7," value2.1/3") - (9," value4.1/1") - (7," value2.2/3") - (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") + (7," value2.1/3") + (8," value3.1/2") + (9," value4.1/1") + (7," value2.2/3") + (8," value3.2/2") + (7," value2.3/3") (10 rows) -- end equivalent @@ -1349,9 +1349,9 @@ SELECT a from multiset_setof_value( TABLE(SELECT 1) ) as a; -- end equivalent -- ERROR: Table Functions do not currently support SFRM_Materialize SELECT * FROM multiset_materialize_good( TABLE( SELECT * from example ) ); -ERROR: set-valued function called in context that cannot accept a set (seg1 slice1 gpadmin:40041 pid=12397) +ERROR: set-valued function called in context that cannot accept a set (seg1 slice1 172.18.0.2:7003 pid=34354) SELECT * FROM multiset_materialize_bad( TABLE( SELECT * from example ) ); -ERROR: table functions must use SFRM_ValuePerCall protocol (seg1 slice1 gpadmin:40041 pid=12397) +ERROR: table functions must use SFRM_ValuePerCall protocol (seg2 slice1 172.18.0.2:7004 pid=34365) -- name resolution rules should work correctly between scalar and anytable, -- i.e. there cannot be any automatic conversion. CREATE FUNCTION nameres(int) RETURNS int @@ -1417,11 +1417,11 @@ DROP FUNCTION nameres(anyelement); explain SELECT * FROM multiset_5( TABLE( SELECT * FROM example SCATTER BY a+1) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.23 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..3.23 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.12 rows=4 width=16) - Hash Key: (example.a + 1) - -> Seq Scan on example (cost=0.00..3.12 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.61 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.21 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.11 rows=3 width=20) + Hash Key: ((example.a + 1)) + -> Seq Scan on example (cost=0.00..1.04 rows=3 width=20) Optimizer: Postgres query optimizer (6 rows) @@ -1553,254 +1553,254 @@ SELECT * FROM multiset_5( TABLE(SELECT a, b from example)) where (a,b) in (selec -- end equivalent -- Explain a couple interesting cases explain SELECT * FROM multiset_5( TABLE (SELECT dbid, gpname FROM gp_id) ); - QUERY PLAN ------------------------------------------------------------------------ - Table Function Scan on multiset_5 (cost=0.00..1.11 rows=64 width=36) - -> Seq Scan on gp_id (cost=0.00..1.01 rows=8 width=66) - Settings: gp_segments_for_planner=8 + QUERY PLAN +---------------------------------------------------------------------- + Table Function Scan on multiset_5 (cost=0.00..1.02 rows=1 width=36) + -> Seq Scan on gp_id (cost=0.00..1.01 rows=1 width=66) + Optimizer: Postgres query optimizer (3 rows) explain SELECT * FROM multiset_5( TABLE (SELECT dbid, gpname FROM gp_id SCATTER BY dbid) ); QUERY PLAN ---------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.11 rows=4 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..1.11 rows=4 width=36) - -> Redistribute Motion 1:3 (slice2) (cost=0.00..1.01 rows=8 width=66) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.18 rows=9 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.06 rows=3 width=36) + -> Redistribute Motion 1:3 (slice2) (cost=0.00..1.03 rows=1 width=66) Hash Key: gp_id.dbid - -> Seq Scan on gp_id (cost=0.00..1.01 rows=8 width=66) - Settings: gp_segments_for_planner=8 + -> Seq Scan on gp_id (cost=0.00..1.01 rows=1 width=66) + Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT dbid, gpname FROM gp_id SCATTER RANDOMLY) ); QUERY PLAN ---------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.11 rows=4 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..1.11 rows=4 width=36) - -> Redistribute Motion 1:3 (slice2) (cost=0.00..1.01 rows=8 width=66) - -> Seq Scan on gp_id (cost=0.00..1.01 rows=8 width=66) - Settings: gp_segments_for_planner=8 + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.18 rows=9 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.06 rows=3 width=36) + -> Redistribute Motion 1:3 (slice2) (cost=0.00..1.03 rows=1 width=66) + -> Seq Scan on gp_id (cost=0.00..1.01 rows=1 width=66) + Optimizer: Postgres query optimizer (5 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.53 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (4 rows) explain SELECT * from multiset_5( TABLE (SELECT * FROM example ORDER BY a limit 10 ) ); - QUERY PLAN ------------------------------------------------------------------------------------------ - Table Function Scan on multiset_5 (cost=2.27..2.62 rows=80 width=36) - -> Limit (cost=2.27..2.49 rows=10 width=16) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.49 rows=5 width=16) + QUERY PLAN +------------------------------------------------------------------------------------------ + Table Function Scan on multiset_5 (cost=1.06..1.30 rows=10 width=36) + -> Limit (cost=1.06..1.20 rows=10 width=16) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.20 rows=10 width=16) Merge Key: example.a - -> Limit (cost=2.27..2.29 rows=5 width=16) - -> Sort (cost=2.27..2.29 rows=5 width=16) - Sort Key (Limit): example.a - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Limit (cost=1.06..1.07 rows=3 width=16) + -> Sort (cost=1.06..1.07 rows=3 width=16) + Sort Key: example.a + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (9 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example SCATTER BY a) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.53 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (4 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example SCATTER BY b) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..2.10 rows=5 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.60 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.20 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=3 width=16) Hash Key: example.b - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example SCATTER RANDOMLY) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..2.10 rows=5 width=16) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.60 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.20 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=3 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (5 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY a, b) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.42 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.42 rows=5 width=36) - -> Sort (cost=2.27..2.29 rows=5 width=16) + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.57 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.17 rows=10 width=36) + -> Sort (cost=1.06..1.07 rows=3 width=16) Sort Key: example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY a, b SCATTER BY a) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.42 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.42 rows=5 width=36) - -> Sort (cost=2.27..2.29 rows=5 width=16) + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.57 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.17 rows=10 width=36) + -> Sort (cost=1.06..1.07 rows=3 width=16) Sort Key: example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY b, a SCATTER BY b) ); QUERY PLAN ----------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.42 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.42 rows=5 width=36) - -> Sort (cost=2.27..2.29 rows=5 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.13..1.64 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.13..1.24 rows=10 width=36) + -> Sort (cost=1.13..1.14 rows=3 width=16) Sort Key: example.b, example.a - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..2.10 rows=5 width=16) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=3 width=16) Hash Key: example.b - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (8 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY b, a SCATTER RANDOMLY) ); QUERY PLAN ----------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.42 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.42 rows=5 width=36) - -> Sort (cost=2.27..2.29 rows=5 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.13..1.64 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.13..1.24 rows=10 width=36) + -> Sort (cost=1.13..1.14 rows=3 width=16) Sort Key: example.b, example.a - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..2.10 rows=5 width=16) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=3 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (7 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY a, b LIMIT 10 SCATTER BY a) ); - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.62 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.62 rows=5 width=36) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=2.27..2.49 rows=10 width=16) + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.84 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.44 rows=10 width=36) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.06..1.34 rows=3 width=16) Hash Key: example.a - -> Limit (cost=2.27..2.49 rows=10 width=16) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=2.27..2.49 rows=5 width=16) + -> Limit (cost=1.06..1.20 rows=10 width=16) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.06..1.20 rows=10 width=16) Merge Key: example.a, example.b - -> Limit (cost=2.27..2.29 rows=5 width=16) - -> Sort (cost=2.27..2.29 rows=5 width=16) - Sort Key (Limit): example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Limit (cost=1.06..1.07 rows=3 width=16) + -> Sort (cost=1.06..1.07 rows=3 width=16) + Sort Key: example.a, example.b + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (12 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY b, a LIMIT 10 SCATTER BY b) ); - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.62 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.62 rows=5 width=36) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=2.27..2.49 rows=10 width=16) + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.84 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.44 rows=10 width=36) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.06..1.34 rows=3 width=16) Hash Key: example.b - -> Limit (cost=2.27..2.49 rows=10 width=16) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=2.27..2.49 rows=5 width=16) + -> Limit (cost=1.06..1.20 rows=10 width=16) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.06..1.20 rows=10 width=16) Merge Key: example.b, example.a - -> Limit (cost=2.27..2.29 rows=5 width=16) - -> Sort (cost=2.27..2.29 rows=5 width=16) - Sort Key (Limit): example.b, example.a - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Limit (cost=1.06..1.07 rows=3 width=16) + -> Sort (cost=1.06..1.07 rows=3 width=16) + Sort Key: example.b, example.a + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (12 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY b, a LIMIT 10 SCATTER RANDOMLY) ); - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.62 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.62 rows=5 width=36) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=2.27..2.49 rows=10 width=16) - -> Limit (cost=2.27..2.49 rows=10 width=16) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=2.27..2.49 rows=5 width=16) + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.84 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.44 rows=10 width=36) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.06..1.34 rows=3 width=16) + -> Limit (cost=1.06..1.20 rows=10 width=16) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.06..1.20 rows=10 width=16) Merge Key: example.b, example.a - -> Limit (cost=2.27..2.29 rows=5 width=16) - -> Sort (cost=2.27..2.29 rows=5 width=16) - Sort Key (Limit): example.b, example.a - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Limit (cost=1.06..1.07 rows=3 width=16) + -> Sort (cost=1.06..1.07 rows=3 width=16) + Sort Key: example.b, example.a + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (11 rows) explain SELECT ARRAY(SELECT a FROM multiset_5( TABLE ( SELECT a, b from example)) order by a); - QUERY PLAN ------------------------------------------------------------------------------------------ - Result (cost=2.42..2.43 rows=1 width=0) + QUERY PLAN +------------------------------------------------------------------------------------------ + Result (cost=1.72..1.73 rows=1 width=32) InitPlan 1 (returns $0) (slice1) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=2.39..2.42 rows=5 width=4) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=1.30..1.72 rows=30 width=4) Merge Key: a - -> Sort (cost=2.39..2.42 rows=5 width=4) - Sort Key: multiset_5.a - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=4) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Sort (cost=1.30..1.32 rows=10 width=4) + Sort Key: a + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=4) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (9 rows) explain SELECT ARRAY(SELECT a FROM multiset_5( TABLE ( SELECT a, b from example order by a))); - QUERY PLAN ------------------------------------------------------------------------------------- - Result (cost=2.42..2.43 rows=1 width=0) + QUERY PLAN +------------------------------------------------------------------------------------- + Result (cost=1.57..1.58 rows=1 width=32) InitPlan 1 (returns $0) (slice1) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=2.27..2.42 rows=5 width=4) - -> Table Function Scan on multiset_5 (cost=2.27..2.42 rows=5 width=4) - -> Sort (cost=2.27..2.29 rows=5 width=16) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=1.06..1.57 rows=30 width=4) + -> Table Function Scan on multiset_5 (cost=1.06..1.17 rows=10 width=4) + -> Sort (cost=1.06..1.07 rows=3 width=16) Sort Key: example.a - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (8 rows) explain SELECT * FROM example where (a,b) in (select * from multiset_5( TABLE(SELECT a, b from example) )); - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=3.55..6.83 rows=10 width=16) - -> Hash Semi Join (cost=3.55..6.83 rows=4 width=16) - Hash Cond: example.a = a AND example.b = b - -> Seq Scan on example (cost=0.00..3.10 rows=4 width=16) - -> Hash (cost=3.40..3.40 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.40 rows=4 width=36) - Hash Key: a - -> Table Function Scan on multiset_5 (cost=0.00..3.20 rows=4 width=36) - -> Seq Scan on example example_1 (cost=0.00..3.10 rows=4 width=16) + QUERY PLAN +------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.08..2.66 rows=10 width=16) + -> Hash Right Semi Join (cost=1.08..2.53 rows=3 width=16) + Hash Cond: ((a = example.a) AND (b = example.b)) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.33 rows=10 width=36) + Hash Key: a + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example example_1 (cost=0.00..1.03 rows=3 width=16) + -> Hash (cost=1.03..1.03 rows=3 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (10 rows) explain SELECT * FROM example where (a,b) in (select * from multiset_5( TABLE(SELECT a, b from example scatter by b) )); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=3.55..6.83 rows=10 width=16) - -> Hash Semi Join (cost=3.55..6.83 rows=4 width=16) - Hash Cond: example.a = a AND example.b = b - -> Seq Scan on example (cost=0.00..3.10 rows=4 width=16) - -> Hash (cost=3.40..3.40 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.40 rows=4 width=36) - Hash Key: a - -> Table Function Scan on multiset_5 (cost=0.00..3.20 rows=4 width=36) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..3.10 rows=4 width=16) - Hash Key: example_1.b - -> Seq Scan on example example_1 (cost=0.00..3.10 rows=4 width=16) + QUERY PLAN +----------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=1.08..2.73 rows=10 width=16) + -> Hash Right Semi Join (cost=1.08..2.59 rows=3 width=16) + Hash Cond: ((a = example.a) AND (b = example.b)) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.40 rows=10 width=36) + Hash Key: a + -> Table Function Scan on multiset_5 (cost=0.00..1.20 rows=10 width=36) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.10 rows=3 width=16) + Hash Key: example_1.b + -> Seq Scan on example example_1 (cost=0.00..1.03 rows=3 width=16) + -> Hash (cost=1.03..1.03 rows=3 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (12 rows) explain SELECT * FROM multiset_5( TABLE(SELECT a, b from example)) where (a,b) in (select a,b from example); - QUERY PLAN ---------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=1.32..2.58 rows=4 width=36) - -> Hash Semi Join (cost=1.32..2.52 rows=1 width=36) - Hash Cond: ((a = example.a) AND (b = example.b)) - -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) - -> Seq Scan on example example_1 (cost=0.00..1.03 rows=3 width=16) - -> Hash (cost=1.17..1.17 rows=10 width=16) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.17 rows=10 width=16) - -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + QUERY PLAN +--------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=1.28..2.59 rows=4 width=36) + -> Hash Right Semi Join (cost=1.28..2.54 rows=1 width=36) + Hash Cond: ((example.a = a) AND (example.b = b)) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.17 rows=10 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + -> Hash (cost=1.13..1.13 rows=10 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example example_1 (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (9 rows) @@ -1821,107 +1821,107 @@ explain SELECT * FROM multiset_5( TABLE(SELECT a, b from example scatter by b)) (11 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * from example_r) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Seq Scan on example_r (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.53 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example_r (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (4 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * FROM example_r SCATTER by a||b) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.28 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..3.28 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.18 rows=4 width=16) - Hash Key: (example_r.a::text || example_r.b) - -> Seq Scan on example_r (cost=0.00..3.18 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.62 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.23 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.12 rows=3 width=48) + Hash Key: (((example_r.a)::text || example_r.b)) + -> Seq Scan on example_r (cost=0.00..1.06 rows=3 width=48) Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * FROM example_r SCATTER by b, a, a||b) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.28 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..3.28 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.18 rows=4 width=16) - Hash Key: example_r.b, example_r.a, (example_r.a::text || example_r.b) - -> Seq Scan on example_r (cost=0.00..3.18 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.62 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.23 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.12 rows=3 width=48) + Hash Key: example_r.b, example_r.a, (((example_r.a)::text || example_r.b)) + -> Seq Scan on example_r (cost=0.00..1.06 rows=3 width=48) Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * FROM example_r SCATTER RANDOMLY) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..2.10 rows=5 width=16) - -> Seq Scan on example_r (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.60 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.20 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=3 width=16) + -> Seq Scan on example_r (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (5 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example) ); QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.09..2.29 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.09..2.29 rows=4 width=36) - -> HashAggregate (cost=2.09..2.19 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.05..1.58 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.05..1.18 rows=10 width=36) + -> HashAggregate (cost=1.05..1.08 rows=3 width=16) Group Key: example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example SCATTER BY a) ); QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.09..2.29 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.09..2.29 rows=4 width=36) - -> HashAggregate (cost=2.09..2.19 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.05..1.58 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.05..1.18 rows=10 width=36) + -> HashAggregate (cost=1.05..1.08 rows=3 width=16) Group Key: example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a / 2, b FROM example SCATTER BY a / 2) ); QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.38..2.80 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.38..2.80 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.38..2.70 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.12..1.73 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.12..1.33 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.12..1.23 rows=3 width=16) Hash Key: ((example.a / 2)) - -> HashAggregate (cost=2.38..2.50 rows=4 width=16) + -> HashAggregate (cost=1.12..1.17 rows=3 width=16) Group Key: ((example.a / 2)), example.b - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..2.33 rows=4 width=16) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.11 rows=3 width=16) Hash Key: ((example.a / 2)), example.b - -> Seq Scan on example (cost=0.00..2.12 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.04 rows=3 width=16) Optimizer: Postgres query optimizer (10 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example SCATTER BY b) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.09..2.49 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.09..2.49 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.09..2.39 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.05..1.65 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.05..1.25 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.05..1.15 rows=3 width=16) Hash Key: example.b - -> HashAggregate (cost=2.09..2.19 rows=4 width=16) + -> HashAggregate (cost=1.05..1.08 rows=3 width=16) Group Key: example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (8 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example ORDER BY b, a SCATTER RANDOMLY) ); QUERY PLAN ----------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.62..2.74 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.62..2.74 rows=4 width=36) - -> Sort (cost=2.62..2.64 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.18..1.69 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.18..1.29 rows=10 width=36) + -> Sort (cost=1.18..1.19 rows=3 width=16) Sort Key: example.b, example.a - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.15..2.45 rows=4 width=16) - -> HashAggregate (cost=2.15..2.25 rows=4 width=16) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.05..1.15 rows=3 width=16) + -> HashAggregate (cost=1.05..1.08 rows=3 width=16) Group Key: example.b, example.a - -> Seq Scan on example (cost=0.00..2.10 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (9 rows) @@ -1941,28 +1941,28 @@ explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example ORDER explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example ORDER BY b, a SCATTER BY b) ); QUERY PLAN ----------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.62..2.74 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.62..2.74 rows=4 width=36) - -> Sort (cost=2.62..2.64 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.18..1.69 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.18..1.29 rows=10 width=36) + -> Sort (cost=1.18..1.19 rows=3 width=16) Sort Key: example.b, example.a - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.15..2.45 rows=4 width=16) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.05..1.15 rows=3 width=16) Hash Key: example.b - -> HashAggregate (cost=2.15..2.25 rows=4 width=16) + -> HashAggregate (cost=1.05..1.08 rows=3 width=16) Group Key: example.b, example.a - -> Seq Scan on example (cost=0.00..2.10 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (10 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example ORDER BY b, a LIMIT 2 SCATTER RANDOMLY) ); QUERY PLAN -------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=1.07..1.28 rows=9 width=36) - -> Table Function Scan on multiset_5 (cost=1.07..1.16 rows=3 width=36) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.07..1.13 rows=1 width=16) - -> Limit (cost=1.07..1.10 rows=2 width=16) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.07..1.16 rows=6 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.27 rows=9 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.15 rows=3 width=36) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.06..1.12 rows=1 width=16) + -> Limit (cost=1.06..1.09 rows=2 width=16) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.06..1.16 rows=6 width=16) Merge Key: example.b, example.a - -> Limit (cost=1.07..1.08 rows=2 width=16) + -> Limit (cost=1.06..1.08 rows=2 width=16) -> Unique (cost=1.06..1.09 rows=3 width=16) Group Key: example.b, example.a -> Sort (cost=1.06..1.07 rows=3 width=16) @@ -1974,72 +1974,72 @@ explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example ORDER explain SELECT * FROM multiset_5( TABLE( SELECT count(*)::integer, 'hello'::text from example_r ) ); QUERY PLAN ---------------------------------------------------------------------------------------- - Table Function Scan on multiset_5 (cost=3.16..3.18 rows=1 width=36) - -> Finalize Aggregate (cost=3.16..3.17 rows=1 width=36) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=3.12..3.15 rows=1 width=8) - -> Partial Aggregate (cost=3.12..3.13 rows=1 width=8) - -> Seq Scan on example_r (cost=0.00..3.10 rows=4 width=0) + Table Function Scan on multiset_5 (cost=1.10..1.12 rows=1 width=36) + -> Finalize Aggregate (cost=1.10..1.11 rows=1 width=36) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=1.04..1.09 rows=3 width=8) + -> Partial Aggregate (cost=1.04..1.05 rows=1 width=8) + -> Seq Scan on example_r (cost=0.00..1.03 rows=3 width=0) Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM example_r WHERE (10, 'hello') in (SELECT * FROM multiset_5( TABLE( SELECT count(*)::integer, 'hello'::text from example_r ))); QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.10 rows=5 width=16) - -> Seq Scan on example_r (cost=0.00..3.10 rows=2 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.10 rows=5 width=16) + -> Seq Scan on example_r (cost=0.00..1.03 rows=2 width=16) Filter: (hashed SubPlan 1) SubPlan 1 - -> Broadcast Motion 1:3 (slice2) (cost=3.16..3.18 rows=1 width=36) - -> Table Function Scan on multiset_5 (cost=3.16..3.18 rows=1 width=36) - -> Finalize Aggregate (cost=3.16..3.17 rows=1 width=36) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=3.12..3.15 rows=1 width=8) - -> Partial Aggregate (cost=3.12..3.13 rows=1 width=8) - -> Seq Scan on example_r example_r_1 (cost=0.00..3.10 rows=4 width=0) + -> Broadcast Motion 1:3 (slice2) (cost=1.10..1.12 rows=1 width=36) + -> Table Function Scan on multiset_5 (cost=1.10..1.12 rows=1 width=36) + -> Finalize Aggregate (cost=1.10..1.11 rows=1 width=36) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.04..1.09 rows=3 width=8) + -> Partial Aggregate (cost=1.04..1.05 rows=1 width=8) + -> Seq Scan on example_r example_r_1 (cost=0.00..1.03 rows=3 width=0) Optimizer: Postgres query optimizer (11 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * from example_v) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.53 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (4 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * FROM example WHERE a >= (SELECT min(a) FROM example))); QUERY PLAN ------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.17..4.33 rows=4 width=36) - -> Table Function Scan on multiset_5 (cost=2.17..4.33 rows=2 width=36) - -> Seq Scan on example (cost=2.17..4.29 rows=2 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.11..2.32 rows=10 width=36) + -> Table Function Scan on multiset_5 (cost=1.11..2.18 rows=3 width=36) + -> Seq Scan on example (cost=1.11..2.15 rows=1 width=16) Filter: (a >= $0) InitPlan 1 (returns $0) (slice2) - -> Finalize Aggregate (cost=2.16..2.17 rows=1 width=4) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=2.12..2.15 rows=1 width=4) - -> Partial Aggregate (cost=2.12..2.13 rows=1 width=4) - -> Seq Scan on example example_1 (cost=0.00..2.10 rows=4 width=4) + -> Finalize Aggregate (cost=1.10..1.11 rows=1 width=4) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.04..1.09 rows=3 width=4) + -> Partial Aggregate (cost=1.04..1.05 rows=1 width=4) + -> Seq Scan on example example_1 (cost=0.00..1.03 rows=3 width=4) Optimizer: Postgres query optimizer (10 rows) explain WITH cte AS (SELECT * FROM example) SELECT * FROM multiset_5( TABLE ( SELECT * FROM cte ) ) order by a, b; - QUERY PLAN ----------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.39..2.42 rows=5 width=36) + QUERY PLAN +----------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=1.30..1.72 rows=30 width=36) Merge Key: a, b - -> Sort (cost=2.39..2.42 rows=5 width=36) - Sort Key: multiset_5.a, multiset_5.b - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Sort (cost=1.30..1.32 rows=10 width=36) + Sort Key: a, b + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (7 rows) explain WITH cte AS (SELECT * FROM example) SELECT x.* FROM multiset_5( TABLE ( SELECT * FROM cte ) ) x, (SELECT count(*) FROM cte) y order by x.a, x.b; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=10000000004.89..10000000005.12 rows=10 width=36) + QUERY PLAN +---------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=10000000002.39..10000000002.53 rows=10 width=36) Merge Key: a, b - -> Sort (cost=10000000004.89..10000000004.92 rows=4 width=36) + -> Sort (cost=10000000002.39..10000000002.39 rows=3 width=36) Sort Key: a, b -> Nested Loop (cost=10000000001.08..10000000002.36 rows=3 width=36) -> Broadcast Motion 1:3 (slice2; segments: 1) (cost=1.08..1.12 rows=1 width=0) @@ -2057,81 +2057,81 @@ explain WITH cte AS (SELECT * FROM example) SELECT x.* FROM multiset_5( TABLE ( explain select * from multiset_2( TABLE( SELECT distinct a.a, b.b from example a, example b where a.a = b.a) ) order by 1,2; QUERY PLAN ---------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=8.19..8.26 rows=30 width=36) + Gather Motion 3:1 (slice1; segments: 3) (cost=3.41..4.68 rows=90 width=36) Merge Key: a, b - -> Sort (cost=8.19..8.26 rows=10 width=36) + -> Sort (cost=3.41..3.48 rows=30 width=36) Sort Key: a, b - -> Table Function Scan on multiset_2 (cost=6.85..7.45 rows=10 width=36) - -> HashAggregate (cost=6.85..7.15 rows=10 width=36) + -> Table Function Scan on multiset_2 (cost=2.27..2.67 rows=30 width=36) + -> HashAggregate (cost=2.27..2.37 rows=10 width=16) Group Key: a.a, b.b - -> Hash Join (cost=3.23..6.70 rows=11 width=16) - Hash Cond: a.a = b.a - -> Seq Scan on example a (cost=0.00..3.10 rows=4 width=4) - -> Hash (cost=3.10..3.10 rows=4 width=16) - -> Seq Scan on example b (cost=0.00..3.10 rows=4 width=16) + -> Hash Join (cost=1.08..2.22 rows=10 width=16) + Hash Cond: (a.a = b.a) + -> Seq Scan on example a (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.03..1.03 rows=3 width=16) + -> Seq Scan on example b (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (13 rows) explain select * from multiset_2( TABLE( SELECT distinct a.a, b.b from example a join example b using (a) ) ) order by 1,2; QUERY PLAN ---------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=8.19..8.26 rows=30 width=36) + Gather Motion 3:1 (slice1; segments: 3) (cost=3.41..4.68 rows=90 width=36) Merge Key: a, b - -> Sort (cost=8.19..8.26 rows=10 width=36) + -> Sort (cost=3.41..3.48 rows=30 width=36) Sort Key: a, b - -> Table Function Scan on multiset_2 (cost=6.85..7.45 rows=10 width=36) - -> HashAggregate (cost=6.85..7.15 rows=10 width=36) + -> Table Function Scan on multiset_2 (cost=2.27..2.67 rows=30 width=36) + -> HashAggregate (cost=2.27..2.37 rows=10 width=16) Group Key: a.a, b.b - -> Hash Join (cost=3.23..6.70 rows=11 width=16) - Hash Cond: a.a = b.a - -> Seq Scan on example a (cost=0.00..3.10 rows=4 width=4) - -> Hash (cost=3.10..3.10 rows=4 width=16) - -> Seq Scan on example b (cost=0.00..3.10 rows=4 width=16) + -> Hash Join (cost=1.08..2.22 rows=10 width=16) + Hash Cond: (a.a = b.a) + -> Seq Scan on example a (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.03..1.03 rows=3 width=16) + -> Seq Scan on example b (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (13 rows) explain select * from multiset_2( TABLE ( SELECT * FROM example WHERE a = 2 ) ) WHERE a = 2; QUERY PLAN ----------------------------------------------------------------------------- - Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..2.17 rows=1 width=36) - -> Table Function Scan on multiset_2 (cost=0.00..2.17 rows=1 width=36) - Filter: a = 2 - -> Seq Scan on example (cost=0.00..2.12 rows=2 width=16) - Filter: a = 2 - Settings: gp_segments_for_planner=8 + Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..1.10 rows=1 width=36) + -> Table Function Scan on multiset_2 (cost=0.00..1.08 rows=1 width=36) + Filter: (a = 2) + -> Seq Scan on example (cost=0.00..1.04 rows=1 width=16) + Filter: (a = 2) + Optimizer: Postgres query optimizer (6 rows) -- Not rescannable, should produce materialize node explain SELECT x.* FROM multiset_5( TABLE ( SELECT 1 ) ) x right join (SELECT 1) y on (true); QUERY PLAN ------------------------------------------------------------------------------------ - Nested Loop Left Join (cost=0.03..1.33 rows=27 width=36) + Nested Loop Left Join (cost=10000000000.00..10000000000.04 rows=3 width=36) -> Result (cost=0.00..0.01 rows=1 width=0) - -> Materialize (cost=0.03..0.11 rows=4 width=36) - -> Table Function Scan on multiset_5 x (cost=0.00..0.02 rows=8 width=36) - -> Result (cost=0.00..0.01 rows=1 width=0) - Settings: gp_segments_for_planner=8 + -> Materialize (cost=0.00..0.03 rows=1 width=36) + -> Table Function Scan on multiset_5 x (cost=0.00..0.02 rows=1 width=36) + -> Result (cost=0.00..0.01 rows=1 width=4) + Optimizer: Postgres query optimizer (6 rows) -- Do an explain analyze while we are at it: explain analyze SELECT * FROM multiset_5( TABLE( SELECT count(*)::integer, 'hello'::text from example_r scatter randomly) ); - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=3.16..3.22 rows=1 width=36) (actual time=1.893..2.348 rows=1 loops=1) - -> Table Function Scan on multiset_5 (cost=3.16..3.20 rows=1 width=36) (actual time=1.553..1.557 rows=1 loops=1) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=3.16..3.19 rows=1 width=36) (actual time=1.539..1.540 rows=1 loops=1) - -> Finalize Aggregate (cost=3.16..3.17 rows=1 width=36) (actual time=1.146..1.147 rows=1 loops=1) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=3.12..3.15 rows=1 width=8) (actual time=0.872..1.133 rows=3 loops=1) - -> Partial Aggregate (cost=3.12..3.13 rows=1 width=8) (actual time=0.054..0.054 rows=1 loops=1) - -> Seq Scan on example_r (cost=0.00..3.10 rows=4 width=0) (actual time=0.044..0.046 rows=4 loops=1) - Planning time: 0.533 ms - (slice0) Executor memory: 127K bytes. - (slice1) Executor memory: 35K bytes avg x 3 workers, 40K bytes max (seg0). - (slice2) Executor memory: 63K bytes (seg0). - (slice3) Executor memory: 70K bytes avg x 3 workers, 92K bytes max (seg0). + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=1.10..1.28 rows=9 width=36) (actual time=19.775..19.778 rows=1 loops=1) + -> Table Function Scan on multiset_5 (cost=1.10..1.16 rows=3 width=36) (actual time=19.269..19.272 rows=1 loops=1) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.10..1.13 rows=1 width=36) (actual time=19.263..19.264 rows=1 loops=1) + -> Finalize Aggregate (cost=1.10..1.11 rows=1 width=36) (actual time=11.021..11.022 rows=1 loops=1) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.04..1.09 rows=3 width=8) (actual time=0.003..11.005 rows=3 loops=1) + -> Partial Aggregate (cost=1.04..1.05 rows=1 width=8) (actual time=2.788..2.789 rows=1 loops=1) + -> Seq Scan on example_r (cost=0.00..1.03 rows=3 width=0) (actual time=2.768..2.782 rows=5 loops=1) + Planning Time: 0.203 ms + (slice0) Executor memory: 37K bytes. + (slice1) Executor memory: 10K bytes avg x 3x(0) workers, 10K bytes max (seg0). + (slice2) Executor memory: 118K bytes (seg2). + (slice3) Executor memory: 120K bytes avg x 3x(0) workers, 120K bytes max (seg2). Memory used: 128000kB Optimizer: Postgres query optimizer - Execution time: 3.194 ms + Execution Time: 29.203 ms (15 rows) -- Test for an old bug in aggregate planning - this used to crash. @@ -2378,9 +2378,9 @@ explain SELECT *, generate_series(1,2) FROM multi_args( TABLE(SELECT 1::int, 'he explain SELECT * FROM multi_args( TABLE(SELECT 1::int, 'hello'::text), 2); QUERY PLAN ---------------------------------------------------------------------- - Table Function Scan on multi_args (cost=0.00..0.02 rows=8 width=36) - -> Result (cost=0.00..0.01 rows=1 width=0) - Settings: gp_segments_for_planner=8 + Table Function Scan on multi_args (cost=0.00..0.02 rows=1 width=36) + -> Result (cost=0.00..0.01 rows=1 width=36) + Optimizer: Postgres query optimizer (3 rows) -- Error: don't support sets as arguments that are not TableValueExpr @@ -2394,11 +2394,11 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'a' HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. QUERY PLAN ----------------------------------------------------------------------------------- - Redistribute Motion 1:3 (slice1; segments: 1) (cost=0.00..0.02 rows=8 width=36) - Hash Key: a - -> Table Function Scan on multi_args (cost=0.00..0.02 rows=8 width=36) - -> Result (cost=0.00..0.01 rows=1 width=0) - Settings: gp_segments_for_planner=8 + Redistribute Motion 1:3 (slice1; segments: 1) (cost=0.00..0.04 rows=1 width=36) + Hash Key: multi_args.a + -> Table Function Scan on multi_args (cost=0.00..0.02 rows=1 width=36) + -> Result (cost=0.00..0.01 rows=1 width=36) + Optimizer: Postgres query optimizer (5 rows) CREATE TABLE example_out AS SELECT * FROM multi_args( TABLE(SELECT 1::int, 'hello'::text), 2); @@ -2434,6 +2434,7 @@ SELECT * FROM multiset_5( TABLE( SELECT 1::integer, 'hello'::text) ) as tf; -- start_ignore -- These may have been created by previous test create language plpython3u; +ERROR: extension "plpython3u" already exists -- end_ignore CREATE FUNCTION tf_sql(anytable) returns int AS $$ SELECT 1 $$ language sql CONTAINS SQL; ERROR: SQL functions cannot have arguments of type anytable @@ -2988,14 +2989,14 @@ SELECT * FROM project( TABLE( SELECT * FROM pg_am WHERE amname not in ('pax') ), amname ----------- heap - ao_row - ao_column btree hash gist gin spgist brin + ao_row + ao_column bitmap heap2 (11 rows) @@ -3005,14 +3006,14 @@ SELECT * FROM project( TABLE( SELECT * FROM pg_am WHERE amname not in ('pax') ), amname ----------- heap - ao_row - ao_column btree hash gist gin spgist brin + ao_row + ao_column bitmap heap2 (11 rows) @@ -3027,7 +3028,7 @@ SELECT "time"+1 FROM project( TABLE( SELECT * FROM history ), 2); ERROR: operator does not exist: timestamp without time zone + integer LINE 1: SELECT "time"+1 FROM project( TABLE( SELECT * FROM history )... ^ -HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. +HINT: No operator matches the given name and argument types. You might need to add explicit type casts. -- ERROR: select columns projected out by the function SELECT id FROM project( TABLE( SELECT * FROM history ), 2); ERROR: column "id" does not exist @@ -3096,13 +3097,9 @@ CREATE FUNCTION noop_project(anytable) RETURNS setof RECORD SELECT * FROM noop_project( TABLE( SELECT * FROM history ) ) AS s (id integer, time timestamp); id | time ----+-------------------------- - 1 | Mon Aug 22 10:15:04 2011 - 1 | Mon Aug 22 10:16:10 2011 - 1 | Sun Aug 21 10:15:02 2011 - 1 | Sun Aug 21 10:15:30 2011 2 | Sun Aug 21 10:15:02 2011 - 2 | Sun Aug 21 10:16:02 2011 2 | Sun Aug 21 22:15:02 2011 + 2 | Sun Aug 21 10:16:02 2011 2 | Sun Aug 21 22:16:02 2011 3 | Fri Aug 19 19:05:13 2011 3 | Fri Aug 19 19:06:50 2011 @@ -3114,6 +3111,10 @@ SELECT * FROM noop_project( TABLE( SELECT * FROM history ) ) AS s (id integer, t 3 | Sat Aug 20 10:11:29 2011 3 | Sat Aug 20 10:17:10 2011 3 | Sat Aug 20 10:17:42 2011 + 1 | Sun Aug 21 10:15:02 2011 + 1 | Sun Aug 21 10:15:30 2011 + 1 | Mon Aug 22 10:15:04 2011 + 1 | Mon Aug 22 10:16:10 2011 (18 rows) -- SCATTER BY vs MEDIAN @@ -3139,6 +3140,7 @@ SELECT * FROM noop_project( TABLE( SELECT count(*) FROM history GROUP BY time SC cnt ----- 1 + 2 1 1 1 @@ -3154,7 +3156,6 @@ SELECT * FROM noop_project( TABLE( SELECT count(*) FROM history GROUP BY time SC 1 1 1 - 2 (17 rows) -- ======================== diff --git a/src/backend/cdb/cdbpath.c b/src/backend/cdb/cdbpath.c index 1f835283dcc..c8a9896f861 100644 --- a/src/backend/cdb/cdbpath.c +++ b/src/backend/cdb/cdbpath.c @@ -1469,7 +1469,13 @@ cdbpath_motion_for_join(PlannerInfo *root, outer.ok_to_replicate = false; break; case JOIN_RIGHT: + case JOIN_RIGHT_SEMI: case JOIN_RIGHT_ANTI: + /* + * GPDB: A right-semi join emits inner (build-side) rows, so just + * like JOIN_RIGHT/JOIN_RIGHT_ANTI the inner side must not be + * replicated, or matched inner rows could be emitted more than once. + */ inner.ok_to_replicate = false; break; case JOIN_FULL: @@ -3220,6 +3226,7 @@ cdbpath_motion_for_parallel_join(PlannerInfo *root, case JOIN_UNIQUE_OUTER: case JOIN_UNIQUE_INNER: case JOIN_RIGHT: + case JOIN_RIGHT_SEMI: case JOIN_RIGHT_ANTI: case JOIN_FULL: outer.ok_to_replicate = false; diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index cb00fea9fdf..b268cf7fe22 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -2183,6 +2183,9 @@ ExplainNode(PlanState *planstate, List *ancestors, case JOIN_LASJ_NOTIN: jointype = "Left Anti Semi (Not-In)"; break; + case JOIN_RIGHT_SEMI: + jointype = "Right Semi"; + break; case JOIN_RIGHT_ANTI: jointype = "Right Anti"; break; diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c index f9b2f957021..1bc4ab5b130 100644 --- a/src/backend/executor/nodeHashjoin.c +++ b/src/backend/executor/nodeHashjoin.c @@ -688,6 +688,14 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel) } } + /* + * In a right-semijoin, we only need the first match for each + * inner tuple. + */ + if (node->js.jointype == JOIN_RIGHT_SEMI && + HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple))) + continue; + /* * We've got a match, but still need to test non-hashed quals. * ExecScanHashBucket already set up all the state needed to @@ -704,10 +712,10 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel) { node->hj_MatchedOuter = true; - /* - * This is really only needed if HJ_FILL_INNER(node), but - * we'll avoid the branch and just set it always. + * This is really only needed if HJ_FILL_INNER(node) or if + * we are in a right-semijoin, but we'll avoid the branch + * and just set it always. */ if (!HeapTupleHeaderHasMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple))) HeapTupleHeaderSetMatch(HJTUPLE_MINTUPLE(node->hj_CurTuple)); @@ -1024,6 +1032,7 @@ ExecInitHashJoin(HashJoin *node, EState *estate, int eflags) { case JOIN_INNER: case JOIN_SEMI: + case JOIN_RIGHT_SEMI: break; case JOIN_LEFT: case JOIN_ANTI: @@ -1792,10 +1801,11 @@ ExecReScanHashJoin(HashJoinState *node) /* * Okay to reuse the hash table; needn't rescan inner, either. * - * However, if it's a right/right-anti/full join, we'd better - * reset the inner-tuple match flags contained in the table. + * However, if it's a right/right-anti/right-semi/full join, we'd + * better reset the inner-tuple match flags contained in the + * table. */ - if (HJ_FILL_INNER(node)) + if (HJ_FILL_INNER(node) || node->js.jointype == JOIN_RIGHT_SEMI) ExecHashTableResetMatchFlags(node->hj_HashTable); /* diff --git a/src/backend/gpopt/config/CConfigParamMapping.cpp b/src/backend/gpopt/config/CConfigParamMapping.cpp index 5bd9091f604..1e27578df6a 100644 --- a/src/backend/gpopt/config/CConfigParamMapping.cpp +++ b/src/backend/gpopt/config/CConfigParamMapping.cpp @@ -442,6 +442,15 @@ CConfigParamMapping::PackConfigParamInBitset( hash_join_bitste->Release(); } + // disable right semi/anti hash join (Mark Join) xforms if the GUC is off + if (!optimizer_enable_right_semi_join) + { + traceflag_bitset->ExchangeSet( + GPOPT_DISABLE_XFORM_TF(CXform::ExfLeftSemiJoin2RightSemiHashJoin)); + traceflag_bitset->ExchangeSet(GPOPT_DISABLE_XFORM_TF( + CXform::ExfLeftAntiSemiJoin2RightAntiSemiHashJoin)); + } + if (!optimizer_enable_dynamictablescan) { // disable dynamic table scan if the corresponding GUC is turned off diff --git a/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp b/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp index 8b7898cc103..a0819705488 100644 --- a/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp +++ b/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp @@ -1559,6 +1559,24 @@ CTranslatorDXLToPlStmt::TranslateDXLHashJoin( // translate join children CDXLNode *left_tree_dxlnode = (*hj_dxlnode)[EdxlhjIndexHashLeft]; CDXLNode *right_tree_dxlnode = (*hj_dxlnode)[EdxlhjIndexHashRight]; + + // For JOIN_RIGHT_SEMI / JOIN_RIGHT_ANTI the GPDB executor builds the hash + // table on the inner (right) child and emits inner-side rows, but ORCA + // places the semantically-preserved LHS as the DXL left child. Swap which + // DXL child becomes the executor's outer (probe) vs inner (build/Hash) so + // that the LHS ends up as the inner -- mirroring the PostgreSQL planner, + // which generates JOIN_RIGHT_SEMI with inner = LHS. OUTER_VAR/INNER_VAR + // assignment follows the child-context order (context[0] -> OUTER_VAR, + // context[1] -> INNER_VAR), so the target list, quals and hash clauses are + // remapped automatically; the outer/inner hash-key extraction below is + // also swapped to match. + BOOL fSwapBuildSide = (join->jointype == JOIN_RIGHT_SEMI || + join->jointype == JOIN_RIGHT_ANTI); + CDXLNode *outer_tree_dxlnode = + fSwapBuildSide ? right_tree_dxlnode : left_tree_dxlnode; + CDXLNode *inner_tree_dxlnode = + fSwapBuildSide ? left_tree_dxlnode : right_tree_dxlnode; + CDXLNode *project_list_dxlnode = (*hj_dxlnode)[EdxlhjIndexProjList]; CDXLNode *filter_dxlnode = (*hj_dxlnode)[EdxlhjIndexFilter]; CDXLNode *join_filter_dxlnode = (*hj_dxlnode)[EdxlhjIndexJoinFilter]; @@ -1570,7 +1588,7 @@ CTranslatorDXLToPlStmt::TranslateDXLHashJoin( m_mp, false, output_context->GetColIdToParamIdMap()); Plan *left_plan = - TranslateDXLOperatorToPlan(left_tree_dxlnode, &left_dxl_translate_ctxt, + TranslateDXLOperatorToPlan(outer_tree_dxlnode, &left_dxl_translate_ctxt, ctxt_translation_prev_siblings); // the right side of the join is the one where the hash phase is done @@ -1580,9 +1598,16 @@ CTranslatorDXLToPlStmt::TranslateDXLHashJoin( translation_context_arr_with_siblings->AppendArray( ctxt_translation_prev_siblings); Plan *right_plan = - (Plan *) TranslateDXLHash(right_tree_dxlnode, &right_dxl_translate_ctxt, + (Plan *) TranslateDXLHash(inner_tree_dxlnode, &right_dxl_translate_ctxt, translation_context_arr_with_siblings); + // INVARIANT: child_contexts[0] must hold the context of the plan's outer + // (left) child and [1] the inner (right) child, because OUTER_VAR/INNER_VAR + // are assigned by this order. left_dxl_translate_ctxt was populated from + // outer_tree_dxlnode and right_dxl_translate_ctxt from inner_tree_dxlnode + // (both already swapped when fSwapBuildSide), so this order is correct for + // JOIN_RIGHT_SEMI/ANTI as well. Do not reorder these appends without also + // reordering the TranslateDXL* calls above. CDXLTranslationContextArray *child_contexts = GPOS_NEW(m_mp) CDXLTranslationContextArray(m_mp); child_contexts->Append(&left_dxl_translate_ctxt); @@ -1740,8 +1765,26 @@ CTranslatorDXLToPlStmt::TranslateDXLHashJoin( hashoperators = gpdb::LAppendOid(hashoperators, hclause->opno); hashcollations = gpdb::LAppendOid(hashcollations, hclause->inputcollid); - outer_hashkeys = gpdb::LAppend(outer_hashkeys, linitial(hclause->args)); - inner_hashkeys = gpdb::LAppend(inner_hashkeys, lsecond(hclause->args)); + // Hash clauses are built as (DXL-left-key OP DXL-right-key). Normally + // DXL-left is the outer child, so linitial is the outer key. When the + // build side is swapped (JOIN_RIGHT_SEMI / JOIN_RIGHT_ANTI), the DXL + // left child became the executor's inner and the right child the + // outer, so the outer/inner hash keys must be taken from the opposite + // operands to stay consistent with the swapped lefttree/righttree. + if (fSwapBuildSide) + { + outer_hashkeys = + gpdb::LAppend(outer_hashkeys, lsecond(hclause->args)); + inner_hashkeys = + gpdb::LAppend(inner_hashkeys, linitial(hclause->args)); + } + else + { + outer_hashkeys = + gpdb::LAppend(outer_hashkeys, linitial(hclause->args)); + inner_hashkeys = + gpdb::LAppend(inner_hashkeys, lsecond(hclause->args)); + } } hashjoin->hashoperators = hashoperators; @@ -6778,6 +6821,12 @@ CTranslatorDXLToPlStmt::GetGPDBJoinTypeFromDXLJoinType(EdxlJoinType join_type) case EdxljtLeftAntiSemijoinNotIn: jt = JOIN_LASJ_NOTIN; break; + case EdxljtRightSemijoin: + jt = JOIN_RIGHT_SEMI; + break; + case EdxljtRightAntiSemijoin: + jt = JOIN_RIGHT_ANTI; + break; default: GPOS_ASSERT(!"Unrecognized join type"); } diff --git a/src/backend/gpopt/translate/CTranslatorUtils.cpp b/src/backend/gpopt/translate/CTranslatorUtils.cpp index 221f295df52..648d8cfdceb 100644 --- a/src/backend/gpopt/translate/CTranslatorUtils.cpp +++ b/src/backend/gpopt/translate/CTranslatorUtils.cpp @@ -702,6 +702,14 @@ CTranslatorUtils::ConvertToDXLJoinType(JoinType jt) join_type = EdxljtLeftAntiSemijoinNotIn; break; + case JOIN_RIGHT_SEMI: + join_type = EdxljtRightSemijoin; + break; + + case JOIN_RIGHT_ANTI: + join_type = EdxljtRightAntiSemijoin; + break; + default: GPOS_ASSERT(!"Unrecognized join type"); } diff --git a/src/backend/gporca/libgpdbcost/include/gpdbcost/CCostModelGPDB.h b/src/backend/gporca/libgpdbcost/include/gpdbcost/CCostModelGPDB.h index 7db2cdbbdd1..95ccbc97804 100644 --- a/src/backend/gporca/libgpdbcost/include/gpdbcost/CCostModelGPDB.h +++ b/src/backend/gporca/libgpdbcost/include/gpdbcost/CCostModelGPDB.h @@ -178,6 +178,21 @@ class CCostModelGPDB : public ICostModel const CCostModelGPDB *pcmgpdb, const SCostingInfo *pci); + // cost of right semi hash join (Mark Join): build = outer/LHS, probe = + // inner/RHS, finalize emits LHS rows with at least one match. Reuses the + // CostHashJoin formula with the build/probe input roles swapped. + static CCost CostRightSemiHashJoin(CMemoryPool *mp, + CExpressionHandle &exprhdl, + const CCostModelGPDB *pcmgpdb, + const SCostingInfo *pci); + + // cost of right anti semi hash join (build = outer/LHS, emit unmatched + // build rows). Same skeleton as CostRightSemiHashJoin. + static CCost CostRightAntiSemiHashJoin(CMemoryPool *mp, + CExpressionHandle &exprhdl, + const CCostModelGPDB *pcmgpdb, + const SCostingInfo *pci); + // cost of merge join static CCost CostMergeJoin(CMemoryPool *mp, CExpressionHandle &exprhdl, const CCostModelGPDB *pcmgpdb, diff --git a/src/backend/gporca/libgpdbcost/src/CCostModelGPDB.cpp b/src/backend/gporca/libgpdbcost/src/CCostModelGPDB.cpp index 575f6473ff0..bb88c134c26 100644 --- a/src/backend/gporca/libgpdbcost/src/CCostModelGPDB.cpp +++ b/src/backend/gporca/libgpdbcost/src/CCostModelGPDB.cpp @@ -1239,6 +1239,164 @@ CCostModelGPDB::CostMergeJoin(CMemoryPool *mp, CExpressionHandle &exprhdl, } +// @function: +// CCostModelGPDB::CostRightSemiHashJoin +// +// @doc: +// Cost of right semi hash join (PG-style: build = outer/left, probe = +// inner/right, finalize emits left rows that have at least one match). +// Reuses CostHashJoin formula with child[0]/child[1] roles swapped, then +// adds a finalize-phase scan term. Also used by CostRightAntiSemiHashJoin +// (the build/probe cost is identical), so the operator may be either the +// right-semi or the right-anti-semi hash join. +// +//--------------------------------------------------------------------------- +CCost +CCostModelGPDB::CostRightSemiHashJoin(CMemoryPool *mp, + CExpressionHandle &exprhdl, + const CCostModelGPDB *pcmgpdb, + const SCostingInfo *pci) +{ + GPOS_ASSERT(nullptr != pcmgpdb); + GPOS_ASSERT(nullptr != pci); + GPOS_ASSERT(COperator::EopPhysicalRightSemiHashJoin == + exprhdl.Pop()->Eopid() || + COperator::EopPhysicalRightAntiSemiHashJoin == + exprhdl.Pop()->Eopid()); + + // + // RIGHT_SEMI cost: build = outer (PG LHS, child 0), probe = inner + // (PG RHS, child 1). This is the inverse of CostHashJoin which + // builds on child 1. We mirror the spill / no-spill formulas from + // CostHashJoin verbatim, just feeding the swapped rows / widths. + // + const DOUBLE dRowsBuild = pci->PdRows()[0]; // outer = build + const DOUBLE dWidthBuild = pci->GetWidth()[0]; + const DOUBLE dRowsProbe = pci->PdRows()[1]; // inner = probe + const DOUBLE dWidthProbe = pci->GetWidth()[1]; + + const CDouble dHJHashTableInitCostFactor = + pcmgpdb->GetCostModelParams() + ->PcpLookup(CCostModelParamsGPDB::EcpHJHashTableInitCostFactor) + ->Get(); + const CDouble dHJHashTableColumnCostUnit = + pcmgpdb->GetCostModelParams() + ->PcpLookup(CCostModelParamsGPDB::EcpHJHashTableColumnCostUnit) + ->Get(); + const CDouble dHJHashTableWidthCostUnit = + pcmgpdb->GetCostModelParams() + ->PcpLookup(CCostModelParamsGPDB::EcpHJHashTableWidthCostUnit) + ->Get(); + const CDouble dJoinFeedingTupColumnCostUnit = + pcmgpdb->GetCostModelParams() + ->PcpLookup(CCostModelParamsGPDB::EcpJoinFeedingTupColumnCostUnit) + ->Get(); + const CDouble dJoinFeedingTupWidthCostUnit = + pcmgpdb->GetCostModelParams() + ->PcpLookup(CCostModelParamsGPDB::EcpJoinFeedingTupWidthCostUnit) + ->Get(); + const CDouble dHJHashingTupWidthCostUnit = + pcmgpdb->GetCostModelParams() + ->PcpLookup(CCostModelParamsGPDB::EcpHJHashingTupWidthCostUnit) + ->Get(); + const CDouble dJoinOutputTupCostUnit = + pcmgpdb->GetCostModelParams() + ->PcpLookup(CCostModelParamsGPDB::EcpJoinOutputTupCostUnit) + ->Get(); + const CDouble dHJSpillingMemThreshold = + pcmgpdb->GetCostModelParams() + ->PcpLookup(CCostModelParamsGPDB::EcpHJSpillingMemThreshold) + ->Get(); + const CDouble dHJFeedingTupColumnSpillingCostUnit = + pcmgpdb->GetCostModelParams() + ->PcpLookup( + CCostModelParamsGPDB::EcpHJFeedingTupColumnSpillingCostUnit) + ->Get(); + const CDouble dHJFeedingTupWidthSpillingCostUnit = + pcmgpdb->GetCostModelParams() + ->PcpLookup( + CCostModelParamsGPDB::EcpHJFeedingTupWidthSpillingCostUnit) + ->Get(); + const CDouble dHJHashingTupWidthSpillingCostUnit = + pcmgpdb->GetCostModelParams() + ->PcpLookup( + CCostModelParamsGPDB::EcpHJHashingTupWidthSpillingCostUnit) + ->Get(); + + CExpression *pexprJoinCond = exprhdl.PexprScalarRepChild(2); + CColRefSet *pcrsUsed = pexprJoinCond->DeriveUsedColumns(); + const ULONG ulColsUsed = pcrsUsed->Size(); + + CCost costLocal(0); + + if (dRowsBuild * dWidthBuild <= dHJSpillingMemThreshold) + { + // build fits in memory + costLocal = CCost( + pci->NumRebinds() * + (dRowsBuild * (ulColsUsed * dHJHashTableColumnCostUnit + + dWidthBuild * dHJHashTableWidthCostUnit) + + ulColsUsed * dRowsProbe * dJoinFeedingTupColumnCostUnit + + dWidthProbe * dRowsProbe * dJoinFeedingTupWidthCostUnit + + dWidthBuild * dRowsBuild * dHJHashingTupWidthCostUnit + + pci->Rows() * pci->Width() * dJoinOutputTupCostUnit)); + } + else + { + // build spills -- same base spill formula as CostHashJoin with the + // build/probe roles swapped. We deliberately do NOT add an extra + // asymmetric IO penalty here (unlike the Lightning vec variant): the + // base build-hashing terms already make a smaller build cheaper, so + // RIGHT_SEMI vs LEFT_SEMI is compared fairly on the same formula + // without globally perturbing CostHashJoin for all other joins. + costLocal = CCost( + pci->NumRebinds() * + (dHJHashTableInitCostFactor + + dRowsBuild * (ulColsUsed * dHJHashTableColumnCostUnit + + dWidthBuild * dHJHashTableWidthCostUnit) + + ulColsUsed * dRowsProbe * dHJFeedingTupColumnSpillingCostUnit + + dWidthProbe * dRowsProbe * dHJFeedingTupWidthSpillingCostUnit + + dWidthBuild * dRowsBuild * dHJHashingTupWidthSpillingCostUnit + + pci->Rows() * pci->Width() * dJoinOutputTupCostUnit)); + } + + CCost costChild = + CostChildren(mp, exprhdl, pci, pcmgpdb->GetCostModelParams()); + (void) mp; + return costChild + costLocal; +} + + +//--------------------------------------------------------------------------- +// @function: +// CCostModelGPDB::CostRightAntiSemiHashJoin +// +// @doc: +// Cost of right anti semi hash join (build = outer/left, emit unvisited). +// Same skeleton as RightSemi; finalize accounts for build_rows minus +// matched_rows (estimated from pci->Rows() which is the relation-level +// semantic output i.e. matched count). +// +//--------------------------------------------------------------------------- +CCost +CCostModelGPDB::CostRightAntiSemiHashJoin(CMemoryPool *mp, + CExpressionHandle &exprhdl, + const CCostModelGPDB *pcmgpdb, + const SCostingInfo *pci) +{ + GPOS_ASSERT(nullptr != pcmgpdb); + GPOS_ASSERT(nullptr != pci); + GPOS_ASSERT(COperator::EopPhysicalRightAntiSemiHashJoin == + exprhdl.Pop()->Eopid()); + + // ANTI shares the build/probe shape of SEMI -- after probe marks + // matched build rows via visited bits, finalize emits the unvisited + // build rows. The finalize cost is proportional to build_rows and is + // dominated by the build hashing term already in CostRightSemiHashJoin, + // so reuse the same formula. (See design doc M3.3.) + return CostRightSemiHashJoin(mp, exprhdl, pcmgpdb, pci); +} + //--------------------------------------------------------------------------- // @function: // CCostModelGPDB::CostIndexNLJoin @@ -2720,6 +2878,16 @@ CCostModelGPDB::Cost( return CostHashJoin(m_mp, exprhdl, this, pci); } + case COperator::EopPhysicalRightSemiHashJoin: + { + return CostRightSemiHashJoin(m_mp, exprhdl, this, pci); + } + + case COperator::EopPhysicalRightAntiSemiHashJoin: + { + return CostRightAntiSemiHashJoin(m_mp, exprhdl, this, pci); + } + case COperator::EopPhysicalInnerIndexNLJoin: case COperator::EopPhysicalLeftOuterIndexNLJoin: { diff --git a/src/backend/gporca/libgpopt/include/gpopt/operators/COperator.h b/src/backend/gporca/libgpopt/include/gpopt/operators/COperator.h index 5d10a1cee99..080d77b35bb 100644 --- a/src/backend/gporca/libgpopt/include/gpopt/operators/COperator.h +++ b/src/backend/gporca/libgpopt/include/gpopt/operators/COperator.h @@ -222,6 +222,8 @@ class COperator : public CRefCount, public DbgPrintMixin EopPhysicalLeftSemiHashJoin, EopPhysicalLeftAntiSemiHashJoin, EopPhysicalLeftAntiSemiHashJoinNotIn, + EopPhysicalRightSemiHashJoin, + EopPhysicalRightAntiSemiHashJoin, EopPhysicalRightOuterHashJoin, EopPhysicalFullHashJoin, diff --git a/src/backend/gporca/libgpopt/include/gpopt/operators/CPhysicalRightAntiSemiHashJoin.h b/src/backend/gporca/libgpopt/include/gpopt/operators/CPhysicalRightAntiSemiHashJoin.h new file mode 100644 index 00000000000..deba17691f6 --- /dev/null +++ b/src/backend/gporca/libgpopt/include/gpopt/operators/CPhysicalRightAntiSemiHashJoin.h @@ -0,0 +1,99 @@ +//--------------------------------------------------------------------------- +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +// Greenplum Database +// Portions Copyright (c) 2023-2026, HashData Technology Limited. +// +// @filename: +// CPhysicalRightAntiSemiHashJoin.h +// +// @doc: +// Right anti semi hash join operator (PG-style: build = outer/left, +// probe = inner/right, finalize emits left rows that were not visited (unmatched). +// Mirror of CPhysicalLeftAntiSemiHashJoin with build/probe roles flipped. +//--------------------------------------------------------------------------- +#ifndef GPOPT_CPhysicalRightAntiSemiHashJoin_H +#define GPOPT_CPhysicalRightAntiSemiHashJoin_H + +#include "gpos/base.h" + +#include "gpopt/operators/CPhysicalHashJoin.h" + +namespace gpopt +{ +//--------------------------------------------------------------------------- +// @class: +// CPhysicalRightAntiSemiHashJoin +// +// @doc: +// Right anti semi hash join operator +// +//--------------------------------------------------------------------------- +class CPhysicalRightAntiSemiHashJoin : public CPhysicalHashJoin +{ +private: +public: + CPhysicalRightAntiSemiHashJoin(const CPhysicalRightAntiSemiHashJoin &) = + delete; + + // ctor + CPhysicalRightAntiSemiHashJoin( + CMemoryPool *mp, CExpressionArray *pdrgpexprOuterKeys, + CExpressionArray *pdrgpexprInnerKeys, IMdIdArray *hash_opfamilies, + BOOL is_null_aware = true, + CXform::EXformId origin_xform = CXform::ExfSentinel); + + // dtor + ~CPhysicalRightAntiSemiHashJoin() override; + + // ident accessors + EOperatorId + Eopid() const override + { + return EopPhysicalRightAntiSemiHashJoin; + } + + // return a string for operator name + const CHAR * + SzId() const override + { + return "CPhysicalRightAntiSemiHashJoin"; + } + + // check if required columns are included in output columns + BOOL FProvidesReqdCols(CExpressionHandle &exprhdl, CColRefSet *pcrsRequired, + ULONG ulOptReq) const override; + + // conversion function + static CPhysicalRightAntiSemiHashJoin * + PopConvert(COperator *pop) + { + GPOS_ASSERT(EopPhysicalRightAntiSemiHashJoin == pop->Eopid()); + + return dynamic_cast(pop); + } + + +}; // class CPhysicalRightAntiSemiHashJoin + +} // namespace gpopt + +#endif // !GPOPT_CPhysicalRightAntiSemiHashJoin_H + +// EOF diff --git a/src/backend/gporca/libgpopt/include/gpopt/operators/CPhysicalRightSemiHashJoin.h b/src/backend/gporca/libgpopt/include/gpopt/operators/CPhysicalRightSemiHashJoin.h new file mode 100644 index 00000000000..a805649b792 --- /dev/null +++ b/src/backend/gporca/libgpopt/include/gpopt/operators/CPhysicalRightSemiHashJoin.h @@ -0,0 +1,111 @@ +//--------------------------------------------------------------------------- +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +// Greenplum Database +// Portions Copyright (c) 2023-2026, HashData Technology Limited. +// +// @filename: +// CPhysicalRightSemiHashJoin.h +// +// @doc: +// Right semi hash join operator (PG-style: build = outer/left, +// probe = inner/right, finalize emits left rows that were visited (matched). +// Mirror of CPhysicalLeftSemiHashJoin with build/probe roles flipped. +//--------------------------------------------------------------------------- +#ifndef GPOPT_CPhysicalRightSemiHashJoin_H +#define GPOPT_CPhysicalRightSemiHashJoin_H + +#include "gpos/base.h" + +#include "gpopt/operators/CPhysicalHashJoin.h" + +namespace gpopt +{ +//--------------------------------------------------------------------------- +// @class: +// CPhysicalRightSemiHashJoin +// +// @doc: +// Right semi hash join operator +// +//--------------------------------------------------------------------------- +class CPhysicalRightSemiHashJoin : public CPhysicalHashJoin +{ +private: +public: + CPhysicalRightSemiHashJoin(const CPhysicalRightSemiHashJoin &) = delete; + + // ctor + CPhysicalRightSemiHashJoin( + CMemoryPool *mp, CExpressionArray *pdrgpexprOuterKeys, + CExpressionArray *pdrgpexprInnerKeys, IMdIdArray *hash_opfamilies, + BOOL is_null_aware = true, + CXform::EXformId origin_xform = CXform::ExfSentinel); + + // dtor + ~CPhysicalRightSemiHashJoin() override; + + // ident accessors + EOperatorId + Eopid() const override + { + return EopPhysicalRightSemiHashJoin; + } + + // return a string for operator name + const CHAR * + SzId() const override + { + return "CPhysicalRightSemiHashJoin"; + } + + // NB: deliberately does NOT override PppsRequired/PppsDerive. The GPDB + // executor builds this join on the outer (LHS) child (see the build-side + // swap in CTranslatorDXLToPlStmt), which is the opposite of what + // PppsRequiredForJoins assumes (selector on the inner/build child, consumer + // on the outer/probe child). Hosting a join-driven Partition Selector here + // would place it on the wrong execution side and crash ExecInitPartitionSelector. + // Inheriting CPhysical's base behaviour keeps right-semi out of join-driven + // dynamic partition elimination (matching CPhysicalRightAntiSemiHashJoin), + // so a partitioned semijoin falls back to the regular Hash Semi Join that + // carries the selector correctly. + + // check if required columns are included in output columns. + // Right semi join semantically preserves left-side rows (same as Left + // semi join), so output columns come from the outer (left) child. + BOOL FProvidesReqdCols(CExpressionHandle &exprhdl, CColRefSet *pcrsRequired, + ULONG ulOptReq) const override; + + // conversion function + static CPhysicalRightSemiHashJoin * + PopConvert(COperator *pop) + { + GPOS_ASSERT(EopPhysicalRightSemiHashJoin == pop->Eopid()); + + return dynamic_cast(pop); + } + + +}; // class CPhysicalRightSemiHashJoin + +} // namespace gpopt + +#endif // !GPOPT_CPhysicalRightSemiHashJoin_H + +// EOF diff --git a/src/backend/gporca/libgpopt/include/gpopt/xforms/CXform.h b/src/backend/gporca/libgpopt/include/gpopt/xforms/CXform.h index d0fca8219ac..c2de738ad7a 100644 --- a/src/backend/gporca/libgpopt/include/gpopt/xforms/CXform.h +++ b/src/backend/gporca/libgpopt/include/gpopt/xforms/CXform.h @@ -241,6 +241,15 @@ class CXform : public CRefCount, public DbgPrintMixin ExfFullOuterJoin2HashJoin, ExfFullJoinCommutativity, ExfSplitWindowFunc, + /* + * Right semi/anti hash join xforms (Mark Join, PG18 backport). + * Kept at the END of this enum to preserve the integer values of + * pre-existing IDs -- inserting in the middle breaks ABI (CBitSet / + * xform-id sequence checks in CXformFactory). Same lesson as the + * PG JoinType enum placement (see nodes.h JOIN_RIGHT_SEMI). + */ + ExfLeftSemiJoin2RightSemiHashJoin, + ExfLeftAntiSemiJoin2RightAntiSemiHashJoin, ExfInvalid, ExfSentinel = ExfInvalid }; diff --git a/src/backend/gporca/libgpopt/include/gpopt/xforms/CXformLeftAntiSemiJoin2RightAntiSemiHashJoin.h b/src/backend/gporca/libgpopt/include/gpopt/xforms/CXformLeftAntiSemiJoin2RightAntiSemiHashJoin.h new file mode 100644 index 00000000000..b244a0178af --- /dev/null +++ b/src/backend/gporca/libgpopt/include/gpopt/xforms/CXformLeftAntiSemiJoin2RightAntiSemiHashJoin.h @@ -0,0 +1,81 @@ +//--------------------------------------------------------------------------- +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +// Greenplum Database +// Portions Copyright (c) 2023-2026, HashData Technology Limited. +// +// @filename: +// CXformLeftAntiSemiJoin2RightAntiSemiHashJoin.h +// +// @doc: +// Transform logical left anti semi join to physical right anti semi +// hash join. Symmetric to CXformLeftAntiSemiJoin2HashJoin. +//--------------------------------------------------------------------------- +#ifndef GPOPT_CXformLeftAntiSemiJoin2RightAntiSemiHashJoin_H +#define GPOPT_CXformLeftAntiSemiJoin2RightAntiSemiHashJoin_H + +#include "gpos/base.h" + +#include "gpopt/xforms/CXformImplementation.h" + +namespace gpopt +{ +using namespace gpos; + +class CXformLeftAntiSemiJoin2RightAntiSemiHashJoin : public CXformImplementation +{ +private: +public: + CXformLeftAntiSemiJoin2RightAntiSemiHashJoin( + const CXformLeftAntiSemiJoin2RightAntiSemiHashJoin &) = delete; + + // ctor + explicit CXformLeftAntiSemiJoin2RightAntiSemiHashJoin(CMemoryPool *mp); + + // dtor + ~CXformLeftAntiSemiJoin2RightAntiSemiHashJoin() override = default; + + // ident accessors + EXformId + Exfid() const override + { + return ExfLeftAntiSemiJoin2RightAntiSemiHashJoin; + } + + // return a string for xform name + const CHAR * + SzId() const override + { + return "CXformLeftAntiSemiJoin2RightAntiSemiHashJoin"; + } + + // compute xform promise for a given expression handle + EXformPromise Exfp(CExpressionHandle &exprhdl) const override; + + // actual transform + void Transform(CXformContext *pxfctxt, CXformResult *pxfres, + CExpression *pexpr) const override; + +}; // class CXformLeftAntiSemiJoin2RightAntiSemiHashJoin + +} // namespace gpopt + +#endif // !GPOPT_CXformLeftAntiSemiJoin2RightAntiSemiHashJoin_H + +// EOF diff --git a/src/backend/gporca/libgpopt/include/gpopt/xforms/CXformLeftSemiJoin2RightSemiHashJoin.h b/src/backend/gporca/libgpopt/include/gpopt/xforms/CXformLeftSemiJoin2RightSemiHashJoin.h new file mode 100644 index 00000000000..7aa4d0f0965 --- /dev/null +++ b/src/backend/gporca/libgpopt/include/gpopt/xforms/CXformLeftSemiJoin2RightSemiHashJoin.h @@ -0,0 +1,91 @@ +//--------------------------------------------------------------------------- +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +// Greenplum Database +// Portions Copyright (c) 2023-2026, HashData Technology Limited. +// +// @filename: +// CXformLeftSemiJoin2RightSemiHashJoin.h +// +// @doc: +// Transform logical left semi join to physical right semi hash join. +// Symmetric to CXformLeftSemiJoin2HashJoin but generates the RIGHT +// (build = outer) physical candidate. Memo will hold both Left and +// Right candidates; cost model picks the cheaper one (M3). +//--------------------------------------------------------------------------- +#ifndef GPOPT_CXformLeftSemiJoin2RightSemiHashJoin_H +#define GPOPT_CXformLeftSemiJoin2RightSemiHashJoin_H + +#include "gpos/base.h" + +#include "gpopt/xforms/CXformImplementation.h" + +namespace gpopt +{ +using namespace gpos; + +//--------------------------------------------------------------------------- +// @class: +// CXformLeftSemiJoin2RightSemiHashJoin +// +// @doc: +// Transform left semi join to right semi hash join (build = outer) +// +//--------------------------------------------------------------------------- +class CXformLeftSemiJoin2RightSemiHashJoin : public CXformImplementation +{ +private: +public: + CXformLeftSemiJoin2RightSemiHashJoin( + const CXformLeftSemiJoin2RightSemiHashJoin &) = delete; + + // ctor + explicit CXformLeftSemiJoin2RightSemiHashJoin(CMemoryPool *mp); + + // dtor + ~CXformLeftSemiJoin2RightSemiHashJoin() override = default; + + // ident accessors + EXformId + Exfid() const override + { + return ExfLeftSemiJoin2RightSemiHashJoin; + } + + // return a string for xform name + const CHAR * + SzId() const override + { + return "CXformLeftSemiJoin2RightSemiHashJoin"; + } + + // compute xform promise for a given expression handle + EXformPromise Exfp(CExpressionHandle &exprhdl) const override; + + // actual transform + void Transform(CXformContext *pxfctxt, CXformResult *pxfres, + CExpression *pexpr) const override; + +}; // class CXformLeftSemiJoin2RightSemiHashJoin + +} // namespace gpopt + +#endif // !GPOPT_CXformLeftSemiJoin2RightSemiHashJoin_H + +// EOF diff --git a/src/backend/gporca/libgpopt/include/gpopt/xforms/xforms.h b/src/backend/gporca/libgpopt/include/gpopt/xforms/xforms.h index 0ee9beb2eb7..1d8dc6baa12 100644 --- a/src/backend/gporca/libgpopt/include/gpopt/xforms/xforms.h +++ b/src/backend/gporca/libgpopt/include/gpopt/xforms/xforms.h @@ -119,6 +119,8 @@ #include "gpopt/xforms/CXformLeftSemiApplyWithExternalCorrs2InnerJoin.h" #include "gpopt/xforms/CXformLeftSemiJoin2CrossProduct.h" #include "gpopt/xforms/CXformLeftSemiJoin2HashJoin.h" +#include "gpopt/xforms/CXformLeftSemiJoin2RightSemiHashJoin.h" +#include "gpopt/xforms/CXformLeftAntiSemiJoin2RightAntiSemiHashJoin.h" #include "gpopt/xforms/CXformLeftSemiJoin2InnerJoin.h" #include "gpopt/xforms/CXformLeftSemiJoin2InnerJoinUnderGb.h" #include "gpopt/xforms/CXformLeftSemiJoin2NLJoin.h" diff --git a/src/backend/gporca/libgpopt/src/operators/CLogicalLeftAntiSemiJoin.cpp b/src/backend/gporca/libgpopt/src/operators/CLogicalLeftAntiSemiJoin.cpp index 9648290d77c..e9d74dc5777 100644 --- a/src/backend/gporca/libgpopt/src/operators/CLogicalLeftAntiSemiJoin.cpp +++ b/src/backend/gporca/libgpopt/src/operators/CLogicalLeftAntiSemiJoin.cpp @@ -75,6 +75,10 @@ CLogicalLeftAntiSemiJoin::PxfsCandidates(CMemoryPool *mp) const (void) xform_set->ExchangeSet(CXform::ExfLeftAntiSemiJoin2CrossProduct); (void) xform_set->ExchangeSet(CXform::ExfLeftAntiSemiJoin2NLJoin); (void) xform_set->ExchangeSet(CXform::ExfLeftAntiSemiJoin2HashJoin); + // Right-anti hash join (build on the smaller LHS). CTranslatorDXLToPlStmt + // swaps the build (inner) side and the outer/inner hash keys to the LHS for + // JOIN_RIGHT_ANTI, matching the PostgreSQL planner / executor. + (void) xform_set->ExchangeSet(CXform::ExfLeftAntiSemiJoin2RightAntiSemiHashJoin); return xform_set; } diff --git a/src/backend/gporca/libgpopt/src/operators/CLogicalLeftSemiJoin.cpp b/src/backend/gporca/libgpopt/src/operators/CLogicalLeftSemiJoin.cpp index 70df5a66741..1eefe774c78 100644 --- a/src/backend/gporca/libgpopt/src/operators/CLogicalLeftSemiJoin.cpp +++ b/src/backend/gporca/libgpopt/src/operators/CLogicalLeftSemiJoin.cpp @@ -60,6 +60,10 @@ CLogicalLeftSemiJoin::PxfsCandidates(CMemoryPool *mp) const (void) xform_set->ExchangeSet(CXform::ExfLeftSemiJoin2CrossProduct); (void) xform_set->ExchangeSet(CXform::ExfLeftSemiJoin2NLJoin); (void) xform_set->ExchangeSet(CXform::ExfLeftSemiJoin2HashJoin); + // Right-semi hash join (build on the smaller LHS). CTranslatorDXLToPlStmt + // swaps the build (inner) side and the outer/inner hash keys to the LHS for + // JOIN_RIGHT_SEMI, matching the PostgreSQL planner / executor. + (void) xform_set->ExchangeSet(CXform::ExfLeftSemiJoin2RightSemiHashJoin); return xform_set; } diff --git a/src/backend/gporca/libgpopt/src/operators/CPhysicalRightAntiSemiHashJoin.cpp b/src/backend/gporca/libgpopt/src/operators/CPhysicalRightAntiSemiHashJoin.cpp new file mode 100644 index 00000000000..2ecce5f8ab3 --- /dev/null +++ b/src/backend/gporca/libgpopt/src/operators/CPhysicalRightAntiSemiHashJoin.cpp @@ -0,0 +1,93 @@ +//--------------------------------------------------------------------------- +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +// Greenplum Database +// Portions Copyright (c) 2023-2026, HashData Technology Limited. +// +// @filename: +// CPhysicalRightAntiSemiHashJoin.cpp +// +// @doc: +// Implementation of right anti semi hash join operator. +// Mirror of CPhysicalLeftAntiSemiHashJoin with build/probe roles flipped: +// - LeftAntiSemi: build = inner (right child), probe = outer (left) +// - RightAntiSemi: build = outer (left child), probe = inner (right) +// Finalize emits left-side rows that have no match. Output column +// semantics identical to LeftAntiSemi. +//--------------------------------------------------------------------------- + +#include "gpopt/operators/CPhysicalRightAntiSemiHashJoin.h" + +#include "gpos/base.h" + +#include "gpopt/base/CDistributionSpecHashed.h" + + +using namespace gpopt; + + +//--------------------------------------------------------------------------- +// @function: +// CPhysicalRightAntiSemiHashJoin::CPhysicalRightAntiSemiHashJoin +// +// @doc: +// Ctor +// +//--------------------------------------------------------------------------- +CPhysicalRightAntiSemiHashJoin::CPhysicalRightAntiSemiHashJoin( + CMemoryPool *mp, CExpressionArray *pdrgpexprOuterKeys, + CExpressionArray *pdrgpexprInnerKeys, IMdIdArray *hash_opfamilies, + BOOL is_null_aware, CXform::EXformId origin_xform) + : CPhysicalHashJoin(mp, pdrgpexprOuterKeys, pdrgpexprInnerKeys, + hash_opfamilies, is_null_aware, origin_xform) +{ +} + + +//--------------------------------------------------------------------------- +// @function: +// CPhysicalRightAntiSemiHashJoin::~CPhysicalRightAntiSemiHashJoin +// +// @doc: +// Dtor +// +//--------------------------------------------------------------------------- +CPhysicalRightAntiSemiHashJoin::~CPhysicalRightAntiSemiHashJoin() = default; + + +//--------------------------------------------------------------------------- +// @function: +// CPhysicalRightAntiSemiHashJoin::FProvidesReqdCols +// +// @doc: +// Check if required columns are included in output columns +// +//--------------------------------------------------------------------------- +BOOL +CPhysicalRightAntiSemiHashJoin::FProvidesReqdCols(CExpressionHandle &exprhdl, + CColRefSet *pcrsRequired, + ULONG // ulOptReq +) const +{ + // Right anti semi join semantically preserves left-side rows (same as + // Left anti semi). Output columns come from the outer (left) child. + return FOuterProvidesReqdCols(exprhdl, pcrsRequired); +} + +// EOF diff --git a/src/backend/gporca/libgpopt/src/operators/CPhysicalRightSemiHashJoin.cpp b/src/backend/gporca/libgpopt/src/operators/CPhysicalRightSemiHashJoin.cpp new file mode 100644 index 00000000000..13658f68155 --- /dev/null +++ b/src/backend/gporca/libgpopt/src/operators/CPhysicalRightSemiHashJoin.cpp @@ -0,0 +1,105 @@ +//--------------------------------------------------------------------------- +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +// Greenplum Database +// Portions Copyright (c) 2023-2026, HashData Technology Limited. +// +// @filename: +// CPhysicalRightSemiHashJoin.cpp +// +// @doc: +// Implementation of right semi hash join operator. +// Mirror of CPhysicalLeftSemiHashJoin with build/probe roles flipped: +// - LeftSemi: build = inner (right child), probe = outer (left child) +// - RightSemi: build = outer (left child), probe = inner (right child) +// Output schema and FProvidesReqdCols semantics are identical to LeftSemi +// (both preserve left-side rows). The flip is encoded in the operator +// EOperatorId, queried by M3 cost model and M4 DXL translation. +//--------------------------------------------------------------------------- + +#include "gpopt/operators/CPhysicalRightSemiHashJoin.h" + +#include "gpos/base.h" + +#include "gpopt/base/CDistributionSpecHashed.h" +#include "gpopt/base/CUtils.h" + + +using namespace gpopt; + + +//--------------------------------------------------------------------------- +// @function: +// CPhysicalRightSemiHashJoin::CPhysicalRightSemiHashJoin +// +// @doc: +// Ctor +// +//--------------------------------------------------------------------------- +CPhysicalRightSemiHashJoin::CPhysicalRightSemiHashJoin( + CMemoryPool *mp, CExpressionArray *pdrgpexprOuterKeys, + CExpressionArray *pdrgpexprInnerKeys, IMdIdArray *hash_opfamilies, + BOOL is_null_aware, CXform::EXformId origin_xform) + : CPhysicalHashJoin(mp, pdrgpexprOuterKeys, pdrgpexprInnerKeys, + hash_opfamilies, is_null_aware, origin_xform) +{ +} + + +//--------------------------------------------------------------------------- +// @function: +// CPhysicalRightSemiHashJoin::~CPhysicalRightSemiHashJoin +// +// @doc: +// Dtor +// +//--------------------------------------------------------------------------- +CPhysicalRightSemiHashJoin::~CPhysicalRightSemiHashJoin() = default; + + +//--------------------------------------------------------------------------- +// @function: +// CPhysicalRightSemiHashJoin::FProvidesReqdCols +// +// @doc: +// Check if required columns are included in output columns +// +//--------------------------------------------------------------------------- +BOOL +CPhysicalRightSemiHashJoin::FProvidesReqdCols(CExpressionHandle &exprhdl, + CColRefSet *pcrsRequired, + ULONG // ulOptReq +) const +{ + // Right semi join semantically preserves left-side rows (same as Left + // semi). Physical build side is the left child, finalize phase scans the + // build hash table and emits visited left rows -- so output columns come + // from the outer (left) child. + return FOuterProvidesReqdCols(exprhdl, pcrsRequired); +} + +// NB: PppsRequired/PppsDerive are intentionally NOT overridden here; this +// operator inherits CPhysical's base behaviour so it does not host a +// join-driven Partition Selector. Because the GPDB executor builds this join +// on the outer (LHS) child (build-side swap in CTranslatorDXLToPlStmt), a +// selector placed by PppsRequiredForJoins (which assumes selector-on-inner) +// would land on the probe side and crash ExecInitPartitionSelector. A +// partitioned semijoin therefore falls back to the regular Hash Semi Join, +// which carries the selector correctly (matches CPhysicalRightAntiSemiHashJoin). +// EOF diff --git a/src/backend/gporca/libgpopt/src/operators/Makefile b/src/backend/gporca/libgpopt/src/operators/Makefile index ce5362e9049..5f0ecdb5a1a 100644 --- a/src/backend/gporca/libgpopt/src/operators/Makefile +++ b/src/backend/gporca/libgpopt/src/operators/Makefile @@ -112,6 +112,8 @@ OBJS = CExpression.o \ CPhysicalLeftOuterIndexNLJoin.o \ CPhysicalLeftOuterNLJoin.o \ CPhysicalLeftSemiHashJoin.o \ + CPhysicalRightSemiHashJoin.o \ + CPhysicalRightAntiSemiHashJoin.o \ CPhysicalLeftSemiNLJoin.o \ CPhysicalFullHashJoin.o \ CPhysicalLimit.o \ diff --git a/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp b/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp index 51acac518be..5b24ad06bca 100644 --- a/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp +++ b/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp @@ -457,6 +457,8 @@ CTranslatorExprToDXL::CreateDXLNode(CExpression *pexpr, case COperator::EopPhysicalLeftSemiHashJoin: case COperator::EopPhysicalLeftAntiSemiHashJoin: case COperator::EopPhysicalLeftAntiSemiHashJoinNotIn: + case COperator::EopPhysicalRightSemiHashJoin: + case COperator::EopPhysicalRightAntiSemiHashJoin: case COperator::EopPhysicalRightOuterHashJoin: case COperator::EopPhysicalFullHashJoin: dxlnode = CTranslatorExprToDXL::PdxlnHashJoin( @@ -5069,6 +5071,12 @@ CTranslatorExprToDXL::EdxljtHashJoin(CPhysicalHashJoin *popHJ) case COperator::EopPhysicalLeftAntiSemiHashJoinNotIn: return EdxljtLeftAntiSemijoinNotIn; + case COperator::EopPhysicalRightSemiHashJoin: + return EdxljtRightSemijoin; + + case COperator::EopPhysicalRightAntiSemiHashJoin: + return EdxljtRightAntiSemijoin; + case COperator::EopPhysicalFullHashJoin: return EdxljtFull; diff --git a/src/backend/gporca/libgpopt/src/xforms/CXformFactory.cpp b/src/backend/gporca/libgpopt/src/xforms/CXformFactory.cpp index 7ffe39774dc..3be749e3833 100644 --- a/src/backend/gporca/libgpopt/src/xforms/CXformFactory.cpp +++ b/src/backend/gporca/libgpopt/src/xforms/CXformFactory.cpp @@ -306,6 +306,12 @@ CXformFactory::Instantiate() Add(GPOS_NEW(m_mp) CXformFullOuterJoin2HashJoin(m_mp)); Add(GPOS_NEW(m_mp) CXformFullJoinCommutativity(m_mp)); Add(GPOS_NEW(m_mp) CXformSplitWindowFunc(m_mp)); + // Right semi/anti hash join xforms (Mark Join) -- kept at the END of the + // Add list to match the enum-end positioning in CXform.h (preserves the + // integer values of pre-existing xform IDs; same lesson as the PG + // JoinType enum placement for JOIN_RIGHT_SEMI). + Add(GPOS_NEW(m_mp) CXformLeftSemiJoin2RightSemiHashJoin(m_mp)); + Add(GPOS_NEW(m_mp) CXformLeftAntiSemiJoin2RightAntiSemiHashJoin(m_mp)); GPOS_ASSERT(nullptr != m_rgpxf[CXform::ExfSentinel - 1] && "Not all xforms have been instantiated"); diff --git a/src/backend/gporca/libgpopt/src/xforms/CXformLeftAntiSemiJoin2RightAntiSemiHashJoin.cpp b/src/backend/gporca/libgpopt/src/xforms/CXformLeftAntiSemiJoin2RightAntiSemiHashJoin.cpp new file mode 100644 index 00000000000..0f65c6a6b53 --- /dev/null +++ b/src/backend/gporca/libgpopt/src/xforms/CXformLeftAntiSemiJoin2RightAntiSemiHashJoin.cpp @@ -0,0 +1,99 @@ +//--------------------------------------------------------------------------- +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +// Greenplum Database +// Portions Copyright (c) 2023-2026, HashData Technology Limited. +// +// @filename: +// CXformLeftAntiSemiJoin2RightAntiSemiHashJoin.cpp +// +// @doc: +// Implementation of transform: logical left anti semi join -> +// physical right anti semi hash join (build = outer/left). +//--------------------------------------------------------------------------- + +#include "gpopt/xforms/CXformLeftAntiSemiJoin2RightAntiSemiHashJoin.h" + +#include "gpos/base.h" + +#include "gpopt/operators/CLogicalLeftAntiSemiJoin.h" +#include "gpopt/operators/CPatternLeaf.h" +#include "gpopt/operators/CPhysicalRightAntiSemiHashJoin.h" +#include "gpopt/operators/CPredicateUtils.h" +#include "gpopt/xforms/CXformUtils.h" + +using namespace gpopt; + + +CXformLeftAntiSemiJoin2RightAntiSemiHashJoin:: + CXformLeftAntiSemiJoin2RightAntiSemiHashJoin(CMemoryPool *mp) + : // pattern + CXformImplementation(GPOS_NEW(mp) CExpression( + mp, GPOS_NEW(mp) CLogicalLeftAntiSemiJoin(mp), + GPOS_NEW(mp) + CExpression(mp, GPOS_NEW(mp) CPatternLeaf(mp)), // left child + GPOS_NEW(mp) + CExpression(mp, GPOS_NEW(mp) CPatternLeaf(mp)), // right child + GPOS_NEW(mp) + CExpression(mp, GPOS_NEW(mp) CPatternTree(mp)) // predicate + )) +{ +} + + +CXform::EXformPromise +CXformLeftAntiSemiJoin2RightAntiSemiHashJoin::Exfp( + CExpressionHandle &exprhdl) const +{ + return CXformUtils::ExfpLogicalJoin2PhysicalJoin(exprhdl); +} + + +void +CXformLeftAntiSemiJoin2RightAntiSemiHashJoin::Transform( + CXformContext *pxfctxt, CXformResult *pxfres, CExpression *pexpr) const +{ + GPOS_ASSERT(nullptr != pxfctxt); + GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr)); + GPOS_ASSERT(FCheckPattern(pexpr)); + + CXformUtils::ImplementHashJoin( + pxfctxt, pxfres, pexpr); + + if (pxfres->Pdrgpexpr()->Size() == 0) + { + // No alternative was generated because the anti-semi join predicate + // could not be turned into hash clauses. Mirror + // CXformLeftAntiSemiJoin2HashJoin: retry after simplifying the + // GPDB-style (IsNotFalse-wrapped) join predicate, otherwise the + // right-anti-semi hash join is silently never considered for this + // class of anti joins. + CExpression *pexprProcessed = nullptr; + if (CXformUtils::FProcessGPDBAntiSemiHashJoin(pxfctxt->Pmp(), pexpr, + &pexprProcessed)) + { + CXformUtils::ImplementHashJoin( + pxfctxt, pxfres, pexprProcessed); + pexprProcessed->Release(); + } + } +} + + +// EOF diff --git a/src/backend/gporca/libgpopt/src/xforms/CXformLeftSemiJoin2RightSemiHashJoin.cpp b/src/backend/gporca/libgpopt/src/xforms/CXformLeftSemiJoin2RightSemiHashJoin.cpp new file mode 100644 index 00000000000..d46373c79aa --- /dev/null +++ b/src/backend/gporca/libgpopt/src/xforms/CXformLeftSemiJoin2RightSemiHashJoin.cpp @@ -0,0 +1,110 @@ +//--------------------------------------------------------------------------- +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +// Greenplum Database +// Portions Copyright (c) 2023-2026, HashData Technology Limited. +// +// @filename: +// CXformLeftSemiJoin2RightSemiHashJoin.cpp +// +// @doc: +// Implementation of transform: logical left semi join -> physical +// right semi hash join (build = outer/left, probe = inner/right). +// Generates the RIGHT candidate; cost model (M3) picks vs LEFT. +//--------------------------------------------------------------------------- + +#include "gpopt/xforms/CXformLeftSemiJoin2RightSemiHashJoin.h" + +#include "gpos/base.h" + +#include "gpopt/operators/CLogicalLeftSemiJoin.h" +#include "gpopt/operators/CPatternLeaf.h" +#include "gpopt/operators/CPhysicalRightSemiHashJoin.h" +#include "gpopt/operators/CPredicateUtils.h" +#include "gpopt/xforms/CXformUtils.h" + +using namespace gpopt; + + +//--------------------------------------------------------------------------- +// @function: +// CXformLeftSemiJoin2RightSemiHashJoin::CXformLeftSemiJoin2RightSemiHashJoin +// +// @doc: +// ctor -- pattern identical to LeftSemi xform (same logical pattern) +// +//--------------------------------------------------------------------------- +CXformLeftSemiJoin2RightSemiHashJoin::CXformLeftSemiJoin2RightSemiHashJoin( + CMemoryPool *mp) + : // pattern + CXformImplementation(GPOS_NEW(mp) CExpression( + mp, GPOS_NEW(mp) CLogicalLeftSemiJoin(mp), + GPOS_NEW(mp) + CExpression(mp, GPOS_NEW(mp) CPatternLeaf(mp)), // left child + GPOS_NEW(mp) + CExpression(mp, GPOS_NEW(mp) CPatternLeaf(mp)), // right child + GPOS_NEW(mp) + CExpression(mp, GPOS_NEW(mp) CPatternTree(mp)) // predicate + )) +{ +} + + +//--------------------------------------------------------------------------- +// @function: +// CXformLeftSemiJoin2RightSemiHashJoin::Exfp +// +// @doc: +// Compute xform promise. Generate RIGHT_SEMI candidate whenever the +// expression can be implemented as a hash join. Cost model decides +// LEFT vs RIGHT -- no GUC, no heuristic in xform layer. +// +//--------------------------------------------------------------------------- +CXform::EXformPromise +CXformLeftSemiJoin2RightSemiHashJoin::Exfp(CExpressionHandle &exprhdl) const +{ + return CXformUtils::ExfpLogicalJoin2PhysicalJoin(exprhdl); +} + + +//--------------------------------------------------------------------------- +// @function: +// CXformLeftSemiJoin2RightSemiHashJoin::Transform +// +// @doc: +// Actual transformation: instantiate CPhysicalRightSemiHashJoin with +// children in original [outer, inner] order. The RIGHT operator's +// Eopid encodes the build/probe flip. +// +//--------------------------------------------------------------------------- +void +CXformLeftSemiJoin2RightSemiHashJoin::Transform(CXformContext *pxfctxt, + CXformResult *pxfres, + CExpression *pexpr) const +{ + GPOS_ASSERT(nullptr != pxfctxt); + GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr)); + GPOS_ASSERT(FCheckPattern(pexpr)); + + CXformUtils::ImplementHashJoin(pxfctxt, pxfres, + pexpr); +} + + +// EOF diff --git a/src/backend/gporca/libgpopt/src/xforms/Makefile b/src/backend/gporca/libgpopt/src/xforms/Makefile index 66da51e28bb..3b89739dd4e 100644 --- a/src/backend/gporca/libgpopt/src/xforms/Makefile +++ b/src/backend/gporca/libgpopt/src/xforms/Makefile @@ -102,6 +102,8 @@ OBJS = CDecorrelator.o \ CXformLeftSemiApplyWithExternalCorrs2InnerJoin.o \ CXformLeftSemiJoin2CrossProduct.o \ CXformLeftSemiJoin2HashJoin.o \ + CXformLeftSemiJoin2RightSemiHashJoin.o \ + CXformLeftAntiSemiJoin2RightAntiSemiHashJoin.o \ CXformLeftSemiJoin2InnerJoin.o \ CXformLeftSemiJoin2InnerJoinUnderGb.o \ CXformLeftSemiJoin2NLJoin.o \ diff --git a/src/backend/gporca/libnaucrates/include/naucrates/dxl/operators/CDXLOperator.h b/src/backend/gporca/libnaucrates/include/naucrates/dxl/operators/CDXLOperator.h index e583e9974a3..29344f893fc 100644 --- a/src/backend/gporca/libnaucrates/include/naucrates/dxl/operators/CDXLOperator.h +++ b/src/backend/gporca/libnaucrates/include/naucrates/dxl/operators/CDXLOperator.h @@ -183,6 +183,8 @@ enum EdxlJoinType EdxljtIn, EdxljtLeftAntiSemijoin, EdxljtLeftAntiSemijoinNotIn, + EdxljtRightSemijoin, /* PG JOIN_RIGHT_SEMI -- build = LHS */ + EdxljtRightAntiSemijoin, /* PG JOIN_RIGHT_ANTI -- build = LHS */ EdxljtSentinel }; diff --git a/src/backend/gporca/libnaucrates/include/naucrates/dxl/xml/dxltokens.h b/src/backend/gporca/libnaucrates/include/naucrates/dxl/xml/dxltokens.h index 9c5d89fe8ae..3fae5cd1a1f 100644 --- a/src/backend/gporca/libnaucrates/include/naucrates/dxl/xml/dxltokens.h +++ b/src/backend/gporca/libnaucrates/include/naucrates/dxl/xml/dxltokens.h @@ -309,6 +309,8 @@ enum Edxltoken EdxltokenJoinIn, EdxltokenJoinLeftAntiSemiJoin, EdxltokenJoinLeftAntiSemiJoinNotIn, + EdxltokenJoinRightSemiJoin, + EdxltokenJoinRightAntiSemiJoin, EdxltokenMergeJoinUniqueOuter, diff --git a/src/backend/gporca/libnaucrates/src/operators/CDXLOperator.cpp b/src/backend/gporca/libnaucrates/src/operators/CDXLOperator.cpp index 2b80db9adcc..0ef9089a6fc 100644 --- a/src/backend/gporca/libnaucrates/src/operators/CDXLOperator.cpp +++ b/src/backend/gporca/libnaucrates/src/operators/CDXLOperator.cpp @@ -75,6 +75,12 @@ CDXLOperator::GetJoinTypeNameStr(EdxlJoinType join_type) return CDXLTokens::GetDXLTokenStr( EdxltokenJoinLeftAntiSemiJoinNotIn); + case EdxljtRightSemijoin: + return CDXLTokens::GetDXLTokenStr(EdxltokenJoinRightSemiJoin); + + case EdxljtRightAntiSemijoin: + return CDXLTokens::GetDXLTokenStr(EdxltokenJoinRightAntiSemiJoin); + default: return CDXLTokens::GetDXLTokenStr(EdxltokenUnknown); } diff --git a/src/backend/gporca/libnaucrates/src/operators/CDXLOperatorFactory.cpp b/src/backend/gporca/libnaucrates/src/operators/CDXLOperatorFactory.cpp index a4d4914b731..bb3189f6d7f 100644 --- a/src/backend/gporca/libnaucrates/src/operators/CDXLOperatorFactory.cpp +++ b/src/backend/gporca/libnaucrates/src/operators/CDXLOperatorFactory.cpp @@ -3444,6 +3444,18 @@ CDXLOperatorFactory::ParseJoinType(const XMLCh *join_type_xml, { join_type = EdxljtLeftAntiSemijoinNotIn; } + else if (0 == XMLString::compareString( + CDXLTokens::XmlstrToken(EdxltokenJoinRightSemiJoin), + join_type_xml)) + { + join_type = EdxljtRightSemijoin; + } + else if (0 == XMLString::compareString( + CDXLTokens::XmlstrToken(EdxltokenJoinRightAntiSemiJoin), + join_type_xml)) + { + join_type = EdxljtRightAntiSemijoin; + } else { GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiDXLInvalidAttributeValue, diff --git a/src/backend/gporca/libnaucrates/src/xml/dxltokens.cpp b/src/backend/gporca/libnaucrates/src/xml/dxltokens.cpp index 79fcc9f7d6a..65ad7ac1d1f 100644 --- a/src/backend/gporca/libnaucrates/src/xml/dxltokens.cpp +++ b/src/backend/gporca/libnaucrates/src/xml/dxltokens.cpp @@ -302,6 +302,8 @@ CDXLTokens::Init(CMemoryPool *mp) {EdxltokenJoinLeftAntiSemiJoin, GPOS_WSZ_LIT("LeftAntiSemiJoin")}, {EdxltokenJoinLeftAntiSemiJoinNotIn, GPOS_WSZ_LIT("LeftAntiSemiJoinNotIn")}, + {EdxltokenJoinRightSemiJoin, GPOS_WSZ_LIT("RightSemiJoin")}, + {EdxltokenJoinRightAntiSemiJoin, GPOS_WSZ_LIT("RightAntiSemiJoin")}, {EdxltokenMergeJoinUniqueOuter, GPOS_WSZ_LIT("UniqueOuter")}, diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index 95f5da829a3..fa7434b7266 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -338,8 +338,8 @@ add_paths_to_join_relation(PlannerInfo *root, * sorted. This includes both nestloops and mergejoins where the outer * path is already ordered. Again, skip this if we can't mergejoin. * (That's okay because we know that nestloop can't handle - * right/right-anti/full joins at all, so it wouldn't work in the - * prohibited cases either.) + * right/right-anti/right-semi/full joins at all, so it wouldn't work in + * the prohibited cases either.) */ if (mergejoin_allowed) match_unsorted_outer(root, joinrel, outerrel, innerrel, @@ -1897,6 +1897,13 @@ match_unsorted_outer(PlannerInfo *root, if (jointype == JOIN_DEDUP_SEMI || jointype == JOIN_DEDUP_SEMI_REVERSE) jointype = JOIN_INNER; + /* + * For now we do not support RIGHT_SEMI join in mergejoin or nestloop + * join. + */ + if (jointype == JOIN_RIGHT_SEMI) + return; + /* * Nestloop only supports inner, left, semi, and anti joins. Also, if we * are doing a right, right-anti or full mergejoin, we must use *all* the @@ -2501,12 +2508,13 @@ hash_inner_and_outer(PlannerInfo *root, * total inner path will also be parallel-safe, but if not, we'll * have to search for the cheapest safe, unparameterized inner * path. If doing JOIN_UNIQUE_INNER, we can't use any alternative - * inner path. If full, right, or right-anti join, we can't use - * parallelism (building the hash table in each backend) because - * no one process has all the match bits. + * inner path. If full, right, right-semi or right-anti join, we + * can't use parallelism (building the hash table in each backend) + * because no one process has all the match bits. */ if (save_jointype == JOIN_FULL || save_jointype == JOIN_RIGHT || + save_jointype == JOIN_RIGHT_SEMI || save_jointype == JOIN_RIGHT_ANTI) cheapest_safe_inner = NULL; else if (cheapest_total_inner->parallel_safe) @@ -2533,13 +2541,13 @@ hash_inner_and_outer(PlannerInfo *root, * Returns a list of RestrictInfo nodes for those clauses. * * *mergejoin_allowed is normally set to true, but it is set to false if - * this is a right/right-anti/full join and there are nonmergejoinable join - * clauses. The executor's mergejoin machinery cannot handle such cases, so - * we have to avoid generating a mergejoin plan. (Note that this flag does - * NOT consider whether there are actually any mergejoinable clauses. This is - * correct because in some cases we need to build a clauseless mergejoin. - * Simply returning NIL is therefore not enough to distinguish safe from - * unsafe cases.) + * this is a right-semi join, or this is a right/right-anti/full join and + * there are nonmergejoinable join clauses. The executor's mergejoin + * machinery cannot handle such cases, so we have to avoid generating a + * mergejoin plan. (Note that this flag does NOT consider whether there are + * actually any mergejoinable clauses. This is correct because in some + * cases we need to build a clauseless mergejoin. Simply returning NIL is + * therefore not enough to distinguish safe from unsafe cases.) * * We also mark each selected RestrictInfo to show which side is currently * being considered as outer. These are transient markings that are only @@ -2563,6 +2571,16 @@ select_mergejoin_clauses(PlannerInfo *root, bool have_nonmergeable_joinclause = false; ListCell *l; + /* + * For now we do not support RIGHT_SEMI join in mergejoin: the benefit of + * swapping inputs tends to be small here. + */ + if (jointype == JOIN_RIGHT_SEMI) + { + *mergejoin_allowed = false; + return NIL; + } + foreach(l, restrictlist) { RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(l); diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c index d4de56186ab..000b31267cc 100644 --- a/src/backend/optimizer/path/joinrels.c +++ b/src/backend/optimizer/path/joinrels.c @@ -1128,6 +1128,18 @@ populate_joinrel_with_paths(PlannerInfo *root, RelOptInfo *rel1, JOIN_SEMI, sjinfo, restrictlist); + /* + * Also consider "Right Semi Join" plan shapes, with the inputs + * swapped so that the LHS (rel1) becomes the hash/build side. + * This lets us hash the smaller table. Like JOIN_SEMI above, + * this does not add a UniquePath, so (unlike the GPDB + * JOIN_DEDUP_SEMI paths below) it is safe to consider + * unconditionally. + */ + add_paths_to_joinrel(root, joinrel, rel2, rel1, + JOIN_RIGHT_SEMI, sjinfo, + restrictlist); + if (root->upd_del_replicated_table > 0 && (bms_is_member(root->upd_del_replicated_table, rel1->relids) || bms_is_member(root->upd_del_replicated_table, rel2->relids))) diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c index ba99bb1e7bf..88f6971b0aa 100644 --- a/src/backend/optimizer/path/pathkeys.c +++ b/src/backend/optimizer/path/pathkeys.c @@ -1425,6 +1425,9 @@ build_join_pathkeys(PlannerInfo *root, JoinType jointype, List *outer_pathkeys) { + /* RIGHT_SEMI should not come here */ + Assert(jointype != JOIN_RIGHT_SEMI); + if (jointype == JOIN_FULL || jointype == JOIN_RIGHT || jointype == JOIN_RIGHT_ANTI) diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c index dde7402c572..e4c05815d16 100644 --- a/src/backend/optimizer/prep/prepjointree.c +++ b/src/backend/optimizer/prep/prepjointree.c @@ -430,8 +430,8 @@ pull_up_sublinks_jointree_recurse(PlannerInfo *root, Node *jtnode, * point of the available_rels machinations is to ensure that we only * pull up quals for which that's okay. * - * We don't expect to see any pre-existing JOIN_SEMI, JOIN_ANTI, or - * JOIN_RIGHT_ANTI jointypes here. + * We don't expect to see any pre-existing JOIN_SEMI, JOIN_ANTI, + * JOIN_RIGHT_SEMI, or JOIN_RIGHT_ANTI jointypes here. */ switch (j->jointype) { @@ -3277,7 +3277,7 @@ reduce_outer_joins_pass2(Node *jtnode, * These could only have been introduced by pull_up_sublinks, * so there's no way that upper quals could refer to their * righthand sides, and no point in checking. We don't expect - * to see JOIN_RIGHT_ANTI yet. + * to see JOIN_RIGHT_SEMI or JOIN_RIGHT_ANTI yet. */ break; default: diff --git a/src/backend/utils/misc/guc_gp.c b/src/backend/utils/misc/guc_gp.c index 4312c86ad15..77385044f53 100644 --- a/src/backend/utils/misc/guc_gp.c +++ b/src/backend/utils/misc/guc_gp.c @@ -352,6 +352,7 @@ bool optimizer_enable_dml; bool optimizer_enable_dml_constraints; bool optimizer_enable_master_only_queries; bool optimizer_enable_hashjoin; +bool optimizer_enable_right_semi_join = true; bool optimizer_enable_dynamictablescan; bool optimizer_enable_dynamicindexscan; bool optimizer_enable_dynamicindexonlyscan; @@ -2354,6 +2355,17 @@ struct config_bool ConfigureNamesBool_gp[] = NULL, NULL, NULL }, + { + {"optimizer_enable_right_semi_join", PGC_USERSET, DEVELOPER_OPTIONS, + gettext_noop("Enables the optimizer's use of right semi/anti hash join plans."), + NULL, + GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE + }, + &optimizer_enable_right_semi_join, + true, + NULL, NULL, NULL + }, + { {"optimizer_enable_dynamictablescan", PGC_USERSET, DEVELOPER_OPTIONS, gettext_noop("Enables the optimizer's use of plans with dynamic table scan."), diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index bd2c1bcf58c..f81b6de79cc 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -1045,7 +1045,19 @@ typedef enum JoinType * moving the larger of the two relations. */ JOIN_DEDUP_SEMI, /* inner join, LHS path must be made unique afterwards */ - JOIN_DEDUP_SEMI_REVERSE /* inner join, RHS path must be made unique afterwards */ + JOIN_DEDUP_SEMI_REVERSE, /* inner join, RHS path must be made unique afterwards */ + + /* + * JOIN_RIGHT_SEMI (backported from upstream commit aa86129e1) is an + * executor-supported join type, but it is deliberately placed at the END + * of this enum rather than next to JOIN_RIGHT_ANTI where upstream puts it. + * Inserting it in the middle would shift the integer values of the + * GPDB-specific JOIN_DEDUP_SEMI/REVERSE (and JOIN_UNIQUE_*) codes, which + * breaks value-dependent code elsewhere and corrupts MPP motion planning + * (observed as a SIGSEGV during dispatch on semijoins over non-partitioned + * loci). Appending here keeps every pre-existing value stable. + */ + JOIN_RIGHT_SEMI /* 1 copy of each RHS row that has match(es) */ /* * We might need additional join types someday. @@ -1054,10 +1066,10 @@ typedef enum JoinType /* * OUTER joins are those for which pushed-down quals must behave differently - * from the join's own quals. This is in fact everything except INNER and - * SEMI joins. However, this macro must also exclude the JOIN_UNIQUE symbols - * since those are temporary proxies for what will eventually be an INNER - * join. + * from the join's own quals. This is in fact everything except INNER, SEMI + * and RIGHT_SEMI joins. However, this macro must also exclude the + * JOIN_UNIQUE symbols since those are temporary proxies for what will + * eventually be an INNER join. * * Note: semijoins are a hybrid case, but we choose to treat them as not * being outer joins. This is okay principally because the SQL syntax makes diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index 9face599e2a..0c85f55c9c7 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -3275,9 +3275,9 @@ typedef struct PlaceHolderVar * min_lefthand and min_righthand for higher joins.) * * jointype is never JOIN_RIGHT; a RIGHT JOIN is handled by switching - * the inputs to make it a LEFT JOIN. It's never JOIN_RIGHT_ANTI either. - * So the allowed values of jointype in a join_info_list member are only - * LEFT, FULL, SEMI, or ANTI. + * the inputs to make it a LEFT JOIN. It's never JOIN_RIGHT_SEMI or + * JOIN_RIGHT_ANTI either. So the allowed values of jointype in a + * join_info_list member are only LEFT, FULL, SEMI, or ANTI. * * ojrelid is the RT index of the join RTE representing this outer join, * if there is one. It is zero when jointype is INNER or SEMI, and can be diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index 4f6401fb43f..4ff7b7eef19 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -540,6 +540,7 @@ extern bool optimizer_enable_dml_constraints; extern bool optimizer_enable_direct_dispatch; extern bool optimizer_enable_master_only_queries; extern bool optimizer_enable_hashjoin; +extern bool optimizer_enable_right_semi_join; extern bool optimizer_enable_dynamictablescan; extern bool optimizer_enable_dynamicindexscan; extern bool optimizer_enable_dynamicindexonlyscan; diff --git a/src/include/utils/unsync_guc_name.h b/src/include/utils/unsync_guc_name.h index 02b04fdc5c4..3df4c8cbd71 100644 --- a/src/include/utils/unsync_guc_name.h +++ b/src/include/utils/unsync_guc_name.h @@ -424,6 +424,7 @@ "optimizer_discard_redistribute_hashjoin", "optimizer_enable_indexjoin", "optimizer_enable_indexonlyscan", + "optimizer_enable_right_semi_join", "optimizer_enable_indexscan", "optimizer_enable_master_only_queries", "optimizer_enable_materialize", diff --git a/src/test/regress/expected/bfv_partition_plans.out b/src/test/regress/expected/bfv_partition_plans.out index 034624e6d17..42e259528de 100644 --- a/src/test/regress/expected/bfv_partition_plans.out +++ b/src/test/regress/expected/bfv_partition_plans.out @@ -24,7 +24,7 @@ SET optimizer_trace_fallback=on; -- -- start_ignore create language plpython3u; -ERROR: language "plpython3u" already exists +ERROR: extension "plpython3u" already exists -- end_ignore create or replace function count_operator(query text, operator text) returns int as $$ @@ -98,10 +98,10 @@ insert into mpp7980 values('2009-03-03','xyz','zyz','4',1,3,'1'); select cust_type, subscription_status,count(distinct subscription_id),sum(voice_call_min),sum(minute_per_call) from mpp7980 where month_id ='2009-04-01' group by rollup(1,2); cust_type | subscription_status | count | sum | sum -----------+---------------------+-------+------+------ - | | 1 | 3.00 | 2.00 - zyz | | 1 | 3.00 | 2.00 zyz | 1 | 1 | 1.00 | 1.00 zyz | 2 | 1 | 2.00 | 1.00 + zyz | | 1 | 3.00 | 2.00 + | | 1 | 3.00 | 2.00 (4 rows) -- CLEANUP @@ -113,6 +113,7 @@ drop table mpp7980; -- SETUP -- start_ignore set optimizer_enable_bitmapscan=on; +set optimizer_enable_dynamicbitmapscan=on; set optimizer_enable_indexjoin=on; drop table if exists mpp23195_t1; NOTICE: table "mpp23195_t1" does not exist, skipping @@ -157,6 +158,7 @@ select * from mpp23195_t1,mpp23195_t2 where mpp23195_t1.i < mpp23195_t2.i; drop table if exists mpp23195_t1; drop table if exists mpp23195_t2; set optimizer_enable_bitmapscan=off; +set optimizer_enable_dynamicbitmapscan=off; set optimizer_enable_indexjoin=off; -- end_ignore -- @@ -795,6 +797,7 @@ reset optimizer_segments; -- SETUP -- start_ignore DROP TABLE IF EXISTS bar; +NOTICE: table "bar" does not exist, skipping -- end_ignore CREATE TABLE bar (b int, c int) PARTITION BY RANGE (b) @@ -809,26 +812,26 @@ ANALYZE bar; SELECT b FROM bar GROUP BY b; b ---- + 15 + 0 + 1 + 12 + 8 + 19 7 + 18 4 - 19 + 2 + 16 3 - 5 - 18 - 6 + 17 11 - 9 - 8 - 12 + 13 10 - 17 - 1 - 0 - 2 - 16 - 15 + 9 + 5 + 6 14 - 13 (20 rows) EXPLAIN SELECT b FROM bar GROUP BY b; @@ -845,6 +848,7 @@ EXPLAIN SELECT b FROM bar GROUP BY b; -- CLEANUP DROP TABLE IF EXISTS foo; +NOTICE: table "foo" does not exist, skipping DROP TABLE IF EXISTS bar; -- Test EXPLAIN ANALYZE on a partitioned table. There used to be a bug, where -- you got an internal error with this, because the EXPLAIN ANALYZE sends the @@ -867,26 +871,26 @@ HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sur explain analyze select a.* from mpp8031 a, mpp8031 b where a.oid = b.oid; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2743.00..2475974.00 rows=80883360 width=16) (actual time=0.707..0.709 rows=0 loops=1) - -> Hash Join (cost=2743.00..1397529.20 rows=26961120 width=16) (actual time=0.024..0.028 rows=0 loops=1) + Gather Motion 3:1 (slice1; segments: 3) (cost=2743.00..2475974.00 rows=80883360 width=16) (actual time=0.379..0.381 rows=0 loops=1) + -> Hash Join (cost=2743.00..1397529.20 rows=26961120 width=16) (actual time=0.037..0.040 rows=0 loops=1) Hash Cond: (a.oid = b.oid) - -> Append (cost=0.00..1558.00 rows=94800 width=16) (actual time=0.021..0.023 rows=0 loops=1) - -> Seq Scan on mpp8031_1_prt_foo_1 a_1 (cost=0.00..271.00 rows=23700 width=16) (actual time=0.010..0.010 rows=0 loops=1) - -> Seq Scan on mpp8031_1_prt_2 a_2 (cost=0.00..271.00 rows=23700 width=16) (actual time=0.003..0.004 rows=0 loops=1) - -> Seq Scan on mpp8031_1_prt_3 a_3 (cost=0.00..271.00 rows=23700 width=16) (actual time=0.003..0.003 rows=0 loops=1) - -> Seq Scan on mpp8031_1_prt_4 a_4 (cost=0.00..271.00 rows=23700 width=16) (actual time=0.003..0.003 rows=0 loops=1) + -> Append (cost=0.00..1558.00 rows=94800 width=16) (actual time=0.036..0.037 rows=0 loops=1) + -> Seq Scan on mpp8031_1_prt_foo_1 a_1 (cost=0.00..271.00 rows=23700 width=16) (actual time=0.015..0.015 rows=0 loops=1) + -> Seq Scan on mpp8031_1_prt_2 a_2 (cost=0.00..271.00 rows=23700 width=16) (actual time=0.007..0.007 rows=0 loops=1) + -> Seq Scan on mpp8031_1_prt_3 a_3 (cost=0.00..271.00 rows=23700 width=16) (actual time=0.006..0.006 rows=0 loops=1) + -> Seq Scan on mpp8031_1_prt_4 a_4 (cost=0.00..271.00 rows=23700 width=16) (actual time=0.007..0.007 rows=0 loops=1) -> Hash (cost=1558.00..1558.00 rows=94800 width=4) (never executed) -> Append (cost=0.00..1558.00 rows=94800 width=4) (never executed) -> Seq Scan on mpp8031_1_prt_foo_1 b_1 (cost=0.00..271.00 rows=23700 width=4) (never executed) -> Seq Scan on mpp8031_1_prt_2 b_2 (cost=0.00..271.00 rows=23700 width=4) (never executed) -> Seq Scan on mpp8031_1_prt_3 b_3 (cost=0.00..271.00 rows=23700 width=4) (never executed) -> Seq Scan on mpp8031_1_prt_4 b_4 (cost=0.00..271.00 rows=23700 width=4) (never executed) - Planning Time: 2.080 ms - (slice0) Executor memory: 122K bytes. + Planning Time: 0.303 ms + (slice0) Executor memory: 53K bytes. (slice1) Executor memory: 121K bytes avg x 3x(0) workers, 121K bytes max (seg0). Memory used: 128000kB Optimizer: Postgres query optimizer - Execution Time: 1.279 ms + Execution Time: 0.661 ms (20 rows) drop table mpp8031; @@ -915,6 +919,9 @@ INSERT INTO part_tbl VALUES (2015111000, 479534741, 99999999); INSERT INTO part_tbl VALUES (2015111000, 479534742, 99999999); CREATE INDEX part_tbl_idx ON part_tbl(profile_key); +-- start_ignore +analyze part_tbl; +-- end_ignore EXPLAIN SELECT * FROM part_tbl WHERE profile_key = 99999999; QUERY PLAN --------------------------------------------------------------------------------------------------------------------- @@ -1140,9 +1147,9 @@ explain select * from fact where dd < current_date; --partitions eliminated ----------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=40) -> Seq Scan on fact_1_prt_1 fact (cost=0.00..1.01 rows=1 width=40) - Filter: (dd < '04-28-2022'::date) + Filter: (dd < '06-17-2026'::date) Optimizer: Postgres query optimizer -(6 rows) +(4 rows) -- Test partition elimination in prepared statements prepare f1(date) as select * from fact where dd < $1; @@ -1227,39 +1234,37 @@ INSERT INTO delete_from_pt SELECT i, i%6 FROM generate_series(1, 10)i; INSERT INTO t VALUES (1); ANALYZE delete_from_pt, t; EXPLAIN (COSTS OFF, TIMING OFF, SUMMARY OFF, ANALYZE) DELETE FROM delete_from_pt WHERE b IN (SELECT b FROM delete_from_pt, t WHERE t.a=delete_from_pt.b); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +----------------------------------------------------------------------------------------------------------- Delete on delete_from_pt (actual rows=0 loops=1) Delete on delete_from_pt_1_prt_1 delete_from_pt_2 Delete on delete_from_pt_1_prt_2 delete_from_pt_3 Delete on delete_from_pt_1_prt_3 delete_from_pt_4 - -> Hash Semi Join (actual rows=1 loops=1) - Hash Cond: (delete_from_pt.b = t.a) - Extra Text: (seg0) Hash chain length 2.0 avg, 2 max, using 1 of 131072 buckets. - -> Append (actual rows=3 loops=1) - Partition Selectors: $1 - -> Seq Scan on delete_from_pt_1_prt_1 delete_from_pt_2 (actual rows=3 loops=1) - -> Seq Scan on delete_from_pt_1_prt_2 delete_from_pt_3 (never executed) - -> Seq Scan on delete_from_pt_1_prt_3 delete_from_pt_4 (never executed) - -> Hash (actual rows=2 loops=1) + -> Hash Right Semi Join (actual rows=1 loops=1) + Hash Cond: (t.a = delete_from_pt.b) + Extra Text: (seg0) Hash chain length 1.2 avg, 2 max, using 4 of 131072 buckets. + -> Broadcast Motion 3:3 (slice1; segments: 3) (actual rows=2 loops=1) + -> Hash Join (actual rows=1 loops=1) + Hash Cond: (delete_from_pt_1.b = t.a) + Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 1 of 262144 buckets. + -> Append (actual rows=3 loops=1) + Partition Selectors: $1 + -> Seq Scan on delete_from_pt_1_prt_1 delete_from_pt_5 (actual rows=3 loops=1) + -> Seq Scan on delete_from_pt_1_prt_2 delete_from_pt_6 (never executed) + -> Seq Scan on delete_from_pt_1_prt_3 delete_from_pt_7 (never executed) + -> Hash (actual rows=1 loops=1) + Buckets: 262144 Batches: 1 Memory Usage: 2049kB + -> Partition Selector (selector id: $1) (actual rows=1 loops=1) + -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=1 loops=1) + -> Seq Scan on t (actual rows=1 loops=1) + -> Hash (actual rows=5 loops=1) Buckets: 131072 Batches: 1 Memory Usage: 1025kB - -> Partition Selector (selector id: $1) (actual rows=2 loops=1) - -> Broadcast Motion 3:3 (slice1; segments: 3) (actual rows=2 loops=1) - -> Hash Join (actual rows=1 loops=1) - Hash Cond: (delete_from_pt_1.b = t.a) - Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 1 of 262144 buckets. - -> Append (actual rows=3 loops=1) - Partition Selectors: $2 - -> Seq Scan on delete_from_pt_1_prt_1 delete_from_pt_5 (actual rows=3 loops=1) - -> Seq Scan on delete_from_pt_1_prt_2 delete_from_pt_6 (never executed) - -> Seq Scan on delete_from_pt_1_prt_3 delete_from_pt_7 (never executed) - -> Hash (actual rows=1 loops=1) - Buckets: 262144 Batches: 1 Memory Usage: 2049kB - -> Partition Selector (selector id: $2) (actual rows=1 loops=1) - -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=1 loops=1) - -> Seq Scan on t (actual rows=1 loops=1) + -> Append (actual rows=5 loops=1) + -> Seq Scan on delete_from_pt_1_prt_1 delete_from_pt_2 (actual rows=3 loops=1) + -> Seq Scan on delete_from_pt_1_prt_2 delete_from_pt_3 (actual rows=3 loops=1) + -> Seq Scan on delete_from_pt_1_prt_3 delete_from_pt_4 (actual rows=0 loops=1) Optimizer: Postgres query optimizer -(30 rows) +(28 rows) SELECT * FROM delete_from_pt order by a; a | b @@ -1278,7 +1283,10 @@ RESET optimizer_trace_fallback; -- CLEANUP -- start_ignore drop schema if exists bfv_partition_plans cascade; -NOTICE: drop cascades to 2 other objects +NOTICE: drop cascades to 5 other objects DETAIL: drop cascades to function count_operator(text,text) drop cascades to function find_operator(text,text) +drop cascades to table delete_from_indexed_pt +drop cascades to table delete_from_pt +drop cascades to table t -- end_ignore diff --git a/src/test/regress/expected/bfv_partition_plans_optimizer.out b/src/test/regress/expected/bfv_partition_plans_optimizer.out index dd9a07b4d0b..9cb53257a07 100644 --- a/src/test/regress/expected/bfv_partition_plans_optimizer.out +++ b/src/test/regress/expected/bfv_partition_plans_optimizer.out @@ -24,7 +24,7 @@ SET optimizer_trace_fallback=on; -- -- start_ignore create language plpython3u; -ERROR: language "plpython3u" already exists +ERROR: extension "plpython3u" already exists -- end_ignore create or replace function count_operator(query text, operator text) returns int as $$ @@ -61,6 +61,8 @@ update mpp3061 set i = 2 where i = 1; INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: DML(update) on partitioned tables select tableoid::regclass, * from mpp3061 where i = 2; +NOTICE: One or more columns in the following table(s) do not have statistics: mpp3061 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. tableoid | i -----------------+--- mpp3061_1_prt_2 | 2 @@ -91,6 +93,8 @@ distributed by (subscription_id, bill_stmt_id) select count_operator('select cust_type, subscription_status,count(distinct subscription_id),sum(voice_call_min),sum(minute_per_call) from mpp7980 where month_id =E''2009-04-01'' group by rollup(1,2);','SIGSEGV'); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: SIRV functions +NOTICE: One or more columns in the following table(s) do not have statistics: mpp7980 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. count_operator ---------------- 0 @@ -100,12 +104,14 @@ insert into mpp7980 values('2009-04-01','xyz','zyz','1',1,1,'1'); insert into mpp7980 values('2009-04-01','zxyz','zyz','2',2,1,'1'); insert into mpp7980 values('2009-03-03','xyz','zyz','4',1,3,'1'); select cust_type, subscription_status,count(distinct subscription_id),sum(voice_call_min),sum(minute_per_call) from mpp7980 where month_id ='2009-04-01' group by rollup(1,2); +NOTICE: One or more columns in the following table(s) do not have statistics: mpp7980 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. cust_type | subscription_status | count | sum | sum -----------+---------------------+-------+------+------ - | | 1 | 3.00 | 2.00 - zyz | | 1 | 3.00 | 2.00 zyz | 1 | 1 | 1.00 | 1.00 zyz | 2 | 1 | 2.00 | 1.00 + zyz | | 1 | 3.00 | 2.00 + | | 1 | 3.00 | 2.00 (4 rows) -- CLEANUP @@ -117,6 +123,7 @@ drop table mpp7980; -- SETUP -- start_ignore set optimizer_enable_bitmapscan=on; +set optimizer_enable_dynamicbitmapscan=on; set optimizer_enable_indexjoin=on; drop table if exists mpp23195_t1; NOTICE: table "mpp23195_t1" does not exist, skipping @@ -136,12 +143,16 @@ insert into mpp23195_t2 values (1); select find_operator('select * from mpp23195_t1,mpp23195_t2 where mpp23195_t1.i < mpp23195_t2.i;', 'Dynamic Index Scan'); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: SIRV functions +NOTICE: One or more columns in the following table(s) do not have statistics: mpp23195_t1 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. find_operator --------------- ['true'] (1 row) select * from mpp23195_t1,mpp23195_t2 where mpp23195_t1.i < mpp23195_t2.i; +NOTICE: One or more columns in the following table(s) do not have statistics: mpp23195_t1 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. i | i ---+--- (0 rows) @@ -169,6 +180,7 @@ HINT: For non-partitioned tables, run analyze (). For drop table if exists mpp23195_t1; drop table if exists mpp23195_t2; set optimizer_enable_bitmapscan=off; +set optimizer_enable_dynamicbitmapscan=off; set optimizer_enable_indexjoin=off; -- end_ignore -- @@ -194,6 +206,8 @@ set optimizer_enable_hashjoin = off; select find_operator('analyze select * from mpp21834_t2,mpp21834_t1 where mpp21834_t2.i < mpp21834_t1.i;','Dynamic Index Scan'); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: SIRV functions +NOTICE: One or more columns in the following table(s) do not have statistics: mpp21834_t1 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. find_operator --------------- ['false'] @@ -202,6 +216,8 @@ DETAIL: Falling back to Postgres-based planner because GPORCA does not support select find_operator('analyze select * from mpp21834_t2,mpp21834_t1 where mpp21834_t2.i < mpp21834_t1.i;','Nested Loop'); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: SIRV functions +NOTICE: One or more columns in the following table(s) do not have statistics: mpp21834_t1 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. find_operator --------------- ['true'] @@ -652,6 +668,8 @@ create index dbs_index on dbs using bitmap(c3); select find_operator('(select * from dts where c2 = 1) union (select * from dts where c2 = 2) union (select * from dts where c2 = 3) union (select * from dts where c2 = 4) union (select * from dts where c2 = 5) union (select * from dts where c2 = 6) union (select * from dts where c2 = 7) union (select * from dts where c2 = 8) union (select * from dts where c2 = 9) union (select * from dts where c2 = 10);', 'Dynamic Seq Scan'); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: SIRV functions +NOTICE: One or more columns in the following table(s) do not have statistics: dts +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. find_operator --------------- ['true'] @@ -667,6 +685,8 @@ DETAIL: Falling back to Postgres-based planner because GPORCA does not support (select * from dts where c2 = 8) union (select * from dts where c2 = 9) union (select * from dts where c2 = 10); +NOTICE: One or more columns in the following table(s) do not have statistics: dts +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. c1 | c2 ----+---- (0 rows) @@ -675,6 +695,8 @@ set optimizer_enable_dynamictablescan = off; select find_operator('(select * from dis where c3 = 1) union (select * from dis where c3 = 2) union (select * from dis where c3 = 3) union (select * from dis where c3 = 4) union (select * from dis where c3 = 5) union (select * from dis where c3 = 6) union (select * from dis where c3 = 7) union (select * from dis where c3 = 8) union (select * from dis where c3 = 9) union (select * from dis where c3 = 10);', 'Dynamic Index Scan'); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: SIRV functions +NOTICE: One or more columns in the following table(s) do not have statistics: dis +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. find_operator --------------- ['true'] @@ -690,6 +712,8 @@ DETAIL: Falling back to Postgres-based planner because GPORCA does not support (select * from dis where c3 = 8) union (select * from dis where c3 = 9) union (select * from dis where c3 = 10); +NOTICE: One or more columns in the following table(s) do not have statistics: dis +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. c1 | c2 | c3 ----+----+---- (0 rows) @@ -794,6 +818,8 @@ PARTITION BY LIST(month_id) ); -- TEST select * from ds_4 where month_id = '200800'; +NOTICE: One or more columns in the following table(s) do not have statistics: ds_4 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. month_id | cust_group_acc | mobile_no ----------+----------------+----------- (0 rows) @@ -801,12 +827,16 @@ select * from ds_4 where month_id = '200800'; select count_operator('select * from ds_4 where month_id = E''200800'';','Partition Selector'); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: SIRV functions +NOTICE: One or more columns in the following table(s) do not have statistics: ds_4 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. count_operator ---------------- 0 (1 row) select * from ds_4 where month_id > '200800'; +NOTICE: One or more columns in the following table(s) do not have statistics: ds_4 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. month_id | cust_group_acc | mobile_no ----------+----------------+----------- (0 rows) @@ -814,12 +844,16 @@ select * from ds_4 where month_id > '200800'; select count_operator('select * from ds_4 where month_id > E''200800'';','Partition Selector'); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: SIRV functions +NOTICE: One or more columns in the following table(s) do not have statistics: ds_4 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. count_operator ---------------- 0 (1 row) select * from ds_4 where month_id <= '200800'; +NOTICE: One or more columns in the following table(s) do not have statistics: ds_4 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. month_id | cust_group_acc | mobile_no ----------+----------------+----------- (0 rows) @@ -827,12 +861,16 @@ select * from ds_4 where month_id <= '200800'; select count_operator('select * from ds_4 where month_id <= E''200800'';','Partition Selector'); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: SIRV functions +NOTICE: One or more columns in the following table(s) do not have statistics: ds_4 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. count_operator ---------------- 0 (1 row) select * from ds_4 a1,ds_4 a2 where a1.month_id = a2.month_id and a1.month_id > '200800'; +NOTICE: One or more columns in the following table(s) do not have statistics: ds_4 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. month_id | cust_group_acc | mobile_no | month_id | cust_group_acc | mobile_no ----------+----------------+-----------+----------+----------------+----------- (0 rows) @@ -840,6 +878,8 @@ select * from ds_4 a1,ds_4 a2 where a1.month_id = a2.month_id and a1.month_id > select count_operator('select * from ds_4 a1,ds_4 a2 where a1.month_id = a2.month_id and a1.month_id > E''200800'';','Partition Selector'); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: SIRV functions +NOTICE: One or more columns in the following table(s) do not have statistics: ds_4 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. count_operator ---------------- 1 @@ -857,6 +897,7 @@ reset optimizer_segments; -- SETUP -- start_ignore DROP TABLE IF EXISTS bar; +NOTICE: table "bar" does not exist, skipping -- end_ignore CREATE TABLE bar (b int, c int) PARTITION BY RANGE (b) @@ -871,26 +912,26 @@ ANALYZE bar; SELECT b FROM bar GROUP BY b; b ---- - 7 - 4 - 19 - 3 - 5 - 18 - 6 + 15 + 0 + 1 + 12 + 17 11 + 13 + 10 9 + 5 + 6 + 14 8 - 12 - 10 - 17 - 1 - 0 + 19 + 7 + 18 + 4 2 16 - 15 - 14 - 13 + 3 (20 rows) EXPLAIN SELECT b FROM bar GROUP BY b; @@ -901,11 +942,12 @@ EXPLAIN SELECT b FROM bar GROUP BY b; Group Key: b -> Dynamic Seq Scan on bar (cost=0.00..431.01 rows=334 width=4) Number of partitions to scan: 2 (out of 2) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (6 rows) -- CLEANUP DROP TABLE IF EXISTS foo; +NOTICE: table "foo" does not exist, skipping DROP TABLE IF EXISTS bar; -- Test EXPLAIN ANALYZE on a partitioned table. There used to be a bug, where -- you got an internal error with this, because the EXPLAIN ANALYZE sends the @@ -926,24 +968,26 @@ EVERY ('2 mons'::interval) NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'oid' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. explain analyze select a.* from mpp8031 a, mpp8031 b where a.oid = b.oid; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=1 width=16) (actual time=2.533..2.533 rows=0 loops=1) - -> Hash Join (cost=0.00..862.00 rows=1 width=16) (never executed) +NOTICE: One or more columns in the following table(s) do not have statistics: mpp8031 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=1 width=16) (actual time=2.953..2.954 rows=0 loops=1) + -> Hash Join (cost=0.00..862.00 rows=1 width=16) (actual time=2.691..2.693 rows=0 loops=1) Hash Cond: (a.oid = b.oid) -> Dynamic Seq Scan on mpp8031 a (cost=0.00..431.00 rows=1 width=16) (never executed) Number of partitions to scan: 4 (out of 4) - -> Hash (cost=431.00..431.00 rows=1 width=4) (never executed) + -> Hash (cost=431.00..431.00 rows=1 width=4) (actual time=0.131..0.132 rows=0 loops=1) Buckets: 524288 Batches: 1 Memory Usage: 4096kB - -> Dynamic Seq Scan on mpp8031 b (cost=0.00..431.00 rows=1 width=4) (actual time=0.000..0.324 rows=0 loops=1) + -> Dynamic Seq Scan on mpp8031 b (cost=0.00..431.00 rows=1 width=4) (actual time=0.131..0.131 rows=0 loops=1) Number of partitions to scan: 4 (out of 4) Partitions scanned: Avg 4.0 x 3 workers. Max 4 parts (seg0). - Planning Time: 4.433 ms - (slice0) Executor memory: 31K bytes. - (slice1) Executor memory: 4156K bytes avg x 3 workers, 4156K bytes max (seg0). Work_mem: 4096K bytes max. + Planning Time: 3.321 ms + (slice0) Executor memory: 25K bytes. + (slice1) Executor memory: 4227K bytes avg x 3x(0) workers, 4227K bytes max (seg0). Work_mem: 4096K bytes max. Memory used: 128000kB - Optimizer: Pivotal Optimizer (GPORCA) - Execution Time: 3.231 ms + Optimizer: GPORCA + Execution Time: 3.214 ms (16 rows) drop table mpp8031; @@ -976,13 +1020,16 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Multi-level partitioned tables CREATE INDEX part_tbl_idx ON part_tbl(profile_key); +-- start_ignore +analyze part_tbl; +-- end_ignore EXPLAIN SELECT * FROM part_tbl WHERE profile_key = 99999999; INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Multi-level partitioned tables - QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.07 rows=2 width=25) - -> Append (cost=0.00..2.03 rows=1 width=25) + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.11 rows=6 width=25) + -> Append (cost=0.00..2.03 rows=2 width=25) -> Seq Scan on part_tbl_1_prt_p20151110_2_prt_package5 part_tbl_1 (cost=0.00..1.01 rows=1 width=25) Filter: (profile_key = '99999999'::numeric) -> Seq Scan on part_tbl_1_prt_p20151110_2_prt_other_services part_tbl_2 (cost=0.00..1.01 rows=1 width=25) @@ -995,8 +1042,8 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Multi-level partitioned tables time_client_key | ngin_service_key | profile_key -----------------+------------------+------------- - 2015111000 | 479534742 | 99999999 2015111000 | 479534741 | 99999999 + 2015111000 | 479534742 | 99999999 (2 rows) DROP TABLE part_tbl; @@ -1025,6 +1072,8 @@ HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sur insert into r_part values (1,1), (2,2), (3,3), (4,4), (5,5), (6,6), (7,7), (8,8); -- following tests rely on the data distribution, verify them select gp_segment_id, * from r_part order by a,b; +NOTICE: One or more columns in the following table(s) do not have statistics: r_part +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. gp_segment_id | a | b ---------------+---+--- 1 | 1 | 1 @@ -1041,8 +1090,8 @@ analyze r_part; explain select * from r_part r1, r_part r2 where r1.a=1; -- should eliminate partitions in the r1 copy of r_part QUERY PLAN --------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.53 rows=8 width=16) - -> Nested Loop (cost=0.00..1324032.53 rows=3 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.54 rows=8 width=16) + -> Nested Loop (cost=0.00..1324032.54 rows=3 width=16) Join Filter: true -> Dynamic Seq Scan on r_part r2 (cost=0.00..431.00 rows=3 width=8) Number of partitions to scan: 9 (out of 9) @@ -1051,7 +1100,7 @@ explain select * from r_part r1, r_part r2 where r1.a=1; -- should eliminate par -> Dynamic Seq Scan on r_part r1 (cost=0.00..431.00 rows=1 width=8) Number of partitions to scan: 1 (out of 9) Filter: (a = 1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) -- the numbers in the filter should be both on segment 0 @@ -1062,7 +1111,7 @@ explain select * from r_part where a in (7,8); -- should eliminate partitions -> Dynamic Seq Scan on r_part (cost=0.00..431.00 rows=1 width=8) Number of partitions to scan: 2 (out of 9) Filter: (a = ANY ('{7,8}'::integer[])) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) -- Test partition elimination in prepared statements @@ -1096,7 +1145,7 @@ explain select * from r_part where a = 1 order by a,b; -- should eliminate parti -> Dynamic Seq Scan on r_part (cost=0.00..431.00 rows=1 width=8) Number of partitions to scan: 1 (out of 9) Filter: (a = 1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) --force_explain @@ -1110,7 +1159,7 @@ explain execute f1(1); -- should eliminate partitions -> Dynamic Seq Scan on r_part (cost=0.00..431.00 rows=1 width=8) Number of partitions to scan: 1 (out of 9) Filter: (a = 1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) --force_explain @@ -1124,7 +1173,7 @@ explain execute f2(2); -- should eliminate partitions -> Dynamic Seq Scan on r_part (cost=0.00..431.00 rows=1 width=8) Number of partitions to scan: 1 (out of 9) Filter: (a = 2) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) -- Test partition elimination on CO tables @@ -1137,7 +1186,7 @@ explain select * from r_co where a=2; -- should eliminate partitions -> Dynamic Seq Scan on r_co (cost=0.00..431.00 rows=1 width=8) Number of partitions to scan: 1 (out of 9) Filter: (a = 2) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) -- test partition elimination in prepared statements on CO tables @@ -1153,7 +1202,7 @@ explain execute f3(2); -- should eliminate partitions -> Dynamic Seq Scan on r_co (cost=0.00..431.00 rows=1 width=8) Number of partitions to scan: 1 (out of 9) Filter: (a = 2) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) -- start_ignore @@ -1187,7 +1236,7 @@ explain select * from fact where dd < '2009-01-02'::date; -- partitions eliminat -> Dynamic Seq Scan on fact (cost=0.00..431.00 rows=1 width=16) Number of partitions to scan: 1 (out of 4) Filter: (dd < '01-02-2009'::date) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) explain select * from fact where dd < to_date('2009-01-02','YYYY-MM-DD'); -- partitions eliminated @@ -1197,7 +1246,7 @@ explain select * from fact where dd < to_date('2009-01-02','YYYY-MM-DD'); -- par -> Dynamic Seq Scan on fact (cost=0.00..431.00 rows=1 width=16) Number of partitions to scan: 1 (out of 4) Filter: (dd < '01-02-2009'::date) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) explain select * from fact where dd < current_date; --partitions eliminated @@ -1206,8 +1255,8 @@ explain select * from fact where dd < current_date; --partitions eliminated Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=16) -> Dynamic Seq Scan on fact (cost=0.00..431.00 rows=1 width=16) Number of partitions to scan: 1 (out of 4) - Filter: (dd < '09-30-2022'::date) - Optimizer: Pivotal Optimizer (GPORCA) + Filter: (dd < '06-17-2026'::date) + Optimizer: GPORCA (5 rows) -- Test partition elimination in prepared statements @@ -1220,7 +1269,7 @@ explain execute f1('2009-01-02'::date); -- should eliminate partitions -> Dynamic Seq Scan on fact (cost=0.00..431.00 rows=1 width=16) Number of partitions to scan: 1 (out of 4) Filter: (dd < '01-02-2009'::date) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) -- force_explain @@ -1231,7 +1280,7 @@ explain execute f1(to_date('2009-01-02', 'YYYY-MM-DD')); -- should eliminate par -> Dynamic Seq Scan on fact (cost=0.00..431.00 rows=1 width=16) Number of partitions to scan: 1 (out of 4) Filter: (dd < '01-02-2009'::date) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) -- start_ignore @@ -1280,6 +1329,8 @@ DELETE FROM delete_from_indexed_pt WHERE b=1; INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: DML(delete) on partitioned tables SELECT * FROM delete_from_indexed_pt; +NOTICE: One or more columns in the following table(s) do not have statistics: delete_from_indexed_pt +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b ----+--- 6 | 0 @@ -1305,39 +1356,37 @@ ANALYZE delete_from_pt, t; EXPLAIN (COSTS OFF, TIMING OFF, SUMMARY OFF, ANALYZE) DELETE FROM delete_from_pt WHERE b IN (SELECT b FROM delete_from_pt, t WHERE t.a=delete_from_pt.b); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: DML(delete) on partitioned tables - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +----------------------------------------------------------------------------------------------------------- Delete on delete_from_pt (actual rows=0 loops=1) Delete on delete_from_pt_1_prt_1 delete_from_pt_2 Delete on delete_from_pt_1_prt_2 delete_from_pt_3 Delete on delete_from_pt_1_prt_3 delete_from_pt_4 - -> Hash Semi Join (actual rows=1 loops=1) - Hash Cond: (delete_from_pt.b = t.a) - Extra Text: (seg0) Hash chain length 2.0 avg, 2 max, using 1 of 131072 buckets. - -> Append (actual rows=3 loops=1) - Partition Selectors: $1 - -> Seq Scan on delete_from_pt_1_prt_1 delete_from_pt_2 (actual rows=3 loops=1) - -> Seq Scan on delete_from_pt_1_prt_2 delete_from_pt_3 (never executed) - -> Seq Scan on delete_from_pt_1_prt_3 delete_from_pt_4 (never executed) - -> Hash (actual rows=2 loops=1) + -> Hash Right Semi Join (actual rows=1 loops=1) + Hash Cond: (t.a = delete_from_pt.b) + Extra Text: (seg0) Hash chain length 1.2 avg, 2 max, using 4 of 131072 buckets. + -> Broadcast Motion 3:3 (slice1; segments: 3) (actual rows=2 loops=1) + -> Hash Join (actual rows=1 loops=1) + Hash Cond: (delete_from_pt_1.b = t.a) + Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 1 of 262144 buckets. + -> Append (actual rows=3 loops=1) + Partition Selectors: $1 + -> Seq Scan on delete_from_pt_1_prt_1 delete_from_pt_5 (actual rows=3 loops=1) + -> Seq Scan on delete_from_pt_1_prt_2 delete_from_pt_6 (never executed) + -> Seq Scan on delete_from_pt_1_prt_3 delete_from_pt_7 (never executed) + -> Hash (actual rows=1 loops=1) + Buckets: 262144 Batches: 1 Memory Usage: 2049kB + -> Partition Selector (selector id: $1) (actual rows=1 loops=1) + -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=1 loops=1) + -> Seq Scan on t (actual rows=1 loops=1) + -> Hash (actual rows=5 loops=1) Buckets: 131072 Batches: 1 Memory Usage: 1025kB - -> Partition Selector (selector id: $1) (actual rows=2 loops=1) - -> Broadcast Motion 3:3 (slice1; segments: 3) (actual rows=2 loops=1) - -> Hash Join (actual rows=1 loops=1) - Hash Cond: (delete_from_pt_1.b = t.a) - Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 1 of 262144 buckets. - -> Append (actual rows=3 loops=1) - Partition Selectors: $2 - -> Seq Scan on delete_from_pt_1_prt_1 delete_from_pt_5 (actual rows=3 loops=1) - -> Seq Scan on delete_from_pt_1_prt_2 delete_from_pt_6 (never executed) - -> Seq Scan on delete_from_pt_1_prt_3 delete_from_pt_7 (never executed) - -> Hash (actual rows=1 loops=1) - Buckets: 262144 Batches: 1 Memory Usage: 2049kB - -> Partition Selector (selector id: $2) (actual rows=1 loops=1) - -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=1 loops=1) - -> Seq Scan on t (actual rows=1 loops=1) + -> Append (actual rows=5 loops=1) + -> Seq Scan on delete_from_pt_1_prt_1 delete_from_pt_2 (actual rows=3 loops=1) + -> Seq Scan on delete_from_pt_1_prt_2 delete_from_pt_3 (actual rows=3 loops=1) + -> Seq Scan on delete_from_pt_1_prt_3 delete_from_pt_4 (actual rows=0 loops=1) Optimizer: Postgres query optimizer -(30 rows) +(28 rows) SELECT * FROM delete_from_pt order by a; a | b @@ -1356,7 +1405,10 @@ RESET optimizer_trace_fallback; -- CLEANUP -- start_ignore drop schema if exists bfv_partition_plans cascade; -NOTICE: drop cascades to 2 other objects +NOTICE: drop cascades to 5 other objects DETAIL: drop cascades to function count_operator(text,text) drop cascades to function find_operator(text,text) +drop cascades to table delete_from_indexed_pt +drop cascades to table delete_from_pt +drop cascades to table t -- end_ignore diff --git a/src/test/regress/expected/bfv_planner_optimizer.out b/src/test/regress/expected/bfv_planner_optimizer.out index 56ab8968024..011948af4a4 100644 --- a/src/test/regress/expected/bfv_planner_optimizer.out +++ b/src/test/regress/expected/bfv_planner_optimizer.out @@ -205,11 +205,11 @@ delete from p where b = 1 or (b=2 and a in (select r.a from r)); select * from p; a | b ---+--- + 2 | 2 + 2 | 3 3 | 3 1 | 2 1 | 3 - 2 | 2 - 2 | 3 (5 rows) delete from p where b = 1 or (b=2 and a in (select b from r)); @@ -234,8 +234,8 @@ select * from booltest a, booltest b where (a.b = b.b) is not false; b | b ---+--- | - | t t | + | t t | t (4 rows) @@ -339,7 +339,7 @@ INSERT INTO oneoffplantest VALUES (0), (0), (0); -- cached. So we expect the NOTICE to be printed only once, -- regardless of the number of tuples in the table. select volatilefunc(a) from oneoffplantest; -NOTICE: immutablefunc executed (seg0 slice1 127.0.1.1:25432 pid=6257) +NOTICE: immutablefunc executed (seg1 slice1 172.18.0.2:7003 pid=62356) volatilefunc -------------- 0 @@ -353,7 +353,6 @@ CREATE TABLE bfv_planner_t2 (f int,g int) DISTRIBUTED BY (f) PARTITION BY RANGE( ( PARTITION "201612" START (1) END (10) ); -NOTICE: CREATE TABLE will create partition "bfv_planner_t2_1_prt_201612" for table "bfv_planner_t2" insert into bfv_planner_t1 values(1,2,3), (2,3,4), (3,4,5); insert into bfv_planner_t2 values(3,1), (4,2), (5,2); select count(*) from @@ -362,6 +361,8 @@ join (select f,g from bfv_planner_t2) T2 on T1.a=T2.g and T1.c=T2.f; +NOTICE: One or more columns in the following table(s) do not have statistics: bfv_planner_t2 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. count ------- 2 @@ -404,8 +405,8 @@ explain (costs off) select * from (select a from generate_series(1, 10)a) x, t_hashdist where x.a > random(); - QUERY PLAN ----------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -414,7 +415,7 @@ where x.a > random(); -> Result Filter: ((generate_series.generate_series)::double precision > random()) -> Function Scan on generate_series - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) ---- join qual @@ -433,7 +434,7 @@ where x.a + y.a > random(); Join Filter: (((generate_series_1.generate_series + generate_series.generate_series))::double precision > random()) -> Function Scan on generate_series generate_series_1 -> Function Scan on generate_series - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) ---- sublink & subquery @@ -449,28 +450,28 @@ explain (costs off) select * from t_hashdist where a > All (select random() from Filter: ((CASE WHEN (sum((CASE WHEN ((t_hashdist.a)::double precision <= random()) THEN 1 ELSE 0 END)) IS NULL) THEN true WHEN (sum((CASE WHEN (random() IS NULL) THEN 1 ELSE 0 END)) > '0'::bigint) THEN NULL::boolean WHEN ((t_hashdist.a)::double precision IS NULL) THEN NULL::boolean WHEN (sum((CASE WHEN ((t_hashdist.a)::double precision <= random()) THEN 1 ELSE 0 END)) = '0'::bigint) THEN true ELSE false END) = true) -> Aggregate -> Function Scan on generate_series - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) explain (costs off) select * from t_hashdist where a in (select random()::int from generate_series(1, 10)); - QUERY PLAN ----------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join + -> Hash Right Semi Join Hash Cond: (t_hashdist.a = ((random())::integer)) - -> Seq Scan on t_hashdist + -> Redistribute Motion 1:3 (slice2) + Hash Key: ((random())::integer) + -> Function Scan on generate_series -> Hash - -> Redistribute Motion 1:3 (slice2) - Hash Key: ((random())::integer) - -> Function Scan on generate_series - Optimizer: Pivotal Optimizer (GPORCA) + -> Seq Scan on t_hashdist + Optimizer: GPORCA (9 rows) -- subplan explain (costs off, verbose) select * from t_hashdist left join (select a from generate_series(1, 10) a) x on t_hashdist.a > any (select random() from generate_series(1, 10)); - QUERY PLAN ------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: t_hashdist.a, t_hashdist.b, t_hashdist.c, a.a -> Nested Loop Left Join @@ -489,8 +490,8 @@ t_hashdist left join (select a from generate_series(1, 10) a) x on t_hashdist.a -> Function Scan on pg_catalog.generate_series a Output: a.a Function Call: generate_series(1, 10) + Settings: optimizer = 'on', enable_bitmapscan = 'off', enable_seqscan = 'off' Optimizer: Postgres query optimizer - Settings: enable_bitmapscan=off, enable_seqscan=off, optimizer=on (20 rows) -- targetlist @@ -504,9 +505,9 @@ explain (costs off) select * from t_hashdist cross join (select random () from g -> Seq Scan on t_hashdist -> Materialize -> Result - One-Time Filter: (gp_execution_segment() = 2) + One-Time Filter: (gp_execution_segment() = 1) -> Function Scan on generate_series - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) explain (costs off) select * from t_hashdist cross join (select a, sum(random()) from generate_series(1, 10) a group by a) x; @@ -522,7 +523,7 @@ explain (costs off) select * from t_hashdist cross join (select a, sum(random()) -> HashAggregate Group Key: generate_series.generate_series -> Function Scan on generate_series - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) explain (costs off) select * from t_hashdist cross join (select random() as k, sum(a) from generate_series(1, 10) a group by k) x; @@ -539,7 +540,7 @@ explain (costs off) select * from t_hashdist cross join (select random() as k, s -> Materialize -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on t_hashdist - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) explain (costs off) select * from t_hashdist cross join (select a, count(1) as s from generate_series(1, 10) a group by a having count(1) > random() order by a) x ; @@ -554,7 +555,7 @@ explain (costs off) select * from t_hashdist cross join (select a, count(1) as s Group Key: generate_series.generate_series -> Function Scan on generate_series -> Seq Scan on t_hashdist - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) -- limit @@ -567,20 +568,20 @@ explain (costs off) select * from t_hashdist cross join (select * from generate_ -> Seq Scan on t_hashdist -> Limit -> Function Scan on generate_series - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) -- CTAS on general locus into replicated table create temp SEQUENCE test_seq; explain (costs off) create table t_rep as select nextval('test_seq') from (select generate_series(1, 10)) t1 distributed replicated; - QUERY PLAN ---------------------------------------- + QUERY PLAN +-------------------------------------- Result -> Broadcast Motion 1:3 (slice1) -> Result -> ProjectSet -> Result - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (6 rows) create table t_rep1 as select nextval('test_seq') from (select generate_series(1, 10)) t1 distributed replicated; @@ -609,7 +610,7 @@ explain (costs off) create table t_rep as select i from generate_series(5, 15) a Group Key: generate_series -> Result -> Function Scan on generate_series - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) create table t_rep2 as select i from generate_series(5, 15) as i group by i having i < nextval('test_seq') distributed replicated; @@ -639,7 +640,7 @@ explain (costs off) create table t_rep as select i > nextval('test_seq') from ge -> Redistribute Motion 1:3 (slice2) Hash Key: ((generate_series > nextval('test_seq'::regclass))) -> Function Scan on generate_series - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) create table t_rep3 as select i > nextval('test_seq') as a from generate_series(5, 15) as i group by i > nextval('test_seq') distributed replicated; @@ -664,7 +665,7 @@ explain (costs off) create table t_rep as select nextval('test_seq') from rep_tb Result -> Broadcast Motion 1:3 (slice1; segments: 1) -> Seq Scan on rep_tbl - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) create table t_rep4 as select nextval('test_seq') from rep_tbl distributed replicated; @@ -738,25 +739,25 @@ from ) x; QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------- - Finalize Aggregate (cost=60000000416.93..60000000416.94 rows=1 width=8) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=60000000416.88..60000000416.93 rows=3 width=8) - -> Partial Aggregate (cost=60000000416.88..60000000416.89 rows=1 width=8) - -> Append (cost=20000000001.29..60000000391.87 rows=10003 width=0) - -> Subquery Scan on "*SELECT* 1" (cost=20000000001.29..20000000169.80 rows=5000 width=0) + Finalize Aggregate (cost=60000000366.91..60000000366.92 rows=1 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=60000000366.85..60000000366.90 rows=3 width=8) + -> Partial Aggregate (cost=60000000366.85..60000000366.86 rows=1 width=8) + -> Append (cost=20000000001.29..60000000341.84 rows=10003 width=0) + -> Subquery Scan on "*SELECT* 1" (cost=20000000001.29..20000000144.80 rows=5000 width=0) -> Hash Left Join (cost=20000000001.29..20000000119.80 rows=5000 width=16) Hash Cond: (t1_12146.b = t3_12146.b) -> Seq Scan on t1_12146 (cost=10000000000.00..10000000056.00 rows=5000 width=4) -> Hash (cost=10000000001.17..10000000001.17 rows=10 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=10000000000.00..10000000001.17 rows=10 width=4) -> Seq Scan on t3_12146 (cost=10000000000.00..10000000001.03 rows=3 width=4) - -> Subquery Scan on "*SELECT* 2" (cost=20000000001.29..20000000169.80 rows=5000 width=0) + -> Subquery Scan on "*SELECT* 2" (cost=20000000001.29..20000000144.80 rows=5000 width=0) -> Hash Left Join (cost=20000000001.29..20000000119.80 rows=5000 width=16) Hash Cond: (t2_12146.b = t4_12146.b) -> Seq Scan on t2_12146 (cost=10000000000.00..10000000056.00 rows=5000 width=4) -> Hash (cost=10000000001.17..10000000001.17 rows=10 width=4) -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=10000000000.00..10000000001.17 rows=10 width=4) -> Seq Scan on t4_12146 (cost=10000000000.00..10000000001.03 rows=3 width=4) - -> Subquery Scan on "*SELECT* 3" (cost=20000000001.08..20000000002.25 rows=3 width=0) + -> Subquery Scan on "*SELECT* 3" (cost=20000000001.08..20000000002.23 rows=3 width=0) -> Hash Join (cost=20000000001.08..20000000002.22 rows=3 width=16) Hash Cond: (t3_12146_1.b = t4_12146_1.a) -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=10000000000.00..10000000001.10 rows=3 width=4) diff --git a/src/test/regress/expected/cte_prune.out b/src/test/regress/expected/cte_prune.out index e3fed71c3d3..39654ab1454 100644 --- a/src/test/regress/expected/cte_prune.out +++ b/src/test/regress/expected/cte_prune.out @@ -31,16 +31,17 @@ explain verbose with c1 as (select v1, v2, v3 from t1) select c11.v1 from c1 as -> Seq Scan on cte_prune.t1 t1_1 (cost=0.00..1.04 rows=1 width=12) Output: t1_1.v1, t1_1.v2, t1_1.v3 Filter: (t1_1.v1 < 5) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(15 rows) +(16 rows) with c1 as (select v1, v2, v3 from t1) select c11.v1 from c1 as c11 left join c1 as c22 on c11.v1=c22.v1 where c11.v1 < 5; v1 ---- + 1 2 3 4 - 1 (4 rows) explain verbose with c1 as (select v1, v2, v3 from t1) select c11.v2 from c1 as c11 left join c1 as c22 on c11.v1=c22.v1 where c11.v1 < 5; @@ -60,8 +61,9 @@ explain verbose with c1 as (select v1, v2, v3 from t1) select c11.v2 from c1 as -> Seq Scan on cte_prune.t1 t1_1 (cost=0.00..1.04 rows=1 width=12) Output: t1_1.v1, t1_1.v2, t1_1.v3 Filter: (t1_1.v1 < 5) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(15 rows) +(16 rows) with c1 as (select v1, v2, v3 from t1) select c11.v2 from c1 as c11 left join c1 as c22 on c11.v1=c22.v1 where c11.v1 < 5; v2 @@ -89,8 +91,9 @@ explain verbose with c1 as (select v1, v2, v3 from t1) select c11.v3 from c1 as -> Seq Scan on cte_prune.t1 t1_1 (cost=0.00..1.04 rows=1 width=12) Output: t1_1.v1, t1_1.v2, t1_1.v3 Filter: (t1_1.v1 < 5) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(15 rows) +(16 rows) with c1 as (select v1, v2, v3 from t1) select c11.v3 from c1 as c11 left join c1 as c22 on c11.v1=c22.v1 where c11.v1 < 5; v3 @@ -119,16 +122,17 @@ explain verbose with c1 as (select * from t1) select c11.v1 from c1 as c11 left -> Seq Scan on cte_prune.t1 t1_1 (cost=0.00..1.04 rows=1 width=12) Output: t1_1.v1, t1_1.v2, t1_1.v3 Filter: (t1_1.v1 < 5) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(15 rows) +(16 rows) with c1 as (select * from t1) select c11.v1 from c1 as c11 left join c1 as c22 on c11.v1=c22.v1 where c11.v1 < 5; v1 ---- + 1 2 3 4 - 1 (4 rows) -- no push filter @@ -153,22 +157,23 @@ explain verbose with c1 as (select v1, v2, v3 from t1) select c11.v3 from c1 as Output: c11.v3, c11.v1 -> Seq Scan on cte_prune.t1 t1_1 (cost=0.00..1.03 rows=3 width=12) Output: t1_1.v1, t1_1.v2, t1_1.v3 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(19 rows) +(20 rows) with c1 as (select v1, v2, v3 from t1) select c11.v3 from c1 as c11 left join c1 as c22 on c11.v1=c22.v2; v3 ---- + 26 + 25 + 30 + 29 27 23 28 24 22 21 - 26 - 25 - 30 - 29 (10 rows) explain verbose with c1 as (select v1, v2, v3 from t1) select c11.v2 from c1 as c11 left join c1 as c22 on c11.v1=c22.v2; @@ -192,22 +197,23 @@ explain verbose with c1 as (select v1, v2, v3 from t1) select c11.v2 from c1 as Output: c11.v2, c11.v1 -> Seq Scan on cte_prune.t1 t1_1 (cost=0.00..1.03 rows=3 width=12) Output: t1_1.v1, t1_1.v2, t1_1.v3 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(19 rows) +(20 rows) with c1 as (select v1, v2, v3 from t1) select c11.v2 from c1 as c11 left join c1 as c22 on c11.v1=c22.v2; v2 ---- - 11 - 16 - 15 - 20 - 19 17 13 18 14 12 + 16 + 15 + 20 + 19 + 11 (10 rows) -- distribution col can be pruned which is better than do redistribute in CTE consumer @@ -235,22 +241,23 @@ explain verbose with c1 as (select v1, v2, v3 from t1) select c11.v2 from c1 as Output: c22.v2 -> Seq Scan on cte_prune.t1 t1_1 (cost=0.00..1.03 rows=3 width=12) Output: t1_1.v1, t1_1.v2, t1_1.v3 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(22 rows) +(23 rows) with c1 as (select v1, v2, v3 from t1) select c11.v2 from c1 as c11 left join c1 as c22 on c11.v2=c22.v2; v2 ---- - 13 - 14 - 17 - 11 18 16 19 12 15 20 + 13 + 14 + 17 + 11 (10 rows) explain verbose with c1 as (select v1, v2, v3 from t1) select c11.v3 from c1 as c11 left join c1 as c22 on c11.v3=c22.v3; @@ -277,22 +284,23 @@ explain verbose with c1 as (select v1, v2, v3 from t1) select c11.v3 from c1 as Output: c22.v3 -> Seq Scan on cte_prune.t1 t1_1 (cost=0.00..1.03 rows=3 width=12) Output: t1_1.v1, t1_1.v2, t1_1.v3 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(22 rows) +(23 rows) with c1 as (select v1, v2, v3 from t1) select c11.v3 from c1 as c11 left join c1 as c22 on c11.v3=c22.v3; v3 ---- + 23 + 26 + 30 + 28 + 25 + 21 22 24 27 29 - 28 - 21 - 25 - 23 - 26 - 30 (10 rows) -- groupby/order by/window function/grouping set should be contains in CTE output @@ -316,22 +324,23 @@ explain verbose with c1 as (select v1, v2, v3 from t1) select sum(c11.v1) from c Output: c22.v1 -> Seq Scan on cte_prune.t1 t1_1 (cost=0.00..1.03 rows=3 width=12) Output: t1_1.v1, t1_1.v2, t1_1.v3 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(17 rows) +(18 rows) with c1 as (select v1, v2, v3 from t1) select sum(c11.v1) from c1 as c11 left join c1 as c22 on c11.v1=c22.v1 group by c11.v1; sum ----- - 10 - 9 - 6 - 5 - 1 4 2 8 7 3 + 10 + 9 + 6 + 5 + 1 (10 rows) explain verbose with c1 as (select v1, v2, v3 from t1) select sum(c11.v1) from c1 as c11 left join c1 as c22 on c11.v1=c22.v1 group by c11.v2; @@ -356,22 +365,23 @@ explain verbose with c1 as (select v1, v2, v3 from t1) select sum(c11.v1) from c Output: c22.v1 -> Seq Scan on cte_prune.t1 t1_1 (cost=0.00..1.03 rows=3 width=12) Output: t1_1.v1, t1_1.v2, t1_1.v3 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(20 rows) +(21 rows) with c1 as (select v1, v2, v3 from t1) select sum(c11.v1) from c1 as c11 left join c1 as c22 on c11.v1=c22.v1 group by c11.v2; sum ----- - 1 - 3 - 4 - 7 6 9 8 10 2 5 + 1 + 3 + 4 + 7 (10 rows) explain verbose with c1 as (select v1, v2, v3 from t1) select sum(c11.v3) from c1 as c11 left join c1 as c22 on c11.v1=c22.v1 group by c11.v2; @@ -396,19 +406,20 @@ explain verbose with c1 as (select v1, v2, v3 from t1) select sum(c11.v3) from c Output: c22.v1 -> Seq Scan on cte_prune.t1 t1_1 (cost=0.00..1.03 rows=3 width=12) Output: t1_1.v1, t1_1.v2, t1_1.v3 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(20 rows) +(21 rows) with c1 as (select v1, v2, v3 from t1) select sum(c11.v3) from c1 as c11 left join c1 as c22 on c11.v1=c22.v1 group by c11.v2; sum ----- + 30 + 22 + 25 21 23 24 27 - 30 - 22 - 25 26 29 28 @@ -435,8 +446,9 @@ explain verbose with c1 as (select v1, v2, v3 from t1) select c11.v1 from c1 as Output: c22.v1 -> Seq Scan on cte_prune.t1 t1_1 (cost=0.00..1.03 rows=3 width=12) Output: t1_1.v1, t1_1.v2, t1_1.v3 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(18 rows) +(19 rows) with c1 as (select v1, v2, v3 from t1) select c11.v1 from c1 as c11 left join c1 as c22 on c11.v1=c22.v1 order by c22.v1; v1 @@ -473,8 +485,9 @@ explain verbose with c1 as (select v1, v2, v3 from t1) select c11.v1 from c1 as Output: c22.v3, c22.v1 -> Seq Scan on cte_prune.t1 t1_1 (cost=0.00..1.03 rows=3 width=12) Output: t1_1.v1, t1_1.v2, t1_1.v3 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(18 rows) +(19 rows) with c1 as (select v1, v2, v3 from t1) select c11.v1 from c1 as c11 left join c1 as c22 on c11.v1=c22.v1 order by c22.v3; v1 @@ -515,8 +528,9 @@ explain verbose with c1 as (select v1, v2, v3 from t1) select sum(c11.v1) OVER ( Output: c22.v1 -> Seq Scan on cte_prune.t1 t1_1 (cost=0.00..1.03 rows=3 width=12) Output: t1_1.v1, t1_1.v2, t1_1.v3 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(21 rows) +(22 rows) with c1 as (select v1, v2, v3 from t1) select sum(c11.v1) OVER (ORDER BY c11.v2) from c1 as c11 left join c1 as c22 on c11.v1=c22.v1; sum @@ -556,8 +570,9 @@ explain verbose with c1 as (select v1, v2, v3 from t1) select sum(c11.v2) OVER ( Output: c22.v1 -> Seq Scan on cte_prune.t1 t1_1 (cost=0.00..1.03 rows=3 width=12) Output: t1_1.v1, t1_1.v2, t1_1.v3 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(21 rows) +(22 rows) with c1 as (select v1, v2, v3 from t1) select sum(c11.v2) OVER (ORDER BY c11.v3) from c1 as c11 left join c1 as c22 on c11.v1=c22.v1; sum @@ -600,8 +615,9 @@ explain verbose with c1 as (select v1, v2, v3 from t1) select sum(c11.v2) from c Output: c22.v1 -> Seq Scan on cte_prune.t1 t1_1 (cost=0.00..1.03 rows=3 width=12) Output: t1_1.v1, t1_1.v2, t1_1.v3 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(23 rows) +(24 rows) with c1 as (select v1, v2, v3 from t1) select sum(c11.v2) from c1 as c11 left join c1 as c22 on c11.v1=c22.v1 group by ROLLUP(c11.v1,c11.v2); sum @@ -654,8 +670,9 @@ explain verbose with c1 as (select v1, v2, v3 from t1) select sum(c11.v2) from c Output: c22.v1 -> Seq Scan on cte_prune.t1 t1_1 (cost=0.00..1.03 rows=3 width=12) Output: t1_1.v1, t1_1.v2, t1_1.v3 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(23 rows) +(24 rows) with c1 as (select v1, v2, v3 from t1) select sum(c11.v2) OVER (ORDER BY c11.v3) from c1 as c11 left join c1 as c22 on c11.v1=c22.v1; sum @@ -704,23 +721,24 @@ select c11.v1 from c1 as c11 left join c1 as c22 on c11.v1=c22.v1; Output: t1_1.v1 -> Seq Scan on cte_prune.t1 t1_1 (cost=0.00..1.03 rows=3 width=4) Output: t1_1.v1 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(28 rows) +(29 rows) with c1 as (select t1.v1 as v1, t2.v1 as t21, t2.v2 as t22, t2.v3 as t23 from t1 join t2 on t1.v1 = t2.v1) select c11.v1 from c1 as c11 left join c1 as c22 on c11.v1=c22.v1; v1 ---- + 5 + 6 + 9 + 10 1 2 3 4 7 8 - 5 - 6 - 9 - 10 (10 rows) explain verbose with c1 as (select sum(v1) as v1, sum(v2) as v2, v3 from t1 group by v3) @@ -760,8 +778,9 @@ select c11.v1 from c1 as c11 left join c1 as c22 on c11.v1=c22.v1; Hash Key: t1_1.v3 -> Seq Scan on cte_prune.t1 t1_1 (cost=0.00..1.03 rows=3 width=12) Output: t1_1.v3, t1_1.v1, t1_1.v2 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(34 rows) +(35 rows) with c1 as (select lt1.v3 as v3, lt1.v1 as lo1, rt1.v1 as ro1 from t1 lt1, t1 rt1 where lt1.v2 = rt1.v2 and lt1.v1 = rt1.v1) select * from t1 where t1.v1 in (select v3 from c1) and t1.v1 in (select v3 from c1 where v3 > 0); @@ -906,97 +925,92 @@ explain verbose with frequent_ss_items as having count(*) >4) select t1.v1 from t1 where t1.v1 in (select item_sk from frequent_ss_items where true) and t1.v1 in (select item_sk from frequent_ss_items where item_sk > 0); - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=452.31..452.37 rows=3 width=4) + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=451.79..452.33 rows=3 width=4) Output: t1.v1 - -> HashAggregate (cost=452.31..452.32 rows=1 width=4) + -> Hash Right Semi Join (cost=451.79..452.29 rows=1 width=4) Output: t1.v1 - Group Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=451.79..452.31 rows=1 width=4) - Output: t1.v1, (RowIdExpr) - Hash Key: (RowIdExpr) - -> Hash Join (cost=451.79..452.29 rows=1 width=4) - Output: t1.v1, (RowIdExpr) - Hash Cond: (frequent_ss_items.item_sk = t1.v1) - -> Subquery Scan on frequent_ss_items (cost=223.67..224.14 rows=6 width=4) - Output: frequent_ss_items.item_sk - -> GroupAggregate (cost=223.67..224.14 rows=6 width=48) - Output: (substr((tpcds_item.i_item_desc)::text, 1, 30)), tpcds_item.i_item_sk, tpcds_date_dim.d_date, count(*) - Group Key: (substr((tpcds_item.i_item_desc)::text, 1, 30)), tpcds_item.i_item_sk, tpcds_date_dim.d_date - Filter: (count(*) > 4) - -> Sort (cost=223.67..223.72 rows=18 width=40) - Output: (substr((tpcds_item.i_item_desc)::text, 1, 30)), tpcds_item.i_item_sk, tpcds_date_dim.d_date - Sort Key: (substr((tpcds_item.i_item_desc)::text, 1, 30)), tpcds_item.i_item_sk, tpcds_date_dim.d_date - -> Hash Join (cost=181.20..223.30 rows=18 width=40) - Output: substr((tpcds_item.i_item_desc)::text, 1, 30), tpcds_item.i_item_sk, tpcds_date_dim.d_date - Hash Cond: (tpcds_item.i_item_sk = tpcds_store_sales.ss_item_sk) - -> Seq Scan on cte_prune.tpcds_item (cost=0.00..39.33 rows=533 width=422) - Output: tpcds_item.i_item_sk, tpcds_item.i_item_id, tpcds_item.i_rec_start_date, tpcds_item.i_rec_end_date, tpcds_item.i_item_desc, tpcds_item.i_current_price, tpcds_item.i_wholesale_cost, tpcds_item.i_brand_id, tpcds_item.i_brand, tpcds_item.i_class_id, tpcds_item.i_class, tpcds_item.i_category_id, tpcds_item.i_category, tpcds_item.i_manufact_id, tpcds_item.i_manufact, tpcds_item.i_size, tpcds_item.i_formulation, tpcds_item.i_color, tpcds_item.i_units, tpcds_item.i_container, tpcds_item.i_manager_id, tpcds_item.i_product_name - -> Hash (cost=180.98..180.98 rows=18 width=8) + Hash Cond: (frequent_ss_items.item_sk = t1.v1) + -> Subquery Scan on frequent_ss_items (cost=223.67..224.14 rows=6 width=4) + Output: frequent_ss_items.item_sk + -> GroupAggregate (cost=223.67..224.14 rows=6 width=48) + Output: (substr((tpcds_item.i_item_desc)::text, 1, 30)), tpcds_item.i_item_sk, tpcds_date_dim.d_date, count(*) + Group Key: (substr((tpcds_item.i_item_desc)::text, 1, 30)), tpcds_item.i_item_sk, tpcds_date_dim.d_date + Filter: (count(*) > 4) + -> Sort (cost=223.67..223.72 rows=18 width=40) + Output: (substr((tpcds_item.i_item_desc)::text, 1, 30)), tpcds_item.i_item_sk, tpcds_date_dim.d_date + Sort Key: (substr((tpcds_item.i_item_desc)::text, 1, 30)), tpcds_item.i_item_sk, tpcds_date_dim.d_date + -> Hash Join (cost=181.20..223.30 rows=18 width=40) + Output: substr((tpcds_item.i_item_desc)::text, 1, 30), tpcds_item.i_item_sk, tpcds_date_dim.d_date + Hash Cond: (tpcds_item.i_item_sk = tpcds_store_sales.ss_item_sk) + -> Seq Scan on cte_prune.tpcds_item (cost=0.00..39.33 rows=533 width=422) + Output: tpcds_item.i_item_sk, tpcds_item.i_item_id, tpcds_item.i_rec_start_date, tpcds_item.i_rec_end_date, tpcds_item.i_item_desc, tpcds_item.i_current_price, tpcds_item.i_wholesale_cost, tpcds_item.i_brand_id, tpcds_item.i_brand, tpcds_item.i_class_id, tpcds_item.i_class, tpcds_item.i_category_id, tpcds_item.i_category, tpcds_item.i_manufact_id, tpcds_item.i_manufact, tpcds_item.i_size, tpcds_item.i_formulation, tpcds_item.i_color, tpcds_item.i_units, tpcds_item.i_container, tpcds_item.i_manager_id, tpcds_item.i_product_name + -> Hash (cost=180.98..180.98 rows=18 width=8) + Output: tpcds_store_sales.ss_item_sk, tpcds_date_dim.d_date + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=89.63..180.98 rows=18 width=8) + Output: tpcds_store_sales.ss_item_sk, tpcds_date_dim.d_date + Hash Key: tpcds_store_sales.ss_item_sk + -> Hash Join (cost=89.63..180.62 rows=18 width=8) Output: tpcds_store_sales.ss_item_sk, tpcds_date_dim.d_date - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=89.63..180.98 rows=18 width=8) - Output: tpcds_store_sales.ss_item_sk, tpcds_date_dim.d_date - Hash Key: tpcds_store_sales.ss_item_sk - -> Hash Join (cost=89.63..180.62 rows=18 width=8) - Output: tpcds_store_sales.ss_item_sk, tpcds_date_dim.d_date - Inner Unique: true - Hash Cond: (tpcds_store_sales.ss_sold_date_sk = tpcds_date_dim.d_date_sk) - -> Seq Scan on cte_prune.tpcds_store_sales (cost=0.00..79.00 rows=4500 width=8) - Output: tpcds_store_sales.ss_sold_date_sk, tpcds_store_sales.ss_sold_time_sk, tpcds_store_sales.ss_item_sk, tpcds_store_sales.ss_customer_sk, tpcds_store_sales.ss_cdemo_sk, tpcds_store_sales.ss_hdemo_sk, tpcds_store_sales.ss_addr_sk, tpcds_store_sales.ss_store_sk, tpcds_store_sales.ss_promo_sk, tpcds_store_sales.ss_ticket_number, tpcds_store_sales.ss_quantity, tpcds_store_sales.ss_wholesale_cost, tpcds_store_sales.ss_list_price, tpcds_store_sales.ss_sales_price, tpcds_store_sales.ss_ext_discount_amt, tpcds_store_sales.ss_ext_sales_price, tpcds_store_sales.ss_ext_wholesale_cost, tpcds_store_sales.ss_ext_list_price, tpcds_store_sales.ss_ext_tax, tpcds_store_sales.ss_coupon_amt, tpcds_store_sales.ss_net_paid, tpcds_store_sales.ss_net_paid_inc_tax, tpcds_store_sales.ss_net_profit - -> Hash (cost=89.08..89.08 rows=44 width=8) + Inner Unique: true + Hash Cond: (tpcds_store_sales.ss_sold_date_sk = tpcds_date_dim.d_date_sk) + -> Seq Scan on cte_prune.tpcds_store_sales (cost=0.00..79.00 rows=4500 width=8) + Output: tpcds_store_sales.ss_sold_date_sk, tpcds_store_sales.ss_sold_time_sk, tpcds_store_sales.ss_item_sk, tpcds_store_sales.ss_customer_sk, tpcds_store_sales.ss_cdemo_sk, tpcds_store_sales.ss_hdemo_sk, tpcds_store_sales.ss_addr_sk, tpcds_store_sales.ss_store_sk, tpcds_store_sales.ss_promo_sk, tpcds_store_sales.ss_ticket_number, tpcds_store_sales.ss_quantity, tpcds_store_sales.ss_wholesale_cost, tpcds_store_sales.ss_list_price, tpcds_store_sales.ss_sales_price, tpcds_store_sales.ss_ext_discount_amt, tpcds_store_sales.ss_ext_sales_price, tpcds_store_sales.ss_ext_wholesale_cost, tpcds_store_sales.ss_ext_list_price, tpcds_store_sales.ss_ext_tax, tpcds_store_sales.ss_coupon_amt, tpcds_store_sales.ss_net_paid, tpcds_store_sales.ss_net_paid_inc_tax, tpcds_store_sales.ss_net_profit + -> Hash (cost=89.08..89.08 rows=44 width=8) + Output: tpcds_date_dim.d_date, tpcds_date_dim.d_date_sk + -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..89.08 rows=44 width=8) + Output: tpcds_date_dim.d_date, tpcds_date_dim.d_date_sk + -> Seq Scan on cte_prune.tpcds_date_dim (cost=0.00..88.50 rows=15 width=8) Output: tpcds_date_dim.d_date, tpcds_date_dim.d_date_sk - -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..89.08 rows=44 width=8) - Output: tpcds_date_dim.d_date, tpcds_date_dim.d_date_sk - -> Seq Scan on cte_prune.tpcds_date_dim (cost=0.00..88.50 rows=15 width=8) - Output: tpcds_date_dim.d_date, tpcds_date_dim.d_date_sk - Filter: (tpcds_date_dim.d_year = ANY ('{1999,2000,2001,2002}'::integer[])) - -> Hash (cost=228.10..228.10 rows=1 width=8) - Output: t1.v1, frequent_ss_items_1.item_sk, (RowIdExpr) - -> Hash Semi Join (cost=227.05..228.10 rows=1 width=8) - Output: t1.v1, frequent_ss_items_1.item_sk, RowIdExpr - Hash Cond: (t1.v1 = frequent_ss_items_1.item_sk) - -> Seq Scan on cte_prune.t1 (cost=0.00..1.03 rows=3 width=4) - Output: t1.v1, t1.v2, t1.v3 - -> Hash (cost=227.04..227.04 rows=1 width=4) - Output: frequent_ss_items_1.item_sk - -> Subquery Scan on frequent_ss_items_1 (cost=226.96..227.04 rows=1 width=4) - Output: frequent_ss_items_1.item_sk - -> GroupAggregate (cost=226.96..227.04 rows=1 width=48) - Output: (substr((tpcds_item_1.i_item_desc)::text, 1, 30)), tpcds_item_1.i_item_sk, tpcds_date_dim_1.d_date, count(*) - Group Key: (substr((tpcds_item_1.i_item_desc)::text, 1, 30)), tpcds_item_1.i_item_sk, tpcds_date_dim_1.d_date - Filter: (count(*) > 4) - -> Sort (cost=226.96..226.97 rows=3 width=40) - Output: (substr((tpcds_item_1.i_item_desc)::text, 1, 30)), tpcds_item_1.i_item_sk, tpcds_date_dim_1.d_date - Sort Key: (substr((tpcds_item_1.i_item_desc)::text, 1, 30)), tpcds_item_1.i_item_sk, tpcds_date_dim_1.d_date - -> Hash Join (cost=132.52..226.94 rows=3 width=40) - Output: substr((tpcds_item_1.i_item_desc)::text, 1, 30), tpcds_item_1.i_item_sk, tpcds_date_dim_1.d_date + Filter: (tpcds_date_dim.d_year = ANY ('{1999,2000,2001,2002}'::integer[])) + -> Hash (cost=228.10..228.10 rows=1 width=8) + Output: t1.v1, frequent_ss_items_1.item_sk + -> Hash Semi Join (cost=227.05..228.10 rows=1 width=8) + Output: t1.v1, frequent_ss_items_1.item_sk + Hash Cond: (t1.v1 = frequent_ss_items_1.item_sk) + -> Seq Scan on cte_prune.t1 (cost=0.00..1.03 rows=3 width=4) + Output: t1.v1, t1.v2, t1.v3 + -> Hash (cost=227.04..227.04 rows=1 width=4) + Output: frequent_ss_items_1.item_sk + -> Subquery Scan on frequent_ss_items_1 (cost=226.96..227.04 rows=1 width=4) + Output: frequent_ss_items_1.item_sk + -> GroupAggregate (cost=226.96..227.04 rows=1 width=48) + Output: (substr((tpcds_item_1.i_item_desc)::text, 1, 30)), tpcds_item_1.i_item_sk, tpcds_date_dim_1.d_date, count(*) + Group Key: (substr((tpcds_item_1.i_item_desc)::text, 1, 30)), tpcds_item_1.i_item_sk, tpcds_date_dim_1.d_date + Filter: (count(*) > 4) + -> Sort (cost=226.96..226.97 rows=3 width=40) + Output: (substr((tpcds_item_1.i_item_desc)::text, 1, 30)), tpcds_item_1.i_item_sk, tpcds_date_dim_1.d_date + Sort Key: (substr((tpcds_item_1.i_item_desc)::text, 1, 30)), tpcds_item_1.i_item_sk, tpcds_date_dim_1.d_date + -> Hash Join (cost=132.52..226.94 rows=3 width=40) + Output: substr((tpcds_item_1.i_item_desc)::text, 1, 30), tpcds_item_1.i_item_sk, tpcds_date_dim_1.d_date + Inner Unique: true + Hash Cond: (tpcds_store_sales_1.ss_item_sk = tpcds_item_1.i_item_sk) + -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=89.63..183.99 rows=6 width=8) + Output: tpcds_store_sales_1.ss_item_sk, tpcds_date_dim_1.d_date + Hash Key: tpcds_store_sales_1.ss_item_sk + -> Hash Join (cost=89.63..183.87 rows=6 width=8) + Output: tpcds_store_sales_1.ss_item_sk, tpcds_date_dim_1.d_date Inner Unique: true - Hash Cond: (tpcds_store_sales_1.ss_item_sk = tpcds_item_1.i_item_sk) - -> Redistribute Motion 3:3 (slice5; segments: 3) (cost=89.63..183.99 rows=6 width=8) - Output: tpcds_store_sales_1.ss_item_sk, tpcds_date_dim_1.d_date - Hash Key: tpcds_store_sales_1.ss_item_sk - -> Hash Join (cost=89.63..183.87 rows=6 width=8) - Output: tpcds_store_sales_1.ss_item_sk, tpcds_date_dim_1.d_date - Inner Unique: true - Hash Cond: (tpcds_store_sales_1.ss_sold_date_sk = tpcds_date_dim_1.d_date_sk) - -> Seq Scan on cte_prune.tpcds_store_sales tpcds_store_sales_1 (cost=0.00..90.25 rows=1500 width=8) - Output: tpcds_store_sales_1.ss_sold_date_sk, tpcds_store_sales_1.ss_sold_time_sk, tpcds_store_sales_1.ss_item_sk, tpcds_store_sales_1.ss_customer_sk, tpcds_store_sales_1.ss_cdemo_sk, tpcds_store_sales_1.ss_hdemo_sk, tpcds_store_sales_1.ss_addr_sk, tpcds_store_sales_1.ss_store_sk, tpcds_store_sales_1.ss_promo_sk, tpcds_store_sales_1.ss_ticket_number, tpcds_store_sales_1.ss_quantity, tpcds_store_sales_1.ss_wholesale_cost, tpcds_store_sales_1.ss_list_price, tpcds_store_sales_1.ss_sales_price, tpcds_store_sales_1.ss_ext_discount_amt, tpcds_store_sales_1.ss_ext_sales_price, tpcds_store_sales_1.ss_ext_wholesale_cost, tpcds_store_sales_1.ss_ext_list_price, tpcds_store_sales_1.ss_ext_tax, tpcds_store_sales_1.ss_coupon_amt, tpcds_store_sales_1.ss_net_paid, tpcds_store_sales_1.ss_net_paid_inc_tax, tpcds_store_sales_1.ss_net_profit - Filter: (tpcds_store_sales_1.ss_item_sk > 0) - -> Hash (cost=89.08..89.08 rows=44 width=8) + Hash Cond: (tpcds_store_sales_1.ss_sold_date_sk = tpcds_date_dim_1.d_date_sk) + -> Seq Scan on cte_prune.tpcds_store_sales tpcds_store_sales_1 (cost=0.00..90.25 rows=1500 width=8) + Output: tpcds_store_sales_1.ss_sold_date_sk, tpcds_store_sales_1.ss_sold_time_sk, tpcds_store_sales_1.ss_item_sk, tpcds_store_sales_1.ss_customer_sk, tpcds_store_sales_1.ss_cdemo_sk, tpcds_store_sales_1.ss_hdemo_sk, tpcds_store_sales_1.ss_addr_sk, tpcds_store_sales_1.ss_store_sk, tpcds_store_sales_1.ss_promo_sk, tpcds_store_sales_1.ss_ticket_number, tpcds_store_sales_1.ss_quantity, tpcds_store_sales_1.ss_wholesale_cost, tpcds_store_sales_1.ss_list_price, tpcds_store_sales_1.ss_sales_price, tpcds_store_sales_1.ss_ext_discount_amt, tpcds_store_sales_1.ss_ext_sales_price, tpcds_store_sales_1.ss_ext_wholesale_cost, tpcds_store_sales_1.ss_ext_list_price, tpcds_store_sales_1.ss_ext_tax, tpcds_store_sales_1.ss_coupon_amt, tpcds_store_sales_1.ss_net_paid, tpcds_store_sales_1.ss_net_paid_inc_tax, tpcds_store_sales_1.ss_net_profit + Filter: (tpcds_store_sales_1.ss_item_sk > 0) + -> Hash (cost=89.08..89.08 rows=44 width=8) + Output: tpcds_date_dim_1.d_date, tpcds_date_dim_1.d_date_sk + -> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..89.08 rows=44 width=8) + Output: tpcds_date_dim_1.d_date, tpcds_date_dim_1.d_date_sk + -> Seq Scan on cte_prune.tpcds_date_dim tpcds_date_dim_1 (cost=0.00..88.50 rows=15 width=8) Output: tpcds_date_dim_1.d_date, tpcds_date_dim_1.d_date_sk - -> Broadcast Motion 3:3 (slice6; segments: 3) (cost=0.00..89.08 rows=44 width=8) - Output: tpcds_date_dim_1.d_date, tpcds_date_dim_1.d_date_sk - -> Seq Scan on cte_prune.tpcds_date_dim tpcds_date_dim_1 (cost=0.00..88.50 rows=15 width=8) - Output: tpcds_date_dim_1.d_date, tpcds_date_dim_1.d_date_sk - Filter: (tpcds_date_dim_1.d_year = ANY ('{1999,2000,2001,2002}'::integer[])) - -> Hash (cost=40.67..40.67 rows=178 width=422) - Output: tpcds_item_1.i_item_desc, tpcds_item_1.i_item_sk - -> Seq Scan on cte_prune.tpcds_item tpcds_item_1 (cost=0.00..40.67 rows=178 width=422) - Output: tpcds_item_1.i_item_desc, tpcds_item_1.i_item_sk - Filter: (tpcds_item_1.i_item_sk > 0) + Filter: (tpcds_date_dim_1.d_year = ANY ('{1999,2000,2001,2002}'::integer[])) + -> Hash (cost=40.67..40.67 rows=178 width=422) + Output: tpcds_item_1.i_item_desc, tpcds_item_1.i_item_sk + -> Seq Scan on cte_prune.tpcds_item tpcds_item_1 (cost=0.00..40.67 rows=178 width=422) + Output: tpcds_item_1.i_item_desc, tpcds_item_1.i_item_sk + Filter: (tpcds_item_1.i_item_sk > 0) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(89 rows) +(83 rows) -- sql 95 explain verbose with ws_wh as @@ -1005,79 +1019,63 @@ explain verbose with ws_wh as where ws1.ws_order_number = ws2.ws_order_number and ws1.ws_warehouse_sk <> ws2.ws_warehouse_sk) select * from t1 where t1.v1 in (select ws_order_number from ws_wh where true) and t1.v1 in (select ws_order_number from ws_wh where ws_order_number > 0); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2559.45..2559.67 rows=14 width=12) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=468.45..2559.24 rows=14 width=12) Output: t1.v1, t1.v2, t1.v3 - -> HashAggregate (cost=2559.45..2559.49 rows=5 width=12) + -> Hash Right Semi Join (cost=468.45..2559.06 rows=5 width=12) Output: t1.v1, t1.v2, t1.v3 - Group Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=468.73..2559.44 rows=5 width=12) - Output: t1.v1, t1.v2, t1.v3, (RowIdExpr) - Hash Key: (RowIdExpr) - -> Hash Join (cost=468.73..2559.35 rows=5 width=12) - Output: t1.v1, t1.v2, t1.v3, (RowIdExpr) - Hash Cond: (ws_wh.ws_order_number = t1.v1) - -> Subquery Scan on ws_wh (cost=179.92..2181.72 rows=35328 width=4) - Output: ws_wh.ws_order_number - -> Hash Join (cost=179.92..2181.72 rows=35328 width=12) - Output: ws1.ws_order_number, ws1.ws_warehouse_sk, ws2.ws_warehouse_sk - Hash Cond: (ws1.ws_order_number = ws2.ws_order_number) - Join Filter: (ws1.ws_warehouse_sk <> ws2.ws_warehouse_sk) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..137.00 rows=3433 width=8) - Output: ws1.ws_order_number, ws1.ws_warehouse_sk - Hash Key: ws1.ws_order_number - -> Seq Scan on cte_prune.tpcds_web_sales ws1 (cost=0.00..68.33 rows=3433 width=8) - Output: ws1.ws_order_number, ws1.ws_warehouse_sk - -> Hash (cost=137.00..137.00 rows=3433 width=8) + Hash Cond: (ws_wh.ws_order_number = t1.v1) + -> Subquery Scan on ws_wh (cost=179.92..2181.72 rows=35328 width=4) + Output: ws_wh.ws_order_number + -> Hash Join (cost=179.92..2181.72 rows=35328 width=12) + Output: ws1.ws_order_number, ws1.ws_warehouse_sk, ws2.ws_warehouse_sk + Hash Cond: (ws1.ws_order_number = ws2.ws_order_number) + Join Filter: (ws1.ws_warehouse_sk <> ws2.ws_warehouse_sk) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..137.00 rows=3433 width=8) + Output: ws1.ws_order_number, ws1.ws_warehouse_sk + Hash Key: ws1.ws_order_number + -> Seq Scan on cte_prune.tpcds_web_sales ws1 (cost=0.00..68.33 rows=3433 width=8) + Output: ws1.ws_order_number, ws1.ws_warehouse_sk + -> Hash (cost=137.00..137.00 rows=3433 width=8) + Output: ws2.ws_warehouse_sk, ws2.ws_order_number + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..137.00 rows=3433 width=8) + Output: ws2.ws_warehouse_sk, ws2.ws_order_number + Hash Key: ws2.ws_order_number + -> Seq Scan on cte_prune.tpcds_web_sales ws2 (cost=0.00..68.33 rows=3433 width=8) Output: ws2.ws_warehouse_sk, ws2.ws_order_number - -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..137.00 rows=3433 width=8) - Output: ws2.ws_warehouse_sk, ws2.ws_order_number - Hash Key: ws2.ws_order_number - -> Seq Scan on cte_prune.tpcds_web_sales ws2 (cost=0.00..68.33 rows=3433 width=8) - Output: ws2.ws_warehouse_sk, ws2.ws_order_number - -> Hash (cost=288.76..288.76 rows=5 width=16) - Output: t1.v1, t1.v2, t1.v3, ws_wh_1.ws_order_number, (RowIdExpr) - -> Redistribute Motion 3:3 (slice5; segments: 3) (cost=288.58..288.76 rows=5 width=16) - Output: t1.v1, t1.v2, t1.v3, ws_wh_1.ws_order_number, (RowIdExpr) - Hash Key: t1.v1 - -> Result (cost=288.58..288.67 rows=5 width=16) - Output: t1.v1, t1.v2, t1.v3, ws_wh_1.ws_order_number, RowIdExpr - -> HashAggregate (cost=288.58..288.63 rows=5 width=16) - Output: t1.v1, t1.v2, t1.v3, ws_wh_1.ws_order_number - Group Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice6; segments: 3) (cost=115.19..288.57 rows=5 width=16) - Output: t1.v1, t1.v2, t1.v3, ws_wh_1.ws_order_number, (RowIdExpr) - Hash Key: (RowIdExpr) - -> Hash Join (cost=115.19..288.48 rows=5 width=16) - Output: t1.v1, t1.v2, t1.v3, ws_wh_1.ws_order_number, (RowIdExpr) - Hash Cond: (ws_wh_1.ws_order_number = t1.v1) - -> Subquery Scan on ws_wh_1 (cost=114.11..277.50 rows=3925 width=4) - Output: ws_wh_1.ws_order_number - -> Hash Join (cost=114.11..277.50 rows=3925 width=12) - Output: ws1_1.ws_order_number, ws1_1.ws_warehouse_sk, ws2_1.ws_warehouse_sk - Hash Cond: (ws1_1.ws_order_number = ws2_1.ws_order_number) - Join Filter: (ws1_1.ws_warehouse_sk <> ws2_1.ws_warehouse_sk) - -> Redistribute Motion 3:3 (slice7; segments: 3) (cost=0.00..99.81 rows=1144 width=8) - Output: ws1_1.ws_order_number, ws1_1.ws_warehouse_sk - Hash Key: ws1_1.ws_order_number - -> Seq Scan on cte_prune.tpcds_web_sales ws1_1 (cost=0.00..76.92 rows=1144 width=8) - Output: ws1_1.ws_order_number, ws1_1.ws_warehouse_sk - Filter: (ws1_1.ws_order_number > 0) - -> Hash (cost=99.81..99.81 rows=1144 width=8) - Output: ws2_1.ws_warehouse_sk, ws2_1.ws_order_number - -> Redistribute Motion 3:3 (slice8; segments: 3) (cost=0.00..99.81 rows=1144 width=8) - Output: ws2_1.ws_warehouse_sk, ws2_1.ws_order_number - Hash Key: ws2_1.ws_order_number - -> Seq Scan on cte_prune.tpcds_web_sales ws2_1 (cost=0.00..76.92 rows=1144 width=8) - Output: ws2_1.ws_warehouse_sk, ws2_1.ws_order_number - Filter: (ws2_1.ws_order_number > 0) - -> Hash (cost=1.03..1.03 rows=3 width=12) - Output: t1.v1, t1.v2, t1.v3, (RowIdExpr) - -> Seq Scan on cte_prune.t1 (cost=0.00..1.03 rows=3 width=12) - Output: t1.v1, t1.v2, t1.v3, RowIdExpr + -> Hash (cost=288.48..288.48 rows=5 width=16) + Output: t1.v1, t1.v2, t1.v3, ws_wh_1.ws_order_number + -> Hash Right Semi Join (cost=115.19..288.48 rows=5 width=16) + Output: t1.v1, t1.v2, t1.v3, ws_wh_1.ws_order_number + Hash Cond: (ws_wh_1.ws_order_number = t1.v1) + -> Subquery Scan on ws_wh_1 (cost=114.11..277.50 rows=3925 width=4) + Output: ws_wh_1.ws_order_number + -> Hash Join (cost=114.11..277.50 rows=3925 width=12) + Output: ws1_1.ws_order_number, ws1_1.ws_warehouse_sk, ws2_1.ws_warehouse_sk + Hash Cond: (ws1_1.ws_order_number = ws2_1.ws_order_number) + Join Filter: (ws1_1.ws_warehouse_sk <> ws2_1.ws_warehouse_sk) + -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..99.81 rows=1144 width=8) + Output: ws1_1.ws_order_number, ws1_1.ws_warehouse_sk + Hash Key: ws1_1.ws_order_number + -> Seq Scan on cte_prune.tpcds_web_sales ws1_1 (cost=0.00..76.92 rows=1144 width=8) + Output: ws1_1.ws_order_number, ws1_1.ws_warehouse_sk + Filter: (ws1_1.ws_order_number > 0) + -> Hash (cost=99.81..99.81 rows=1144 width=8) + Output: ws2_1.ws_warehouse_sk, ws2_1.ws_order_number + -> Redistribute Motion 3:3 (slice5; segments: 3) (cost=0.00..99.81 rows=1144 width=8) + Output: ws2_1.ws_warehouse_sk, ws2_1.ws_order_number + Hash Key: ws2_1.ws_order_number + -> Seq Scan on cte_prune.tpcds_web_sales ws2_1 (cost=0.00..76.92 rows=1144 width=8) + Output: ws2_1.ws_warehouse_sk, ws2_1.ws_order_number + Filter: (ws2_1.ws_order_number > 0) + -> Hash (cost=1.03..1.03 rows=3 width=12) + Output: t1.v1, t1.v2, t1.v3 + -> Seq Scan on cte_prune.t1 (cost=0.00..1.03 rows=3 width=12) + Output: t1.v1, t1.v2, t1.v3 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(71 rows) +(54 rows) explain verbose with ws_wh as (select ws1.ws_order_number,ws1.ws_warehouse_sk wh1,ws2.ws_warehouse_sk wh2 @@ -1157,6 +1155,7 @@ select * from t1 where t1.v1 in (select wh1 from ws_wh where true) and t1.v1 in Output: t1.v1, t1.v2, t1.v3, (RowIdExpr) -> Seq Scan on cte_prune.t1 (cost=0.00..1.03 rows=3 width=12) Output: t1.v1, t1.v2, t1.v3, RowIdExpr + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (72 rows) @@ -1271,6 +1270,7 @@ LIMIT 10; Output: t4_1.c, t4_1.d -> Seq Scan on cte_prune.t4 t4_1 (cost=0.00..1.03 rows=3 width=8) Output: t4_1.c, t4_1.d + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (80 rows) @@ -1349,8 +1349,9 @@ explain verbose select four, x Hash Key: 'foo'::text -> Seq Scan on cte_prune.cte_prune_tenk1 (cost=0.00..73.67 rows=3967 width=36) Output: cte_prune_tenk1.four, 'foo'::text + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(16 rows) +(17 rows) select four, x from (select four, ten, 'foo'::text as x from cte_prune_tenk1) as t @@ -1498,6 +1499,7 @@ where country.percentage = countrylanguage.percentage order by countrylanguage.C -> Seq Scan on cte_prune.country country_2 (cost=0.00..77.33 rows=3 width=52) Output: country_2.code, country_2.name, country_2.capital Filter: (country_2.continent = 'Europe'::text) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (76 rows) @@ -1626,6 +1628,7 @@ order by OUTERMOST_FOO.region,bad_headofstates.headofstate LIMIT 40; Output: city.id -> Seq Scan on cte_prune.city (cost=0.00..126.33 rows=9233 width=4) Output: city.id + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (105 rows) @@ -1693,8 +1696,9 @@ WHERE t6.a = x.c ORDER BY 1; Output: t6.a, t6.b -> Seq Scan on cte_prune.t6 (cost=0.00..321.00 rows=28700 width=8) Output: t6.a, t6.b + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(43 rows) +(44 rows) WITH w AS (SELECT a, b from t6 where b < 5) SELECT * @@ -1730,8 +1734,9 @@ select * from x where f1 = 1; -> Seq Scan on cte_prune.t7 Output: t7.f1 Filter: (t7.f1 = 1) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(6 rows) +(7 rows) with x as (select * from (select f1 from t7) ss) select * from x where f1 = 1; diff --git a/src/test/regress/expected/dedupset.out b/src/test/regress/expected/dedupset.out index bcf9b7f1123..9230cc68270 100644 --- a/src/test/regress/expected/dedupset.out +++ b/src/test/regress/expected/dedupset.out @@ -1,14 +1,25 @@ SET optimizer_trace_fallback = on; -- start_ignore drop table if exists t1; +NOTICE: table "t1" does not exist, skipping drop table if exists t2; +NOTICE: table "t2" does not exist, skipping drop table if exists t3; +NOTICE: table "t3" does not exist, skipping drop table if exists pt1; +NOTICE: table "pt1" does not exist, skipping drop table if exists pt2; +NOTICE: table "pt2" does not exist, skipping -- end_ignore create table t1(v1 int, v2 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'v1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create table t2(v3 int, v4 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'v3' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create table t3(v5 int, v6 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'v5' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into t1 values(generate_series(1, 100), generate_series(1, 100)); insert into t2 values(generate_series(1, 100), generate_series(1, 100)); insert into t3 values(generate_series(1, 100), generate_series(1, 100)); @@ -16,18 +27,30 @@ CREATE TABLE pt1 ( v1 INT, v2 INT ) PARTITION BY RANGE (v1); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'v1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TABLE pt1_p1 PARTITION OF pt1 FOR VALUES FROM (0) TO (20); +NOTICE: table has parent, setting distribution columns to match parent table CREATE TABLE pt1_p2 PARTITION OF pt1 FOR VALUES FROM (20) TO (40); +NOTICE: table has parent, setting distribution columns to match parent table CREATE TABLE pt1_p3 PARTITION OF pt1 FOR VALUES FROM (40) TO (60); +NOTICE: table has parent, setting distribution columns to match parent table CREATE TABLE pt1_p4 PARTITION OF pt1 FOR VALUES FROM (60) TO (400); +NOTICE: table has parent, setting distribution columns to match parent table CREATE TABLE pt2 ( v3 INT, v4 INT ) PARTITION BY RANGE (v3); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'v3' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TABLE pt2_p1 PARTITION OF pt2 FOR VALUES FROM (0) TO (20); +NOTICE: table has parent, setting distribution columns to match parent table CREATE TABLE pt2_p2 PARTITION OF pt2 FOR VALUES FROM (20) TO (40); +NOTICE: table has parent, setting distribution columns to match parent table CREATE TABLE pt2_p3 PARTITION OF pt2 FOR VALUES FROM (40) TO (60); +NOTICE: table has parent, setting distribution columns to match parent table CREATE TABLE pt2_p4 PARTITION OF pt2 FOR VALUES FROM (60) TO (400); +NOTICE: table has parent, setting distribution columns to match parent table insert into pt1 values(generate_series(1, 100), generate_series(1, 100)); insert into pt2 values(generate_series(1, 100), generate_series(1, 100)); analyze t1; @@ -37,58 +60,58 @@ analyze pt1; analyze pt2; -- dedup the subquery with projection explain verbose select * from t1 where v1 in (select v3 from t2) and v1 in (select v3 from t2 where v3 < 10); - QUERY PLAN ---------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.90..4.39 rows=3 width=8) + QUERY PLAN +--------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=2.90..4.38 rows=3 width=8) Output: t1.v1, t1.v2 - -> Hash Semi Join (cost=2.90..4.35 rows=1 width=8) + -> Hash Right Semi Join (cost=2.90..4.33 rows=1 width=8) Output: t1.v1, t1.v2 - Hash Cond: (t1.v1 = t2_1.v3) - -> Hash Semi Join (cost=1.45..2.89 rows=1 width=12) + Hash Cond: (t2_1.v3 = t1.v1) + -> Seq Scan on public.t2 t2_1 (cost=0.00..1.42 rows=3 width=4) + Output: t2_1.v3, t2_1.v4 + Filter: (t2_1.v3 < 10) + -> Hash (cost=2.88..2.88 rows=1 width=12) Output: t1.v1, t1.v2, t2.v3 - Hash Cond: (t1.v1 = t2.v3) - -> Seq Scan on public.t1 (cost=0.00..1.42 rows=3 width=8) - Output: t1.v1, t1.v2 - Filter: (t1.v1 < 10) - -> Hash (cost=1.42..1.42 rows=3 width=4) - Output: t2.v3 + -> Hash Right Semi Join (cost=1.45..2.88 rows=1 width=12) + Output: t1.v1, t1.v2, t2.v3 + Hash Cond: (t2.v3 = t1.v1) -> Seq Scan on public.t2 (cost=0.00..1.42 rows=3 width=4) - Output: t2.v3 + Output: t2.v3, t2.v4 Filter: (t2.v3 < 10) - -> Hash (cost=1.42..1.42 rows=3 width=4) - Output: t2_1.v3 - -> Seq Scan on public.t2 t2_1 (cost=0.00..1.42 rows=3 width=4) - Output: t2_1.v3 - Filter: (t2_1.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'off' + -> Hash (cost=1.42..1.42 rows=3 width=8) + Output: t1.v1, t1.v2 + -> Seq Scan on public.t1 (cost=0.00..1.42 rows=3 width=8) + Output: t1.v1, t1.v2 + Filter: (t1.v1 < 10) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (23 rows) explain verbose select * from t1 where v1 in (select v3 from t2 where v3 < 10) and v1 in (select v3 from t2); -- change the order - QUERY PLAN ---------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.90..4.39 rows=3 width=8) + QUERY PLAN +--------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=2.90..4.38 rows=3 width=8) Output: t1.v1, t1.v2 - -> Hash Semi Join (cost=2.90..4.35 rows=1 width=8) + -> Hash Right Semi Join (cost=2.90..4.33 rows=1 width=8) Output: t1.v1, t1.v2 - Hash Cond: (t1.v1 = t2_1.v3) - -> Hash Semi Join (cost=1.45..2.89 rows=1 width=12) + Hash Cond: (t2_1.v3 = t1.v1) + -> Seq Scan on public.t2 t2_1 (cost=0.00..1.42 rows=3 width=4) + Output: t2_1.v3, t2_1.v4 + Filter: (t2_1.v3 < 10) + -> Hash (cost=2.88..2.88 rows=1 width=12) Output: t1.v1, t1.v2, t2.v3 - Hash Cond: (t1.v1 = t2.v3) - -> Seq Scan on public.t1 (cost=0.00..1.42 rows=3 width=8) - Output: t1.v1, t1.v2 - Filter: (t1.v1 < 10) - -> Hash (cost=1.42..1.42 rows=3 width=4) - Output: t2.v3 + -> Hash Right Semi Join (cost=1.45..2.88 rows=1 width=12) + Output: t1.v1, t1.v2, t2.v3 + Hash Cond: (t2.v3 = t1.v1) -> Seq Scan on public.t2 (cost=0.00..1.42 rows=3 width=4) - Output: t2.v3 + Output: t2.v3, t2.v4 Filter: (t2.v3 < 10) - -> Hash (cost=1.42..1.42 rows=3 width=4) - Output: t2_1.v3 - -> Seq Scan on public.t2 t2_1 (cost=0.00..1.42 rows=3 width=4) - Output: t2_1.v3 - Filter: (t2_1.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'off' + -> Hash (cost=1.42..1.42 rows=3 width=8) + Output: t1.v1, t1.v2 + -> Seq Scan on public.t1 (cost=0.00..1.42 rows=3 width=8) + Output: t1.v1, t1.v2 + Filter: (t1.v1 < 10) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (23 rows) @@ -97,120 +120,117 @@ explain verbose select * from t1 where v1 in (select v3 from t2 where v3 < 10); ---------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=1.45..2.93 rows=3 width=8) Output: t1.v1, t1.v2 - -> Hash Semi Join (cost=1.45..2.89 rows=1 width=8) + -> Hash Right Semi Join (cost=1.45..2.88 rows=1 width=8) Output: t1.v1, t1.v2 - Hash Cond: (t1.v1 = t2.v3) - -> Seq Scan on public.t1 (cost=0.00..1.42 rows=3 width=8) + Hash Cond: (t2.v3 = t1.v1) + -> Seq Scan on public.t2 (cost=0.00..1.42 rows=3 width=4) + Output: t2.v3, t2.v4 + Filter: (t2.v3 < 10) + -> Hash (cost=1.42..1.42 rows=3 width=8) Output: t1.v1, t1.v2 - Filter: (t1.v1 < 10) - -> Hash (cost=1.42..1.42 rows=3 width=4) - Output: t2.v3 - -> Seq Scan on public.t2 (cost=0.00..1.42 rows=3 width=4) - Output: t2.v3 - Filter: (t2.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'off' + -> Seq Scan on public.t1 (cost=0.00..1.42 rows=3 width=8) + Output: t1.v1, t1.v2 + Filter: (t1.v1 < 10) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (15 rows) select * from t1 where v1 in (select v3 from t2) and v1 in (select v3 from t2 where v3 < 10); v1 | v2 ----+---- + 1 | 1 + 5 | 5 + 6 | 6 + 9 | 9 2 | 2 3 | 3 4 | 4 7 | 7 8 | 8 - 1 | 1 - 5 | 5 - 6 | 6 - 9 | 9 (9 rows) select * from t1 where v1 in (select v3 from t2 where v3 < 10); v1 | v2 ----+---- 1 | 1 - 5 | 5 - 6 | 6 - 9 | 9 2 | 2 3 | 3 4 | 4 7 | 7 8 | 8 + 5 | 5 + 6 | 6 + 9 | 9 (9 rows) explain verbose select * from pt1 where v1 in (select v3 from pt2) and v1 in (select v3 from pt2 where v3 < 10); - QUERY PLAN ------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=2.23..3.50 rows=8 width=8) Output: pt1.v1, pt1.v2 -> Hash Semi Join (cost=2.23..3.39 rows=3 width=8) Output: pt1.v1, pt1.v2 Hash Cond: (pt1.v1 = pt2_1.v3) - -> Hash Semi Join (cost=1.11..2.23 rows=3 width=12) + -> Hash Right Semi Join (cost=1.11..2.23 rows=3 width=12) Output: pt1.v1, pt1.v2, pt2.v3 - Hash Cond: (pt1.v1 = pt2.v3) - -> Seq Scan on public.pt1_p1 pt1 (cost=0.00..1.08 rows=3 width=8) - Output: pt1.v1, pt1.v2 - Filter: (pt1.v1 < 10) - -> Hash (cost=1.08..1.08 rows=3 width=4) + Hash Cond: (pt2.v3 = pt1.v1) + -> Seq Scan on public.pt2_p1 pt2 (cost=0.00..1.08 rows=3 width=4) Output: pt2.v3 - -> Partition Selector (selector id: $0) (cost=0.00..1.08 rows=3 width=4) - Output: pt2.v3 - -> Seq Scan on public.pt2_p1 pt2 (cost=0.00..1.08 rows=3 width=4) - Output: pt2.v3 - Filter: (pt2.v3 < 10) + Filter: (pt2.v3 < 10) + -> Hash (cost=1.08..1.08 rows=3 width=8) + Output: pt1.v1, pt1.v2 + -> Seq Scan on public.pt1_p1 pt1 (cost=0.00..1.08 rows=3 width=8) + Output: pt1.v1, pt1.v2 + Filter: (pt1.v1 < 10) -> Hash (cost=1.08..1.08 rows=3 width=4) Output: pt2_1.v3 - -> Partition Selector (selector id: $1) (cost=0.00..1.08 rows=3 width=4) + -> Partition Selector (selector id: $0) (cost=0.00..1.08 rows=3 width=4) Output: pt2_1.v3 -> Seq Scan on public.pt2_p1 pt2_1 (cost=0.00..1.08 rows=3 width=4) Output: pt2_1.v3 Filter: (pt2_1.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(27 rows) +(25 rows) explain verbose select * from pt1 where v1 in (select v3 from pt2 where v3 < 10); - QUERY PLAN ------------------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=1.11..2.35 rows=8 width=8) Output: pt1.v1, pt1.v2 - -> Hash Semi Join (cost=1.11..2.23 rows=3 width=8) + -> Hash Right Semi Join (cost=1.11..2.23 rows=3 width=8) Output: pt1.v1, pt1.v2 - Hash Cond: (pt1.v1 = pt2.v3) - -> Seq Scan on public.pt1_p1 pt1 (cost=0.00..1.08 rows=3 width=8) - Output: pt1.v1, pt1.v2 - Filter: (pt1.v1 < 10) - -> Hash (cost=1.08..1.08 rows=3 width=4) + Hash Cond: (pt2.v3 = pt1.v1) + -> Seq Scan on public.pt2_p1 pt2 (cost=0.00..1.08 rows=3 width=4) Output: pt2.v3 - -> Partition Selector (selector id: $0) (cost=0.00..1.08 rows=3 width=4) - Output: pt2.v3 - -> Seq Scan on public.pt2_p1 pt2 (cost=0.00..1.08 rows=3 width=4) - Output: pt2.v3 - Filter: (pt2.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'off' + Filter: (pt2.v3 < 10) + -> Hash (cost=1.08..1.08 rows=3 width=8) + Output: pt1.v1, pt1.v2 + -> Seq Scan on public.pt1_p1 pt1 (cost=0.00..1.08 rows=3 width=8) + Output: pt1.v1, pt1.v2 + Filter: (pt1.v1 < 10) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(17 rows) +(15 rows) select * from pt1 where v1 in (select v3 from pt2) and v1 in (select v3 from pt2 where v3 < 10); v1 | v2 ----+---- 1 | 1 - 5 | 5 - 6 | 6 - 9 | 9 2 | 2 3 | 3 4 | 4 7 | 7 8 | 8 + 5 | 5 + 6 | 6 + 9 | 9 (9 rows) select * from pt1 where v1 in (select v3 from pt2 where v3 < 10); v1 | v2 ----+---- + 1 | 1 2 | 2 3 | 3 4 | 4 @@ -219,68 +239,56 @@ select * from pt1 where v1 in (select v3 from pt2 where v3 < 10); 5 | 5 6 | 6 9 | 9 - 1 | 1 (9 rows) explain verbose with cte1 as (select v3 from t2) select count(*) from t1,t2 where t1.v1 in (select v3 from cte1) and t1.v1 in (select v3 from cte1 where v3 < 10); - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- - Finalize Aggregate (cost=10000000015.48..10000000015.49 rows=1 width=8) + QUERY PLAN +--------------------------------------------------------------------------------------------------------------- + Finalize Aggregate (cost=10000000015.04..10000000015.05 rows=1 width=8) Output: count(*) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=10000000015.43..10000000015.48 rows=3 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=10000000014.98..10000000015.03 rows=3 width=8) Output: (PARTIAL count(*)) - -> Partial Aggregate (cost=10000000015.43..10000000015.44 rows=1 width=8) + -> Partial Aggregate (cost=10000000014.98..10000000014.99 rows=1 width=8) Output: PARTIAL count(*) - -> Nested Loop (cost=10000000004.85..10000000014.75 rows=270 width=0) - -> Result (cost=4.85..4.86 rows=3 width=0) - -> Unique (cost=4.85..4.86 rows=3 width=0) - Output: (RowIdExpr) - Group Key: (RowIdExpr) - -> Sort (cost=4.85..4.86 rows=3 width=0) - Output: (RowIdExpr) - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.96..4.83 rows=3 width=0) - Output: (RowIdExpr) - Hash Key: (RowIdExpr) - -> Hash Join (cost=2.96..4.78 rows=3 width=0) - Output: (RowIdExpr) - Hash Cond: (t2_1.v3 = t1.v1) - -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=4) - Output: t2_1.v3 - -> Hash (cost=2.93..2.93 rows=3 width=8) - Output: t1.v1, t2_2.v3, (RowIdExpr) - -> Hash Semi Join (cost=1.48..2.93 rows=3 width=8) - Output: t1.v1, t2_2.v3, RowIdExpr - Hash Cond: (t1.v1 = t2_2.v3) - -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=4) - Output: t1.v1, t1.v2 - -> Hash (cost=1.44..1.44 rows=3 width=4) - Output: t2_2.v3 - -> Seq Scan on public.t2 t2_2 (cost=0.00..1.42 rows=3 width=4) - Output: t2_2.v3 - Filter: (t2_2.v3 < 10) + -> Nested Loop (cost=10000000002.93..10000000014.31 rows=270 width=0) + -> Hash Right Semi Join (cost=2.93..4.42 rows=3 width=0) + Hash Cond: (t2_1.v3 = t1.v1) + -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=4) + Output: t2_1.v3 + -> Hash (cost=2.90..2.90 rows=3 width=8) + Output: t1.v1, t2_2.v3 + -> Hash Semi Join (cost=1.45..2.90 rows=3 width=8) + Output: t1.v1, t2_2.v3 + Hash Cond: (t1.v1 = t2_2.v3) + -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=4) + Output: t1.v1, t1.v2 + -> Hash (cost=1.42..1.42 rows=3 width=4) + Output: t2_2.v3 + -> Seq Scan on public.t2 t2_2 (cost=0.00..1.42 rows=3 width=4) + Output: t2_2.v3 + Filter: (t2_2.v3 < 10) -> Materialize (cost=0.00..3.17 rows=100 width=0) - -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..2.67 rows=100 width=0) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..2.67 rows=100 width=0) -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=0) - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(39 rows) +(28 rows) explain verbose with cte1 as (select v3 from t2) select count(*) from t1,t2 where t1.v1 in (select v3 from cte1 where v3 < 10); QUERY PLAN --------------------------------------------------------------------------------------------------------------- - Finalize Aggregate (cost=10000000013.55..10000000013.56 rows=1 width=8) + Finalize Aggregate (cost=10000000013.52..10000000013.53 rows=1 width=8) Output: count(*) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=10000000013.49..10000000013.54 rows=3 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=10000000013.46..10000000013.51 rows=3 width=8) Output: (PARTIAL count(*)) - -> Partial Aggregate (cost=10000000013.49..10000000013.50 rows=1 width=8) + -> Partial Aggregate (cost=10000000013.46..10000000013.47 rows=1 width=8) Output: PARTIAL count(*) - -> Nested Loop (cost=10000000001.48..10000000012.81 rows=270 width=0) - -> Hash Semi Join (cost=1.48..2.93 rows=3 width=0) + -> Nested Loop (cost=10000000001.45..10000000012.79 rows=270 width=0) + -> Hash Semi Join (cost=1.45..2.90 rows=3 width=0) Hash Cond: (t1.v1 = t2_1.v3) -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=4) Output: t1.v1, t1.v2 - -> Hash (cost=1.44..1.44 rows=3 width=4) + -> Hash (cost=1.42..1.42 rows=3 width=4) Output: t2_1.v3 -> Seq Scan on public.t2 t2_1 (cost=0.00..1.42 rows=3 width=4) Output: t2_1.v3 @@ -288,7 +296,7 @@ explain verbose with cte1 as (select v3 from t2) select count(*) from t1,t2 wher -> Materialize (cost=0.00..3.17 rows=100 width=0) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..2.67 rows=100 width=0) -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=0) - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (21 rows) @@ -307,48 +315,37 @@ with cte1 as (select v3 from t2) select count(*) from t1,t2 where t1.v1 in (sele set optimizer_cte_inlining to on; set optimizer_cte_inlining_bound to 2; explain verbose with cte1 as (select v3 from t2) select count(*) from t1,t2 where t1.v1 in (select v3 from cte1) and t1.v1 in (select v3 from cte1 where v3 < 10); - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- - Finalize Aggregate (cost=10000000015.48..10000000015.49 rows=1 width=8) + QUERY PLAN +--------------------------------------------------------------------------------------------------------------- + Finalize Aggregate (cost=10000000015.04..10000000015.05 rows=1 width=8) Output: count(*) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=10000000015.43..10000000015.48 rows=3 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=10000000014.98..10000000015.03 rows=3 width=8) Output: (PARTIAL count(*)) - -> Partial Aggregate (cost=10000000015.43..10000000015.44 rows=1 width=8) + -> Partial Aggregate (cost=10000000014.98..10000000014.99 rows=1 width=8) Output: PARTIAL count(*) - -> Nested Loop (cost=10000000004.85..10000000014.75 rows=270 width=0) - -> Result (cost=4.85..4.86 rows=3 width=0) - -> Unique (cost=4.85..4.86 rows=3 width=0) - Output: (RowIdExpr) - Group Key: (RowIdExpr) - -> Sort (cost=4.85..4.86 rows=3 width=0) - Output: (RowIdExpr) - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.96..4.83 rows=3 width=0) - Output: (RowIdExpr) - Hash Key: (RowIdExpr) - -> Hash Join (cost=2.96..4.78 rows=3 width=0) - Output: (RowIdExpr) - Hash Cond: (t2_1.v3 = t1.v1) - -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=4) - Output: t2_1.v3 - -> Hash (cost=2.93..2.93 rows=3 width=8) - Output: t1.v1, t2_2.v3, (RowIdExpr) - -> Hash Semi Join (cost=1.48..2.93 rows=3 width=8) - Output: t1.v1, t2_2.v3, RowIdExpr - Hash Cond: (t1.v1 = t2_2.v3) - -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=4) - Output: t1.v1, t1.v2 - -> Hash (cost=1.44..1.44 rows=3 width=4) - Output: t2_2.v3 - -> Seq Scan on public.t2 t2_2 (cost=0.00..1.42 rows=3 width=4) - Output: t2_2.v3 - Filter: (t2_2.v3 < 10) + -> Nested Loop (cost=10000000002.93..10000000014.31 rows=270 width=0) + -> Hash Right Semi Join (cost=2.93..4.42 rows=3 width=0) + Hash Cond: (t2_1.v3 = t1.v1) + -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=4) + Output: t2_1.v3 + -> Hash (cost=2.90..2.90 rows=3 width=8) + Output: t1.v1, t2_2.v3 + -> Hash Semi Join (cost=1.45..2.90 rows=3 width=8) + Output: t1.v1, t2_2.v3 + Hash Cond: (t1.v1 = t2_2.v3) + -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=4) + Output: t1.v1, t1.v2 + -> Hash (cost=1.42..1.42 rows=3 width=4) + Output: t2_2.v3 + -> Seq Scan on public.t2 t2_2 (cost=0.00..1.42 rows=3 width=4) + Output: t2_2.v3 + Filter: (t2_2.v3 < 10) -> Materialize (cost=0.00..3.17 rows=100 width=0) - -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..2.67 rows=100 width=0) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..2.67 rows=100 width=0) -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=0) - Settings: enable_parallel = 'off', optimizer = 'off', optimizer_cte_inlining_bound = '2' + Settings: optimizer = 'off', optimizer_cte_inlining_bound = '2' Optimizer: Postgres query optimizer -(39 rows) +(28 rows) with cte1 as (select v3 from t2) select count(*) from t1,t2 where t1.v1 in (select v3 from cte1) and t1.v1 in (select v3 from cte1 where v3 < 10); count @@ -359,32 +356,32 @@ with cte1 as (select v3 from t2) select count(*) from t1,t2 where t1.v1 in (sele reset optimizer_cte_inlining; reset optimizer_cte_inlining_bound; explain verbose select sum(v1) from t1 where v1 in (select v3 from t2) and v1 in (select v3 from t2 where v3 < 10); - QUERY PLAN ---------------------------------------------------------------------------------------- - Aggregate (cost=4.40..4.41 rows=1 width=8) + QUERY PLAN +--------------------------------------------------------------------------------------------- + Aggregate (cost=4.39..4.40 rows=1 width=8) Output: sum(t1.v1) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=2.90..4.39 rows=3 width=4) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=2.90..4.38 rows=3 width=4) Output: t1.v1 - -> Hash Semi Join (cost=2.90..4.35 rows=1 width=4) + -> Hash Right Semi Join (cost=2.90..4.33 rows=1 width=4) Output: t1.v1 - Hash Cond: (t1.v1 = t2_1.v3) - -> Hash Semi Join (cost=1.45..2.89 rows=1 width=8) + Hash Cond: (t2_1.v3 = t1.v1) + -> Seq Scan on public.t2 t2_1 (cost=0.00..1.42 rows=3 width=4) + Output: t2_1.v3, t2_1.v4 + Filter: (t2_1.v3 < 10) + -> Hash (cost=2.88..2.88 rows=1 width=8) Output: t1.v1, t2.v3 - Hash Cond: (t1.v1 = t2.v3) - -> Seq Scan on public.t1 (cost=0.00..1.42 rows=3 width=4) - Output: t1.v1, t1.v2 - Filter: (t1.v1 < 10) - -> Hash (cost=1.42..1.42 rows=3 width=4) - Output: t2.v3 + -> Hash Right Semi Join (cost=1.45..2.88 rows=1 width=8) + Output: t1.v1, t2.v3 + Hash Cond: (t2.v3 = t1.v1) -> Seq Scan on public.t2 (cost=0.00..1.42 rows=3 width=4) - Output: t2.v3 + Output: t2.v3, t2.v4 Filter: (t2.v3 < 10) - -> Hash (cost=1.42..1.42 rows=3 width=4) - Output: t2_1.v3 - -> Seq Scan on public.t2 t2_1 (cost=0.00..1.42 rows=3 width=4) - Output: t2_1.v3 - Filter: (t2_1.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'off' + -> Hash (cost=1.42..1.42 rows=3 width=4) + Output: t1.v1 + -> Seq Scan on public.t1 (cost=0.00..1.42 rows=3 width=4) + Output: t1.v1 + Filter: (t1.v1 < 10) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (25 rows) @@ -395,18 +392,18 @@ explain verbose select sum(v1) from t1 where v1 in (select v3 from t2 where v3 < Output: sum(t1.v1) -> Gather Motion 3:1 (slice1; segments: 3) (cost=1.45..2.93 rows=3 width=4) Output: t1.v1 - -> Hash Semi Join (cost=1.45..2.89 rows=1 width=4) + -> Hash Right Semi Join (cost=1.45..2.88 rows=1 width=4) Output: t1.v1 - Hash Cond: (t1.v1 = t2.v3) - -> Seq Scan on public.t1 (cost=0.00..1.42 rows=3 width=4) - Output: t1.v1, t1.v2 - Filter: (t1.v1 < 10) + Hash Cond: (t2.v3 = t1.v1) + -> Seq Scan on public.t2 (cost=0.00..1.42 rows=3 width=4) + Output: t2.v3, t2.v4 + Filter: (t2.v3 < 10) -> Hash (cost=1.42..1.42 rows=3 width=4) - Output: t2.v3 - -> Seq Scan on public.t2 (cost=0.00..1.42 rows=3 width=4) - Output: t2.v3 - Filter: (t2.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'off' + Output: t1.v1 + -> Seq Scan on public.t1 (cost=0.00..1.42 rows=3 width=4) + Output: t1.v1 + Filter: (t1.v1 < 10) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (17 rows) @@ -423,58 +420,58 @@ select sum(v1) from t1 where v1 in (select v3 from t2 where v3 < 10); (1 row) explain verbose select * from t1 where v1 in (select v3 from t2) and v1 in (select v3 from t2 where v3 < 10) order by v1; - QUERY PLAN ---------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=4.36..4.41 rows=3 width=8) + QUERY PLAN +--------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=4.34..4.39 rows=3 width=8) Output: t1.v1, t1.v2 Merge Key: t1.v1 - -> Sort (cost=4.36..4.36 rows=1 width=8) + -> Sort (cost=4.34..4.35 rows=1 width=8) Output: t1.v1, t1.v2 Sort Key: t1.v1 - -> Hash Semi Join (cost=2.90..4.35 rows=1 width=8) + -> Hash Right Semi Join (cost=2.90..4.33 rows=1 width=8) Output: t1.v1, t1.v2 - Hash Cond: (t1.v1 = t2_1.v3) - -> Hash Semi Join (cost=1.45..2.89 rows=1 width=12) + Hash Cond: (t2_1.v3 = t1.v1) + -> Seq Scan on public.t2 t2_1 (cost=0.00..1.42 rows=3 width=4) + Output: t2_1.v3, t2_1.v4 + Filter: (t2_1.v3 < 10) + -> Hash (cost=2.88..2.88 rows=1 width=12) Output: t1.v1, t1.v2, t2.v3 - Hash Cond: (t1.v1 = t2.v3) - -> Seq Scan on public.t1 (cost=0.00..1.42 rows=3 width=8) - Output: t1.v1, t1.v2 - Filter: (t1.v1 < 10) - -> Hash (cost=1.42..1.42 rows=3 width=4) - Output: t2.v3 + -> Hash Right Semi Join (cost=1.45..2.88 rows=1 width=12) + Output: t1.v1, t1.v2, t2.v3 + Hash Cond: (t2.v3 = t1.v1) -> Seq Scan on public.t2 (cost=0.00..1.42 rows=3 width=4) - Output: t2.v3 + Output: t2.v3, t2.v4 Filter: (t2.v3 < 10) - -> Hash (cost=1.42..1.42 rows=3 width=4) - Output: t2_1.v3 - -> Seq Scan on public.t2 t2_1 (cost=0.00..1.42 rows=3 width=4) - Output: t2_1.v3 - Filter: (t2_1.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'off' + -> Hash (cost=1.42..1.42 rows=3 width=8) + Output: t1.v1, t1.v2 + -> Seq Scan on public.t1 (cost=0.00..1.42 rows=3 width=8) + Output: t1.v1, t1.v2 + Filter: (t1.v1 < 10) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (27 rows) explain verbose select * from t1 where v1 in (select v3 from t2 where v3 < 10) order by v1; QUERY PLAN --------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.90..2.94 rows=3 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=2.89..2.94 rows=3 width=8) Output: t1.v1, t1.v2 Merge Key: t1.v1 - -> Sort (cost=2.90..2.90 rows=1 width=8) + -> Sort (cost=2.89..2.90 rows=1 width=8) Output: t1.v1, t1.v2 Sort Key: t1.v1 - -> Hash Semi Join (cost=1.45..2.89 rows=1 width=8) + -> Hash Right Semi Join (cost=1.45..2.88 rows=1 width=8) Output: t1.v1, t1.v2 - Hash Cond: (t1.v1 = t2.v3) - -> Seq Scan on public.t1 (cost=0.00..1.42 rows=3 width=8) + Hash Cond: (t2.v3 = t1.v1) + -> Seq Scan on public.t2 (cost=0.00..1.42 rows=3 width=4) + Output: t2.v3, t2.v4 + Filter: (t2.v3 < 10) + -> Hash (cost=1.42..1.42 rows=3 width=8) Output: t1.v1, t1.v2 - Filter: (t1.v1 < 10) - -> Hash (cost=1.42..1.42 rows=3 width=4) - Output: t2.v3 - -> Seq Scan on public.t2 (cost=0.00..1.42 rows=3 width=4) - Output: t2.v3 - Filter: (t2.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'off' + -> Seq Scan on public.t1 (cost=0.00..1.42 rows=3 width=8) + Output: t1.v1, t1.v2 + Filter: (t1.v1 < 10) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (19 rows) @@ -507,39 +504,39 @@ select * from t1 where v1 in (select v3 from t2 where v3 < 10) order by v1; (9 rows) explain verbose select sum(v1) from t1 where v1 in (select v3 from t2) and v1 in (select v3 from t2 where v3 < 10) group by v2; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=4.38..4.45 rows=3 width=12) + QUERY PLAN +--------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=4.37..4.43 rows=3 width=12) Output: (sum(t1.v1)), t1.v2 - -> GroupAggregate (cost=4.38..4.40 rows=1 width=12) + -> GroupAggregate (cost=4.37..4.39 rows=1 width=12) Output: sum(t1.v1), t1.v2 Group Key: t1.v2 - -> Sort (cost=4.38..4.39 rows=1 width=8) + -> Sort (cost=4.37..4.37 rows=1 width=8) Output: t1.v2, t1.v1 Sort Key: t1.v2 - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.90..4.37 rows=1 width=8) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.90..4.36 rows=1 width=8) Output: t1.v2, t1.v1 Hash Key: t1.v2 - -> Hash Semi Join (cost=2.90..4.35 rows=1 width=8) + -> Hash Right Semi Join (cost=2.90..4.33 rows=1 width=8) Output: t1.v2, t1.v1 - Hash Cond: (t1.v1 = t2_1.v3) - -> Hash Semi Join (cost=1.45..2.89 rows=1 width=12) + Hash Cond: (t2_1.v3 = t1.v1) + -> Seq Scan on public.t2 t2_1 (cost=0.00..1.42 rows=3 width=4) + Output: t2_1.v3, t2_1.v4 + Filter: (t2_1.v3 < 10) + -> Hash (cost=2.88..2.88 rows=1 width=12) Output: t1.v1, t1.v2, t2.v3 - Hash Cond: (t1.v1 = t2.v3) - -> Seq Scan on public.t1 (cost=0.00..1.42 rows=3 width=8) - Output: t1.v1, t1.v2 - Filter: (t1.v1 < 10) - -> Hash (cost=1.42..1.42 rows=3 width=4) - Output: t2.v3 + -> Hash Right Semi Join (cost=1.45..2.88 rows=1 width=12) + Output: t1.v1, t1.v2, t2.v3 + Hash Cond: (t2.v3 = t1.v1) -> Seq Scan on public.t2 (cost=0.00..1.42 rows=3 width=4) - Output: t2.v3 + Output: t2.v3, t2.v4 Filter: (t2.v3 < 10) - -> Hash (cost=1.42..1.42 rows=3 width=4) - Output: t2_1.v3 - -> Seq Scan on public.t2 t2_1 (cost=0.00..1.42 rows=3 width=4) - Output: t2_1.v3 - Filter: (t2_1.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'off' + -> Hash (cost=1.42..1.42 rows=3 width=8) + Output: t1.v1, t1.v2 + -> Seq Scan on public.t1 (cost=0.00..1.42 rows=3 width=8) + Output: t1.v1, t1.v2 + Filter: (t1.v1 < 10) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (32 rows) @@ -557,18 +554,18 @@ explain verbose select sum(v1) from t1 where v1 in (select v3 from t2 where v3 < -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.45..2.91 rows=1 width=8) Output: t1.v2, t1.v1 Hash Key: t1.v2 - -> Hash Semi Join (cost=1.45..2.89 rows=1 width=8) + -> Hash Right Semi Join (cost=1.45..2.88 rows=1 width=8) Output: t1.v2, t1.v1 - Hash Cond: (t1.v1 = t2.v3) - -> Seq Scan on public.t1 (cost=0.00..1.42 rows=3 width=8) + Hash Cond: (t2.v3 = t1.v1) + -> Seq Scan on public.t2 (cost=0.00..1.42 rows=3 width=4) + Output: t2.v3, t2.v4 + Filter: (t2.v3 < 10) + -> Hash (cost=1.42..1.42 rows=3 width=8) Output: t1.v1, t1.v2 - Filter: (t1.v1 < 10) - -> Hash (cost=1.42..1.42 rows=3 width=4) - Output: t2.v3 - -> Seq Scan on public.t2 (cost=0.00..1.42 rows=3 width=4) - Output: t2.v3 - Filter: (t2.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'off' + -> Seq Scan on public.t1 (cost=0.00..1.42 rows=3 width=8) + Output: t1.v1, t1.v2 + Filter: (t1.v1 < 10) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (24 rows) @@ -589,15 +586,15 @@ select sum(v1) from t1 where v1 in (select v3 from t2) and v1 in (select v3 from select sum(v1) from t1 where v1 in (select v3 from t2 where v3 < 10) group by v2; sum ----- + 1 + 5 + 6 + 9 2 3 4 7 8 - 1 - 5 - 6 - 9 (9 rows) -- dedup the same subqueryany @@ -622,7 +619,7 @@ explain verbose select * from t1 where v1 in (select v3 from t2) and v1 in (sele Output: t2_1.v3 -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=4) Output: t2_1.v3 - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (20 rows) @@ -640,7 +637,7 @@ explain verbose select * from t1 where v1 in (select v3 from t2); Output: t2.v3 -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=4) Output: t2.v3 - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (13 rows) @@ -703,7 +700,7 @@ explain verbose select * from pt1 where v1 in (select v3 from pt2) and v1 in (se Output: pt2_8.v3 -> Seq Scan on public.pt2_p4 pt2_9 (cost=0.00..1.14 rows=14 width=4) Output: pt2_9.v3 - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (46 rows) @@ -738,7 +735,7 @@ explain verbose select * from pt1 where v1 in (select v3 from pt2); Output: pt2_3.v3 -> Seq Scan on public.pt2_p4 pt2_4 (cost=0.00..1.14 rows=14 width=4) Output: pt2_4.v3 - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (30 rows) @@ -757,45 +754,45 @@ select count(*) from pt1 where v1 in (select v3 from pt2); explain verbose with cte1 as (select v3 from t2) select count(*) from t1,t2 where t1.v1 in (select v3 from cte1) and t1.v1 in (select v3 from cte1); QUERY PLAN --------------------------------------------------------------------------------------------------------------- - Finalize Aggregate (cost=10000000137.03..10000000137.04 rows=1 width=8) + Finalize Aggregate (cost=10000000136.36..10000000136.37 rows=1 width=8) Output: count(*) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=10000000136.97..10000000137.02 rows=3 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=10000000136.30..10000000136.35 rows=3 width=8) Output: (PARTIAL count(*)) - -> Partial Aggregate (cost=10000000136.97..10000000136.98 rows=1 width=8) + -> Partial Aggregate (cost=10000000136.30..10000000136.31 rows=1 width=8) Output: PARTIAL count(*) - -> Nested Loop (cost=10000000004.17..10000000128.64 rows=3333 width=0) - -> Hash Semi Join (cost=4.17..6.42 rows=33 width=0) + -> Nested Loop (cost=10000000003.50..10000000127.97 rows=3333 width=0) + -> Hash Semi Join (cost=3.50..5.75 rows=33 width=0) Hash Cond: (t1.v1 = t2_2.v3) - -> Hash Semi Join (cost=2.08..3.87 rows=33 width=8) + -> Hash Semi Join (cost=1.75..3.54 rows=33 width=8) Output: t1.v1, t2_1.v3 Hash Cond: (t1.v1 = t2_1.v3) -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=4) Output: t1.v1, t1.v2 - -> Hash (cost=1.67..1.67 rows=33 width=4) + -> Hash (cost=1.33..1.33 rows=33 width=4) Output: t2_1.v3 -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=4) Output: t2_1.v3 - -> Hash (cost=1.67..1.67 rows=33 width=4) + -> Hash (cost=1.33..1.33 rows=33 width=4) Output: t2_2.v3 -> Seq Scan on public.t2 t2_2 (cost=0.00..1.33 rows=33 width=4) Output: t2_2.v3 -> Materialize (cost=0.00..3.17 rows=100 width=0) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..2.67 rows=100 width=0) -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=0) - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (27 rows) explain verbose with cte1 as (select v3 from t2) select count(*) from t1,t2 where t1.v1 in (select v3 from cte1); QUERY PLAN --------------------------------------------------------------------------------------------------------------- - Finalize Aggregate (cost=10000000102.06..10000000102.07 rows=1 width=8) + Finalize Aggregate (cost=10000000101.72..10000000101.73 rows=1 width=8) Output: count(*) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=10000000102.00..10000000102.05 rows=3 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=10000000101.67..10000000101.72 rows=3 width=8) Output: (PARTIAL count(*)) - -> Partial Aggregate (cost=10000000102.00..10000000102.01 rows=1 width=8) + -> Partial Aggregate (cost=10000000101.67..10000000101.68 rows=1 width=8) Output: PARTIAL count(*) - -> Hash Semi Join (cost=10000000002.08..10000000093.67 rows=3333 width=0) + -> Hash Semi Join (cost=10000000001.75..10000000093.33 rows=3333 width=0) Hash Cond: (t1.v1 = t2_1.v3) -> Nested Loop (cost=10000000000.00..10000000045.75 rows=3333 width=4) Output: t1.v1 @@ -805,11 +802,11 @@ explain verbose with cte1 as (select v3 from t2) select count(*) from t1,t2 wher Output: t1.v1 -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=4) Output: t1.v1 - -> Hash (cost=1.67..1.67 rows=33 width=4) + -> Hash (cost=1.33..1.33 rows=33 width=4) Output: t2_1.v3 -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=4) Output: t2_1.v3 - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (22 rows) @@ -830,32 +827,32 @@ set optimizer_cte_inlining_bound to 2; explain verbose with cte1 as (select v3 from t2) select count(*) from t1,t2 where t1.v1 in (select v3 from cte1) and t1.v1 in (select v3 from cte1); QUERY PLAN --------------------------------------------------------------------------------------------------------------- - Finalize Aggregate (cost=10000000137.03..10000000137.04 rows=1 width=8) + Finalize Aggregate (cost=10000000136.36..10000000136.37 rows=1 width=8) Output: count(*) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=10000000136.97..10000000137.02 rows=3 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=10000000136.30..10000000136.35 rows=3 width=8) Output: (PARTIAL count(*)) - -> Partial Aggregate (cost=10000000136.97..10000000136.98 rows=1 width=8) + -> Partial Aggregate (cost=10000000136.30..10000000136.31 rows=1 width=8) Output: PARTIAL count(*) - -> Nested Loop (cost=10000000004.17..10000000128.64 rows=3333 width=0) - -> Hash Semi Join (cost=4.17..6.42 rows=33 width=0) + -> Nested Loop (cost=10000000003.50..10000000127.97 rows=3333 width=0) + -> Hash Semi Join (cost=3.50..5.75 rows=33 width=0) Hash Cond: (t1.v1 = t2_2.v3) - -> Hash Semi Join (cost=2.08..3.87 rows=33 width=8) + -> Hash Semi Join (cost=1.75..3.54 rows=33 width=8) Output: t1.v1, t2_1.v3 Hash Cond: (t1.v1 = t2_1.v3) -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=4) Output: t1.v1, t1.v2 - -> Hash (cost=1.67..1.67 rows=33 width=4) + -> Hash (cost=1.33..1.33 rows=33 width=4) Output: t2_1.v3 -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=4) Output: t2_1.v3 - -> Hash (cost=1.67..1.67 rows=33 width=4) + -> Hash (cost=1.33..1.33 rows=33 width=4) Output: t2_2.v3 -> Seq Scan on public.t2 t2_2 (cost=0.00..1.33 rows=33 width=4) Output: t2_2.v3 -> Materialize (cost=0.00..3.17 rows=100 width=0) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..2.67 rows=100 width=0) -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=0) - Settings: enable_parallel = 'off', optimizer = 'off', optimizer_cte_inlining_bound = '2' + Settings: optimizer = 'off', optimizer_cte_inlining_bound = '2' Optimizer: Postgres query optimizer (27 rows) @@ -869,187 +866,176 @@ reset optimizer_cte_inlining; reset optimizer_cte_inlining_bound; -- dedup the subquery with inner join explain verbose select * from t1 where v1 in (select v3 from t2) and v1 in (select v3 from t2,t3 where v4=v6); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=7.71..11.29 rows=100 width=8) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=5.92..11.29 rows=100 width=8) Output: t1.v1, t1.v2 - -> Hash Semi Join (cost=7.71..9.96 rows=33 width=8) + -> Hash Semi Join (cost=5.92..9.96 rows=33 width=8) Output: t1.v1, t1.v2 Hash Cond: (t1.v1 = t2.v3) - -> Hash Semi Join (cost=5.96..7.75 rows=33 width=12) + -> Hash Right Semi Join (cost=4.17..7.75 rows=33 width=12) Output: t1.v1, t1.v2, t2_1.v3 - Hash Cond: (t1.v1 = t2_1.v3) - -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=8) - Output: t1.v1, t1.v2 - -> Hash (cost=5.54..5.54 rows=33 width=4) + Hash Cond: (t2_1.v3 = t1.v1) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.42..5.54 rows=33 width=4) Output: t2_1.v3 - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.42..5.54 rows=33 width=4) + Hash Key: t2_1.v3 + -> Hash Join (cost=2.42..4.88 rows=33 width=4) Output: t2_1.v3 - Hash Key: t2_1.v3 - -> Hash Join (cost=2.42..4.88 rows=33 width=4) - Output: t2_1.v3 - Hash Cond: (t2_1.v4 = t3.v6) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..2.00 rows=33 width=8) + Hash Cond: (t2_1.v4 = t3.v6) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..2.00 rows=33 width=8) + Output: t2_1.v4, t2_1.v3 + Hash Key: t2_1.v4 + -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=8) Output: t2_1.v4, t2_1.v3 - Hash Key: t2_1.v4 - -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=8) - Output: t2_1.v4, t2_1.v3 - -> Hash (cost=2.00..2.00 rows=33 width=4) + -> Hash (cost=2.00..2.00 rows=33 width=4) + Output: t3.v6 + -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..2.00 rows=33 width=4) Output: t3.v6 - -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..2.00 rows=33 width=4) + Hash Key: t3.v6 + -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) Output: t3.v6 - Hash Key: t3.v6 - -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) - Output: t3.v6 + -> Hash (cost=1.33..1.33 rows=33 width=8) + Output: t1.v1, t1.v2 + -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=8) + Output: t1.v1, t1.v2 -> Hash (cost=1.33..1.33 rows=33 width=4) Output: t2.v3 -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=4) Output: t2.v3 - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (36 rows) explain verbose select * from t1 where v1 in (select v3 from t2) and v1 in (select v3 from t3,t2 where v4=v6); -- change the join order,different index in inner join - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=7.71..11.29 rows=100 width=8) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=5.92..11.29 rows=100 width=8) Output: t1.v1, t1.v2 - -> Hash Semi Join (cost=7.71..9.96 rows=33 width=8) + -> Hash Semi Join (cost=5.92..9.96 rows=33 width=8) Output: t1.v1, t1.v2 Hash Cond: (t1.v1 = t2.v3) - -> Hash Semi Join (cost=5.96..7.75 rows=33 width=12) + -> Hash Right Semi Join (cost=4.17..7.75 rows=33 width=12) Output: t1.v1, t1.v2, t2_1.v3 - Hash Cond: (t1.v1 = t2_1.v3) - -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=8) - Output: t1.v1, t1.v2 - -> Hash (cost=5.54..5.54 rows=33 width=4) + Hash Cond: (t2_1.v3 = t1.v1) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.42..5.54 rows=33 width=4) Output: t2_1.v3 - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.42..5.54 rows=33 width=4) + Hash Key: t2_1.v3 + -> Hash Join (cost=2.42..4.88 rows=33 width=4) Output: t2_1.v3 - Hash Key: t2_1.v3 - -> Hash Join (cost=2.42..4.88 rows=33 width=4) - Output: t2_1.v3 - Hash Cond: (t3.v6 = t2_1.v4) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..2.00 rows=33 width=4) + Hash Cond: (t3.v6 = t2_1.v4) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..2.00 rows=33 width=4) + Output: t3.v6 + Hash Key: t3.v6 + -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) Output: t3.v6 - Hash Key: t3.v6 - -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) - Output: t3.v6 - -> Hash (cost=2.00..2.00 rows=33 width=8) + -> Hash (cost=2.00..2.00 rows=33 width=8) + Output: t2_1.v4, t2_1.v3 + -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..2.00 rows=33 width=8) Output: t2_1.v4, t2_1.v3 - -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..2.00 rows=33 width=8) + Hash Key: t2_1.v4 + -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=8) Output: t2_1.v4, t2_1.v3 - Hash Key: t2_1.v4 - -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=8) - Output: t2_1.v4, t2_1.v3 + -> Hash (cost=1.33..1.33 rows=33 width=8) + Output: t1.v1, t1.v2 + -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=8) + Output: t1.v1, t1.v2 -> Hash (cost=1.33..1.33 rows=33 width=4) Output: t2.v3 -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=4) Output: t2.v3 - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (36 rows) explain verbose select * from t1 where v1 in (select v3 from t2,t3 where v4=v6); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=5.96..9.08 rows=100 width=8) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=4.17..9.08 rows=100 width=8) Output: t1.v1, t1.v2 - -> Hash Semi Join (cost=5.96..7.75 rows=33 width=8) + -> Hash Right Semi Join (cost=4.17..7.75 rows=33 width=8) Output: t1.v1, t1.v2 - Hash Cond: (t1.v1 = t2.v3) - -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=8) - Output: t1.v1, t1.v2 - -> Hash (cost=5.54..5.54 rows=33 width=4) + Hash Cond: (t2.v3 = t1.v1) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.42..5.54 rows=33 width=4) Output: t2.v3 - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.42..5.54 rows=33 width=4) + Hash Key: t2.v3 + -> Hash Join (cost=2.42..4.88 rows=33 width=4) Output: t2.v3 - Hash Key: t2.v3 - -> Hash Join (cost=2.42..4.88 rows=33 width=4) - Output: t2.v3 - Hash Cond: (t2.v4 = t3.v6) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..2.00 rows=33 width=8) + Hash Cond: (t2.v4 = t3.v6) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..2.00 rows=33 width=8) + Output: t2.v4, t2.v3 + Hash Key: t2.v4 + -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=8) Output: t2.v4, t2.v3 - Hash Key: t2.v4 - -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=8) - Output: t2.v4, t2.v3 - -> Hash (cost=2.00..2.00 rows=33 width=4) + -> Hash (cost=2.00..2.00 rows=33 width=4) + Output: t3.v6 + -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..2.00 rows=33 width=4) Output: t3.v6 - -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..2.00 rows=33 width=4) + Hash Key: t3.v6 + -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) Output: t3.v6 - Hash Key: t3.v6 - -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) - Output: t3.v6 - Settings: enable_parallel = 'off', optimizer = 'off' + -> Hash (cost=1.33..1.33 rows=33 width=8) + Output: t1.v1, t1.v2 + -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=8) + Output: t1.v1, t1.v2 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (29 rows) explain verbose select * from t1 where v1 in (select v3 from t2) and v1 in (select v3 from t2,t3 where v4=v6 and v4 < 10); - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=6.04..6.14 rows=7 width=8) + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=4.50..6.07 rows=7 width=8) Output: t1.v1, t1.v2 - -> Result (cost=6.04..6.05 rows=2 width=8) + -> Hash Right Semi Join (cost=4.50..5.98 rows=2 width=8) Output: t1.v1, t1.v2 - -> Unique (cost=6.04..6.05 rows=2 width=8) - Output: t1.v1, t1.v2, (RowIdExpr) - Group Key: (RowIdExpr) - -> Sort (cost=6.04..6.04 rows=2 width=8) - Output: t1.v1, t1.v2, (RowIdExpr) - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=4.50..6.02 rows=2 width=8) - Output: t1.v1, t1.v2, (RowIdExpr) - Hash Key: (RowIdExpr) - -> Hash Join (cost=4.50..5.98 rows=2 width=8) - Output: t1.v1, t1.v2, (RowIdExpr) - Hash Cond: (t2.v3 = t1.v1) - -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=4) - Output: t2.v3, t2.v4 - -> Hash (cost=4.47..4.47 rows=2 width=12) - Output: t1.v1, t1.v2, t2_1.v3, (RowIdExpr) - -> Hash Semi Join (cost=3.03..4.47 rows=2 width=12) - Output: t1.v1, t1.v2, t2_1.v3, RowIdExpr - Hash Cond: (t1.v1 = t2_1.v3) - -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=8) - Output: t1.v1, t1.v2 - -> Hash (cost=3.01..3.01 rows=1 width=4) - Output: t2_1.v3 - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=1.50..3.01 rows=1 width=4) - Output: t2_1.v3 - Hash Key: t2_1.v3 - -> Hash Join (cost=1.50..2.99 rows=1 width=4) - Output: t2_1.v3 - Hash Cond: (t2_1.v4 = t3.v6) - -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..1.47 rows=3 width=8) - Output: t2_1.v4, t2_1.v3 - Hash Key: t2_1.v4 - -> Seq Scan on public.t2 t2_1 (cost=0.00..1.42 rows=3 width=8) - Output: t2_1.v4, t2_1.v3 - Filter: (t2_1.v4 < 10) - -> Hash (cost=1.47..1.47 rows=3 width=4) - Output: t3.v6 - -> Redistribute Motion 3:3 (slice5; segments: 3) (cost=0.00..1.47 rows=3 width=4) - Output: t3.v6 - Hash Key: t3.v6 - -> Seq Scan on public.t3 (cost=0.00..1.42 rows=3 width=4) - Output: t3.v6 - Filter: (t3.v6 < 10) - Settings: enable_parallel = 'off', optimizer = 'off' + Hash Cond: (t2.v3 = t1.v1) + -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=4) + Output: t2.v3, t2.v4 + -> Hash (cost=4.47..4.47 rows=2 width=12) + Output: t1.v1, t1.v2, t2_1.v3 + -> Hash Semi Join (cost=3.03..4.47 rows=2 width=12) + Output: t1.v1, t1.v2, t2_1.v3 + Hash Cond: (t1.v1 = t2_1.v3) + -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=8) + Output: t1.v1, t1.v2 + -> Hash (cost=3.01..3.01 rows=1 width=4) + Output: t2_1.v3 + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.50..3.01 rows=1 width=4) + Output: t2_1.v3 + Hash Key: t2_1.v3 + -> Hash Join (cost=1.50..2.99 rows=1 width=4) + Output: t2_1.v3 + Hash Cond: (t2_1.v4 = t3.v6) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.47 rows=3 width=8) + Output: t2_1.v4, t2_1.v3 + Hash Key: t2_1.v4 + -> Seq Scan on public.t2 t2_1 (cost=0.00..1.42 rows=3 width=8) + Output: t2_1.v4, t2_1.v3 + Filter: (t2_1.v4 < 10) + -> Hash (cost=1.47..1.47 rows=3 width=4) + Output: t3.v6 + -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..1.47 rows=3 width=4) + Output: t3.v6 + Hash Key: t3.v6 + -> Seq Scan on public.t3 (cost=0.00..1.42 rows=3 width=4) + Output: t3.v6 + Filter: (t3.v6 < 10) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(49 rows) +(38 rows) select * from t1 where v1 in (select v3 from t2) and v1 in (select v3 from t2,t3 where v4=v6 and v4 < 10); v1 | v2 ----+---- + 1 | 1 + 5 | 5 + 6 | 6 + 9 | 9 2 | 2 3 | 3 4 | 4 - 9 | 9 - 8 | 8 - 6 | 6 7 | 7 - 1 | 1 - 5 | 5 + 8 | 8 (9 rows) select * from t1 where v1 in (select v3 from t2,t3 where v4=v6 and v4 < 10); @@ -1060,65 +1046,63 @@ select * from t1 where v1 in (select v3 from t2,t3 where v4=v6 and v4 < 10); 4 | 4 7 | 7 8 | 8 + 1 | 1 5 | 5 6 | 6 9 | 9 - 1 | 1 (9 rows) explain verbose select * from pt1 where v1 in (select v3 from pt2) and v1 in (select v3 from pt2,t3 where v4=v6); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=14.04..20.79 rows=100 width=8) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=12.25..20.79 rows=100 width=8) Output: pt1.v1, pt1.v2 - -> Hash Semi Join (cost=14.04..19.46 rows=33 width=8) + -> Hash Semi Join (cost=12.25..19.46 rows=33 width=8) Output: pt1.v1, pt1.v2 Hash Cond: (pt1.v1 = pt2.v3) - -> Hash Semi Join (cost=9.12..14.08 rows=33 width=12) + -> Hash Right Semi Join (cost=7.33..14.08 rows=33 width=12) Output: pt1.v1, pt1.v2, pt2_1.v3 - Hash Cond: (pt1.v1 = pt2_1.v3) - -> Append (cost=0.00..4.50 rows=33 width=8) - Partition Selectors: $0, $1 - -> Seq Scan on public.pt1_p1 pt1_1 (cost=0.00..1.06 rows=6 width=8) - Output: pt1_1.v1, pt1_1.v2 - -> Seq Scan on public.pt1_p2 pt1_2 (cost=0.00..1.07 rows=7 width=8) - Output: pt1_2.v1, pt1_2.v2 - -> Seq Scan on public.pt1_p3 pt1_3 (cost=0.00..1.07 rows=7 width=8) - Output: pt1_3.v1, pt1_3.v2 - -> Seq Scan on public.pt1_p4 pt1_4 (cost=0.00..1.14 rows=14 width=8) - Output: pt1_4.v1, pt1_4.v2 - -> Hash (cost=8.71..8.71 rows=33 width=4) + Hash Cond: (pt2_1.v3 = pt1.v1) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.42..8.71 rows=33 width=4) Output: pt2_1.v3 - -> Partition Selector (selector id: $0) (cost=2.42..8.71 rows=33 width=4) + Hash Key: pt2_1.v3 + -> Hash Join (cost=2.42..8.04 rows=33 width=4) Output: pt2_1.v3 - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.42..8.71 rows=33 width=4) - Output: pt2_1.v3 - Hash Key: pt2_1.v3 - -> Hash Join (cost=2.42..8.04 rows=33 width=4) - Output: pt2_1.v3 - Hash Cond: (pt2_1.v4 = t3.v6) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..5.17 rows=33 width=8) - Output: pt2_1.v4, pt2_1.v3 - Hash Key: pt2_1.v4 - -> Append (cost=0.00..4.50 rows=33 width=8) - -> Seq Scan on public.pt2_p1 pt2_6 (cost=0.00..1.06 rows=6 width=8) - Output: pt2_6.v4, pt2_6.v3 - -> Seq Scan on public.pt2_p2 pt2_7 (cost=0.00..1.07 rows=7 width=8) - Output: pt2_7.v4, pt2_7.v3 - -> Seq Scan on public.pt2_p3 pt2_8 (cost=0.00..1.07 rows=7 width=8) - Output: pt2_8.v4, pt2_8.v3 - -> Seq Scan on public.pt2_p4 pt2_9 (cost=0.00..1.14 rows=14 width=8) - Output: pt2_9.v4, pt2_9.v3 - -> Hash (cost=2.00..2.00 rows=33 width=4) + Hash Cond: (pt2_1.v4 = t3.v6) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..5.17 rows=33 width=8) + Output: pt2_1.v4, pt2_1.v3 + Hash Key: pt2_1.v4 + -> Append (cost=0.00..4.50 rows=33 width=8) + -> Seq Scan on public.pt2_p1 pt2_6 (cost=0.00..1.06 rows=6 width=8) + Output: pt2_6.v4, pt2_6.v3 + -> Seq Scan on public.pt2_p2 pt2_7 (cost=0.00..1.07 rows=7 width=8) + Output: pt2_7.v4, pt2_7.v3 + -> Seq Scan on public.pt2_p3 pt2_8 (cost=0.00..1.07 rows=7 width=8) + Output: pt2_8.v4, pt2_8.v3 + -> Seq Scan on public.pt2_p4 pt2_9 (cost=0.00..1.14 rows=14 width=8) + Output: pt2_9.v4, pt2_9.v3 + -> Hash (cost=2.00..2.00 rows=33 width=4) + Output: t3.v6 + -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..2.00 rows=33 width=4) + Output: t3.v6 + Hash Key: t3.v6 + -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) Output: t3.v6 - -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..2.00 rows=33 width=4) - Output: t3.v6 - Hash Key: t3.v6 - -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) - Output: t3.v6 + -> Hash (cost=4.50..4.50 rows=33 width=8) + Output: pt1.v1, pt1.v2 + -> Append (cost=0.00..4.50 rows=33 width=8) + Partition Selectors: $0 + -> Seq Scan on public.pt1_p1 pt1_1 (cost=0.00..1.06 rows=6 width=8) + Output: pt1_1.v1, pt1_1.v2 + -> Seq Scan on public.pt1_p2 pt1_2 (cost=0.00..1.07 rows=7 width=8) + Output: pt1_2.v1, pt1_2.v2 + -> Seq Scan on public.pt1_p3 pt1_3 (cost=0.00..1.07 rows=7 width=8) + Output: pt1_3.v1, pt1_3.v2 + -> Seq Scan on public.pt1_p4 pt1_4 (cost=0.00..1.14 rows=14 width=8) + Output: pt1_4.v1, pt1_4.v2 -> Hash (cost=4.50..4.50 rows=33 width=4) Output: pt2.v3 - -> Partition Selector (selector id: $1) (cost=0.00..4.50 rows=33 width=4) + -> Partition Selector (selector id: $0) (cost=0.00..4.50 rows=33 width=4) Output: pt2.v3 -> Append (cost=0.00..4.50 rows=33 width=4) -> Seq Scan on public.pt2_p1 pt2_2 (cost=0.00..1.06 rows=6 width=4) @@ -1129,63 +1113,61 @@ explain verbose select * from pt1 where v1 in (select v3 from pt2) and v1 in (se Output: pt2_4.v3 -> Seq Scan on public.pt2_p4 pt2_5 (cost=0.00..1.14 rows=14 width=4) Output: pt2_5.v3 - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(62 rows) +(60 rows) explain verbose select * from pt1 where v1 in (select v3 from pt2) and v1 in (select v3 from t3,pt2 where v4=v6); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=14.04..20.79 rows=100 width=8) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=12.25..20.79 rows=100 width=8) Output: pt1.v1, pt1.v2 - -> Hash Semi Join (cost=14.04..19.46 rows=33 width=8) + -> Hash Semi Join (cost=12.25..19.46 rows=33 width=8) Output: pt1.v1, pt1.v2 Hash Cond: (pt1.v1 = pt2.v3) - -> Hash Semi Join (cost=9.12..14.08 rows=33 width=12) + -> Hash Right Semi Join (cost=7.33..14.08 rows=33 width=12) Output: pt1.v1, pt1.v2, pt2_1.v3 - Hash Cond: (pt1.v1 = pt2_1.v3) - -> Append (cost=0.00..4.50 rows=33 width=8) - Partition Selectors: $0, $1 - -> Seq Scan on public.pt1_p1 pt1_1 (cost=0.00..1.06 rows=6 width=8) - Output: pt1_1.v1, pt1_1.v2 - -> Seq Scan on public.pt1_p2 pt1_2 (cost=0.00..1.07 rows=7 width=8) - Output: pt1_2.v1, pt1_2.v2 - -> Seq Scan on public.pt1_p3 pt1_3 (cost=0.00..1.07 rows=7 width=8) - Output: pt1_3.v1, pt1_3.v2 - -> Seq Scan on public.pt1_p4 pt1_4 (cost=0.00..1.14 rows=14 width=8) - Output: pt1_4.v1, pt1_4.v2 - -> Hash (cost=8.71..8.71 rows=33 width=4) + Hash Cond: (pt2_1.v3 = pt1.v1) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.42..8.71 rows=33 width=4) Output: pt2_1.v3 - -> Partition Selector (selector id: $0) (cost=2.42..8.71 rows=33 width=4) + Hash Key: pt2_1.v3 + -> Hash Join (cost=2.42..8.04 rows=33 width=4) Output: pt2_1.v3 - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.42..8.71 rows=33 width=4) - Output: pt2_1.v3 - Hash Key: pt2_1.v3 - -> Hash Join (cost=2.42..8.04 rows=33 width=4) - Output: pt2_1.v3 - Hash Cond: (pt2_1.v4 = t3.v6) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..5.17 rows=33 width=8) - Output: pt2_1.v4, pt2_1.v3 - Hash Key: pt2_1.v4 - -> Append (cost=0.00..4.50 rows=33 width=8) - -> Seq Scan on public.pt2_p1 pt2_6 (cost=0.00..1.06 rows=6 width=8) - Output: pt2_6.v4, pt2_6.v3 - -> Seq Scan on public.pt2_p2 pt2_7 (cost=0.00..1.07 rows=7 width=8) - Output: pt2_7.v4, pt2_7.v3 - -> Seq Scan on public.pt2_p3 pt2_8 (cost=0.00..1.07 rows=7 width=8) - Output: pt2_8.v4, pt2_8.v3 - -> Seq Scan on public.pt2_p4 pt2_9 (cost=0.00..1.14 rows=14 width=8) - Output: pt2_9.v4, pt2_9.v3 - -> Hash (cost=2.00..2.00 rows=33 width=4) + Hash Cond: (pt2_1.v4 = t3.v6) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..5.17 rows=33 width=8) + Output: pt2_1.v4, pt2_1.v3 + Hash Key: pt2_1.v4 + -> Append (cost=0.00..4.50 rows=33 width=8) + -> Seq Scan on public.pt2_p1 pt2_6 (cost=0.00..1.06 rows=6 width=8) + Output: pt2_6.v4, pt2_6.v3 + -> Seq Scan on public.pt2_p2 pt2_7 (cost=0.00..1.07 rows=7 width=8) + Output: pt2_7.v4, pt2_7.v3 + -> Seq Scan on public.pt2_p3 pt2_8 (cost=0.00..1.07 rows=7 width=8) + Output: pt2_8.v4, pt2_8.v3 + -> Seq Scan on public.pt2_p4 pt2_9 (cost=0.00..1.14 rows=14 width=8) + Output: pt2_9.v4, pt2_9.v3 + -> Hash (cost=2.00..2.00 rows=33 width=4) + Output: t3.v6 + -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..2.00 rows=33 width=4) + Output: t3.v6 + Hash Key: t3.v6 + -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) Output: t3.v6 - -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..2.00 rows=33 width=4) - Output: t3.v6 - Hash Key: t3.v6 - -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) - Output: t3.v6 + -> Hash (cost=4.50..4.50 rows=33 width=8) + Output: pt1.v1, pt1.v2 + -> Append (cost=0.00..4.50 rows=33 width=8) + Partition Selectors: $0 + -> Seq Scan on public.pt1_p1 pt1_1 (cost=0.00..1.06 rows=6 width=8) + Output: pt1_1.v1, pt1_1.v2 + -> Seq Scan on public.pt1_p2 pt1_2 (cost=0.00..1.07 rows=7 width=8) + Output: pt1_2.v1, pt1_2.v2 + -> Seq Scan on public.pt1_p3 pt1_3 (cost=0.00..1.07 rows=7 width=8) + Output: pt1_3.v1, pt1_3.v2 + -> Seq Scan on public.pt1_p4 pt1_4 (cost=0.00..1.14 rows=14 width=8) + Output: pt1_4.v1, pt1_4.v2 -> Hash (cost=4.50..4.50 rows=33 width=4) Output: pt2.v3 - -> Partition Selector (selector id: $1) (cost=0.00..4.50 rows=33 width=4) + -> Partition Selector (selector id: $0) (cost=0.00..4.50 rows=33 width=4) Output: pt2.v3 -> Append (cost=0.00..4.50 rows=33 width=4) -> Seq Scan on public.pt2_p1 pt2_2 (cost=0.00..1.06 rows=6 width=4) @@ -1196,180 +1178,163 @@ explain verbose select * from pt1 where v1 in (select v3 from pt2) and v1 in (se Output: pt2_4.v3 -> Seq Scan on public.pt2_p4 pt2_5 (cost=0.00..1.14 rows=14 width=4) Output: pt2_5.v3 - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(62 rows) +(60 rows) explain verbose select * from pt1 where v1 in (select v3 from pt2,t3 where v4=v6); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=9.12..15.42 rows=100 width=8) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=7.33..15.42 rows=100 width=8) Output: pt1.v1, pt1.v2 - -> Hash Semi Join (cost=9.12..14.08 rows=33 width=8) + -> Hash Right Semi Join (cost=7.33..14.08 rows=33 width=8) Output: pt1.v1, pt1.v2 - Hash Cond: (pt1.v1 = pt2.v3) - -> Append (cost=0.00..4.50 rows=33 width=8) - Partition Selectors: $0 - -> Seq Scan on public.pt1_p1 pt1_1 (cost=0.00..1.06 rows=6 width=8) - Output: pt1_1.v1, pt1_1.v2 - -> Seq Scan on public.pt1_p2 pt1_2 (cost=0.00..1.07 rows=7 width=8) - Output: pt1_2.v1, pt1_2.v2 - -> Seq Scan on public.pt1_p3 pt1_3 (cost=0.00..1.07 rows=7 width=8) - Output: pt1_3.v1, pt1_3.v2 - -> Seq Scan on public.pt1_p4 pt1_4 (cost=0.00..1.14 rows=14 width=8) - Output: pt1_4.v1, pt1_4.v2 - -> Hash (cost=8.71..8.71 rows=33 width=4) + Hash Cond: (pt2.v3 = pt1.v1) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.42..8.71 rows=33 width=4) Output: pt2.v3 - -> Partition Selector (selector id: $0) (cost=2.42..8.71 rows=33 width=4) + Hash Key: pt2.v3 + -> Hash Join (cost=2.42..8.04 rows=33 width=4) Output: pt2.v3 - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.42..8.71 rows=33 width=4) - Output: pt2.v3 - Hash Key: pt2.v3 - -> Hash Join (cost=2.42..8.04 rows=33 width=4) - Output: pt2.v3 - Hash Cond: (pt2.v4 = t3.v6) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..5.17 rows=33 width=8) - Output: pt2.v4, pt2.v3 - Hash Key: pt2.v4 - -> Append (cost=0.00..4.50 rows=33 width=8) - -> Seq Scan on public.pt2_p1 pt2_1 (cost=0.00..1.06 rows=6 width=8) - Output: pt2_1.v4, pt2_1.v3 - -> Seq Scan on public.pt2_p2 pt2_2 (cost=0.00..1.07 rows=7 width=8) - Output: pt2_2.v4, pt2_2.v3 - -> Seq Scan on public.pt2_p3 pt2_3 (cost=0.00..1.07 rows=7 width=8) - Output: pt2_3.v4, pt2_3.v3 - -> Seq Scan on public.pt2_p4 pt2_4 (cost=0.00..1.14 rows=14 width=8) - Output: pt2_4.v4, pt2_4.v3 - -> Hash (cost=2.00..2.00 rows=33 width=4) + Hash Cond: (pt2.v4 = t3.v6) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..5.17 rows=33 width=8) + Output: pt2.v4, pt2.v3 + Hash Key: pt2.v4 + -> Append (cost=0.00..4.50 rows=33 width=8) + -> Seq Scan on public.pt2_p1 pt2_1 (cost=0.00..1.06 rows=6 width=8) + Output: pt2_1.v4, pt2_1.v3 + -> Seq Scan on public.pt2_p2 pt2_2 (cost=0.00..1.07 rows=7 width=8) + Output: pt2_2.v4, pt2_2.v3 + -> Seq Scan on public.pt2_p3 pt2_3 (cost=0.00..1.07 rows=7 width=8) + Output: pt2_3.v4, pt2_3.v3 + -> Seq Scan on public.pt2_p4 pt2_4 (cost=0.00..1.14 rows=14 width=8) + Output: pt2_4.v4, pt2_4.v3 + -> Hash (cost=2.00..2.00 rows=33 width=4) + Output: t3.v6 + -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..2.00 rows=33 width=4) + Output: t3.v6 + Hash Key: t3.v6 + -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) Output: t3.v6 - -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..2.00 rows=33 width=4) - Output: t3.v6 - Hash Key: t3.v6 - -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) - Output: t3.v6 - Settings: enable_parallel = 'off', optimizer = 'off' + -> Hash (cost=4.50..4.50 rows=33 width=8) + Output: pt1.v1, pt1.v2 + -> Append (cost=0.00..4.50 rows=33 width=8) + -> Seq Scan on public.pt1_p1 pt1_1 (cost=0.00..1.06 rows=6 width=8) + Output: pt1_1.v1, pt1_1.v2 + -> Seq Scan on public.pt1_p2 pt1_2 (cost=0.00..1.07 rows=7 width=8) + Output: pt1_2.v1, pt1_2.v2 + -> Seq Scan on public.pt1_p3 pt1_3 (cost=0.00..1.07 rows=7 width=8) + Output: pt1_3.v1, pt1_3.v2 + -> Seq Scan on public.pt1_p4 pt1_4 (cost=0.00..1.14 rows=14 width=8) + Output: pt1_4.v1, pt1_4.v2 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(46 rows) +(43 rows) explain verbose select * from pt1 where v1 in (select v3 from pt2) and v1 in (select v3 from pt2,t3 where v4=v6 and v4 < 10); - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=15.46..15.56 rows=7 width=8) + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=10.76..15.49 rows=7 width=8) Output: pt1.v1, pt1.v2 - -> Result (cost=15.46..15.47 rows=2 width=8) + -> Hash Right Semi Join (cost=10.76..15.40 rows=2 width=8) Output: pt1.v1, pt1.v2 - -> Unique (cost=15.46..15.47 rows=2 width=8) - Output: pt1.v1, pt1.v2, (RowIdExpr) - Group Key: (RowIdExpr) - -> Sort (cost=15.46..15.47 rows=2 width=8) - Output: pt1.v1, pt1.v2, (RowIdExpr) - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=10.76..15.45 rows=2 width=8) - Output: pt1.v1, pt1.v2, (RowIdExpr) - Hash Key: (RowIdExpr) - -> Hash Join (cost=10.76..15.40 rows=2 width=8) - Output: pt1.v1, pt1.v2, (RowIdExpr) - Hash Cond: (pt2.v3 = pt1.v1) - -> Append (cost=0.00..4.50 rows=33 width=4) - Partition Selectors: $0 - -> Seq Scan on public.pt2_p1 pt2_2 (cost=0.00..1.06 rows=6 width=4) - Output: pt2_2.v3 - -> Seq Scan on public.pt2_p2 pt2_3 (cost=0.00..1.07 rows=7 width=4) - Output: pt2_3.v3 - -> Seq Scan on public.pt2_p3 pt2_4 (cost=0.00..1.07 rows=7 width=4) - Output: pt2_4.v3 - -> Seq Scan on public.pt2_p4 pt2_5 (cost=0.00..1.14 rows=14 width=4) - Output: pt2_5.v3 - -> Hash (cost=10.73..10.73 rows=2 width=12) - Output: pt1.v1, pt1.v2, pt2_1.v3, (RowIdExpr) - -> Partition Selector (selector id: $0) (cost=6.12..10.73 rows=2 width=12) - Output: pt1.v1, pt1.v2, pt2_1.v3, (RowIdExpr) - -> Hash Semi Join (cost=6.12..10.73 rows=2 width=12) - Output: pt1.v1, pt1.v2, pt2_1.v3, RowIdExpr - Hash Cond: (pt1.v1 = pt2_1.v3) - -> Append (cost=0.00..4.50 rows=33 width=8) - Partition Selectors: $1 - -> Seq Scan on public.pt1_p1 pt1_1 (cost=0.00..1.06 rows=6 width=8) - Output: pt1_1.v1, pt1_1.v2 - -> Seq Scan on public.pt1_p2 pt1_2 (cost=0.00..1.07 rows=7 width=8) - Output: pt1_2.v1, pt1_2.v2 - -> Seq Scan on public.pt1_p3 pt1_3 (cost=0.00..1.07 rows=7 width=8) - Output: pt1_3.v1, pt1_3.v2 - -> Seq Scan on public.pt1_p4 pt1_4 (cost=0.00..1.14 rows=14 width=8) - Output: pt1_4.v1, pt1_4.v2 - -> Hash (cost=6.11..6.11 rows=1 width=4) - Output: pt2_1.v3 - -> Partition Selector (selector id: $1) (cost=1.63..6.11 rows=1 width=4) - Output: pt2_1.v3 - -> Hash Join (cost=1.63..6.11 rows=1 width=4) - Output: pt2_1.v3 - Hash Cond: (pt2_1.v4 = t3.v6) - -> Append (cost=0.00..4.45 rows=6 width=8) - -> Seq Scan on public.pt2_p1 pt2_6 (cost=0.00..1.08 rows=3 width=8) - Output: pt2_6.v4, pt2_6.v3 - Filter: (pt2_6.v4 < 10) - -> Seq Scan on public.pt2_p2 pt2_7 (cost=0.00..1.08 rows=1 width=8) - Output: pt2_7.v4, pt2_7.v3 - Filter: (pt2_7.v4 < 10) - -> Seq Scan on public.pt2_p3 pt2_8 (cost=0.00..1.08 rows=1 width=8) - Output: pt2_8.v4, pt2_8.v3 - Filter: (pt2_8.v4 < 10) - -> Seq Scan on public.pt2_p4 pt2_9 (cost=0.00..1.17 rows=1 width=8) - Output: pt2_9.v4, pt2_9.v3 - Filter: (pt2_9.v4 < 10) - -> Hash (cost=1.52..1.52 rows=8 width=4) - Output: t3.v6 - -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..1.52 rows=8 width=4) - Output: t3.v6 - -> Seq Scan on public.t3 (cost=0.00..1.42 rows=3 width=4) - Output: t3.v6 - Filter: (t3.v6 < 10) - Settings: enable_parallel = 'off', optimizer = 'off' + Hash Cond: (pt2.v3 = pt1.v1) + -> Append (cost=0.00..4.50 rows=33 width=4) + -> Seq Scan on public.pt2_p1 pt2_2 (cost=0.00..1.06 rows=6 width=4) + Output: pt2_2.v3 + -> Seq Scan on public.pt2_p2 pt2_3 (cost=0.00..1.07 rows=7 width=4) + Output: pt2_3.v3 + -> Seq Scan on public.pt2_p3 pt2_4 (cost=0.00..1.07 rows=7 width=4) + Output: pt2_4.v3 + -> Seq Scan on public.pt2_p4 pt2_5 (cost=0.00..1.14 rows=14 width=4) + Output: pt2_5.v3 + -> Hash (cost=10.73..10.73 rows=2 width=12) + Output: pt1.v1, pt1.v2, pt2_1.v3 + -> Hash Semi Join (cost=6.12..10.73 rows=2 width=12) + Output: pt1.v1, pt1.v2, pt2_1.v3 + Hash Cond: (pt1.v1 = pt2_1.v3) + -> Append (cost=0.00..4.50 rows=33 width=8) + Partition Selectors: $0 + -> Seq Scan on public.pt1_p1 pt1_1 (cost=0.00..1.06 rows=6 width=8) + Output: pt1_1.v1, pt1_1.v2 + -> Seq Scan on public.pt1_p2 pt1_2 (cost=0.00..1.07 rows=7 width=8) + Output: pt1_2.v1, pt1_2.v2 + -> Seq Scan on public.pt1_p3 pt1_3 (cost=0.00..1.07 rows=7 width=8) + Output: pt1_3.v1, pt1_3.v2 + -> Seq Scan on public.pt1_p4 pt1_4 (cost=0.00..1.14 rows=14 width=8) + Output: pt1_4.v1, pt1_4.v2 + -> Hash (cost=6.11..6.11 rows=1 width=4) + Output: pt2_1.v3 + -> Partition Selector (selector id: $0) (cost=1.63..6.11 rows=1 width=4) + Output: pt2_1.v3 + -> Hash Join (cost=1.63..6.11 rows=1 width=4) + Output: pt2_1.v3 + Hash Cond: (pt2_1.v4 = t3.v6) + -> Append (cost=0.00..4.45 rows=6 width=8) + -> Seq Scan on public.pt2_p1 pt2_6 (cost=0.00..1.08 rows=3 width=8) + Output: pt2_6.v4, pt2_6.v3 + Filter: (pt2_6.v4 < 10) + -> Seq Scan on public.pt2_p2 pt2_7 (cost=0.00..1.08 rows=1 width=8) + Output: pt2_7.v4, pt2_7.v3 + Filter: (pt2_7.v4 < 10) + -> Seq Scan on public.pt2_p3 pt2_8 (cost=0.00..1.08 rows=1 width=8) + Output: pt2_8.v4, pt2_8.v3 + Filter: (pt2_8.v4 < 10) + -> Seq Scan on public.pt2_p4 pt2_9 (cost=0.00..1.17 rows=1 width=8) + Output: pt2_9.v4, pt2_9.v3 + Filter: (pt2_9.v4 < 10) + -> Hash (cost=1.52..1.52 rows=8 width=4) + Output: t3.v6 + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.52 rows=8 width=4) + Output: t3.v6 + -> Seq Scan on public.t3 (cost=0.00..1.42 rows=3 width=4) + Output: t3.v6 + Filter: (t3.v6 < 10) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(72 rows) +(58 rows) select * from pt1 where v1 in (select v3 from pt2) and v1 in (select v3 from pt2,t3 where v4=v6 and v4 < 10); v1 | v2 ----+---- + 5 | 5 + 6 | 6 + 9 | 9 + 1 | 1 2 | 2 3 | 3 4 | 4 - 9 | 9 - 8 | 8 - 6 | 6 7 | 7 - 1 | 1 - 5 | 5 + 8 | 8 (9 rows) select * from pt1 where v1 in (select v3 from pt2,t3 where v4=v6 and v4 < 10); v1 | v2 ----+---- - 5 | 5 - 6 | 6 - 9 | 9 2 | 2 3 | 3 4 | 4 7 | 7 8 | 8 1 | 1 + 5 | 5 + 6 | 6 + 9 | 9 (9 rows) explain verbose with cte1 as (select v3 from t2) select * from t1,t2 where t1.v1 in (select v3 from cte1) and t1.v1 in (select v3 from cte1,t3 where v4=v6); QUERY PLAN ----------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=10000000002.08..10000000192.76 rows=5000 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=10000000001.75..10000000192.43 rows=5000 width=16) Output: t1.v1, t1.v2, t2.v3, t2.v4 - -> Nested Loop (cost=10000000002.08..10000000126.10 rows=1667 width=16) + -> Nested Loop (cost=10000000001.75..10000000125.76 rows=1667 width=16) Output: t1.v1, t1.v2, t2.v3, t2.v4 Join Filter: (SubPlan 1) - -> Hash Semi Join (cost=2.08..3.87 rows=33 width=8) + -> Hash Semi Join (cost=1.75..3.54 rows=33 width=8) Output: t1.v1, t1.v2 Hash Cond: (t1.v1 = t2_1.v3) -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=8) Output: t1.v1, t1.v2 - -> Hash (cost=1.67..1.67 rows=33 width=4) + -> Hash (cost=1.33..1.33 rows=33 width=4) Output: t2_1.v3 -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=4) Output: t2_1.v3 @@ -1399,24 +1364,24 @@ explain verbose with cte1 as (select v3 from t2) select * from t1,t2 where t1.v1 Output: t3.v6 -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) Output: t3.v6 - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (42 rows) explain verbose with cte1 as (select v3 from t2) select * from t1,t2 where t1.v1 in (select v3 from cte1) and t1.v1 in (select v3 from t3,cte1 where v4=v6); QUERY PLAN ----------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=10000000002.08..10000000192.76 rows=5000 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=10000000001.75..10000000192.43 rows=5000 width=16) Output: t1.v1, t1.v2, t2.v3, t2.v4 - -> Nested Loop (cost=10000000002.08..10000000126.10 rows=1667 width=16) + -> Nested Loop (cost=10000000001.75..10000000125.76 rows=1667 width=16) Output: t1.v1, t1.v2, t2.v3, t2.v4 Join Filter: (SubPlan 1) - -> Hash Semi Join (cost=2.08..3.87 rows=33 width=8) + -> Hash Semi Join (cost=1.75..3.54 rows=33 width=8) Output: t1.v1, t1.v2 Hash Cond: (t1.v1 = t2_1.v3) -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=8) Output: t1.v1, t1.v2 - -> Hash (cost=1.67..1.67 rows=33 width=4) + -> Hash (cost=1.33..1.33 rows=33 width=4) Output: t2_1.v3 -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=4) Output: t2_1.v3 @@ -1446,7 +1411,7 @@ explain verbose with cte1 as (select v3 from t2) select * from t1,t2 where t1.v1 Output: t3.v6 -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) Output: t3.v6 - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (42 rows) @@ -1489,24 +1454,24 @@ explain verbose with cte1 as (select v3 from t2) select * from t1,t2 where t1.v1 Output: t3.v6 -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) Output: t3.v6 - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (38 rows) explain verbose with cte1 as (select v3 from t2) select * from t1,t2 where t1.v1 in (select v3 from cte1) and t1.v1 in (select v3 from cte1,t3 where v4=v6 and v4 < 10); QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=10000000002.08..10000000192.76 rows=5000 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=10000000001.75..10000000192.43 rows=5000 width=16) Output: t1.v1, t1.v2, t2.v3, t2.v4 - -> Nested Loop (cost=10000000002.08..10000000126.10 rows=1667 width=16) + -> Nested Loop (cost=10000000001.75..10000000125.76 rows=1667 width=16) Output: t1.v1, t1.v2, t2.v3, t2.v4 Join Filter: (SubPlan 1) - -> Hash Semi Join (cost=2.08..3.87 rows=33 width=8) + -> Hash Semi Join (cost=1.75..3.54 rows=33 width=8) Output: t1.v1, t1.v2 Hash Cond: (t1.v1 = t2_1.v3) -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=8) Output: t1.v1, t1.v2 - -> Hash (cost=1.67..1.67 rows=33 width=4) + -> Hash (cost=1.33..1.33 rows=33 width=4) Output: t2_1.v3 -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=4) Output: t2_1.v3 @@ -1539,7 +1504,7 @@ explain verbose with cte1 as (select v3 from t2) select * from t1,t2 where t1.v1 Output: t3.v6 -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) Output: t3.v6 - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (45 rows) @@ -1560,17 +1525,17 @@ set optimizer_cte_inlining_bound to 2; explain verbose with cte1 as (select v3 from t2) select * from t1,t2 where t1.v1 in (select v3 from cte1) and t1.v1 in (select v3 from cte1,t3 where v4=v6 and v4 < 10); QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=10000000002.08..10000000192.76 rows=5000 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=10000000001.75..10000000192.43 rows=5000 width=16) Output: t1.v1, t1.v2, t2.v3, t2.v4 - -> Nested Loop (cost=10000000002.08..10000000126.10 rows=1667 width=16) + -> Nested Loop (cost=10000000001.75..10000000125.76 rows=1667 width=16) Output: t1.v1, t1.v2, t2.v3, t2.v4 Join Filter: (SubPlan 1) - -> Hash Semi Join (cost=2.08..3.87 rows=33 width=8) + -> Hash Semi Join (cost=1.75..3.54 rows=33 width=8) Output: t1.v1, t1.v2 Hash Cond: (t1.v1 = t2_1.v3) -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=8) Output: t1.v1, t1.v2 - -> Hash (cost=1.67..1.67 rows=33 width=4) + -> Hash (cost=1.33..1.33 rows=33 width=4) Output: t2_1.v3 -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=4) Output: t2_1.v3 @@ -1603,7 +1568,7 @@ explain verbose with cte1 as (select v3 from t2) select * from t1,t2 where t1.v1 Output: t3.v6 -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) Output: t3.v6 - Settings: enable_parallel = 'off', optimizer = 'off', optimizer_cte_inlining_bound = '2' + Settings: optimizer = 'off', optimizer_cte_inlining_bound = '2' Optimizer: Postgres query optimizer (45 rows) @@ -1617,59 +1582,59 @@ reset optimizer_cte_inlining; reset optimizer_cte_inlining_bound; -- dedup the subquery with semi join(still be a scalar in the pre-process) explain verbose select * from t1 where v1 in (select v3 from t2) and v1 in (select v3 from t2 where exists (SELECT 1 FROM t3 WHERE v5 = v3)); - QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=5.71..9.29 rows=100 width=8) + QUERY PLAN +---------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=5.25..9.29 rows=100 width=8) Output: t1.v1, t1.v2 - -> Hash Semi Join (cost=5.71..7.96 rows=33 width=8) + -> Hash Semi Join (cost=5.25..7.96 rows=33 width=8) Output: t1.v1, t1.v2 Hash Cond: (t1.v1 = t2.v3) - -> Hash Semi Join (cost=3.96..5.75 rows=33 width=16) + -> Hash Right Semi Join (cost=3.50..5.75 rows=33 width=16) Output: t1.v1, t1.v2, t2_1.v3, t3.v5 - Hash Cond: (t1.v1 = t3.v5) - -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=8) - Output: t1.v1, t1.v2 - -> Hash (cost=3.54..3.54 rows=33 width=8) + Hash Cond: (t3.v5 = t1.v1) + -> Hash Semi Join (cost=1.75..3.54 rows=33 width=8) Output: t2_1.v3, t3.v5 - -> Hash Semi Join (cost=1.75..3.54 rows=33 width=8) - Output: t2_1.v3, t3.v5 - Hash Cond: (t2_1.v3 = t3.v5) - -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=4) - Output: t2_1.v3, t2_1.v4 - -> Hash (cost=1.33..1.33 rows=33 width=4) + Hash Cond: (t2_1.v3 = t3.v5) + -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=4) + Output: t2_1.v3, t2_1.v4 + -> Hash (cost=1.33..1.33 rows=33 width=4) + Output: t3.v5 + -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) Output: t3.v5 - -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) - Output: t3.v5 + -> Hash (cost=1.33..1.33 rows=33 width=8) + Output: t1.v1, t1.v2 + -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=8) + Output: t1.v1, t1.v2 -> Hash (cost=1.33..1.33 rows=33 width=4) Output: t2.v3 -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=4) Output: t2.v3 - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (27 rows) explain verbose select * from t1 where v1 in (select v3 from t2 where exists (SELECT 1 FROM t3 WHERE v5 = v3)); - QUERY PLAN ----------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=3.96..7.08 rows=100 width=8) + QUERY PLAN +---------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=3.50..7.08 rows=100 width=8) Output: t1.v1, t1.v2 - -> Hash Semi Join (cost=3.96..5.75 rows=33 width=8) + -> Hash Right Semi Join (cost=3.50..5.75 rows=33 width=8) Output: t1.v1, t1.v2 - Hash Cond: (t1.v1 = t3.v5) - -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=8) - Output: t1.v1, t1.v2 - -> Hash (cost=3.54..3.54 rows=33 width=8) + Hash Cond: (t3.v5 = t1.v1) + -> Hash Semi Join (cost=1.75..3.54 rows=33 width=8) Output: t2.v3, t3.v5 - -> Hash Semi Join (cost=1.75..3.54 rows=33 width=8) - Output: t2.v3, t3.v5 - Hash Cond: (t2.v3 = t3.v5) - -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=4) - Output: t2.v3, t2.v4 - -> Hash (cost=1.33..1.33 rows=33 width=4) + Hash Cond: (t2.v3 = t3.v5) + -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=4) + Output: t2.v3, t2.v4 + -> Hash (cost=1.33..1.33 rows=33 width=4) + Output: t3.v5 + -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) Output: t3.v5 - -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) - Output: t3.v5 - Settings: enable_parallel = 'off', optimizer = 'off' + -> Hash (cost=1.33..1.33 rows=33 width=8) + Output: t1.v1, t1.v2 + -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=8) + Output: t1.v1, t1.v2 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (20 rows) @@ -1687,94 +1652,94 @@ select count(*) from t1 where v1 in (select v3 from t2 where exists (SELECT 1 FR -- inner join different key explain verbose select v1 from t1 where v1 in (select v3 from t2) and v1 in (select v5 from t2,t3 where v5 = v3); - QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=5.71..9.29 rows=100 width=4) + QUERY PLAN +---------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=5.25..9.29 rows=100 width=4) Output: t1.v1 - -> Hash Semi Join (cost=5.71..7.96 rows=33 width=4) + -> Hash Semi Join (cost=5.25..7.96 rows=33 width=4) Output: t1.v1 Hash Cond: (t1.v1 = t2.v3) - -> Hash Semi Join (cost=3.96..5.75 rows=33 width=12) + -> Hash Right Semi Join (cost=3.50..5.75 rows=33 width=12) Output: t1.v1, t2_1.v3, t3.v5 - Hash Cond: (t1.v1 = t3.v5) - -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=4) - Output: t1.v1, t1.v2 - -> Hash (cost=3.54..3.54 rows=33 width=8) + Hash Cond: (t3.v5 = t1.v1) + -> Hash Join (cost=1.75..3.54 rows=33 width=8) Output: t2_1.v3, t3.v5 - -> Hash Join (cost=1.75..3.54 rows=33 width=8) - Output: t2_1.v3, t3.v5 - Hash Cond: (t2_1.v3 = t3.v5) - -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=4) - Output: t2_1.v3, t2_1.v4 - -> Hash (cost=1.33..1.33 rows=33 width=4) + Hash Cond: (t2_1.v3 = t3.v5) + -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=4) + Output: t2_1.v3, t2_1.v4 + -> Hash (cost=1.33..1.33 rows=33 width=4) + Output: t3.v5 + -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) Output: t3.v5 - -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) - Output: t3.v5 + -> Hash (cost=1.33..1.33 rows=33 width=4) + Output: t1.v1 + -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=4) + Output: t1.v1 -> Hash (cost=1.33..1.33 rows=33 width=4) Output: t2.v3 -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=4) Output: t2.v3 - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (27 rows) explain verbose select v1 from t1 where v1 in (select v5 from t2,t3 where v5 = v3); - QUERY PLAN ----------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=3.96..7.08 rows=100 width=4) + QUERY PLAN +---------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=3.50..7.08 rows=100 width=4) Output: t1.v1 - -> Hash Semi Join (cost=3.96..5.75 rows=33 width=4) + -> Hash Right Semi Join (cost=3.50..5.75 rows=33 width=4) Output: t1.v1 - Hash Cond: (t1.v1 = t3.v5) - -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=4) - Output: t1.v1, t1.v2 - -> Hash (cost=3.54..3.54 rows=33 width=8) + Hash Cond: (t3.v5 = t1.v1) + -> Hash Join (cost=1.75..3.54 rows=33 width=8) Output: t2.v3, t3.v5 - -> Hash Join (cost=1.75..3.54 rows=33 width=8) - Output: t2.v3, t3.v5 - Hash Cond: (t2.v3 = t3.v5) - -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=4) - Output: t2.v3, t2.v4 - -> Hash (cost=1.33..1.33 rows=33 width=4) + Hash Cond: (t2.v3 = t3.v5) + -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=4) + Output: t2.v3, t2.v4 + -> Hash (cost=1.33..1.33 rows=33 width=4) + Output: t3.v5 + -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) Output: t3.v5 - -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=4) - Output: t3.v5 - Settings: enable_parallel = 'off', optimizer = 'off' + -> Hash (cost=1.33..1.33 rows=33 width=4) + Output: t1.v1 + -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=4) + Output: t1.v1 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (20 rows) explain verbose select v1 from t1 where v1 in (select v3 from t2) and v1 in (select v6 from t2,t3 where v5 = v3); -- no dedup, because v6 is not the join key - QUERY PLAN ------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=6.38..9.96 rows=100 width=4) + QUERY PLAN +----------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=5.25..9.96 rows=100 width=4) Output: t1.v1 - -> Hash Semi Join (cost=6.38..8.62 rows=33 width=4) + -> Hash Semi Join (cost=5.25..8.62 rows=33 width=4) Output: t1.v1 Hash Cond: (t1.v1 = t2.v3) - -> Hash Semi Join (cost=4.63..6.42 rows=33 width=8) + -> Hash Right Semi Join (cost=3.50..6.42 rows=33 width=8) Output: t1.v1, t3.v6 - Hash Cond: (t1.v1 = t3.v6) - -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=4) - Output: t1.v1, t1.v2 - -> Hash (cost=4.21..4.21 rows=33 width=4) + Hash Cond: (t3.v6 = t1.v1) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.75..4.21 rows=33 width=4) Output: t3.v6 - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.75..4.21 rows=33 width=4) + Hash Key: t3.v6 + -> Hash Join (cost=1.75..3.54 rows=33 width=4) Output: t3.v6 - Hash Key: t3.v6 - -> Hash Join (cost=1.75..3.54 rows=33 width=4) - Output: t3.v6 - Hash Cond: (t2_1.v3 = t3.v5) - -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=4) - Output: t2_1.v3, t2_1.v4 - -> Hash (cost=1.33..1.33 rows=33 width=8) + Hash Cond: (t2_1.v3 = t3.v5) + -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=4) + Output: t2_1.v3, t2_1.v4 + -> Hash (cost=1.33..1.33 rows=33 width=8) + Output: t3.v5, t3.v6 + -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=8) Output: t3.v5, t3.v6 - -> Seq Scan on public.t3 (cost=0.00..1.33 rows=33 width=8) - Output: t3.v5, t3.v6 + -> Hash (cost=1.33..1.33 rows=33 width=4) + Output: t1.v1 + -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=4) + Output: t1.v1 -> Hash (cost=1.33..1.33 rows=33 width=4) Output: t2.v3 -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=4) Output: t2.v3 - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (30 rows) @@ -1792,83 +1757,63 @@ select count(v1) from t1 where v1 in (select v5 from t2,t3 where v5 = v3); -- can't dedup explain verbose select * from t1 where v1 in (select v3 from t2) and v1 in (select v4 from t2 where v3 < 10); -- different outpt - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=4.54..4.67 rows=8 width=8) + QUERY PLAN +---------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=2.99..4.58 rows=8 width=8) Output: t1.v1, t1.v2 - -> Result (cost=4.54..4.56 rows=3 width=8) + -> Hash Right Semi Join (cost=2.99..4.47 rows=3 width=8) Output: t1.v1, t1.v2 - -> Unique (cost=4.54..4.56 rows=3 width=8) - Output: t1.v1, t1.v2, (RowIdExpr) - Group Key: (RowIdExpr) - -> Sort (cost=4.54..4.55 rows=3 width=8) - Output: t1.v1, t1.v2, (RowIdExpr) - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.99..4.53 rows=3 width=8) - Output: t1.v1, t1.v2, (RowIdExpr) - Hash Key: (RowIdExpr) - -> Hash Join (cost=2.99..4.47 rows=3 width=8) - Output: t1.v1, t1.v2, (RowIdExpr) - Hash Cond: (t2.v3 = t1.v1) - -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=4) - Output: t2.v3, t2.v4 - -> Hash (cost=2.95..2.95 rows=3 width=12) - Output: t1.v1, t1.v2, t2_1.v4, (RowIdExpr) - -> Hash Semi Join (cost=1.50..2.95 rows=3 width=12) - Output: t1.v1, t1.v2, t2_1.v4, RowIdExpr - Hash Cond: (t1.v1 = t2_1.v4) - -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=8) - Output: t1.v1, t1.v2 - -> Hash (cost=1.47..1.47 rows=3 width=4) - Output: t2_1.v4 - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.47 rows=3 width=4) - Output: t2_1.v4 - Hash Key: t2_1.v4 - -> Seq Scan on public.t2 t2_1 (cost=0.00..1.42 rows=3 width=4) - Output: t2_1.v4 - Filter: (t2_1.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'off' + Hash Cond: (t2.v3 = t1.v1) + -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=4) + Output: t2.v3, t2.v4 + -> Hash (cost=2.95..2.95 rows=3 width=12) + Output: t1.v1, t1.v2, t2_1.v4 + -> Hash Semi Join (cost=1.50..2.95 rows=3 width=12) + Output: t1.v1, t1.v2, t2_1.v4 + Hash Cond: (t1.v1 = t2_1.v4) + -> Seq Scan on public.t1 (cost=0.00..1.33 rows=33 width=8) + Output: t1.v1, t1.v2 + -> Hash (cost=1.47..1.47 rows=3 width=4) + Output: t2_1.v4 + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.47 rows=3 width=4) + Output: t2_1.v4 + Hash Key: t2_1.v4 + -> Seq Scan on public.t2 t2_1 (cost=0.00..1.42 rows=3 width=4) + Output: t2_1.v4 + Filter: (t2_1.v3 < 10) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(35 rows) +(24 rows) explain verbose select * from t1 where v1 in (select v3 from t2) and v2 in (select v3 from t2 where v3 < 10); -- different scalar ident - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=4.43..4.49 rows=3 width=8) + QUERY PLAN +---------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=2.90..4.46 rows=3 width=8) Output: t1.v1, t1.v2 - -> HashAggregate (cost=4.43..4.44 rows=1 width=8) + -> Hash Semi Join (cost=2.90..4.42 rows=1 width=8) Output: t1.v1, t1.v2 - Group Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.98..4.43 rows=1 width=8) - Output: t1.v1, t1.v2, (RowIdExpr) - Hash Key: (RowIdExpr) - -> Hash Join (cost=2.98..4.41 rows=1 width=8) - Output: t1.v1, t1.v2, (RowIdExpr) + Hash Cond: (t1.v2 = t2_1.v3) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.45..2.95 rows=3 width=8) + Output: t1.v1, t1.v2 + Hash Key: t1.v2 + -> Hash Right Semi Join (cost=1.45..2.90 rows=3 width=8) + Output: t1.v1, t1.v2 Hash Cond: (t2.v3 = t1.v1) -> Seq Scan on public.t2 (cost=0.00..1.33 rows=33 width=4) Output: t2.v3, t2.v4 - -> Hash (cost=2.96..2.96 rows=1 width=8) - Output: t1.v1, t1.v2, (RowIdExpr) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=1.45..2.96 rows=1 width=8) - Output: t1.v1, t1.v2, (RowIdExpr) - Hash Key: t1.v1 - -> Hash Semi Join (cost=1.45..2.94 rows=1 width=8) - Output: t1.v1, t1.v2, RowIdExpr - Hash Cond: (t1.v2 = t2_1.v3) - -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..1.47 rows=3 width=8) - Output: t1.v1, t1.v2 - Hash Key: t1.v2 - -> Seq Scan on public.t1 (cost=0.00..1.42 rows=3 width=8) - Output: t1.v1, t1.v2 - Filter: (t1.v2 < 10) - -> Hash (cost=1.42..1.42 rows=3 width=4) - Output: t2_1.v3 - -> Seq Scan on public.t2 t2_1 (cost=0.00..1.42 rows=3 width=4) - Output: t2_1.v3 - Filter: (t2_1.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'off' + -> Hash (cost=1.42..1.42 rows=3 width=8) + Output: t1.v1, t1.v2 + -> Seq Scan on public.t1 (cost=0.00..1.42 rows=3 width=8) + Output: t1.v1, t1.v2 + Filter: (t1.v2 < 10) + -> Hash (cost=1.42..1.42 rows=3 width=4) + Output: t2_1.v3 + -> Seq Scan on public.t2 t2_1 (cost=0.00..1.42 rows=3 width=4) + Output: t2_1.v3 + Filter: (t2_1.v3 < 10) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(34 rows) +(25 rows) explain verbose select * from t1 where v1 in (select v3 from t2) and v2 in (select v3 from t2 group by v3); -- group by QUERY PLAN @@ -1894,7 +1839,7 @@ explain verbose select * from t1 where v1 in (select v3 from t2) and v2 in (sele Output: t2_1.v3 -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=4) Output: t2_1.v3 - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (23 rows) @@ -1922,7 +1867,7 @@ explain verbose select * from t1 where v1 in (select v3 from t2) and v2 in (sele Output: t2_1.v3 -> Seq Scan on public.t2 t2_1 (cost=0.00..1.33 rows=33 width=4) Output: t2_1.v3 - Settings: enable_parallel = 'off', optimizer = 'off' + Settings: optimizer = 'off' Optimizer: Postgres query optimizer (23 rows) diff --git a/src/test/regress/expected/dedupset_optimizer.out b/src/test/regress/expected/dedupset_optimizer.out index f9369e5a87f..8ba56d5dc08 100644 --- a/src/test/regress/expected/dedupset_optimizer.out +++ b/src/test/regress/expected/dedupset_optimizer.out @@ -1,14 +1,25 @@ SET optimizer_trace_fallback = on; -- start_ignore drop table if exists t1; +NOTICE: table "t1" does not exist, skipping drop table if exists t2; +NOTICE: table "t2" does not exist, skipping drop table if exists t3; +NOTICE: table "t3" does not exist, skipping drop table if exists pt1; +NOTICE: table "pt1" does not exist, skipping drop table if exists pt2; +NOTICE: table "pt2" does not exist, skipping -- end_ignore create table t1(v1 int, v2 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'v1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create table t2(v3 int, v4 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'v3' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create table t3(v5 int, v6 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'v5' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into t1 values(generate_series(1, 100), generate_series(1, 100)); insert into t2 values(generate_series(1, 100), generate_series(1, 100)); insert into t3 values(generate_series(1, 100), generate_series(1, 100)); @@ -16,18 +27,30 @@ CREATE TABLE pt1 ( v1 INT, v2 INT ) PARTITION BY RANGE (v1); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'v1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TABLE pt1_p1 PARTITION OF pt1 FOR VALUES FROM (0) TO (20); +NOTICE: table has parent, setting distribution columns to match parent table CREATE TABLE pt1_p2 PARTITION OF pt1 FOR VALUES FROM (20) TO (40); +NOTICE: table has parent, setting distribution columns to match parent table CREATE TABLE pt1_p3 PARTITION OF pt1 FOR VALUES FROM (40) TO (60); +NOTICE: table has parent, setting distribution columns to match parent table CREATE TABLE pt1_p4 PARTITION OF pt1 FOR VALUES FROM (60) TO (400); +NOTICE: table has parent, setting distribution columns to match parent table CREATE TABLE pt2 ( v3 INT, v4 INT ) PARTITION BY RANGE (v3); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'v3' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TABLE pt2_p1 PARTITION OF pt2 FOR VALUES FROM (0) TO (20); +NOTICE: table has parent, setting distribution columns to match parent table CREATE TABLE pt2_p2 PARTITION OF pt2 FOR VALUES FROM (20) TO (40); +NOTICE: table has parent, setting distribution columns to match parent table CREATE TABLE pt2_p3 PARTITION OF pt2 FOR VALUES FROM (40) TO (60); +NOTICE: table has parent, setting distribution columns to match parent table CREATE TABLE pt2_p4 PARTITION OF pt2 FOR VALUES FROM (60) TO (400); +NOTICE: table has parent, setting distribution columns to match parent table insert into pt1 values(generate_series(1, 100), generate_series(1, 100)); insert into pt2 values(generate_series(1, 100), generate_series(1, 100)); analyze t1; @@ -51,7 +74,7 @@ explain verbose select * from t1 where v1 in (select v3 from t2) and v1 in (sele -> Seq Scan on public.t2 (cost=0.00..431.00 rows=4 width=4) Output: t2.v3 Filter: (t2.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (14 rows) @@ -70,7 +93,7 @@ explain verbose select * from t1 where v1 in (select v3 from t2 where v3 < 10) a -> Seq Scan on public.t2 (cost=0.00..431.00 rows=4 width=4) Output: t2.v3 Filter: (t2.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (14 rows) @@ -89,7 +112,7 @@ explain verbose select * from t1 where v1 in (select v3 from t2 where v3 < 10); -> Seq Scan on public.t2 (cost=0.00..431.00 rows=4 width=4) Output: t2.v3 Filter: (t2.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (14 rows) @@ -101,24 +124,24 @@ select * from t1 where v1 in (select v3 from t2) and v1 in (select v3 from t2 wh 4 | 4 7 | 7 8 | 8 - 1 | 1 5 | 5 6 | 6 9 | 9 + 1 | 1 (9 rows) select * from t1 where v1 in (select v3 from t2 where v3 < 10); v1 | v2 ----+---- - 1 | 1 - 5 | 5 - 6 | 6 - 9 | 9 2 | 2 3 | 3 4 | 4 7 | 7 8 | 8 + 5 | 5 + 6 | 6 + 9 | 9 + 1 | 1 (9 rows) explain verbose select * from pt1 where v1 in (select v3 from pt2) and v1 in (select v3 from pt2 where v3 < 10); @@ -140,7 +163,7 @@ explain verbose select * from pt1 where v1 in (select v3 from pt2) and v1 in (se Output: pt2.v3 Number of partitions to scan: 1 (out of 4) Filter: (pt2.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (18 rows) @@ -163,22 +186,22 @@ explain verbose select * from pt1 where v1 in (select v3 from pt2 where v3 < 10) Output: pt2.v3 Number of partitions to scan: 1 (out of 4) Filter: (pt2.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (18 rows) select * from pt1 where v1 in (select v3 from pt2) and v1 in (select v3 from pt2 where v3 < 10); v1 | v2 ----+---- - 1 | 1 - 5 | 5 - 6 | 6 - 9 | 9 2 | 2 3 | 3 4 | 4 7 | 7 8 | 8 + 1 | 1 + 5 | 5 + 6 | 6 + 9 | 9 (9 rows) select * from pt1 where v1 in (select v3 from pt2 where v3 < 10); @@ -189,10 +212,10 @@ select * from pt1 where v1 in (select v3 from pt2 where v3 < 10); 4 | 4 7 | 7 8 | 8 + 1 | 1 5 | 5 6 | 6 9 | 9 - 1 | 1 (9 rows) explain verbose with cte1 as (select v3 from t2) select count(*) from t1,t2 where t1.v1 in (select v3 from cte1) and t1.v1 in (select v3 from cte1 where v3 < 10); @@ -231,7 +254,7 @@ explain verbose with cte1 as (select v3 from t2) select count(*) from t1,t2 wher Filter: (share0_ref2.v3 < 10) -> Shared Scan (share slice:id 3:0) (cost=0.00..431.00 rows=34 width=4) Output: share0_ref2.v3 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (35 rows) @@ -259,7 +282,7 @@ explain verbose with cte1 as (select v3 from t2) select count(*) from t1,t2 wher -> Seq Scan on public.t2 t2_1 (cost=0.00..431.00 rows=4 width=4) Output: t2_1.v3 Filter: (t2_1.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (23 rows) @@ -301,7 +324,7 @@ explain verbose with cte1 as (select v3 from t2) select count(*) from t1,t2 wher -> Seq Scan on public.t2 t2_1 (cost=0.00..431.00 rows=4 width=4) Output: t2_1.v3 Filter: (t2_1.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'on', optimizer_cte_inlining_bound = '2' + Settings: optimizer = 'on', optimizer_cte_inlining_bound = '2' Optimizer: GPORCA (23 rows) @@ -332,7 +355,7 @@ explain verbose select sum(v1) from t1 where v1 in (select v3 from t2) and v1 in -> Seq Scan on public.t2 (cost=0.00..431.00 rows=4 width=4) Output: t2.v3 Filter: (t2.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (18 rows) @@ -355,7 +378,7 @@ explain verbose select sum(v1) from t1 where v1 in (select v3 from t2 where v3 < -> Seq Scan on public.t2 (cost=0.00..431.00 rows=4 width=4) Output: t2.v3 Filter: (t2.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (18 rows) @@ -390,7 +413,7 @@ explain verbose select * from t1 where v1 in (select v3 from t2) and v1 in (sele -> Seq Scan on public.t2 (cost=0.00..431.00 rows=4 width=4) Output: t2.v3 Filter: (t2.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (18 rows) @@ -413,7 +436,7 @@ explain verbose select * from t1 where v1 in (select v3 from t2 where v3 < 10) o -> Seq Scan on public.t2 (cost=0.00..431.00 rows=4 width=4) Output: t2.v3 Filter: (t2.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (18 rows) @@ -469,7 +492,7 @@ explain verbose select sum(v1) from t1 where v1 in (select v3 from t2) and v1 in -> Seq Scan on public.t2 (cost=0.00..431.00 rows=4 width=4) Output: t2.v3 Filter: (t2.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (23 rows) @@ -497,7 +520,7 @@ explain verbose select sum(v1) from t1 where v1 in (select v3 from t2 where v3 < -> Seq Scan on public.t2 (cost=0.00..431.00 rows=4 width=4) Output: t2.v3 Filter: (t2.v3 < 10) - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (23 rows) @@ -523,10 +546,10 @@ select sum(v1) from t1 where v1 in (select v3 from t2 where v3 < 10) group by v2 4 7 8 - 1 5 6 9 + 1 (9 rows) -- dedup the same subqueryany @@ -544,7 +567,7 @@ explain verbose select * from t1 where v1 in (select v3 from t2) and v1 in (sele Output: t2.v3 -> Seq Scan on public.t2 (cost=0.00..431.00 rows=34 width=4) Output: t2.v3 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (13 rows) @@ -562,7 +585,7 @@ explain verbose select * from t1 where v1 in (select v3 from t2); Output: t2.v3 -> Seq Scan on public.t2 (cost=0.00..431.00 rows=34 width=4) Output: t2.v3 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (13 rows) @@ -596,7 +619,7 @@ explain verbose select * from pt1 where v1 in (select v3 from pt2) and v1 in (se -> Dynamic Seq Scan on public.pt2 (cost=0.00..431.00 rows=34 width=4) Output: pt2.v3 Number of partitions to scan: 4 (out of 4) - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (17 rows) @@ -618,7 +641,7 @@ explain verbose select * from pt1 where v1 in (select v3 from pt2); -> Dynamic Seq Scan on public.pt2 (cost=0.00..431.00 rows=34 width=4) Output: pt2.v3 Number of partitions to scan: 4 (out of 4) - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (17 rows) @@ -667,7 +690,7 @@ explain verbose with cte1 as (select v3 from t2) select count(*) from t1,t2 wher Output: share0_ref2.v3 -> Shared Scan (share slice:id 3:0) (cost=0.00..431.00 rows=34 width=4) Output: share0_ref2.v3 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (32 rows) @@ -694,7 +717,7 @@ explain verbose with cte1 as (select v3 from t2) select count(*) from t1,t2 wher Output: t2_1.v3 -> Seq Scan on public.t2 t2_1 (cost=0.00..431.00 rows=34 width=4) Output: t2_1.v3 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (22 rows) @@ -735,7 +758,7 @@ explain verbose with cte1 as (select v3 from t2) select count(*) from t1,t2 wher Output: t2_1.v3 -> Seq Scan on public.t2 t2_1 (cost=0.00..431.00 rows=34 width=4) Output: t2_1.v3 - Settings: enable_parallel = 'off', optimizer = 'on', optimizer_cte_inlining_bound = '2' + Settings: optimizer = 'on', optimizer_cte_inlining_bound = '2' Optimizer: GPORCA (22 rows) @@ -778,7 +801,7 @@ explain verbose select * from t1 where v1 in (select v3 from t2) and v1 in (sele Hash Key: t3.v6 -> Seq Scan on public.t3 (cost=0.00..431.00 rows=34 width=4) Output: t3.v6 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (29 rows) @@ -812,7 +835,7 @@ explain verbose select * from t1 where v1 in (select v3 from t2) and v1 in (sele Hash Key: t3.v6 -> Seq Scan on public.t3 (cost=0.00..431.00 rows=34 width=4) Output: t3.v6 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (29 rows) @@ -846,7 +869,7 @@ explain verbose select * from t1 where v1 in (select v3 from t2,t3 where v4=v6); Hash Key: t3.v6 -> Seq Scan on public.t3 (cost=0.00..431.00 rows=34 width=4) Output: t3.v6 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (29 rows) @@ -882,7 +905,7 @@ explain verbose select * from t1 where v1 in (select v3 from t2) and v1 in (sele -> Seq Scan on public.t3 (cost=0.00..431.00 rows=4 width=4) Output: t3.v6 Filter: (t3.v6 < 10) - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (31 rows) @@ -892,12 +915,12 @@ select * from t1 where v1 in (select v3 from t2) and v1 in (select v3 from t2,t3 2 | 2 3 | 3 4 | 4 - 9 | 9 + 7 | 7 8 | 8 + 5 | 5 6 | 6 - 7 | 7 + 9 | 9 1 | 1 - 5 | 5 (9 rows) select * from t1 where v1 in (select v3 from t2,t3 where v4=v6 and v4 < 10); @@ -948,7 +971,7 @@ explain verbose select * from pt1 where v1 in (select v3 from pt2) and v1 in (se Hash Key: t3.v6 -> Seq Scan on public.t3 (cost=0.00..431.00 rows=34 width=4) Output: t3.v6 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (33 rows) @@ -986,7 +1009,7 @@ explain verbose select * from pt1 where v1 in (select v3 from pt2) and v1 in (se Hash Key: t3.v6 -> Seq Scan on public.t3 (cost=0.00..431.00 rows=34 width=4) Output: t3.v6 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (33 rows) @@ -1024,7 +1047,7 @@ explain verbose select * from pt1 where v1 in (select v3 from pt2,t3 where v4=v6 Hash Key: t3.v6 -> Seq Scan on public.t3 (cost=0.00..431.00 rows=34 width=4) Output: t3.v6 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (33 rows) @@ -1064,35 +1087,35 @@ explain verbose select * from pt1 where v1 in (select v3 from pt2) and v1 in (se -> Seq Scan on public.t3 (cost=0.00..431.00 rows=4 width=4) Output: t3.v6 Filter: (t3.v6 < 10) - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (35 rows) select * from pt1 where v1 in (select v3 from pt2) and v1 in (select v3 from pt2,t3 where v4=v6 and v4 < 10); v1 | v2 ----+---- + 1 | 1 + 5 | 5 + 6 | 6 + 9 | 9 2 | 2 3 | 3 4 | 4 - 9 | 9 - 8 | 8 - 6 | 6 7 | 7 - 1 | 1 - 5 | 5 + 8 | 8 (9 rows) select * from pt1 where v1 in (select v3 from pt2,t3 where v4=v6 and v4 < 10); v1 | v2 ----+---- - 5 | 5 - 6 | 6 - 9 | 9 2 | 2 3 | 3 4 | 4 7 | 7 8 | 8 + 5 | 5 + 6 | 6 + 9 | 9 1 | 1 (9 rows) @@ -1130,7 +1153,7 @@ explain verbose with cte1 as (select v3 from t2) select * from t1,t2 where t1.v1 Output: t3.v6 -> Shared Scan (share slice:id 1:0) (cost=0.00..431.00 rows=34 width=4) Output: share0_ref2.v3 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (33 rows) @@ -1168,7 +1191,7 @@ explain verbose with cte1 as (select v3 from t2) select * from t1,t2 where t1.v1 Output: t3.v6 -> Shared Scan (share slice:id 1:0) (cost=0.00..431.00 rows=34 width=4) Output: share0_ref2.v3 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (33 rows) @@ -1207,7 +1230,7 @@ explain verbose with cte1 as (select v3 from t2) select * from t1,t2 where t1.v1 Filter: (t3.v6 < 10) -> Seq Scan on public.t2 t2_1 (cost=0.00..431.00 rows=34 width=4) Output: t2_1.v3 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (34 rows) @@ -1252,7 +1275,7 @@ explain verbose with cte1 as (select v3 from t2) select * from t1,t2 where t1.v1 Filter: (t3.v6 < 10) -> Shared Scan (share slice:id 1:0) (cost=0.00..431.00 rows=34 width=4) Output: share0_ref2.v3 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (40 rows) @@ -1305,7 +1328,7 @@ explain verbose with cte1 as (select v3 from t2) select * from t1,t2 where t1.v1 Filter: (t3.v6 < 10) -> Seq Scan on public.t2 t2_1 (cost=0.00..431.00 rows=34 width=4) Output: t2_1.v3 - Settings: enable_parallel = 'off', optimizer = 'on', optimizer_cte_inlining_bound = '2' + Settings: optimizer = 'on', optimizer_cte_inlining_bound = '2' Optimizer: GPORCA (34 rows) @@ -1340,7 +1363,7 @@ explain verbose select * from t1 where v1 in (select v3 from t2) and v1 in (sele Output: (1), t3.v5 -> Seq Scan on public.t3 (cost=0.00..431.00 rows=34 width=4) Output: 1, t3.v5 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (21 rows) @@ -1366,7 +1389,7 @@ explain verbose select * from t1 where v1 in (select v3 from t2 where exists (SE Output: (1), t3.v5 -> Seq Scan on public.t3 (cost=0.00..431.00 rows=34 width=4) Output: 1, t3.v5 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (21 rows) @@ -1404,7 +1427,7 @@ explain verbose select v1 from t1 where v1 in (select v3 from t2) and v1 in (sel Output: t3.v5 -> Seq Scan on public.t3 (cost=0.00..431.00 rows=34 width=4) Output: t3.v5 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (20 rows) @@ -1429,42 +1452,42 @@ explain verbose select v1 from t1 where v1 in (select v5 from t2,t3 where v5 = v Output: t3.v5 -> Seq Scan on public.t3 (cost=0.00..431.00 rows=34 width=4) Output: t3.v5 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (20 rows) explain verbose select v1 from t1 where v1 in (select v3 from t2) and v1 in (select v6 from t2,t3 where v5 = v3); -- no dedup, because v6 is not the join key - QUERY PLAN -------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1724.04 rows=100 width=4) Output: t1.v1 - -> Hash Semi Join (cost=0.00..1724.04 rows=34 width=4) + -> Hash Right Semi Join (cost=0.00..1724.04 rows=34 width=4) Output: t1.v1 - Hash Cond: (t1.v1 = t2_1.v3) - -> Hash Semi Join (cost=0.00..1293.03 rows=34 width=4) + Hash Cond: (t1.v1 = t2.v3) + -> Seq Scan on public.t2 (cost=0.00..431.00 rows=34 width=4) + Output: t2.v3 + -> Hash (cost=1293.03..1293.03 rows=34 width=4) Output: t1.v1 - Hash Cond: (t1.v1 = t3.v6) - -> Seq Scan on public.t1 (cost=0.00..431.00 rows=34 width=4) + -> Hash Semi Join (cost=0.00..1293.03 rows=34 width=4) Output: t1.v1 - -> Hash (cost=862.02..862.02 rows=34 width=4) - Output: t3.v6 - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..862.02 rows=34 width=4) + Hash Cond: (t1.v1 = t3.v6) + -> Seq Scan on public.t1 (cost=0.00..431.00 rows=34 width=4) + Output: t1.v1 + -> Hash (cost=862.02..862.02 rows=34 width=4) Output: t3.v6 - Hash Key: t3.v6 - -> Hash Join (cost=0.00..862.02 rows=34 width=4) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..862.02 rows=34 width=4) Output: t3.v6 - Hash Cond: (t3.v5 = t2.v3) - -> Seq Scan on public.t3 (cost=0.00..431.00 rows=34 width=8) - Output: t3.v5, t3.v6 - -> Hash (cost=431.00..431.00 rows=34 width=4) - Output: t2.v3 - -> Seq Scan on public.t2 (cost=0.00..431.00 rows=34 width=4) - Output: t2.v3 - -> Hash (cost=431.00..431.00 rows=34 width=4) - Output: t2_1.v3 - -> Seq Scan on public.t2 t2_1 (cost=0.00..431.00 rows=34 width=4) - Output: t2_1.v3 - Settings: enable_parallel = 'off', optimizer = 'on' + Hash Key: t3.v6 + -> Hash Join (cost=0.00..862.02 rows=34 width=4) + Output: t3.v6 + Hash Cond: (t3.v5 = t2_1.v3) + -> Seq Scan on public.t3 (cost=0.00..431.00 rows=34 width=8) + Output: t3.v5, t3.v6 + -> Hash (cost=431.00..431.00 rows=34 width=4) + Output: t2_1.v3 + -> Seq Scan on public.t2 t2_1 (cost=0.00..431.00 rows=34 width=4) + Output: t2_1.v3 + Settings: optimizer = 'on' Optimizer: GPORCA (30 rows) @@ -1482,63 +1505,63 @@ select count(v1) from t1 where v1 in (select v5 from t2,t3 where v5 = v3); -- can't dedup explain verbose select * from t1 where v1 in (select v3 from t2) and v1 in (select v4 from t2 where v3 < 10); -- different outpt - QUERY PLAN ------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1293.02 rows=10 width=8) Output: t1.v1, t1.v2 - -> Hash Semi Join (cost=0.00..1293.02 rows=4 width=8) + -> Hash Right Semi Join (cost=0.00..1293.02 rows=4 width=8) Output: t1.v1, t1.v2 - Hash Cond: (t1.v1 = t2_1.v3) - -> Hash Semi Join (cost=0.00..862.01 rows=4 width=8) + Hash Cond: (t1.v1 = t2.v3) + -> Seq Scan on public.t2 (cost=0.00..431.00 rows=34 width=4) + Output: t2.v3 + -> Hash (cost=862.01..862.01 rows=4 width=8) Output: t1.v1, t1.v2 - Hash Cond: (t1.v1 = t2.v4) - -> Seq Scan on public.t1 (cost=0.00..431.00 rows=34 width=8) + -> Hash Semi Join (cost=0.00..862.01 rows=4 width=8) Output: t1.v1, t1.v2 - -> Hash (cost=431.00..431.00 rows=4 width=4) - Output: t2.v4 - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=4 width=4) - Output: t2.v4 - Hash Key: t2.v4 - -> Seq Scan on public.t2 (cost=0.00..431.00 rows=4 width=4) - Output: t2.v4 - Filter: (t2.v3 < 10) - -> Hash (cost=431.00..431.00 rows=34 width=4) - Output: t2_1.v3 - -> Seq Scan on public.t2 t2_1 (cost=0.00..431.00 rows=34 width=4) - Output: t2_1.v3 - Settings: enable_parallel = 'off', optimizer = 'on' + Hash Cond: (t1.v1 = t2_1.v4) + -> Seq Scan on public.t1 (cost=0.00..431.00 rows=34 width=8) + Output: t1.v1, t1.v2 + -> Hash (cost=431.00..431.00 rows=4 width=4) + Output: t2_1.v4 + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=4 width=4) + Output: t2_1.v4 + Hash Key: t2_1.v4 + -> Seq Scan on public.t2 t2_1 (cost=0.00..431.00 rows=4 width=4) + Output: t2_1.v4 + Filter: (t2_1.v3 < 10) + Settings: optimizer = 'on' Optimizer: GPORCA (24 rows) explain verbose select * from t1 where v1 in (select v3 from t2) and v2 in (select v3 from t2 where v3 < 10); -- different scalar ident - QUERY PLAN -------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1293.02 rows=10 width=8) Output: t1.v1, t1.v2 - -> Hash Semi Join (cost=0.00..1293.02 rows=4 width=8) + -> Hash Right Semi Join (cost=0.00..1293.02 rows=4 width=8) Output: t1.v1, t1.v2 - Hash Cond: (t1.v1 = t2_1.v3) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..862.01 rows=4 width=8) + Hash Cond: (t1.v1 = t2.v3) + -> Seq Scan on public.t2 (cost=0.00..431.00 rows=34 width=4) + Output: t2.v3 + -> Hash (cost=862.01..862.01 rows=4 width=8) Output: t1.v1, t1.v2 - Hash Key: t1.v1 - -> Hash Semi Join (cost=0.00..862.01 rows=4 width=8) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..862.01 rows=4 width=8) Output: t1.v1, t1.v2 - Hash Cond: (t1.v2 = t2.v3) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..431.00 rows=34 width=8) + Hash Key: t1.v1 + -> Hash Semi Join (cost=0.00..862.01 rows=4 width=8) Output: t1.v1, t1.v2 - Hash Key: t1.v2 - -> Seq Scan on public.t1 (cost=0.00..431.00 rows=34 width=8) + Hash Cond: (t1.v2 = t2_1.v3) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..431.00 rows=34 width=8) Output: t1.v1, t1.v2 - -> Hash (cost=431.00..431.00 rows=4 width=4) - Output: t2.v3 - -> Seq Scan on public.t2 (cost=0.00..431.00 rows=4 width=4) - Output: t2.v3 - Filter: (t2.v3 < 10) - -> Hash (cost=431.00..431.00 rows=34 width=4) - Output: t2_1.v3 - -> Seq Scan on public.t2 t2_1 (cost=0.00..431.00 rows=34 width=4) - Output: t2_1.v3 - Settings: enable_parallel = 'off', optimizer = 'on' + Hash Key: t1.v2 + -> Seq Scan on public.t1 (cost=0.00..431.00 rows=34 width=8) + Output: t1.v1, t1.v2 + -> Hash (cost=431.00..431.00 rows=4 width=4) + Output: t2_1.v3 + -> Seq Scan on public.t2 t2_1 (cost=0.00..431.00 rows=4 width=4) + Output: t2_1.v3 + Filter: (t2_1.v3 < 10) + Settings: optimizer = 'on' Optimizer: GPORCA (27 rows) @@ -1572,7 +1595,7 @@ explain verbose select * from t1 where v1 in (select v3 from t2) and v2 in (sele Sort Key: t2_1.v3 -> Seq Scan on public.t2 t2_1 (cost=0.00..431.00 rows=34 width=4) Output: t2_1.v3 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (29 rows) @@ -1600,7 +1623,7 @@ explain verbose select * from t1 where v1 in (select v3 from t2) and v2 in (sele Output: t2_1.v3 -> Seq Scan on public.t2 t2_1 (cost=0.00..431.00 rows=34 width=4) Output: t2_1.v3 - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (23 rows) diff --git a/src/test/regress/expected/dpe_optimizer.out b/src/test/regress/expected/dpe_optimizer.out index e8510c9293b..7ba66e9db89 100644 --- a/src/test/regress/expected/dpe_optimizer.out +++ b/src/test/regress/expected/dpe_optimizer.out @@ -72,7 +72,11 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'dist' HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into t1 select i, i % 6, 'hello' || i, 'bar' from generate_series(1,2) i; insert into pt1 select * from pt; +NOTICE: One or more columns in the following table(s) do not have statistics: pt +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. insert into pt1 select dist, pt1, pt2, pt3, ptid-100 from pt; +NOTICE: One or more columns in the following table(s) do not have statistics: pt +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. alter table pt1 set with(REORGANIZE=false) DISTRIBUTED RANDOMLY; vacuum analyze pt; analyze pt1; @@ -93,30 +97,30 @@ explain (costs off, timing off, summary off, analyze) select * from t, pt where Index Cond: (ptid = t.tid) Number of partitions to scan: 6 (out of 6) Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) select * from t, pt where tid = ptid; dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid ------+-----+--------+-----+------+---------+-------+-----------+------ - 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 + 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 + 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 + 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 - 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 - 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 - 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 - 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 - 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 - 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 0 | 0 | hello0 | bar | 12 | hello12 | world | drop this | 0 - 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 - 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 0 | 0 | hello0 | bar | 30 | hello30 | world | drop this | 0 0 | 0 | hello0 | bar | 36 | hello36 | world | drop this | 0 - 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 0 | 0 | hello0 | bar | 48 | hello48 | world | drop this | 0 + 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 + 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 + 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 + 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 + 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 + 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 + 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 (18 rows) explain (costs off, timing off, summary off, analyze) select * from t, pt where tid + 1 = ptid; @@ -131,30 +135,30 @@ explain (costs off, timing off, summary off, analyze) select * from t, pt where Index Cond: (ptid = (t.tid + 1)) Number of partitions to scan: 6 (out of 6) Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) select * from t, pt where tid + 1 = ptid; dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid ------+-----+--------+-----+------+---------+-------+-----------+------ - 0 | 0 | hello0 | bar | 1 | hello1 | world | drop this | 1 0 | 0 | hello0 | bar | 7 | hello7 | world | drop this | 1 - 0 | 0 | hello0 | bar | 13 | hello13 | world | drop this | 1 0 | 0 | hello0 | bar | 19 | hello19 | world | drop this | 1 - 0 | 0 | hello0 | bar | 25 | hello25 | world | drop this | 1 - 0 | 0 | hello0 | bar | 31 | hello31 | world | drop this | 1 0 | 0 | hello0 | bar | 37 | hello37 | world | drop this | 1 - 0 | 0 | hello0 | bar | 43 | hello43 | world | drop this | 1 - 0 | 0 | hello0 | bar | 49 | hello49 | world | drop this | 1 1 | 1 | hello1 | bar | 2 | hello2 | world | drop this | 2 1 | 1 | hello1 | bar | 8 | hello8 | world | drop this | 2 - 1 | 1 | hello1 | bar | 14 | hello14 | world | drop this | 2 + 0 | 0 | hello0 | bar | 1 | hello1 | world | drop this | 1 + 0 | 0 | hello0 | bar | 31 | hello31 | world | drop this | 1 + 0 | 0 | hello0 | bar | 49 | hello49 | world | drop this | 1 1 | 1 | hello1 | bar | 20 | hello20 | world | drop this | 2 1 | 1 | hello1 | bar | 26 | hello26 | world | drop this | 2 - 1 | 1 | hello1 | bar | 32 | hello32 | world | drop this | 2 1 | 1 | hello1 | bar | 38 | hello38 | world | drop this | 2 1 | 1 | hello1 | bar | 44 | hello44 | world | drop this | 2 1 | 1 | hello1 | bar | 50 | hello50 | world | drop this | 2 + 0 | 0 | hello0 | bar | 13 | hello13 | world | drop this | 1 + 0 | 0 | hello0 | bar | 25 | hello25 | world | drop this | 1 + 0 | 0 | hello0 | bar | 43 | hello43 | world | drop this | 1 + 1 | 1 | hello1 | bar | 14 | hello14 | world | drop this | 2 + 1 | 1 | hello1 | bar | 32 | hello32 | world | drop this | 2 (18 rows) explain (costs off, timing off, summary off, analyze) select * from t, pt where tid = ptid and t1 = 'hello' || tid; @@ -170,30 +174,30 @@ explain (costs off, timing off, summary off, analyze) select * from t, pt where Index Cond: (ptid = t.tid) Number of partitions to scan: 6 (out of 6) Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) select * from t, pt where tid = ptid and t1 = 'hello' || tid; dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid ------+-----+--------+-----+------+---------+-------+-----------+------ - 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 + 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 + 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 + 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 - 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 - 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 - 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 - 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 - 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 - 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 0 | 0 | hello0 | bar | 12 | hello12 | world | drop this | 0 - 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 - 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 0 | 0 | hello0 | bar | 30 | hello30 | world | drop this | 0 0 | 0 | hello0 | bar | 36 | hello36 | world | drop this | 0 - 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 0 | 0 | hello0 | bar | 48 | hello48 | world | drop this | 0 + 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 + 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 + 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 + 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 + 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 + 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 + 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 (18 rows) explain (costs off, timing off, summary off, analyze) select * from t, pt where t1 = pt1 and ptid = tid; @@ -208,7 +212,7 @@ explain (costs off, timing off, summary off, analyze) select * from t, pt where Index Cond: ((ptid = t.tid) AND (pt1 = t.t1)) Number of partitions to scan: 6 (out of 6) Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) select * from t, pt where t1 = pt1 and ptid = tid; @@ -237,52 +241,51 @@ explain (costs off, timing off, summary off, analyze) select * from pt where pti -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) -> Seq Scan on t (actual rows=2 loops=1) Filter: (t1 = ('hello'::text || (tid)::text)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (14 rows) select * from pt where ptid in (select tid from t where t1 = 'hello' || tid); dist | pt1 | pt2 | pt3 | ptid ------+---------+-------+-----------+------ + 0 | hello0 | world | drop this | 0 + 12 | hello12 | world | drop this | 0 + 30 | hello30 | world | drop this | 0 + 36 | hello36 | world | drop this | 0 + 48 | hello48 | world | drop this | 0 1 | hello1 | world | drop this | 1 - 7 | hello7 | world | drop this | 1 - 13 | hello13 | world | drop this | 1 - 19 | hello19 | world | drop this | 1 - 25 | hello25 | world | drop this | 1 31 | hello31 | world | drop this | 1 - 37 | hello37 | world | drop this | 1 - 43 | hello43 | world | drop this | 1 49 | hello49 | world | drop this | 1 - 0 | hello0 | world | drop this | 0 - 6 | hello6 | world | drop this | 0 - 12 | hello12 | world | drop this | 0 18 | hello18 | world | drop this | 0 24 | hello24 | world | drop this | 0 - 30 | hello30 | world | drop this | 0 - 36 | hello36 | world | drop this | 0 42 | hello42 | world | drop this | 0 - 48 | hello48 | world | drop this | 0 + 7 | hello7 | world | drop this | 1 + 19 | hello19 | world | drop this | 1 + 37 | hello37 | world | drop this | 1 + 6 | hello6 | world | drop this | 0 + 13 | hello13 | world | drop this | 1 + 25 | hello25 | world | drop this | 1 + 43 | hello43 | world | drop this | 1 (18 rows) explain (costs off, timing off, summary off, analyze) select ptid from pt where ptid in (select tid from t where t1 = 'hello' || tid) and pt1 = 'hello1'; - QUERY PLAN ---------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=1 loops=1) - -> Hash Semi Join (actual rows=1 loops=1) + -> Hash Right Semi Join (actual rows=1 loops=1) Hash Cond: (pt.ptid = t.tid) - Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 2 of 524288 buckets. - -> Dynamic Index Only Scan on ptid_pt1_idx on pt (actual rows=1 loops=1) - Index Cond: (pt1 = 'hello1'::text) - Heap Fetches: 0 - Number of partitions to scan: 6 (out of 6) - Partitions scanned: Avg 2.0 x 3 workers. Max 2 parts (seg0). - -> Hash (actual rows=2 loops=1) + Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 1 of 524288 buckets. + -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) + -> Seq Scan on t (actual rows=2 loops=1) + Filter: (t1 = ('hello'::text || (tid)::text)) + -> Hash (actual rows=1 loops=1) Buckets: 524288 Batches: 1 Memory Usage: 4097kB - -> Partition Selector (selector id: $0) (actual rows=2 loops=1) - -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) - -> Seq Scan on t (actual rows=2 loops=1) - Filter: (t1 = ('hello'::text || (tid)::text)) + -> Dynamic Index Only Scan on ptid_pt1_idx on pt (actual rows=1 loops=1) + Index Cond: (pt1 = 'hello1'::text) + Heap Fetches: 0 + Number of partitions to scan: 6 (out of 6) + Partitions scanned: Avg 6.0 x 3 workers. Max 6 parts (seg0). Optimizer: GPORCA -(16 rows) +(15 rows) select ptid from pt where ptid in (select tid from t where t1 = 'hello' || tid) and pt1 = 'hello1'; ptid @@ -318,30 +321,30 @@ explain (costs off, timing off, summary off, analyze) select * from pt where exi -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) -> Seq Scan on t (actual rows=2 loops=1) Filter: (t1 = ('hello'::text || (tid)::text)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (15 rows) select * from pt where exists (select 1 from t where tid = ptid and t1 = 'hello' || tid); dist | pt1 | pt2 | pt3 | ptid ------+---------+-------+-----------+------ - 49 | hello49 | world | drop this | 1 - 43 | hello43 | world | drop this | 1 - 37 | hello37 | world | drop this | 1 - 31 | hello31 | world | drop this | 1 - 25 | hello25 | world | drop this | 1 - 19 | hello19 | world | drop this | 1 - 13 | hello13 | world | drop this | 1 - 7 | hello7 | world | drop this | 1 - 1 | hello1 | world | drop this | 1 - 48 | hello48 | world | drop this | 0 - 42 | hello42 | world | drop this | 0 - 36 | hello36 | world | drop this | 0 - 30 | hello30 | world | drop this | 0 - 24 | hello24 | world | drop this | 0 18 | hello18 | world | drop this | 0 + 24 | hello24 | world | drop this | 0 + 42 | hello42 | world | drop this | 0 + 7 | hello7 | world | drop this | 1 + 19 | hello19 | world | drop this | 1 + 37 | hello37 | world | drop this | 1 + 0 | hello0 | world | drop this | 0 12 | hello12 | world | drop this | 0 + 30 | hello30 | world | drop this | 0 + 36 | hello36 | world | drop this | 0 + 48 | hello48 | world | drop this | 0 + 1 | hello1 | world | drop this | 1 + 31 | hello31 | world | drop this | 1 + 49 | hello49 | world | drop this | 1 6 | hello6 | world | drop this | 0 - 0 | hello0 | world | drop this | 0 + 13 | hello13 | world | drop this | 1 + 25 | hello25 | world | drop this | 1 + 43 | hello43 | world | drop this | 1 (18 rows) -- enable xform @@ -390,7 +393,7 @@ explain (costs off, timing off, summary off, analyze) select *, rank() over (ord Merge Key: pt.ptid, pt.pt1 -> Sort (actual rows=8 loops=1) Sort Key: pt.ptid, pt.pt1 - Sort Method: quicksort Memory: 76kB + Sort Method: quicksort Memory: 75kB -> Nested Loop (actual rows=8 loops=1) Join Filter: true -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) @@ -399,7 +402,7 @@ explain (costs off, timing off, summary off, analyze) select *, rank() over (ord Index Cond: (ptid = t.tid) Number of partitions to scan: 6 (out of 6) Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (16 rows) select *, rank() over (order by ptid,pt1) from t, pt where tid = ptid; @@ -451,7 +454,7 @@ explain (costs off, timing off, summary off, analyze) select * from t, pt where Index Cond: (ptid = (t_1.tid + 2)) Number of partitions to scan: 6 (out of 6) Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (19 rows) select * from t, pt where tid = ptid @@ -459,42 +462,42 @@ select * from t, pt where tid = ptid select * from t, pt where tid + 2 = ptid; dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid ------+-----+--------+-----+------+---------+-------+-----------+------ - 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 + 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 + 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 + 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 - 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 - 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 - 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 - 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 - 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 + 0 | 0 | hello0 | bar | 2 | hello2 | world | drop this | 2 + 0 | 0 | hello0 | bar | 8 | hello8 | world | drop this | 2 1 | 1 | hello1 | bar | 3 | hello3 | world | drop this | 3 - 1 | 1 | hello1 | bar | 9 | hello9 | world | drop this | 3 - 1 | 1 | hello1 | bar | 15 | hello15 | world | drop this | 3 - 1 | 1 | hello1 | bar | 21 | hello21 | world | drop this | 3 1 | 1 | hello1 | bar | 27 | hello27 | world | drop this | 3 - 1 | 1 | hello1 | bar | 33 | hello33 | world | drop this | 3 1 | 1 | hello1 | bar | 39 | hello39 | world | drop this | 3 1 | 1 | hello1 | bar | 45 | hello45 | world | drop this | 3 1 | 1 | hello1 | bar | 51 | hello51 | world | drop this | 3 - 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 + 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 + 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 + 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 + 0 | 0 | hello0 | bar | 14 | hello14 | world | drop this | 2 + 0 | 0 | hello0 | bar | 32 | hello32 | world | drop this | 2 + 1 | 1 | hello1 | bar | 9 | hello9 | world | drop this | 3 + 1 | 1 | hello1 | bar | 21 | hello21 | world | drop this | 3 + 1 | 1 | hello1 | bar | 33 | hello33 | world | drop this | 3 + 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 0 | 0 | hello0 | bar | 12 | hello12 | world | drop this | 0 - 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 - 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 0 | 0 | hello0 | bar | 30 | hello30 | world | drop this | 0 0 | 0 | hello0 | bar | 36 | hello36 | world | drop this | 0 - 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 0 | 0 | hello0 | bar | 48 | hello48 | world | drop this | 0 - 0 | 0 | hello0 | bar | 2 | hello2 | world | drop this | 2 - 0 | 0 | hello0 | bar | 8 | hello8 | world | drop this | 2 - 0 | 0 | hello0 | bar | 14 | hello14 | world | drop this | 2 + 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 + 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 + 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 0 | 0 | hello0 | bar | 20 | hello20 | world | drop this | 2 0 | 0 | hello0 | bar | 26 | hello26 | world | drop this | 2 - 0 | 0 | hello0 | bar | 32 | hello32 | world | drop this | 2 0 | 0 | hello0 | bar | 38 | hello38 | world | drop this | 2 0 | 0 | hello0 | bar | 44 | hello44 | world | drop this | 2 0 | 0 | hello0 | bar | 50 | hello50 | world | drop this | 2 + 1 | 1 | hello1 | bar | 15 | hello15 | world | drop this | 3 (36 rows) -- @@ -527,7 +530,7 @@ explain (costs off, timing off, summary off, analyze) select count(*) from Index Cond: (ptid = (t_1.tid + 2)) Number of partitions to scan: 6 (out of 6) Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (21 rows) select count(*) from @@ -558,30 +561,30 @@ explain (costs off, timing off, summary off, analyze) select * from t, pt where Index Cond: (ptid = t.tid) Number of partitions to scan: 6 (out of 6) Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) select * from t, pt where tid = ptid; dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid ------+-----+--------+-----+------+---------+-------+-----------+------ - 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 + 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 + 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 + 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 - 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 - 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 - 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 - 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 - 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 - 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 0 | 0 | hello0 | bar | 12 | hello12 | world | drop this | 0 - 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 - 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 0 | 0 | hello0 | bar | 30 | hello30 | world | drop this | 0 0 | 0 | hello0 | bar | 36 | hello36 | world | drop this | 0 - 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 0 | 0 | hello0 | bar | 48 | hello48 | world | drop this | 0 + 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 + 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 + 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 + 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 + 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 + 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 + 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 (18 rows) -- @@ -610,7 +613,7 @@ explain (costs off, timing off, summary off, analyze) select * from t, pt where Index Cond: (pt1 = 'hello0'::text) Number of partitions to scan: 6 (out of 6) Partitions scanned: Avg 6.0 x 3 workers. Max 6 parts (seg0). - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) select * from t, pt where tid = ptid and pt1 = 'hello0'; @@ -638,30 +641,30 @@ explain (costs off, timing off, summary off, analyze) select * from t, pt where Index Cond: (ptid = t.tid) Number of partitions to scan: 6 (out of 6) Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) select * from t, pt where tid = ptid; dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid ------+-----+--------+-----+------+---------+-------+-----------+------ - 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 + 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 + 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 + 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 - 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 - 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 - 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 - 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 - 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 - 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 0 | 0 | hello0 | bar | 12 | hello12 | world | drop this | 0 - 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 - 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 0 | 0 | hello0 | bar | 30 | hello30 | world | drop this | 0 0 | 0 | hello0 | bar | 36 | hello36 | world | drop this | 0 - 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 0 | 0 | hello0 | bar | 48 | hello48 | world | drop this | 0 + 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 + 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 + 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 + 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 + 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 + 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 + 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 (18 rows) -- @@ -683,14 +686,14 @@ explain (costs off, timing off, summary off, analyze) select * from t, pt where Index Cond: (pt1 = t.t1) Number of partitions to scan: 6 (out of 6) Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) select * from t, pt where t1 = pt1; dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid ------+-----+--------+-----+------+--------+-------+-----------+------ - 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 + 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 (2 rows) explain (costs off, timing off, summary off, analyze) select * from t, pt where tid < ptid; @@ -705,93 +708,93 @@ explain (costs off, timing off, summary off, analyze) select * from t, pt where Index Cond: (ptid > t.tid) Number of partitions to scan: 6 (out of 6) Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) select * from t, pt where tid < ptid; dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid ------+-----+--------+-----+------+---------+-------+-----------+------ - 1 | 1 | hello1 | bar | 2 | hello2 | world | drop this | 2 + 0 | 0 | hello0 | bar | 7 | hello7 | world | drop this | 1 + 0 | 0 | hello0 | bar | 19 | hello19 | world | drop this | 1 + 0 | 0 | hello0 | bar | 37 | hello37 | world | drop this | 1 0 | 0 | hello0 | bar | 2 | hello2 | world | drop this | 2 - 1 | 1 | hello1 | bar | 8 | hello8 | world | drop this | 2 0 | 0 | hello0 | bar | 8 | hello8 | world | drop this | 2 - 1 | 1 | hello1 | bar | 14 | hello14 | world | drop this | 2 - 0 | 0 | hello0 | bar | 14 | hello14 | world | drop this | 2 - 1 | 1 | hello1 | bar | 20 | hello20 | world | drop this | 2 + 0 | 0 | hello0 | bar | 3 | hello3 | world | drop this | 3 + 0 | 0 | hello0 | bar | 27 | hello27 | world | drop this | 3 + 0 | 0 | hello0 | bar | 39 | hello39 | world | drop this | 3 + 0 | 0 | hello0 | bar | 45 | hello45 | world | drop this | 3 + 0 | 0 | hello0 | bar | 51 | hello51 | world | drop this | 3 + 0 | 0 | hello0 | bar | 4 | hello4 | world | drop this | 4 + 0 | 0 | hello0 | bar | 16 | hello16 | world | drop this | 4 + 0 | 0 | hello0 | bar | 22 | hello22 | world | drop this | 4 + 0 | 0 | hello0 | bar | 34 | hello34 | world | drop this | 4 + 0 | 0 | hello0 | bar | 29 | hello29 | world | drop this | 5 + 0 | 0 | hello0 | bar | 41 | hello41 | world | drop this | 5 + 0 | 0 | hello0 | bar | 53 | hello53 | world | drop this | 5 + 1 | 1 | hello1 | bar | 2 | hello2 | world | drop this | 2 + 1 | 1 | hello1 | bar | 8 | hello8 | world | drop this | 2 + 1 | 1 | hello1 | bar | 3 | hello3 | world | drop this | 3 + 1 | 1 | hello1 | bar | 27 | hello27 | world | drop this | 3 + 1 | 1 | hello1 | bar | 39 | hello39 | world | drop this | 3 + 1 | 1 | hello1 | bar | 45 | hello45 | world | drop this | 3 + 1 | 1 | hello1 | bar | 51 | hello51 | world | drop this | 3 + 1 | 1 | hello1 | bar | 4 | hello4 | world | drop this | 4 + 1 | 1 | hello1 | bar | 16 | hello16 | world | drop this | 4 + 1 | 1 | hello1 | bar | 22 | hello22 | world | drop this | 4 + 1 | 1 | hello1 | bar | 34 | hello34 | world | drop this | 4 + 1 | 1 | hello1 | bar | 29 | hello29 | world | drop this | 5 + 1 | 1 | hello1 | bar | 41 | hello41 | world | drop this | 5 + 1 | 1 | hello1 | bar | 53 | hello53 | world | drop this | 5 + 0 | 0 | hello0 | bar | 1 | hello1 | world | drop this | 1 + 0 | 0 | hello0 | bar | 31 | hello31 | world | drop this | 1 + 0 | 0 | hello0 | bar | 49 | hello49 | world | drop this | 1 0 | 0 | hello0 | bar | 20 | hello20 | world | drop this | 2 - 1 | 1 | hello1 | bar | 26 | hello26 | world | drop this | 2 0 | 0 | hello0 | bar | 26 | hello26 | world | drop this | 2 - 1 | 1 | hello1 | bar | 32 | hello32 | world | drop this | 2 - 0 | 0 | hello0 | bar | 32 | hello32 | world | drop this | 2 - 1 | 1 | hello1 | bar | 38 | hello38 | world | drop this | 2 0 | 0 | hello0 | bar | 38 | hello38 | world | drop this | 2 - 1 | 1 | hello1 | bar | 44 | hello44 | world | drop this | 2 0 | 0 | hello0 | bar | 44 | hello44 | world | drop this | 2 - 1 | 1 | hello1 | bar | 50 | hello50 | world | drop this | 2 0 | 0 | hello0 | bar | 50 | hello50 | world | drop this | 2 - 1 | 1 | hello1 | bar | 4 | hello4 | world | drop this | 4 - 0 | 0 | hello0 | bar | 4 | hello4 | world | drop this | 4 - 1 | 1 | hello1 | bar | 10 | hello10 | world | drop this | 4 - 0 | 0 | hello0 | bar | 10 | hello10 | world | drop this | 4 - 1 | 1 | hello1 | bar | 16 | hello16 | world | drop this | 4 - 0 | 0 | hello0 | bar | 16 | hello16 | world | drop this | 4 - 1 | 1 | hello1 | bar | 22 | hello22 | world | drop this | 4 - 0 | 0 | hello0 | bar | 22 | hello22 | world | drop this | 4 - 1 | 1 | hello1 | bar | 28 | hello28 | world | drop this | 4 - 0 | 0 | hello0 | bar | 28 | hello28 | world | drop this | 4 - 1 | 1 | hello1 | bar | 34 | hello34 | world | drop this | 4 - 0 | 0 | hello0 | bar | 34 | hello34 | world | drop this | 4 - 1 | 1 | hello1 | bar | 40 | hello40 | world | drop this | 4 + 0 | 0 | hello0 | bar | 15 | hello15 | world | drop this | 3 0 | 0 | hello0 | bar | 40 | hello40 | world | drop this | 4 - 1 | 1 | hello1 | bar | 46 | hello46 | world | drop this | 4 0 | 0 | hello0 | bar | 46 | hello46 | world | drop this | 4 - 1 | 1 | hello1 | bar | 52 | hello52 | world | drop this | 4 - 0 | 0 | hello0 | bar | 52 | hello52 | world | drop this | 4 - 1 | 1 | hello1 | bar | 5 | hello5 | world | drop this | 5 - 0 | 0 | hello0 | bar | 5 | hello5 | world | drop this | 5 - 1 | 1 | hello1 | bar | 11 | hello11 | world | drop this | 5 - 0 | 0 | hello0 | bar | 11 | hello11 | world | drop this | 5 - 1 | 1 | hello1 | bar | 17 | hello17 | world | drop this | 5 - 0 | 0 | hello0 | bar | 17 | hello17 | world | drop this | 5 - 1 | 1 | hello1 | bar | 23 | hello23 | world | drop this | 5 0 | 0 | hello0 | bar | 23 | hello23 | world | drop this | 5 - 1 | 1 | hello1 | bar | 29 | hello29 | world | drop this | 5 - 0 | 0 | hello0 | bar | 29 | hello29 | world | drop this | 5 - 1 | 1 | hello1 | bar | 35 | hello35 | world | drop this | 5 0 | 0 | hello0 | bar | 35 | hello35 | world | drop this | 5 - 1 | 1 | hello1 | bar | 41 | hello41 | world | drop this | 5 - 0 | 0 | hello0 | bar | 41 | hello41 | world | drop this | 5 - 1 | 1 | hello1 | bar | 47 | hello47 | world | drop this | 5 0 | 0 | hello0 | bar | 47 | hello47 | world | drop this | 5 - 1 | 1 | hello1 | bar | 53 | hello53 | world | drop this | 5 - 0 | 0 | hello0 | bar | 53 | hello53 | world | drop this | 5 - 0 | 0 | hello0 | bar | 1 | hello1 | world | drop this | 1 - 0 | 0 | hello0 | bar | 7 | hello7 | world | drop this | 1 + 1 | 1 | hello1 | bar | 20 | hello20 | world | drop this | 2 + 1 | 1 | hello1 | bar | 26 | hello26 | world | drop this | 2 + 1 | 1 | hello1 | bar | 38 | hello38 | world | drop this | 2 + 1 | 1 | hello1 | bar | 44 | hello44 | world | drop this | 2 + 1 | 1 | hello1 | bar | 50 | hello50 | world | drop this | 2 + 1 | 1 | hello1 | bar | 15 | hello15 | world | drop this | 3 + 1 | 1 | hello1 | bar | 40 | hello40 | world | drop this | 4 + 1 | 1 | hello1 | bar | 46 | hello46 | world | drop this | 4 + 1 | 1 | hello1 | bar | 23 | hello23 | world | drop this | 5 + 1 | 1 | hello1 | bar | 35 | hello35 | world | drop this | 5 + 1 | 1 | hello1 | bar | 47 | hello47 | world | drop this | 5 0 | 0 | hello0 | bar | 13 | hello13 | world | drop this | 1 - 0 | 0 | hello0 | bar | 19 | hello19 | world | drop this | 1 0 | 0 | hello0 | bar | 25 | hello25 | world | drop this | 1 - 0 | 0 | hello0 | bar | 31 | hello31 | world | drop this | 1 - 0 | 0 | hello0 | bar | 37 | hello37 | world | drop this | 1 0 | 0 | hello0 | bar | 43 | hello43 | world | drop this | 1 - 0 | 0 | hello0 | bar | 49 | hello49 | world | drop this | 1 - 1 | 1 | hello1 | bar | 3 | hello3 | world | drop this | 3 - 0 | 0 | hello0 | bar | 3 | hello3 | world | drop this | 3 - 1 | 1 | hello1 | bar | 9 | hello9 | world | drop this | 3 + 0 | 0 | hello0 | bar | 14 | hello14 | world | drop this | 2 + 0 | 0 | hello0 | bar | 32 | hello32 | world | drop this | 2 0 | 0 | hello0 | bar | 9 | hello9 | world | drop this | 3 - 1 | 1 | hello1 | bar | 15 | hello15 | world | drop this | 3 - 0 | 0 | hello0 | bar | 15 | hello15 | world | drop this | 3 - 1 | 1 | hello1 | bar | 21 | hello21 | world | drop this | 3 0 | 0 | hello0 | bar | 21 | hello21 | world | drop this | 3 - 1 | 1 | hello1 | bar | 27 | hello27 | world | drop this | 3 - 0 | 0 | hello0 | bar | 27 | hello27 | world | drop this | 3 - 1 | 1 | hello1 | bar | 33 | hello33 | world | drop this | 3 0 | 0 | hello0 | bar | 33 | hello33 | world | drop this | 3 - 1 | 1 | hello1 | bar | 39 | hello39 | world | drop this | 3 - 0 | 0 | hello0 | bar | 39 | hello39 | world | drop this | 3 - 1 | 1 | hello1 | bar | 45 | hello45 | world | drop this | 3 - 0 | 0 | hello0 | bar | 45 | hello45 | world | drop this | 3 - 1 | 1 | hello1 | bar | 51 | hello51 | world | drop this | 3 - 0 | 0 | hello0 | bar | 51 | hello51 | world | drop this | 3 + 0 | 0 | hello0 | bar | 10 | hello10 | world | drop this | 4 + 0 | 0 | hello0 | bar | 28 | hello28 | world | drop this | 4 + 0 | 0 | hello0 | bar | 52 | hello52 | world | drop this | 4 + 0 | 0 | hello0 | bar | 5 | hello5 | world | drop this | 5 + 0 | 0 | hello0 | bar | 11 | hello11 | world | drop this | 5 + 0 | 0 | hello0 | bar | 17 | hello17 | world | drop this | 5 + 1 | 1 | hello1 | bar | 14 | hello14 | world | drop this | 2 + 1 | 1 | hello1 | bar | 32 | hello32 | world | drop this | 2 + 1 | 1 | hello1 | bar | 9 | hello9 | world | drop this | 3 + 1 | 1 | hello1 | bar | 21 | hello21 | world | drop this | 3 + 1 | 1 | hello1 | bar | 33 | hello33 | world | drop this | 3 + 1 | 1 | hello1 | bar | 10 | hello10 | world | drop this | 4 + 1 | 1 | hello1 | bar | 28 | hello28 | world | drop this | 4 + 1 | 1 | hello1 | bar | 52 | hello52 | world | drop this | 4 + 1 | 1 | hello1 | bar | 5 | hello5 | world | drop this | 5 + 1 | 1 | hello1 | bar | 11 | hello11 | world | drop this | 5 + 1 | 1 | hello1 | bar | 17 | hello17 | world | drop this | 5 (81 rows) reset enable_indexscan; @@ -821,7 +824,7 @@ explain (costs off, timing off, summary off, analyze) select * from t, t1, pt wh Buckets: 262144 Batches: 1 Memory Usage: 2049kB -> Gather Motion 3:1 (slice3; segments: 3) (actual rows=2 loops=1) -> Seq Scan on t (actual rows=2 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (17 rows) select * from t, t1, pt where t1.t2 = t.t2 and t1.tid = ptid; @@ -837,12 +840,6 @@ select * from t, t1, pt where t1.t2 = t.t2 and t1.tid = ptid; 0 | 0 | hello0 | bar | 2 | 2 | hello2 | bar | 2 | hello2 | world | drop this | 2 1 | 1 | hello1 | bar | 2 | 2 | hello2 | bar | 8 | hello8 | world | drop this | 2 0 | 0 | hello0 | bar | 2 | 2 | hello2 | bar | 8 | hello8 | world | drop this | 2 - 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 - 0 | 0 | hello0 | bar | 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 - 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 - 0 | 0 | hello0 | bar | 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 - 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 - 0 | 0 | hello0 | bar | 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 1 | 1 | hello1 | bar | 2 | 2 | hello2 | bar | 20 | hello20 | world | drop this | 2 0 | 0 | hello0 | bar | 2 | 2 | hello2 | bar | 20 | hello20 | world | drop this | 2 1 | 1 | hello1 | bar | 2 | 2 | hello2 | bar | 26 | hello26 | world | drop this | 2 @@ -853,16 +850,22 @@ select * from t, t1, pt where t1.t2 = t.t2 and t1.tid = ptid; 0 | 0 | hello0 | bar | 2 | 2 | hello2 | bar | 44 | hello44 | world | drop this | 2 1 | 1 | hello1 | bar | 2 | 2 | hello2 | bar | 50 | hello50 | world | drop this | 2 0 | 0 | hello0 | bar | 2 | 2 | hello2 | bar | 50 | hello50 | world | drop this | 2 + 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 + 0 | 0 | hello0 | bar | 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 + 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 + 0 | 0 | hello0 | bar | 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 + 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 + 0 | 0 | hello0 | bar | 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 + 1 | 1 | hello1 | bar | 2 | 2 | hello2 | bar | 14 | hello14 | world | drop this | 2 + 0 | 0 | hello0 | bar | 2 | 2 | hello2 | bar | 14 | hello14 | world | drop this | 2 + 1 | 1 | hello1 | bar | 2 | 2 | hello2 | bar | 32 | hello32 | world | drop this | 2 + 0 | 0 | hello0 | bar | 2 | 2 | hello2 | bar | 32 | hello32 | world | drop this | 2 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 0 | 0 | hello0 | bar | 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 0 | 0 | hello0 | bar | 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 0 | 0 | hello0 | bar | 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 - 1 | 1 | hello1 | bar | 2 | 2 | hello2 | bar | 14 | hello14 | world | drop this | 2 - 0 | 0 | hello0 | bar | 2 | 2 | hello2 | bar | 14 | hello14 | world | drop this | 2 - 1 | 1 | hello1 | bar | 2 | 2 | hello2 | bar | 32 | hello32 | world | drop this | 2 - 0 | 0 | hello0 | bar | 2 | 2 | hello2 | bar | 32 | hello32 | world | drop this | 2 (36 rows) -- Both joined tables can be used for partition elimination. Only partitions @@ -895,21 +898,21 @@ explain (costs off, timing off, summary off, analyze) select * from t, t1, pt wh Index Cond: (ptid = t1.tid) Number of partitions to scan: 6 (out of 6) Partitions scanned: Avg 6.0 x 3 workers of 12 scans. Max 6 parts (seg0). - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (20 rows) select * from t, t1, pt where t1.tid = ptid and t.tid = ptid; dist | tid | t1 | t2 | dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid ------+-----+--------+-----+------+-----+--------+-----+------+---------+-------+-----------+------ - 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 - 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 + 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 + 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 + 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 - 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 - 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 + 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 + 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 - 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 - 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 - 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 + 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 + 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 (9 rows) rollback; @@ -921,8 +924,8 @@ begin; set local from_collapse_limit = 1; set local join_collapse_limit = 1; explain (costs off, timing off, summary off, analyze) select * from t1 inner join (select pt1.*, pt2.ptid as ptid2 from pt as pt1, pt as pt2 WHERE pt1.ptid <= pt2.ptid and pt1.dist = pt2.dist ) as ptx ON t1.dist = ptx.dist and t1.tid = ptx.ptid and t1.tid = ptx.ptid2; - QUERY PLAN -------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=2 loops=1) -> Nested Loop (actual rows=1 loops=1) Join Filter: true @@ -939,7 +942,7 @@ explain (costs off, timing off, summary off, analyze) select * from t1 inner joi Filter: ((ptid <= pt2.ptid) AND (ptid = pt2.ptid) AND (dist = pt2.dist)) Number of partitions to scan: 6 (out of 6) Partitions scanned: Avg 6.0 x 2 workers. Max 6 parts (seg0). - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (17 rows) rollback; @@ -969,7 +972,7 @@ explain (costs off, timing off, summary off, analyze) select * from pt, pt1 wher Index Cond: (pt1 = 'hello0'::text) Number of partitions to scan: 6 (out of 6) Partitions scanned: Avg 6.0 x 3 workers. Max 6 parts (seg0). - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (20 rows) select * from pt, pt1 where pt.ptid = pt1.ptid and pt.pt1 = 'hello0' order by pt1.dist; @@ -987,8 +990,8 @@ select * from pt, pt1 where pt.ptid = pt1.ptid and pt.pt1 = 'hello0' order by pt (9 rows) explain (costs off, timing off, summary off, analyze) select count(*) from pt, pt1 where pt.ptid = pt1.ptid and pt.pt1 = 'hello0'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- Finalize Aggregate (actual rows=1 loops=1) -> Gather Motion 3:1 (slice1; segments: 3) (actual rows=3 loops=1) -> Partial Aggregate (actual rows=1 loops=1) @@ -1007,8 +1010,8 @@ explain (costs off, timing off, summary off, analyze) select count(*) from pt, p Heap Fetches: 0 Number of partitions to scan: 6 (out of 6) Partitions scanned: Avg 6.0 x 3 workers. Max 6 parts (seg0). - Optimizer: Pivotal Optimizer (GPORCA) -(18 rows) + Optimizer: GPORCA +(19 rows) select count(*) from pt, pt1 where pt.ptid = pt1.ptid and pt.pt1 = 'hello0'; count @@ -1034,8 +1037,8 @@ set enable_hashjoin=off; set enable_seqscan=on; set enable_nestloop=on; explain (costs off, timing off, summary off, analyze) select * from t, pt where a = b; - QUERY PLAN ------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=5 loops=1) -> Hash Join (actual rows=3 loops=1) Hash Cond: (t.a = pt.b) @@ -1050,8 +1053,8 @@ explain (costs off, timing off, summary off, analyze) select * from t, pt where -> Dynamic Seq Scan on pt (actual rows=3 loops=1) Number of partitions to scan: 5 (out of 5) Partitions scanned: Avg 5.0 x 3 workers. Max 5 parts (seg0). - Optimizer: Pivotal Optimizer (GPORCA) -(14 rows) + Optimizer: GPORCA +(15 rows) select * from t, pt where a = b; id | a | id | b @@ -1100,7 +1103,7 @@ explain (costs off, timing off, summary off, analyze) select * from t, pt where Buckets: 524288 Batches: 1 Memory Usage: 4097kB -> Partition Selector (selector id: $0) (actual rows=4 loops=1) -> Seq Scan on t (actual rows=4 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) select * from t, pt where a = b; @@ -1148,13 +1151,13 @@ insert into fact1 select 1, i % 4 , 'CA', i + 10000 from generate_series (1,100) -- set gp_dynamic_partition_pruning=off; explain (costs off, timing off, summary off, analyze) select * from dim1 inner join fact1 on (dim1.pid=fact1.pid and dim1.code=fact1.code) order by fact1.u; - QUERY PLAN ----------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=50 loops=1) Merge Key: fact1.u -> Sort (actual rows=50 loops=1) Sort Key: fact1.u - Sort Method: quicksort Memory: 158kB + Sort Method: quicksort Memory: 78kB -> Hash Join (actual rows=50 loops=1) Hash Cond: ((fact1.pid = dim1.pid) AND (fact1.code = dim1.code)) Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 131072 buckets. @@ -1241,7 +1244,7 @@ explain (costs off, timing off, summary off, analyze) select * from dim1 inner j Merge Key: fact1.u -> Sort (actual rows=50 loops=1) Sort Key: fact1.u - Sort Method: quicksort Memory: 158kB + Sort Method: quicksort Memory: 78kB -> Hash Join (actual rows=50 loops=1) Hash Cond: ((fact1.pid = dim1.pid) AND (fact1.code = dim1.code)) Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 131072 buckets. @@ -1265,7 +1268,7 @@ explain (costs off, timing off, summary off, analyze) select * from dim1 inner j -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=3 loops=1) -> Seq Scan on dim1 (actual rows=3 loops=1) Optimizer: Postgres query optimizer -(27 rows) +(28 rows) select * from dim1 inner join fact1 on (dim1.pid=fact1.pid and dim1.code=fact1.code) order by fact1.u; dist | pid | code | t1 | dist | pid | code | u @@ -1327,13 +1330,13 @@ select * from dim1 inner join fact1 on (dim1.pid=fact1.pid and dim1.code=fact1.c -- set gp_dynamic_partition_pruning=off; explain (costs off, timing off, summary off, analyze) select * from dim1 inner join fact1 on (dim1.pid=fact1.pid) order by fact1.u; - QUERY PLAN ----------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=100 loops=1) Merge Key: fact1.u -> Sort (actual rows=100 loops=1) Sort Key: fact1.u - Sort Method: quicksort Memory: 166kB + Sort Method: quicksort Memory: 81kB -> Hash Join (actual rows=100 loops=1) Hash Cond: (fact1.pid = dim1.pid) Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 131072 buckets. @@ -1470,7 +1473,7 @@ explain (costs off, timing off, summary off, analyze) select * from dim1 inner j Merge Key: fact1.u -> Sort (actual rows=100 loops=1) Sort Key: fact1.u - Sort Method: quicksort Memory: 166kB + Sort Method: quicksort Memory: 81kB -> Hash Join (actual rows=100 loops=1) Hash Cond: (fact1.pid = dim1.pid) Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 131072 buckets. @@ -1607,8 +1610,8 @@ select * from dim1 inner join fact1 on (dim1.pid=fact1.pid) order by fact1.u; set gp_dynamic_partition_pruning=off; explain (costs off, timing off, summary off, analyze) select * from dim1 inner join fact1 on (dim1.dist = fact1.dist and dim1.code=fact1.code); - QUERY PLAN ----------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=200 loops=1) -> Hash Join (actual rows=200 loops=1) Hash Cond: ((fact1.dist = dim1.dist) AND (fact1.code = dim1.code)) @@ -1840,8 +1843,8 @@ select * from dim1 inner join fact1 on (dim1.dist = fact1.dist and dim1.code=fac set gp_dynamic_partition_pruning=on; explain (costs off, timing off, summary off, analyze) select * from dim1 inner join fact1 on (dim1.dist = fact1.dist and dim1.code=fact1.code); - QUERY PLAN ----------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=200 loops=1) -> Hash Join (actual rows=200 loops=1) Hash Cond: ((fact1.dist = dim1.dist) AND (fact1.code = dim1.code)) @@ -1865,7 +1868,7 @@ select * from dim1 inner join fact1 on (dim1.dist = fact1.dist and dim1.code=fac -> Partition Selector (selector id: $0) (actual rows=3 loops=1) -> Seq Scan on dim1 (actual rows=3 loops=1) Optimizer: Postgres query optimizer -(22 rows) +(23 rows) select * from dim1 inner join fact1 on (dim1.dist = fact1.dist and dim1.code=fact1.code); dist | pid | code | t1 | dist | pid | code | u @@ -2077,13 +2080,13 @@ select * from dim1 inner join fact1 on (dim1.dist = fact1.dist and dim1.code=fac -- set gp_dynamic_partition_pruning=off; explain (costs off, timing off, summary off, analyze) select * from dim1 inner join fact1 on (dim1.pid=fact1.pid) and fact1.code = 'OH' order by fact1.u; - QUERY PLAN ---------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=50 loops=1) Merge Key: fact1.u -> Sort (actual rows=50 loops=1) Sort Key: fact1.u - Sort Method: quicksort Memory: 158kB + Sort Method: quicksort Memory: 78kB -> Hash Join (actual rows=50 loops=1) Hash Cond: (fact1.pid = dim1.pid) Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 131072 buckets. @@ -2101,7 +2104,7 @@ explain (costs off, timing off, summary off, analyze) select * from dim1 inner j -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=3 loops=1) -> Seq Scan on dim1 (actual rows=3 loops=1) Optimizer: Postgres query optimizer -(21 rows) +(22 rows) select * from dim1 inner join fact1 on (dim1.pid=fact1.pid) and fact1.code = 'OH' order by fact1.u; dist | pid | code | t1 | dist | pid | code | u @@ -2166,7 +2169,7 @@ explain (costs off, timing off, summary off, analyze) select * from dim1 inner j Merge Key: fact1.u -> Sort (actual rows=50 loops=1) Sort Key: fact1.u - Sort Method: quicksort Memory: 158kB + Sort Method: quicksort Memory: 78kB -> Hash Join (actual rows=50 loops=1) Hash Cond: (fact1.pid = dim1.pid) Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 131072 buckets. @@ -2186,7 +2189,7 @@ explain (costs off, timing off, summary off, analyze) select * from dim1 inner j -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=3 loops=1) -> Seq Scan on dim1 (actual rows=3 loops=1) Optimizer: Postgres query optimizer -(23 rows) +(24 rows) select * from dim1 inner join fact1 on (dim1.pid=fact1.pid) and fact1.code = 'OH' order by fact1.u; dist | pid | code | t1 | dist | pid | code | u @@ -2248,15 +2251,15 @@ select * from dim1 inner join fact1 on (dim1.pid=fact1.pid) and fact1.code = 'OH -- set gp_dynamic_partition_pruning=off; explain (costs off, timing off, summary off, analyze) select fact1.code, count(*) from dim1 inner join fact1 on (dim1.pid=fact1.pid) group by 1 order by 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=2 loops=1) Merge Key: fact1.code -> GroupAggregate (actual rows=2 loops=1) Group Key: fact1.code -> Sort (actual rows=100 loops=1) Sort Key: fact1.code - Sort Method: quicksort Memory: 160kB + Sort Method: quicksort Memory: 76kB -> Redistribute Motion 3:3 (slice2; segments: 3) (actual rows=100 loops=1) Hash Key: fact1.code -> Hash Join (actual rows=100 loops=1) @@ -2280,7 +2283,7 @@ explain (costs off, timing off, summary off, analyze) select fact1.code, count(* -> Broadcast Motion 3:3 (slice3; segments: 3) (actual rows=3 loops=1) -> Seq Scan on dim1 (actual rows=3 loops=1) Optimizer: Postgres query optimizer -(29 rows) +(30 rows) select fact1.code, count(*) from dim1 inner join fact1 on (dim1.pid=fact1.pid) group by 1 order by 1; code | count @@ -2299,7 +2302,7 @@ explain (costs off, timing off, summary off, analyze) select fact1.code, count(* Group Key: fact1.code -> Sort (actual rows=100 loops=1) Sort Key: fact1.code - Sort Method: quicksort Memory: 160kB + Sort Method: quicksort Memory: 76kB -> Redistribute Motion 3:3 (slice2; segments: 3) (actual rows=100 loops=1) Hash Key: fact1.code -> Hash Join (actual rows=100 loops=1) @@ -2325,7 +2328,7 @@ explain (costs off, timing off, summary off, analyze) select fact1.code, count(* -> Broadcast Motion 3:3 (slice3; segments: 3) (actual rows=3 loops=1) -> Seq Scan on dim1 (actual rows=3 loops=1) Optimizer: Postgres query optimizer -(31 rows) +(32 rows) select fact1.code, count(*) from dim1 inner join fact1 on (dim1.pid=fact1.pid) group by 1 order by 1; code | count @@ -2440,8 +2443,8 @@ analyze b; analyze c; set gp_dynamic_partition_pruning = off; explain (costs off, timing off, summary off, analyze) select * from apart as a, b, c where a.t = b.t and a.id = c.id; - QUERY PLAN ---------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=5 loops=1) -> Hash Join (actual rows=3 loops=1) Hash Cond: (a.id = c.id) @@ -2460,23 +2463,23 @@ explain (costs off, timing off, summary off, analyze) select * from apart as a, Buckets: 262144 Batches: 1 Memory Usage: 2049kB -> Partition Selector (selector id: $0) (actual rows=8 loops=1) -> Seq Scan on c (actual rows=8 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) -(17 rows) + Optimizer: GPORCA +(19 rows) select * from apart as a, b, c where a.t = b.t and a.id = c.id; id | t | id | t | id | t ----+---+----+---+----+--- + 1 | 1 | 1 | 1 | 1 | 1 + 2 | 2 | 2 | 2 | 2 | 2 3 | 3 | 3 | 3 | 3 | 3 4 | 4 | 4 | 4 | 4 | 4 5 | 5 | 5 | 5 | 5 | 5 - 1 | 1 | 1 | 1 | 1 | 1 - 2 | 2 | 2 | 2 | 2 | 2 (5 rows) set gp_dynamic_partition_pruning = on; explain (costs off, timing off, summary off, analyze) select * from apart as a, b, c where a.t = b.t and a.id = c.id; - QUERY PLAN ---------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=5 loops=1) -> Hash Join (actual rows=3 loops=1) Hash Cond: (a.id = c.id) @@ -2495,17 +2498,17 @@ explain (costs off, timing off, summary off, analyze) select * from apart as a, Buckets: 262144 Batches: 1 Memory Usage: 2049kB -> Partition Selector (selector id: $0) (actual rows=8 loops=1) -> Seq Scan on c (actual rows=8 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) -(17 rows) + Optimizer: GPORCA +(19 rows) select * from apart as a, b, c where a.t = b.t and a.id = c.id; id | t | id | t | id | t ----+---+----+---+----+--- + 2 | 2 | 2 | 2 | 2 | 2 3 | 3 | 3 | 3 | 3 | 3 4 | 4 | 4 | 4 | 4 | 4 5 | 5 | 5 | 5 | 5 | 5 1 | 1 | 1 | 1 | 1 | 1 - 2 | 2 | 2 | 2 | 2 | 2 (5 rows) -- @@ -2530,6 +2533,8 @@ analyze jpat; -- Known_opt_diff: MPP-21323 -- end_ignore explain (costs off, timing off, summary off, analyze) select * from (select count(*) over (order by a rows between 1 preceding and 1 following), a, b from jpat)jpat inner join pat using(b); +NOTICE: One or more columns in the following table(s) do not have statistics: pat +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN ------------------------------------------------------------------------------------ Hash Join (actual rows=1 loops=1) @@ -2541,7 +2546,7 @@ explain (costs off, timing off, summary off, analyze) select * from (select coun Merge Key: jpat.a -> Sort (actual rows=1 loops=1) Sort Key: jpat.a - Sort Method: quicksort Memory: 150kB + Sort Method: quicksort Memory: 75kB -> Seq Scan on jpat (actual rows=1 loops=1) -> Hash (actual rows=10 loops=1) Buckets: 131072 Batches: 1 Memory Usage: 1025kB @@ -2549,10 +2554,12 @@ explain (costs off, timing off, summary off, analyze) select * from (select coun -> Dynamic Seq Scan on pat (actual rows=5 loops=1) Number of partitions to scan: 5 (out of 5) Partitions scanned: Avg 5.0 x 3 workers. Max 5 parts (seg0). - Optimizer: Pivotal Optimizer (GPORCA) -(17 rows) + Optimizer: GPORCA +(18 rows) select * from (select count(*) over (order by a rows between 1 preceding and 1 following), a, b from jpat)jpat inner join pat using(b); +NOTICE: One or more columns in the following table(s) do not have statistics: pat +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. b | count | a | a ------------+-------+---+--- 01-02-2010 | 1 | 1 | 1 @@ -2593,8 +2600,8 @@ analyze pt; -- Prune on the simple partition columns, but not on the expression explain (analyze, costs off, timing off, summary off) select * from pt, t where t.id = pt.id; - QUERY PLAN --------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=2 loops=1) -> Hash Join (actual rows=1 loops=1) Hash Cond: (pt.id = t.id) @@ -2611,13 +2618,13 @@ select * from pt, t where t.id = pt.id; -> Partition Selector (selector id: $0) (actual rows=1 loops=1) -> Seq Scan on t (actual rows=1 loops=1) Optimizer: Postgres query optimizer -(15 rows) +(16 rows) insert into t values (4, 4), (6, 6), (8, 8), (10, 10); explain (analyze, costs off, timing off, summary off) select * from pt, t where t.id = pt.id; - QUERY PLAN --------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=4 loops=1) -> Hash Join (actual rows=2 loops=1) Hash Cond: (pt.id = t.id) @@ -2634,14 +2641,14 @@ select * from pt, t where t.id = pt.id; -> Partition Selector (selector id: $0) (actual rows=3 loops=1) -> Seq Scan on t (actual rows=3 loops=1) Optimizer: Postgres query optimizer -(15 rows) +(16 rows) -- Plan-time pruning based on the 'id' partitioning column, and -- run-time join pruning based on the expression explain (analyze, costs off, timing off, summary off) select * from pt, t where pt.id = 4 and t.id = 4 and (t.b % 2) = (pt.b % 2); - QUERY PLAN --------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------- Gather Motion 1:1 (slice1; segments: 1) (actual rows=1 loops=1) -> Hash Join (actual rows=1 loops=1) Hash Cond: ((pt.b % 2) = (t.b % 2)) @@ -2659,14 +2666,14 @@ select * from pt, t where pt.id = 4 and t.id = 4 and (t.b % 2) = (pt.b % 2); Filter: (id = 4) Rows Removed by Filter: 2 Optimizer: Postgres query optimizer -(16 rows) +(17 rows) -- Mixed case insert into pt values (4, 5); explain (analyze, costs off, timing off, summary off) select * from pt, t where t.id = pt.id and (t.b % 2) = (pt.b % 2); - QUERY PLAN --------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=4 loops=1) -> Hash Join (actual rows=2 loops=1) Hash Cond: ((pt.id = t.id) AND ((pt.b % 2) = (t.b % 2))) @@ -2683,7 +2690,7 @@ select * from pt, t where t.id = pt.id and (t.b % 2) = (pt.b % 2); -> Partition Selector (selector id: $0) (actual rows=3 loops=1) -> Seq Scan on t (actual rows=3 loops=1) Optimizer: Postgres query optimizer -(15 rows) +(16 rows) -- -- Join pruning on an inequality qual @@ -2711,8 +2718,8 @@ analyze t; analyze pt; explain (analyze, costs off, timing off, summary off) select * from pt, t where t.dist = pt.dist and t.tid < pt.ptid; - QUERY PLAN --------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=11 loops=1) -> Hash Join (actual rows=11 loops=1) Hash Cond: (pt.dist = t.dist) @@ -2726,8 +2733,8 @@ select * from pt, t where t.dist = pt.dist and t.tid < pt.ptid; Buckets: 524288 Batches: 1 Memory Usage: 4097kB -> Partition Selector (selector id: $0) (actual rows=2 loops=1) -> Seq Scan on t (actual rows=2 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) -(13 rows) + Optimizer: GPORCA +(14 rows) -- -- Test join pruning with a MergeAppend @@ -2778,6 +2785,6 @@ select * from pt, t where t.dist = pt.dist and t.tid = pt.ptid order by t.tid, t Buckets: 262144 Batches: 1 Memory Usage: 2050kB -> Partition Selector (selector id: $0) (cost=0.00..431.00 rows=33 width=12) (actual rows=37 loops=1) -> Seq Scan on t (cost=0.00..431.00 rows=33 width=12) (actual rows=37 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (16 rows) diff --git a/src/test/regress/expected/gporca_optimizer.out b/src/test/regress/expected/gporca_optimizer.out index b8b83e01ab2..779b4d3e38a 100644 --- a/src/test/regress/expected/gporca_optimizer.out +++ b/src/test/regress/expected/gporca_optimizer.out @@ -22,6 +22,10 @@ set optimizer_segments = 3; set optimizer_enable_master_only_queries = on; -- master only tables create schema orca; +-- start_ignore +GRANT ALL ON SCHEMA orca TO PUBLIC; +SET search_path to orca, public; +-- end_ignore create table orca.r(); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause, and no column type is suitable for a distribution key. Creating a NULL policy entry. set allow_system_table_mods=true; @@ -1920,12 +1924,12 @@ select b from orca.r group by b having count(*) > 2; select b from orca.r group by b having count(*) <= avg(a) + (select count(*) from orca.s where s.c = r.b); b --- - 3 + 1 2 + 3 + 4 5 6 - 1 - 4 (6 rows) select sum(a) from orca.r group by b having count(*) > 2 order by b+1; @@ -2167,14 +2171,14 @@ analyze orca.bar2; select x2 from orca.foo where x1 in (select x2 from orca.bar1); x2 ---- - 4 - 6 - 8 - 10 3 + 4 5 - 7 + 8 9 + 6 + 7 + 10 11 (9 rows) @@ -2241,46 +2245,46 @@ select distinct 1, sum(x1) from orca.foo; select distinct x1, rank() over(order by x1) from (select x1 from orca.foo order by x1) x; --order none x1 | rank ----+------ + 9 | 9 + 10 | 10 1 | 1 + 6 | 6 + 8 | 8 2 | 2 3 | 3 4 | 4 5 | 5 - 6 | 6 7 | 7 - 8 | 8 - 9 | 9 - 10 | 10 (10 rows) select distinct x1, sum(x3) from orca.foo group by x1,x2; x1 | sum ----+----- + 5 | 7 + 6 | 8 + 9 | 11 + 10 | 12 1 | 3 2 | 4 3 | 5 4 | 6 - 5 | 7 - 6 | 8 7 | 9 8 | 10 - 9 | 11 - 10 | 12 (10 rows) select distinct s from (select sum(x2) s from orca.foo group by x1) x; s ---- - 3 - 5 - 7 - 9 - 11 2 + 3 4 - 6 + 7 8 + 5 + 6 + 9 10 + 11 (10 rows) select * from orca.foo a where a.x1 = (select distinct sum(b.x1)+avg(b.x1) sa from orca.bar1 b group by b.x3 order by sa limit 1); @@ -2299,15 +2303,15 @@ select distinct a.x1 from orca.foo a where a.x1 <= (select distinct sum(b.x1)+av select * from orca.foo a where a.x1 = (select distinct b.x1 from orca.bar1 b where b.x1=a.x1 limit 1); x1 | x2 | x3 ----+----+---- - 1 | 2 | 3 - 3 | 4 | 5 - 5 | 6 | 7 - 7 | 8 | 9 - 9 | 10 | 11 2 | 3 | 4 + 3 | 4 | 5 4 | 5 | 6 - 6 | 7 | 8 + 7 | 8 | 9 8 | 9 | 10 + 1 | 2 | 3 + 5 | 6 | 7 + 6 | 7 | 8 + 9 | 10 | 11 10 | 11 | 12 (10 rows) @@ -2316,15 +2320,15 @@ with cte1 as (select * from orca.foo) select a.x1+1 from (select * from cte1) a ?column? ---------- 3 + 4 5 - 7 + 8 9 - 11 2 - 4 6 - 8 + 7 10 + 11 (10 rows) select count(*)+1 from orca.bar1 b where b.x1 < any (with cte1 as (select * from orca.foo) select a.x1+1 from (select * from cte1) a group by a.x1); @@ -2399,9 +2403,9 @@ explain select case when bar1.x2 = bar2.x2 then coalesce((select 1 from orca.foo from orca.bar1 inner join orca.bar2 on (bar1.x2 = bar2.x2) order by bar1.x1; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ - Sort (cost=0.00..1765423.13 rows=20 width=8) + Sort (cost=0.00..1765423.18 rows=20 width=8) Sort Key: bar1.x1 - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1765423.13 rows=20 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1765423.18 rows=20 width=8) -> Hash Join (cost=0.00..862.00 rows=7 width=12) Hash Cond: (bar1.x2 = bar2.x2) -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=7 width=8) @@ -2419,7 +2423,7 @@ from orca.bar1 inner join orca.bar2 on (bar1.x2 = bar2.x2) order by bar1.x1; -> Materialize (cost=0.00..431.00 rows=10 width=4) -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..431.00 rows=10 width=4) -> Seq Scan on foo (cost=0.00..431.00 rows=4 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (21 rows) select case when bar1.x2 = bar2.x2 then coalesce((select 1 from orca.foo where bar1.x2 = bar2.x2 and bar1.x2 = random() and foo.x2 = bar2.x2),0) else 1 end as col1, bar1.x1 @@ -2462,30 +2466,30 @@ select * from orca.r, orca.s where r.a=s.c; a | b | c | d ---+---+---+--- 2 | 2 | 2 | 0 + 3 | 0 | 3 | 1 4 | 1 | 4 | 0 - 6 | 0 | 6 | 0 2 | 2 | 2 | 1 + 3 | 0 | 3 | 0 4 | 1 | 4 | 1 - 6 | 0 | 6 | 1 2 | 2 | 2 | 0 + 3 | 0 | 3 | 1 4 | 1 | 4 | 0 - 6 | 0 | 6 | 0 2 | 2 | 2 | 1 + 3 | 0 | 3 | 0 4 | 1 | 4 | 1 - 6 | 0 | 6 | 1 2 | 2 | 2 | 0 - 1 | 1 | 1 | 1 - 3 | 0 | 3 | 1 5 | 2 | 5 | 1 - 1 | 1 | 1 | 0 - 3 | 0 | 3 | 0 + 6 | 0 | 6 | 0 5 | 2 | 5 | 0 - 1 | 1 | 1 | 1 - 3 | 0 | 3 | 1 + 6 | 0 | 6 | 1 5 | 2 | 5 | 1 - 1 | 1 | 1 | 0 - 3 | 0 | 3 | 0 + 6 | 0 | 6 | 0 5 | 2 | 5 | 0 + 6 | 0 | 6 | 1 + 1 | 1 | 1 | 1 + 1 | 1 | 1 | 0 + 1 | 1 | 1 | 1 + 1 | 1 | 1 | 0 1 | 1 | 1 | 1 (26 rows) @@ -2493,647 +2497,637 @@ select * from orca.r, orca.s where r.a=s.c; select * from orca.r, orca.s where r.as.c; a | b | c | d ----+---+---+--- - 1 | 1 | 1 | 1 - 3 | 0 | 1 | 1 - 5 | 2 | 1 | 1 - 7 | 1 | 1 | 1 - 9 | 0 | 1 | 1 - 11 | 2 | 1 | 1 - 13 | 1 | 1 | 1 - 15 | 0 | 1 | 1 - 17 | 2 | 1 | 1 - 19 | 1 | 1 | 1 - 2 | 2 | 1 | 1 - 4 | 1 | 1 | 1 - 6 | 0 | 1 | 1 - 8 | 2 | 1 | 1 - 10 | 1 | 1 | 1 - 12 | 0 | 1 | 1 - 14 | 2 | 1 | 1 - 16 | 1 | 1 | 1 - 18 | 0 | 1 | 1 - 20 | 2 | 1 | 1 - 1 | 1 | 3 | 1 - 3 | 0 | 3 | 1 - 5 | 2 | 3 | 1 - 7 | 1 | 3 | 1 - 9 | 0 | 3 | 1 - 11 | 2 | 3 | 1 - 13 | 1 | 3 | 1 - 15 | 0 | 3 | 1 - 17 | 2 | 3 | 1 - 19 | 1 | 3 | 1 - 2 | 2 | 3 | 1 - 4 | 1 | 3 | 1 - 6 | 0 | 3 | 1 - 8 | 2 | 3 | 1 - 10 | 1 | 3 | 1 - 12 | 0 | 3 | 1 - 14 | 2 | 3 | 1 - 16 | 1 | 3 | 1 - 18 | 0 | 3 | 1 - 20 | 2 | 3 | 1 - 1 | 1 | 5 | 1 - 3 | 0 | 5 | 1 - 5 | 2 | 5 | 1 - 7 | 1 | 5 | 1 - 9 | 0 | 5 | 1 - 11 | 2 | 5 | 1 - 13 | 1 | 5 | 1 - 15 | 0 | 5 | 1 - 17 | 2 | 5 | 1 - 19 | 1 | 5 | 1 2 | 2 | 5 | 1 + 3 | 0 | 5 | 1 4 | 1 | 5 | 1 - 6 | 0 | 5 | 1 + 7 | 1 | 5 | 1 8 | 2 | 5 | 1 - 10 | 1 | 5 | 1 - 12 | 0 | 5 | 1 - 14 | 2 | 5 | 1 16 | 1 | 5 | 1 18 | 0 | 5 | 1 - 20 | 2 | 5 | 1 - 1 | 1 | 1 | 0 - 3 | 0 | 1 | 0 - 5 | 2 | 1 | 0 - 7 | 1 | 1 | 0 - 9 | 0 | 1 | 0 - 11 | 2 | 1 | 0 - 13 | 1 | 1 | 0 - 15 | 0 | 1 | 0 - 17 | 2 | 1 | 0 - 19 | 1 | 1 | 0 - 2 | 2 | 1 | 0 - 4 | 1 | 1 | 0 - 6 | 0 | 1 | 0 - 8 | 2 | 1 | 0 - 10 | 1 | 1 | 0 - 12 | 0 | 1 | 0 - 14 | 2 | 1 | 0 - 16 | 1 | 1 | 0 - 18 | 0 | 1 | 0 - 20 | 2 | 1 | 0 - 1 | 1 | 3 | 0 - 3 | 0 | 3 | 0 - 5 | 2 | 3 | 0 - 7 | 1 | 3 | 0 - 9 | 0 | 3 | 0 - 11 | 2 | 3 | 0 - 13 | 1 | 3 | 0 - 15 | 0 | 3 | 0 - 17 | 2 | 3 | 0 - 19 | 1 | 3 | 0 - 2 | 2 | 3 | 0 - 4 | 1 | 3 | 0 - 6 | 0 | 3 | 0 - 8 | 2 | 3 | 0 - 10 | 1 | 3 | 0 - 12 | 0 | 3 | 0 - 14 | 2 | 3 | 0 - 16 | 1 | 3 | 0 - 18 | 0 | 3 | 0 - 20 | 2 | 3 | 0 - 1 | 1 | 5 | 0 + 19 | 1 | 5 | 1 + 2 | 2 | 6 | 0 + 3 | 0 | 6 | 0 + 4 | 1 | 6 | 0 + 7 | 1 | 6 | 0 + 8 | 2 | 6 | 0 + 16 | 1 | 6 | 0 + 18 | 0 | 6 | 0 + 19 | 1 | 6 | 0 + 2 | 2 | 5 | 0 3 | 0 | 5 | 0 - 5 | 2 | 5 | 0 + 4 | 1 | 5 | 0 7 | 1 | 5 | 0 - 9 | 0 | 5 | 0 - 11 | 2 | 5 | 0 - 13 | 1 | 5 | 0 - 15 | 0 | 5 | 0 - 17 | 2 | 5 | 0 + 8 | 2 | 5 | 0 + 16 | 1 | 5 | 0 + 18 | 0 | 5 | 0 19 | 1 | 5 | 0 + 2 | 2 | 6 | 1 + 3 | 0 | 6 | 1 + 4 | 1 | 6 | 1 + 7 | 1 | 6 | 1 + 8 | 2 | 6 | 1 + 16 | 1 | 6 | 1 + 18 | 0 | 6 | 1 + 19 | 1 | 6 | 1 + 2 | 2 | 5 | 1 + 3 | 0 | 5 | 1 + 4 | 1 | 5 | 1 + 7 | 1 | 5 | 1 + 8 | 2 | 5 | 1 + 16 | 1 | 5 | 1 + 18 | 0 | 5 | 1 + 19 | 1 | 5 | 1 + 2 | 2 | 6 | 0 + 3 | 0 | 6 | 0 + 4 | 1 | 6 | 0 + 7 | 1 | 6 | 0 + 8 | 2 | 6 | 0 + 16 | 1 | 6 | 0 + 18 | 0 | 6 | 0 + 19 | 1 | 6 | 0 2 | 2 | 5 | 0 + 3 | 0 | 5 | 0 4 | 1 | 5 | 0 - 6 | 0 | 5 | 0 + 7 | 1 | 5 | 0 8 | 2 | 5 | 0 - 10 | 1 | 5 | 0 - 12 | 0 | 5 | 0 - 14 | 2 | 5 | 0 16 | 1 | 5 | 0 18 | 0 | 5 | 0 - 20 | 2 | 5 | 0 - 1 | 1 | 1 | 1 + 19 | 1 | 5 | 0 + 2 | 2 | 6 | 1 + 3 | 0 | 6 | 1 + 4 | 1 | 6 | 1 + 7 | 1 | 6 | 1 + 8 | 2 | 6 | 1 + 16 | 1 | 6 | 1 + 18 | 0 | 6 | 1 + 19 | 1 | 6 | 1 + 2 | 2 | 1 | 1 3 | 0 | 1 | 1 - 5 | 2 | 1 | 1 + 4 | 1 | 1 | 1 7 | 1 | 1 | 1 - 9 | 0 | 1 | 1 - 11 | 2 | 1 | 1 - 13 | 1 | 1 | 1 - 15 | 0 | 1 | 1 - 17 | 2 | 1 | 1 - 19 | 1 | 1 | 1 - 2 | 2 | 1 | 1 - 4 | 1 | 1 | 1 - 6 | 0 | 1 | 1 8 | 2 | 1 | 1 - 10 | 1 | 1 | 1 - 12 | 0 | 1 | 1 - 14 | 2 | 1 | 1 16 | 1 | 1 | 1 18 | 0 | 1 | 1 - 20 | 2 | 1 | 1 - 1 | 1 | 3 | 1 - 3 | 0 | 3 | 1 - 5 | 2 | 3 | 1 - 7 | 1 | 3 | 1 - 9 | 0 | 3 | 1 - 11 | 2 | 3 | 1 - 13 | 1 | 3 | 1 - 15 | 0 | 3 | 1 - 17 | 2 | 3 | 1 - 19 | 1 | 3 | 1 - 2 | 2 | 3 | 1 - 4 | 1 | 3 | 1 - 6 | 0 | 3 | 1 - 8 | 2 | 3 | 1 - 10 | 1 | 3 | 1 - 12 | 0 | 3 | 1 - 14 | 2 | 3 | 1 - 16 | 1 | 3 | 1 - 18 | 0 | 3 | 1 - 20 | 2 | 3 | 1 - 1 | 1 | 5 | 1 - 3 | 0 | 5 | 1 - 5 | 2 | 5 | 1 - 7 | 1 | 5 | 1 - 9 | 0 | 5 | 1 - 11 | 2 | 5 | 1 - 13 | 1 | 5 | 1 - 15 | 0 | 5 | 1 - 17 | 2 | 5 | 1 - 19 | 1 | 5 | 1 - 2 | 2 | 5 | 1 - 4 | 1 | 5 | 1 - 6 | 0 | 5 | 1 - 8 | 2 | 5 | 1 - 10 | 1 | 5 | 1 - 12 | 0 | 5 | 1 - 14 | 2 | 5 | 1 - 16 | 1 | 5 | 1 - 18 | 0 | 5 | 1 - 20 | 2 | 5 | 1 - 1 | 1 | 1 | 0 - 3 | 0 | 1 | 0 - 5 | 2 | 1 | 0 - 7 | 1 | 1 | 0 - 9 | 0 | 1 | 0 - 11 | 2 | 1 | 0 - 13 | 1 | 1 | 0 - 15 | 0 | 1 | 0 - 17 | 2 | 1 | 0 - 19 | 1 | 1 | 0 + 19 | 1 | 1 | 1 + 2 | 2 | 0 | 1 + 3 | 0 | 0 | 1 + 4 | 1 | 0 | 1 + 7 | 1 | 0 | 1 + 8 | 2 | 0 | 1 + 16 | 1 | 0 | 1 + 18 | 0 | 0 | 1 + 19 | 1 | 0 | 1 2 | 2 | 1 | 0 + 3 | 0 | 1 | 0 4 | 1 | 1 | 0 - 6 | 0 | 1 | 0 + 7 | 1 | 1 | 0 8 | 2 | 1 | 0 - 10 | 1 | 1 | 0 - 12 | 0 | 1 | 0 - 14 | 2 | 1 | 0 16 | 1 | 1 | 0 18 | 0 | 1 | 0 - 20 | 2 | 1 | 0 - 1 | 1 | 3 | 0 - 3 | 0 | 3 | 0 - 5 | 2 | 3 | 0 - 7 | 1 | 3 | 0 - 9 | 0 | 3 | 0 - 11 | 2 | 3 | 0 - 13 | 1 | 3 | 0 - 15 | 0 | 3 | 0 - 17 | 2 | 3 | 0 - 19 | 1 | 3 | 0 - 2 | 2 | 3 | 0 - 4 | 1 | 3 | 0 - 6 | 0 | 3 | 0 - 8 | 2 | 3 | 0 - 10 | 1 | 3 | 0 - 12 | 0 | 3 | 0 - 14 | 2 | 3 | 0 - 16 | 1 | 3 | 0 - 18 | 0 | 3 | 0 - 20 | 2 | 3 | 0 - 1 | 1 | 5 | 0 - 3 | 0 | 5 | 0 - 5 | 2 | 5 | 0 - 7 | 1 | 5 | 0 - 9 | 0 | 5 | 0 - 11 | 2 | 5 | 0 - 13 | 1 | 5 | 0 - 15 | 0 | 5 | 0 - 17 | 2 | 5 | 0 - 19 | 1 | 5 | 0 - 2 | 2 | 5 | 0 - 4 | 1 | 5 | 0 - 6 | 0 | 5 | 0 - 8 | 2 | 5 | 0 - 10 | 1 | 5 | 0 - 12 | 0 | 5 | 0 - 14 | 2 | 5 | 0 - 16 | 1 | 5 | 0 - 18 | 0 | 5 | 0 - 20 | 2 | 5 | 0 - 1 | 1 | 1 | 1 + 19 | 1 | 1 | 0 + 2 | 2 | 0 | 0 + 3 | 0 | 0 | 0 + 4 | 1 | 0 | 0 + 7 | 1 | 0 | 0 + 8 | 2 | 0 | 0 + 16 | 1 | 0 | 0 + 18 | 0 | 0 | 0 + 19 | 1 | 0 | 0 + 2 | 2 | 1 | 1 3 | 0 | 1 | 1 - 5 | 2 | 1 | 1 + 4 | 1 | 1 | 1 7 | 1 | 1 | 1 - 9 | 0 | 1 | 1 - 11 | 2 | 1 | 1 - 13 | 1 | 1 | 1 - 15 | 0 | 1 | 1 - 17 | 2 | 1 | 1 + 8 | 2 | 1 | 1 + 16 | 1 | 1 | 1 + 18 | 0 | 1 | 1 19 | 1 | 1 | 1 + 2 | 2 | 0 | 1 + 3 | 0 | 0 | 1 + 4 | 1 | 0 | 1 + 7 | 1 | 0 | 1 + 8 | 2 | 0 | 1 + 16 | 1 | 0 | 1 + 18 | 0 | 0 | 1 + 19 | 1 | 0 | 1 + 2 | 2 | 1 | 0 + 3 | 0 | 1 | 0 + 4 | 1 | 1 | 0 + 7 | 1 | 1 | 0 + 8 | 2 | 1 | 0 + 16 | 1 | 1 | 0 + 18 | 0 | 1 | 0 + 19 | 1 | 1 | 0 + 2 | 2 | 0 | 0 + 3 | 0 | 0 | 0 + 4 | 1 | 0 | 0 + 7 | 1 | 0 | 0 + 8 | 2 | 0 | 0 + 16 | 1 | 0 | 0 + 18 | 0 | 0 | 0 + 19 | 1 | 0 | 0 2 | 2 | 1 | 1 + 3 | 0 | 1 | 1 4 | 1 | 1 | 1 - 6 | 0 | 1 | 1 + 7 | 1 | 1 | 1 8 | 2 | 1 | 1 - 10 | 1 | 1 | 1 - 12 | 0 | 1 | 1 - 14 | 2 | 1 | 1 16 | 1 | 1 | 1 18 | 0 | 1 | 1 - 20 | 2 | 1 | 1 - 1 | 1 | 2 | 0 - 3 | 0 | 2 | 0 - 5 | 2 | 2 | 0 - 7 | 1 | 2 | 0 - 9 | 0 | 2 | 0 - 11 | 2 | 2 | 0 - 13 | 1 | 2 | 0 - 15 | 0 | 2 | 0 - 17 | 2 | 2 | 0 - 19 | 1 | 2 | 0 + 19 | 1 | 1 | 1 2 | 2 | 2 | 0 + 3 | 0 | 2 | 0 4 | 1 | 2 | 0 - 6 | 0 | 2 | 0 + 7 | 1 | 2 | 0 8 | 2 | 2 | 0 - 10 | 1 | 2 | 0 - 12 | 0 | 2 | 0 - 14 | 2 | 2 | 0 16 | 1 | 2 | 0 18 | 0 | 2 | 0 - 20 | 2 | 2 | 0 - 1 | 1 | 4 | 0 + 19 | 1 | 2 | 0 + 2 | 2 | 3 | 1 + 3 | 0 | 3 | 1 + 4 | 1 | 3 | 1 + 7 | 1 | 3 | 1 + 8 | 2 | 3 | 1 + 16 | 1 | 3 | 1 + 18 | 0 | 3 | 1 + 19 | 1 | 3 | 1 + 2 | 2 | 4 | 0 3 | 0 | 4 | 0 - 5 | 2 | 4 | 0 + 4 | 1 | 4 | 0 7 | 1 | 4 | 0 - 9 | 0 | 4 | 0 - 11 | 2 | 4 | 0 - 13 | 1 | 4 | 0 - 15 | 0 | 4 | 0 - 17 | 2 | 4 | 0 + 8 | 2 | 4 | 0 + 16 | 1 | 4 | 0 + 18 | 0 | 4 | 0 19 | 1 | 4 | 0 + 2 | 2 | 2 | 1 + 3 | 0 | 2 | 1 + 4 | 1 | 2 | 1 + 7 | 1 | 2 | 1 + 8 | 2 | 2 | 1 + 16 | 1 | 2 | 1 + 18 | 0 | 2 | 1 + 19 | 1 | 2 | 1 + 2 | 2 | 3 | 0 + 3 | 0 | 3 | 0 + 4 | 1 | 3 | 0 + 7 | 1 | 3 | 0 + 8 | 2 | 3 | 0 + 16 | 1 | 3 | 0 + 18 | 0 | 3 | 0 + 19 | 1 | 3 | 0 + 2 | 2 | 4 | 1 + 3 | 0 | 4 | 1 + 4 | 1 | 4 | 1 + 7 | 1 | 4 | 1 + 8 | 2 | 4 | 1 + 16 | 1 | 4 | 1 + 18 | 0 | 4 | 1 + 19 | 1 | 4 | 1 + 2 | 2 | 2 | 0 + 3 | 0 | 2 | 0 + 4 | 1 | 2 | 0 + 7 | 1 | 2 | 0 + 8 | 2 | 2 | 0 + 16 | 1 | 2 | 0 + 18 | 0 | 2 | 0 + 19 | 1 | 2 | 0 + 2 | 2 | 3 | 1 + 3 | 0 | 3 | 1 + 4 | 1 | 3 | 1 + 7 | 1 | 3 | 1 + 8 | 2 | 3 | 1 + 16 | 1 | 3 | 1 + 18 | 0 | 3 | 1 + 19 | 1 | 3 | 1 2 | 2 | 4 | 0 + 3 | 0 | 4 | 0 4 | 1 | 4 | 0 - 6 | 0 | 4 | 0 + 7 | 1 | 4 | 0 8 | 2 | 4 | 0 - 10 | 1 | 4 | 0 - 12 | 0 | 4 | 0 - 14 | 2 | 4 | 0 16 | 1 | 4 | 0 18 | 0 | 4 | 0 - 20 | 2 | 4 | 0 - 1 | 1 | 6 | 0 - 3 | 0 | 6 | 0 - 5 | 2 | 6 | 0 - 7 | 1 | 6 | 0 - 9 | 0 | 6 | 0 - 11 | 2 | 6 | 0 - 13 | 1 | 6 | 0 - 15 | 0 | 6 | 0 - 17 | 2 | 6 | 0 - 19 | 1 | 6 | 0 - 2 | 2 | 6 | 0 - 4 | 1 | 6 | 0 - 6 | 0 | 6 | 0 - 8 | 2 | 6 | 0 - 10 | 1 | 6 | 0 - 12 | 0 | 6 | 0 - 14 | 2 | 6 | 0 - 16 | 1 | 6 | 0 - 18 | 0 | 6 | 0 - 20 | 2 | 6 | 0 - 1 | 1 | 0 | 1 - 3 | 0 | 0 | 1 - 5 | 2 | 0 | 1 - 7 | 1 | 0 | 1 - 9 | 0 | 0 | 1 - 11 | 2 | 0 | 1 - 13 | 1 | 0 | 1 - 15 | 0 | 0 | 1 - 17 | 2 | 0 | 1 - 19 | 1 | 0 | 1 - 2 | 2 | 0 | 1 - 4 | 1 | 0 | 1 - 6 | 0 | 0 | 1 - 8 | 2 | 0 | 1 - 10 | 1 | 0 | 1 - 12 | 0 | 0 | 1 - 14 | 2 | 0 | 1 - 16 | 1 | 0 | 1 - 18 | 0 | 0 | 1 - 20 | 2 | 0 | 1 - 1 | 1 | 2 | 1 - 3 | 0 | 2 | 1 - 5 | 2 | 2 | 1 - 7 | 1 | 2 | 1 - 9 | 0 | 2 | 1 - 11 | 2 | 2 | 1 - 13 | 1 | 2 | 1 - 15 | 0 | 2 | 1 - 17 | 2 | 2 | 1 - 19 | 1 | 2 | 1 + 19 | 1 | 4 | 0 2 | 2 | 2 | 1 + 3 | 0 | 2 | 1 4 | 1 | 2 | 1 - 6 | 0 | 2 | 1 + 7 | 1 | 2 | 1 8 | 2 | 2 | 1 - 10 | 1 | 2 | 1 - 12 | 0 | 2 | 1 - 14 | 2 | 2 | 1 16 | 1 | 2 | 1 18 | 0 | 2 | 1 - 20 | 2 | 2 | 1 - 1 | 1 | 4 | 1 - 3 | 0 | 4 | 1 - 5 | 2 | 4 | 1 - 7 | 1 | 4 | 1 - 9 | 0 | 4 | 1 - 11 | 2 | 4 | 1 - 13 | 1 | 4 | 1 - 15 | 0 | 4 | 1 - 17 | 2 | 4 | 1 - 19 | 1 | 4 | 1 + 19 | 1 | 2 | 1 + 2 | 2 | 3 | 0 + 3 | 0 | 3 | 0 + 4 | 1 | 3 | 0 + 7 | 1 | 3 | 0 + 8 | 2 | 3 | 0 + 16 | 1 | 3 | 0 + 18 | 0 | 3 | 0 + 19 | 1 | 3 | 0 2 | 2 | 4 | 1 + 3 | 0 | 4 | 1 4 | 1 | 4 | 1 - 6 | 0 | 4 | 1 + 7 | 1 | 4 | 1 8 | 2 | 4 | 1 - 10 | 1 | 4 | 1 - 12 | 0 | 4 | 1 - 14 | 2 | 4 | 1 16 | 1 | 4 | 1 18 | 0 | 4 | 1 - 20 | 2 | 4 | 1 + 19 | 1 | 4 | 1 + 2 | 2 | 2 | 0 + 3 | 0 | 2 | 0 + 4 | 1 | 2 | 0 + 7 | 1 | 2 | 0 + 8 | 2 | 2 | 0 + 16 | 1 | 2 | 0 + 18 | 0 | 2 | 0 + 19 | 1 | 2 | 0 + 1 | 1 | 5 | 1 + 12 | 0 | 5 | 1 + 15 | 0 | 5 | 1 + 20 | 2 | 5 | 1 + 1 | 1 | 6 | 0 + 12 | 0 | 6 | 0 + 15 | 0 | 6 | 0 + 20 | 2 | 6 | 0 + 1 | 1 | 5 | 0 + 12 | 0 | 5 | 0 + 15 | 0 | 5 | 0 + 20 | 2 | 5 | 0 1 | 1 | 6 | 1 - 3 | 0 | 6 | 1 - 5 | 2 | 6 | 1 - 7 | 1 | 6 | 1 - 9 | 0 | 6 | 1 - 11 | 2 | 6 | 1 - 13 | 1 | 6 | 1 + 12 | 0 | 6 | 1 15 | 0 | 6 | 1 - 17 | 2 | 6 | 1 - 19 | 1 | 6 | 1 - 2 | 2 | 6 | 1 - 4 | 1 | 6 | 1 - 6 | 0 | 6 | 1 - 8 | 2 | 6 | 1 - 10 | 1 | 6 | 1 + 20 | 2 | 6 | 1 + 1 | 1 | 5 | 1 + 12 | 0 | 5 | 1 + 15 | 0 | 5 | 1 + 20 | 2 | 5 | 1 + 1 | 1 | 6 | 0 + 12 | 0 | 6 | 0 + 15 | 0 | 6 | 0 + 20 | 2 | 6 | 0 + 1 | 1 | 5 | 0 + 12 | 0 | 5 | 0 + 15 | 0 | 5 | 0 + 20 | 2 | 5 | 0 + 1 | 1 | 6 | 1 12 | 0 | 6 | 1 - 14 | 2 | 6 | 1 - 16 | 1 | 6 | 1 - 18 | 0 | 6 | 1 + 15 | 0 | 6 | 1 20 | 2 | 6 | 1 + 1 | 1 | 1 | 1 + 12 | 0 | 1 | 1 + 15 | 0 | 1 | 1 + 20 | 2 | 1 | 1 + 1 | 1 | 0 | 1 + 12 | 0 | 0 | 1 + 15 | 0 | 0 | 1 + 20 | 2 | 0 | 1 + 1 | 1 | 1 | 0 + 12 | 0 | 1 | 0 + 15 | 0 | 1 | 0 + 20 | 2 | 1 | 0 1 | 1 | 0 | 0 - 3 | 0 | 0 | 0 - 5 | 2 | 0 | 0 - 7 | 1 | 0 | 0 - 9 | 0 | 0 | 0 - 11 | 2 | 0 | 0 - 13 | 1 | 0 | 0 + 12 | 0 | 0 | 0 15 | 0 | 0 | 0 - 17 | 2 | 0 | 0 - 19 | 1 | 0 | 0 - 2 | 2 | 0 | 0 - 4 | 1 | 0 | 0 - 6 | 0 | 0 | 0 - 8 | 2 | 0 | 0 - 10 | 1 | 0 | 0 + 20 | 2 | 0 | 0 + 1 | 1 | 1 | 1 + 12 | 0 | 1 | 1 + 15 | 0 | 1 | 1 + 20 | 2 | 1 | 1 + 1 | 1 | 0 | 1 + 12 | 0 | 0 | 1 + 15 | 0 | 0 | 1 + 20 | 2 | 0 | 1 + 1 | 1 | 1 | 0 + 12 | 0 | 1 | 0 + 15 | 0 | 1 | 0 + 20 | 2 | 1 | 0 + 1 | 1 | 0 | 0 12 | 0 | 0 | 0 - 14 | 2 | 0 | 0 - 16 | 1 | 0 | 0 - 18 | 0 | 0 | 0 + 15 | 0 | 0 | 0 20 | 2 | 0 | 0 + 1 | 1 | 1 | 1 + 12 | 0 | 1 | 1 + 15 | 0 | 1 | 1 + 20 | 2 | 1 | 1 1 | 1 | 2 | 0 - 3 | 0 | 2 | 0 - 5 | 2 | 2 | 0 - 7 | 1 | 2 | 0 - 9 | 0 | 2 | 0 - 11 | 2 | 2 | 0 - 13 | 1 | 2 | 0 - 15 | 0 | 2 | 0 - 17 | 2 | 2 | 0 - 19 | 1 | 2 | 0 - 2 | 2 | 2 | 0 - 4 | 1 | 2 | 0 - 6 | 0 | 2 | 0 - 8 | 2 | 2 | 0 - 10 | 1 | 2 | 0 12 | 0 | 2 | 0 - 14 | 2 | 2 | 0 - 16 | 1 | 2 | 0 - 18 | 0 | 2 | 0 + 15 | 0 | 2 | 0 20 | 2 | 2 | 0 + 1 | 1 | 3 | 1 + 12 | 0 | 3 | 1 + 15 | 0 | 3 | 1 + 20 | 2 | 3 | 1 1 | 1 | 4 | 0 - 3 | 0 | 4 | 0 - 5 | 2 | 4 | 0 - 7 | 1 | 4 | 0 - 9 | 0 | 4 | 0 - 11 | 2 | 4 | 0 - 13 | 1 | 4 | 0 + 12 | 0 | 4 | 0 15 | 0 | 4 | 0 - 17 | 2 | 4 | 0 - 19 | 1 | 4 | 0 - 2 | 2 | 4 | 0 - 4 | 1 | 4 | 0 - 6 | 0 | 4 | 0 - 8 | 2 | 4 | 0 - 10 | 1 | 4 | 0 + 20 | 2 | 4 | 0 + 1 | 1 | 2 | 1 + 12 | 0 | 2 | 1 + 15 | 0 | 2 | 1 + 20 | 2 | 2 | 1 + 1 | 1 | 3 | 0 + 12 | 0 | 3 | 0 + 15 | 0 | 3 | 0 + 20 | 2 | 3 | 0 + 1 | 1 | 4 | 1 + 12 | 0 | 4 | 1 + 15 | 0 | 4 | 1 + 20 | 2 | 4 | 1 + 1 | 1 | 2 | 0 + 12 | 0 | 2 | 0 + 15 | 0 | 2 | 0 + 20 | 2 | 2 | 0 + 1 | 1 | 3 | 1 + 12 | 0 | 3 | 1 + 15 | 0 | 3 | 1 + 20 | 2 | 3 | 1 + 1 | 1 | 4 | 0 12 | 0 | 4 | 0 - 14 | 2 | 4 | 0 - 16 | 1 | 4 | 0 - 18 | 0 | 4 | 0 + 15 | 0 | 4 | 0 20 | 2 | 4 | 0 - 1 | 1 | 6 | 0 - 3 | 0 | 6 | 0 - 5 | 2 | 6 | 0 - 7 | 1 | 6 | 0 - 9 | 0 | 6 | 0 - 11 | 2 | 6 | 0 - 13 | 1 | 6 | 0 - 15 | 0 | 6 | 0 - 17 | 2 | 6 | 0 - 19 | 1 | 6 | 0 - 2 | 2 | 6 | 0 - 4 | 1 | 6 | 0 - 6 | 0 | 6 | 0 - 8 | 2 | 6 | 0 - 10 | 1 | 6 | 0 - 12 | 0 | 6 | 0 - 14 | 2 | 6 | 0 - 16 | 1 | 6 | 0 - 18 | 0 | 6 | 0 - 20 | 2 | 6 | 0 - 1 | 1 | 0 | 1 - 3 | 0 | 0 | 1 - 5 | 2 | 0 | 1 - 7 | 1 | 0 | 1 - 9 | 0 | 0 | 1 - 11 | 2 | 0 | 1 - 13 | 1 | 0 | 1 - 15 | 0 | 0 | 1 - 17 | 2 | 0 | 1 - 19 | 1 | 0 | 1 - 2 | 2 | 0 | 1 - 4 | 1 | 0 | 1 - 6 | 0 | 0 | 1 - 8 | 2 | 0 | 1 - 10 | 1 | 0 | 1 - 12 | 0 | 0 | 1 - 14 | 2 | 0 | 1 - 16 | 1 | 0 | 1 - 18 | 0 | 0 | 1 - 20 | 2 | 0 | 1 1 | 1 | 2 | 1 - 3 | 0 | 2 | 1 - 5 | 2 | 2 | 1 - 7 | 1 | 2 | 1 - 9 | 0 | 2 | 1 - 11 | 2 | 2 | 1 - 13 | 1 | 2 | 1 - 15 | 0 | 2 | 1 - 17 | 2 | 2 | 1 - 19 | 1 | 2 | 1 - 2 | 2 | 2 | 1 - 4 | 1 | 2 | 1 - 6 | 0 | 2 | 1 - 8 | 2 | 2 | 1 - 10 | 1 | 2 | 1 12 | 0 | 2 | 1 - 14 | 2 | 2 | 1 - 16 | 1 | 2 | 1 - 18 | 0 | 2 | 1 + 15 | 0 | 2 | 1 20 | 2 | 2 | 1 + 1 | 1 | 3 | 0 + 12 | 0 | 3 | 0 + 15 | 0 | 3 | 0 + 20 | 2 | 3 | 0 1 | 1 | 4 | 1 - 3 | 0 | 4 | 1 - 5 | 2 | 4 | 1 - 7 | 1 | 4 | 1 - 9 | 0 | 4 | 1 - 11 | 2 | 4 | 1 - 13 | 1 | 4 | 1 - 15 | 0 | 4 | 1 - 17 | 2 | 4 | 1 - 19 | 1 | 4 | 1 - 2 | 2 | 4 | 1 - 4 | 1 | 4 | 1 - 6 | 0 | 4 | 1 - 8 | 2 | 4 | 1 - 10 | 1 | 4 | 1 12 | 0 | 4 | 1 - 14 | 2 | 4 | 1 - 16 | 1 | 4 | 1 - 18 | 0 | 4 | 1 + 15 | 0 | 4 | 1 20 | 2 | 4 | 1 - 1 | 1 | 6 | 1 - 3 | 0 | 6 | 1 + 1 | 1 | 2 | 0 + 12 | 0 | 2 | 0 + 15 | 0 | 2 | 0 + 20 | 2 | 2 | 0 + 5 | 2 | 5 | 1 + 6 | 0 | 5 | 1 + 9 | 0 | 5 | 1 + 10 | 1 | 5 | 1 + 11 | 2 | 5 | 1 + 13 | 1 | 5 | 1 + 14 | 2 | 5 | 1 + 17 | 2 | 5 | 1 + 5 | 2 | 6 | 0 + 6 | 0 | 6 | 0 + 9 | 0 | 6 | 0 + 10 | 1 | 6 | 0 + 11 | 2 | 6 | 0 + 13 | 1 | 6 | 0 + 14 | 2 | 6 | 0 + 17 | 2 | 6 | 0 + 5 | 2 | 5 | 0 + 6 | 0 | 5 | 0 + 9 | 0 | 5 | 0 + 10 | 1 | 5 | 0 + 11 | 2 | 5 | 0 + 13 | 1 | 5 | 0 + 14 | 2 | 5 | 0 + 17 | 2 | 5 | 0 5 | 2 | 6 | 1 - 7 | 1 | 6 | 1 + 6 | 0 | 6 | 1 9 | 0 | 6 | 1 + 10 | 1 | 6 | 1 11 | 2 | 6 | 1 13 | 1 | 6 | 1 - 15 | 0 | 6 | 1 + 14 | 2 | 6 | 1 17 | 2 | 6 | 1 - 19 | 1 | 6 | 1 - 2 | 2 | 6 | 1 - 4 | 1 | 6 | 1 + 5 | 2 | 5 | 1 + 6 | 0 | 5 | 1 + 9 | 0 | 5 | 1 + 10 | 1 | 5 | 1 + 11 | 2 | 5 | 1 + 13 | 1 | 5 | 1 + 14 | 2 | 5 | 1 + 17 | 2 | 5 | 1 + 5 | 2 | 6 | 0 + 6 | 0 | 6 | 0 + 9 | 0 | 6 | 0 + 10 | 1 | 6 | 0 + 11 | 2 | 6 | 0 + 13 | 1 | 6 | 0 + 14 | 2 | 6 | 0 + 17 | 2 | 6 | 0 + 5 | 2 | 5 | 0 + 6 | 0 | 5 | 0 + 9 | 0 | 5 | 0 + 10 | 1 | 5 | 0 + 11 | 2 | 5 | 0 + 13 | 1 | 5 | 0 + 14 | 2 | 5 | 0 + 17 | 2 | 5 | 0 + 5 | 2 | 6 | 1 6 | 0 | 6 | 1 - 8 | 2 | 6 | 1 + 9 | 0 | 6 | 1 10 | 1 | 6 | 1 - 12 | 0 | 6 | 1 + 11 | 2 | 6 | 1 + 13 | 1 | 6 | 1 14 | 2 | 6 | 1 - 16 | 1 | 6 | 1 - 18 | 0 | 6 | 1 - 20 | 2 | 6 | 1 - 1 | 1 | 0 | 0 - 3 | 0 | 0 | 0 + 17 | 2 | 6 | 1 + 5 | 2 | 1 | 1 + 6 | 0 | 1 | 1 + 9 | 0 | 1 | 1 + 10 | 1 | 1 | 1 + 11 | 2 | 1 | 1 + 13 | 1 | 1 | 1 + 14 | 2 | 1 | 1 + 17 | 2 | 1 | 1 + 5 | 2 | 0 | 1 + 6 | 0 | 0 | 1 + 9 | 0 | 0 | 1 + 10 | 1 | 0 | 1 + 11 | 2 | 0 | 1 + 13 | 1 | 0 | 1 + 14 | 2 | 0 | 1 + 17 | 2 | 0 | 1 + 5 | 2 | 1 | 0 + 6 | 0 | 1 | 0 + 9 | 0 | 1 | 0 + 10 | 1 | 1 | 0 + 11 | 2 | 1 | 0 + 13 | 1 | 1 | 0 + 14 | 2 | 1 | 0 + 17 | 2 | 1 | 0 5 | 2 | 0 | 0 - 7 | 1 | 0 | 0 + 6 | 0 | 0 | 0 9 | 0 | 0 | 0 + 10 | 1 | 0 | 0 11 | 2 | 0 | 0 13 | 1 | 0 | 0 - 15 | 0 | 0 | 0 + 14 | 2 | 0 | 0 17 | 2 | 0 | 0 - 19 | 1 | 0 | 0 - 2 | 2 | 0 | 0 - 4 | 1 | 0 | 0 + 5 | 2 | 1 | 1 + 6 | 0 | 1 | 1 + 9 | 0 | 1 | 1 + 10 | 1 | 1 | 1 + 11 | 2 | 1 | 1 + 13 | 1 | 1 | 1 + 14 | 2 | 1 | 1 + 17 | 2 | 1 | 1 + 5 | 2 | 0 | 1 + 6 | 0 | 0 | 1 + 9 | 0 | 0 | 1 + 10 | 1 | 0 | 1 + 11 | 2 | 0 | 1 + 13 | 1 | 0 | 1 + 14 | 2 | 0 | 1 + 17 | 2 | 0 | 1 + 5 | 2 | 1 | 0 + 6 | 0 | 1 | 0 + 9 | 0 | 1 | 0 + 10 | 1 | 1 | 0 + 11 | 2 | 1 | 0 + 13 | 1 | 1 | 0 + 14 | 2 | 1 | 0 + 17 | 2 | 1 | 0 + 5 | 2 | 0 | 0 6 | 0 | 0 | 0 - 8 | 2 | 0 | 0 + 9 | 0 | 0 | 0 10 | 1 | 0 | 0 - 12 | 0 | 0 | 0 + 11 | 2 | 0 | 0 + 13 | 1 | 0 | 0 14 | 2 | 0 | 0 - 16 | 1 | 0 | 0 - 18 | 0 | 0 | 0 - 20 | 2 | 0 | 0 - 1 | 1 | 2 | 0 - 3 | 0 | 2 | 0 + 17 | 2 | 0 | 0 + 5 | 2 | 1 | 1 + 6 | 0 | 1 | 1 + 9 | 0 | 1 | 1 + 10 | 1 | 1 | 1 + 11 | 2 | 1 | 1 + 13 | 1 | 1 | 1 + 14 | 2 | 1 | 1 + 17 | 2 | 1 | 1 5 | 2 | 2 | 0 - 7 | 1 | 2 | 0 + 6 | 0 | 2 | 0 9 | 0 | 2 | 0 + 10 | 1 | 2 | 0 11 | 2 | 2 | 0 13 | 1 | 2 | 0 - 15 | 0 | 2 | 0 - 17 | 2 | 2 | 0 - 19 | 1 | 2 | 0 - 2 | 2 | 2 | 0 - 4 | 1 | 2 | 0 - 6 | 0 | 2 | 0 - 8 | 2 | 2 | 0 - 10 | 1 | 2 | 0 - 12 | 0 | 2 | 0 14 | 2 | 2 | 0 - 16 | 1 | 2 | 0 - 18 | 0 | 2 | 0 - 20 | 2 | 2 | 0 -(600 rows) - --- empty target list -select r.* from orca.r, orca.s where s.c=2; - a | b -----+--- - 2 | 2 - 2 | 2 - 2 | 2 - 2 | 2 - 2 | 2 - 4 | 1 - 4 | 1 - 4 | 1 - 4 | 1 - 4 | 1 - 6 | 0 - 6 | 0 - 6 | 0 - 6 | 0 - 6 | 0 - 8 | 2 + 17 | 2 | 2 | 0 + 5 | 2 | 3 | 1 + 6 | 0 | 3 | 1 + 9 | 0 | 3 | 1 + 10 | 1 | 3 | 1 + 11 | 2 | 3 | 1 + 13 | 1 | 3 | 1 + 14 | 2 | 3 | 1 + 17 | 2 | 3 | 1 + 5 | 2 | 4 | 0 + 6 | 0 | 4 | 0 + 9 | 0 | 4 | 0 + 10 | 1 | 4 | 0 + 11 | 2 | 4 | 0 + 13 | 1 | 4 | 0 + 14 | 2 | 4 | 0 + 17 | 2 | 4 | 0 + 5 | 2 | 2 | 1 + 6 | 0 | 2 | 1 + 9 | 0 | 2 | 1 + 10 | 1 | 2 | 1 + 11 | 2 | 2 | 1 + 13 | 1 | 2 | 1 + 14 | 2 | 2 | 1 + 17 | 2 | 2 | 1 + 5 | 2 | 3 | 0 + 6 | 0 | 3 | 0 + 9 | 0 | 3 | 0 + 10 | 1 | 3 | 0 + 11 | 2 | 3 | 0 + 13 | 1 | 3 | 0 + 14 | 2 | 3 | 0 + 17 | 2 | 3 | 0 + 5 | 2 | 4 | 1 + 6 | 0 | 4 | 1 + 9 | 0 | 4 | 1 + 10 | 1 | 4 | 1 + 11 | 2 | 4 | 1 + 13 | 1 | 4 | 1 + 14 | 2 | 4 | 1 + 17 | 2 | 4 | 1 + 5 | 2 | 2 | 0 + 6 | 0 | 2 | 0 + 9 | 0 | 2 | 0 + 10 | 1 | 2 | 0 + 11 | 2 | 2 | 0 + 13 | 1 | 2 | 0 + 14 | 2 | 2 | 0 + 17 | 2 | 2 | 0 + 5 | 2 | 3 | 1 + 6 | 0 | 3 | 1 + 9 | 0 | 3 | 1 + 10 | 1 | 3 | 1 + 11 | 2 | 3 | 1 + 13 | 1 | 3 | 1 + 14 | 2 | 3 | 1 + 17 | 2 | 3 | 1 + 5 | 2 | 4 | 0 + 6 | 0 | 4 | 0 + 9 | 0 | 4 | 0 + 10 | 1 | 4 | 0 + 11 | 2 | 4 | 0 + 13 | 1 | 4 | 0 + 14 | 2 | 4 | 0 + 17 | 2 | 4 | 0 + 5 | 2 | 2 | 1 + 6 | 0 | 2 | 1 + 9 | 0 | 2 | 1 + 10 | 1 | 2 | 1 + 11 | 2 | 2 | 1 + 13 | 1 | 2 | 1 + 14 | 2 | 2 | 1 + 17 | 2 | 2 | 1 + 5 | 2 | 3 | 0 + 6 | 0 | 3 | 0 + 9 | 0 | 3 | 0 + 10 | 1 | 3 | 0 + 11 | 2 | 3 | 0 + 13 | 1 | 3 | 0 + 14 | 2 | 3 | 0 + 17 | 2 | 3 | 0 + 5 | 2 | 4 | 1 + 6 | 0 | 4 | 1 + 9 | 0 | 4 | 1 + 10 | 1 | 4 | 1 + 11 | 2 | 4 | 1 + 13 | 1 | 4 | 1 + 14 | 2 | 4 | 1 + 17 | 2 | 4 | 1 + 5 | 2 | 2 | 0 + 6 | 0 | 2 | 0 + 9 | 0 | 2 | 0 + 10 | 1 | 2 | 0 + 11 | 2 | 2 | 0 + 13 | 1 | 2 | 0 + 14 | 2 | 2 | 0 + 17 | 2 | 2 | 0 +(600 rows) + +-- empty target list +select r.* from orca.r, orca.s where s.c=2; + a | b +----+--- + 2 | 2 + 2 | 2 + 2 | 2 + 2 | 2 + 2 | 2 + 3 | 0 + 3 | 0 + 3 | 0 + 3 | 0 + 3 | 0 + 4 | 1 + 4 | 1 + 4 | 1 + 4 | 1 + 4 | 1 + 7 | 1 + 7 | 1 + 7 | 1 + 7 | 1 + 7 | 1 + 8 | 2 8 | 2 8 | 2 8 | 2 8 | 2 - 10 | 1 - 10 | 1 - 10 | 1 - 10 | 1 - 10 | 1 - 12 | 0 - 12 | 0 - 12 | 0 - 12 | 0 - 12 | 0 - 14 | 2 - 14 | 2 - 14 | 2 - 14 | 2 - 14 | 2 16 | 1 16 | 1 16 | 1 @@ -3144,36 +3138,31 @@ select r.* from orca.r, orca.s where s.c=2; 18 | 0 18 | 0 18 | 0 - 20 | 2 - 20 | 2 - 20 | 2 - 20 | 2 - 20 | 2 - 1 | 1 - 1 | 1 - 1 | 1 - 1 | 1 - 1 | 1 - 3 | 0 - 3 | 0 - 3 | 0 - 3 | 0 - 3 | 0 + 19 | 1 + 19 | 1 + 19 | 1 + 19 | 1 + 19 | 1 5 | 2 5 | 2 5 | 2 5 | 2 5 | 2 - 7 | 1 - 7 | 1 - 7 | 1 - 7 | 1 - 7 | 1 + 6 | 0 + 6 | 0 + 6 | 0 + 6 | 0 + 6 | 0 9 | 0 9 | 0 9 | 0 9 | 0 9 | 0 + 10 | 1 + 10 | 1 + 10 | 1 + 10 | 1 + 10 | 1 11 | 2 11 | 2 11 | 2 @@ -3184,21 +3173,36 @@ select r.* from orca.r, orca.s where s.c=2; 13 | 1 13 | 1 13 | 1 - 15 | 0 - 15 | 0 - 15 | 0 - 15 | 0 - 15 | 0 + 14 | 2 + 14 | 2 + 14 | 2 + 14 | 2 + 14 | 2 17 | 2 17 | 2 17 | 2 17 | 2 17 | 2 - 19 | 1 - 19 | 1 - 19 | 1 - 19 | 1 - 19 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 12 | 0 + 12 | 0 + 12 | 0 + 12 | 0 + 12 | 0 + 15 | 0 + 15 | 0 + 15 | 0 + 15 | 0 + 15 | 0 + 20 | 2 + 20 | 2 + 20 | 2 + 20 | 2 + 20 | 2 (100 rows) create table orca.m(); @@ -3221,42 +3225,42 @@ select r.a, s.c from orca.r left outer join orca.s on(r.a=s.c); 2 | 2 2 | 2 2 | 2 + 3 | 3 + 3 | 3 + 3 | 3 + 3 | 3 4 | 4 4 | 4 4 | 4 4 | 4 - 6 | 6 - 6 | 6 - 6 | 6 - 6 | 6 + 7 | 8 | - 10 | - 12 | - 14 | 16 | 18 | - 20 | + 19 | + | 1 | 1 1 | 1 1 | 1 1 | 1 1 | 1 - 3 | 3 - 3 | 3 - 3 | 3 - 3 | 3 + 12 | + 15 | + 20 | 5 | 5 5 | 5 5 | 5 5 | 5 - 7 | + 6 | 6 + 6 | 6 + 6 | 6 + 6 | 6 9 | + 10 | 11 | 13 | - 15 | + 14 | 17 | - 19 | - | (41 rows) select r.a, s.c from orca.r left outer join orca.s on(r.a=s.c and r.a=r.b and s.c=s.d) order by r.a,s.c; @@ -3311,132 +3315,132 @@ select r.a, s.c from orca.r right outer join orca.s on(r.a=s.c); a | c ---+--- 1 | 1 - 3 | 3 - 5 | 5 + | 0 1 | 1 - 3 | 3 - 5 | 5 + | 0 1 | 1 - 3 | 3 - 5 | 5 + | 0 1 | 1 - 3 | 3 - 5 | 5 + | 0 1 | 1 2 | 2 + 3 | 3 4 | 4 - 6 | 6 - | 0 2 | 2 + 3 | 3 4 | 4 - 6 | 6 - | 0 2 | 2 + 3 | 3 4 | 4 - 6 | 6 - | 0 2 | 2 + 3 | 3 4 | 4 - 6 | 6 - | 0 2 | 2 + 5 | 5 + 6 | 6 + 5 | 5 + 6 | 6 + 5 | 5 + 6 | 6 + 5 | 5 + 6 | 6 (30 rows) select * from orca.r where exists (select * from orca.s where s.c=r.a + 2); a | b ---+--- - 2 | 2 - 4 | 1 1 | 1 + 2 | 2 3 | 0 + 4 | 1 (4 rows) select * from orca.r where exists (select * from orca.s where s.c=r.b); a | b ----+--- - 15 | 0 - 9 | 0 - 3 | 0 - 17 | 2 - 11 | 2 + 2 | 2 + 8 | 2 + 20 | 2 5 | 2 - | 1 - 19 | 1 - 13 | 1 + 11 | 2 + 14 | 2 + 17 | 2 + 3 | 0 + 18 | 0 + 4 | 1 7 | 1 - 1 | 1 16 | 1 - 10 | 1 - 4 | 1 - 18 | 0 + 19 | 1 + | 1 12 | 0 + 15 | 0 + 1 | 1 6 | 0 - 20 | 2 - 14 | 2 - 8 | 2 - 2 | 2 + 9 | 0 + 10 | 1 + 13 | 1 (21 rows) select * from orca.m where m.a not in (select a from orca.m1 where a=5); a | b ----+--- - 0 | 1 1 | 0 - 2 | 1 3 | 0 + 9 | 0 + 14 | 1 + 17 | 0 + 22 | 1 + 24 | 1 + 26 | 1 + 28 | 1 + 29 | 0 + 30 | 1 + 32 | 1 + 34 | 1 + 0 | 1 + 2 | 1 4 | 1 - 6 | 1 - 7 | 0 8 | 1 - 9 | 0 - 10 | 1 - 11 | 0 12 | 1 13 | 0 - 14 | 1 15 | 0 - 16 | 1 - 17 | 0 18 | 1 19 | 0 20 | 1 21 | 0 - 22 | 1 + 27 | 0 + 33 | 0 + 6 | 1 + 7 | 0 + 10 | 1 + 11 | 0 + 16 | 1 23 | 0 - 24 | 1 25 | 0 - 26 | 1 - 27 | 0 - 28 | 1 - 29 | 0 - 30 | 1 31 | 0 - 32 | 1 - 33 | 0 - 34 | 1 (34 rows) select * from orca.m where m.a not in (select a from orca.m1); a | b ----+--- 24 | 1 - 25 | 0 26 | 1 - 27 | 0 28 | 1 29 | 0 30 | 1 - 31 | 0 32 | 1 - 33 | 0 34 | 1 + 25 | 0 + 31 | 0 + 27 | 0 + 33 | 0 (11 rows) select * from orca.m where m.a in (select a from orca.m1 where m1.a-1 = m.b); a | b ---+--- - 1 | 0 2 | 1 + 1 | 0 (2 rows) -- enable_hashjoin=off; enable_mergejoin=on @@ -3465,25 +3469,25 @@ select 1 from orca.m, orca.m1 where m.a = m1.a and m.b!=m1.b; select * from orca.r left outer join orca.s on (r.a=s.c and r.b Seq Scan on s (cost=0.00..431.00 rows=10 width=8) -> Hash (cost=431.00..431.00 rows=7 width=8) -> Seq Scan on r (cost=0.00..431.00 rows=7 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) -- explain Hash Join with equality join condition @@ -3506,13 +3510,13 @@ explain select * from orca.r, orca.s where r.a is not distinct from s.c; explain select * from orca.r, orca.s where r.a = s.c; QUERY PLAN -------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..491.01 rows=30 width=16) - -> Nested Loop (cost=0.00..491.00 rows=10 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..611.01 rows=30 width=16) + -> Nested Loop (cost=0.00..611.00 rows=10 width=16) Join Filter: true -> Seq Scan on s (cost=0.00..431.00 rows=10 width=8) -> Index Scan using r_a on r (cost=0.00..180.00 rows=1 width=8) Index Cond: (a = s.c) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) -- sort @@ -3640,86 +3644,86 @@ insert into orca.m values (1,-1), (1,2), (1,1); select a,a,a+b from orca.m; a | a | ?column? ----+----+---------- - 0 | 0 | 1 - 1 | 1 | 1 - 2 | 2 | 3 - 3 | 3 | 3 - 4 | 4 | 5 5 | 5 | 5 6 | 6 | 7 7 | 7 | 7 - 8 | 8 | 9 - 9 | 9 | 9 10 | 10 | 11 11 | 11 | 11 + 16 | 16 | 17 + 23 | 23 | 23 + 25 | 25 | 25 + 31 | 31 | 31 + 1 | 1 | 0 + 0 | 0 | 1 + 2 | 2 | 3 + 4 | 4 | 5 + 8 | 8 | 9 12 | 12 | 13 13 | 13 | 13 - 14 | 14 | 15 15 | 15 | 15 - 16 | 16 | 17 - 17 | 17 | 17 18 | 18 | 19 19 | 19 | 19 20 | 20 | 21 21 | 21 | 21 + 27 | 27 | 27 + 33 | 33 | 33 + 1 | 1 | 3 + 1 | 1 | 1 + 3 | 3 | 3 + 9 | 9 | 9 + 14 | 14 | 15 + 17 | 17 | 17 22 | 22 | 23 - 23 | 23 | 23 24 | 24 | 25 - 25 | 25 | 25 26 | 26 | 27 - 27 | 27 | 27 28 | 28 | 29 29 | 29 | 29 30 | 30 | 31 - 31 | 31 | 31 32 | 32 | 33 - 33 | 33 | 33 34 | 34 | 35 - 1 | 1 | 0 - 1 | 1 | 3 1 | 1 | 2 (38 rows) select a,a+b,a+b from orca.m; a | ?column? | ?column? ----+----------+---------- - 0 | 1 | 1 - 1 | 1 | 1 - 2 | 3 | 3 - 3 | 3 | 3 - 4 | 5 | 5 5 | 5 | 5 6 | 7 | 7 7 | 7 | 7 - 8 | 9 | 9 - 9 | 9 | 9 10 | 11 | 11 11 | 11 | 11 + 16 | 17 | 17 + 23 | 23 | 23 + 25 | 25 | 25 + 31 | 31 | 31 + 1 | 0 | 0 + 0 | 1 | 1 + 2 | 3 | 3 + 4 | 5 | 5 + 8 | 9 | 9 12 | 13 | 13 13 | 13 | 13 - 14 | 15 | 15 15 | 15 | 15 - 16 | 17 | 17 - 17 | 17 | 17 18 | 19 | 19 19 | 19 | 19 20 | 21 | 21 21 | 21 | 21 + 27 | 27 | 27 + 33 | 33 | 33 + 1 | 3 | 3 + 1 | 1 | 1 + 3 | 3 | 3 + 9 | 9 | 9 + 14 | 15 | 15 + 17 | 17 | 17 22 | 23 | 23 - 23 | 23 | 23 24 | 25 | 25 - 25 | 25 | 25 26 | 27 | 27 - 27 | 27 | 27 28 | 29 | 29 29 | 29 | 29 30 | 31 | 31 - 31 | 31 | 31 32 | 33 | 33 - 33 | 33 | 33 34 | 35 | 35 - 1 | 0 | 0 - 1 | 3 | 3 1 | 2 | 2 (38 rows) @@ -3735,131 +3739,116 @@ select * from orca.m where a=abs(b); select a,b,count(*) from orca.m group by grouping sets ((a), (a,b)); a | b | count ----+----+------- - 0 | 1 | 1 1 | -1 | 1 - 1 | 0 | 1 1 | 1 | 1 1 | 2 | 1 - 2 | 1 | 1 - 3 | 0 | 1 - 4 | 1 | 1 - 5 | 0 | 1 - 6 | 1 | 1 7 | 0 | 1 - 8 | 1 | 1 - 9 | 0 | 1 10 | 1 | 1 - 11 | 0 | 1 12 | 1 | 1 - 13 | 0 | 1 - 14 | 1 | 1 - 15 | 0 | 1 16 | 1 | 1 - 17 | 0 | 1 - 18 | 1 | 1 - 19 | 0 | 1 20 | 1 | 1 - 21 | 0 | 1 - 22 | 1 | 1 - 23 | 0 | 1 24 | 1 | 1 - 25 | 0 | 1 - 26 | 1 | 1 27 | 0 | 1 - 28 | 1 | 1 - 29 | 0 | 1 - 30 | 1 | 1 31 | 0 | 1 - 32 | 1 | 1 - 33 | 0 | 1 34 | 1 | 1 0 | | 1 1 | | 4 - 2 | | 1 - 3 | | 1 - 4 | | 1 + 12 | | 1 + 15 | | 1 + 20 | | 1 + 23 | | 1 + 26 | | 1 + 30 | | 1 + 31 | | 1 + 3 | 0 | 1 + 5 | 0 | 1 + 9 | 0 | 1 + 11 | 0 | 1 + 14 | 1 | 1 + 15 | 0 | 1 + 17 | 0 | 1 + 21 | 0 | 1 + 26 | 1 | 1 + 28 | 1 | 1 + 30 | 1 | 1 5 | | 1 6 | | 1 - 7 | | 1 - 8 | | 1 9 | | 1 10 | | 1 11 | | 1 - 12 | | 1 13 | | 1 14 | | 1 - 15 | | 1 - 16 | | 1 17 | | 1 - 18 | | 1 - 19 | | 1 - 20 | | 1 21 | | 1 - 22 | | 1 - 23 | | 1 - 24 | | 1 25 | | 1 - 26 | | 1 - 27 | | 1 28 | | 1 - 29 | | 1 - 30 | | 1 - 31 | | 1 32 | | 1 33 | | 1 + 0 | 1 | 1 + 1 | 0 | 1 + 2 | 1 | 1 + 4 | 1 | 1 + 6 | 1 | 1 + 8 | 1 | 1 + 13 | 0 | 1 + 18 | 1 | 1 + 19 | 0 | 1 + 22 | 1 | 1 + 23 | 0 | 1 + 25 | 0 | 1 + 29 | 0 | 1 + 32 | 1 | 1 + 33 | 0 | 1 + 2 | | 1 + 3 | | 1 + 4 | | 1 + 7 | | 1 + 8 | | 1 + 16 | | 1 + 18 | | 1 + 19 | | 1 + 22 | | 1 + 24 | | 1 + 27 | | 1 + 29 | | 1 34 | | 1 (73 rows) select b,count(*) from orca.m group by grouping sets ((a), (a,b)); b | count ----+------- - 1 | 1 -1 | 1 - 0 | 1 1 | 1 2 | 1 - 1 | 1 0 | 1 1 | 1 - 0 | 1 1 | 1 - 0 | 1 1 | 1 - 0 | 1 1 | 1 - 0 | 1 1 | 1 0 | 1 - 1 | 1 0 | 1 1 | 1 + | 1 + | 4 + | 1 + | 1 + | 1 + | 1 + | 1 + | 1 + | 1 0 | 1 - 1 | 1 0 | 1 - 1 | 1 0 | 1 - 1 | 1 0 | 1 1 | 1 0 | 1 - 1 | 1 0 | 1 - 1 | 1 0 | 1 1 | 1 - 0 | 1 1 | 1 - 0 | 1 1 | 1 - | 1 - | 4 - | 1 - | 1 - | 1 - | 1 - | 1 - | 1 - | 1 | 1 | 1 | 1 @@ -3873,6 +3862,21 @@ select b,count(*) from orca.m group by grouping sets ((a), (a,b)); | 1 | 1 | 1 + 1 | 1 + 0 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 0 | 1 + 1 | 1 + 0 | 1 + 1 | 1 + 0 | 1 + 0 | 1 + 0 | 1 + 1 | 1 + 0 | 1 | 1 | 1 | 1 @@ -3891,78 +3895,78 @@ select b,count(*) from orca.m group by grouping sets ((a), (a,b)); select a,count(*) from orca.m group by grouping sets ((a), (a,b)); a | count ----+------- - 0 | 1 - 1 | 1 - 1 | 1 - 1 | 1 - 1 | 1 - 2 | 1 3 | 1 - 4 | 1 + 5 | 1 + 9 | 1 + 11 | 1 + 14 | 1 + 15 | 1 + 17 | 1 + 21 | 1 + 26 | 1 + 28 | 1 + 30 | 1 5 | 1 6 | 1 - 7 | 1 - 8 | 1 9 | 1 10 | 1 11 | 1 - 12 | 1 13 | 1 14 | 1 - 15 | 1 - 16 | 1 17 | 1 - 18 | 1 - 19 | 1 - 20 | 1 21 | 1 - 22 | 1 - 23 | 1 - 24 | 1 25 | 1 - 26 | 1 - 27 | 1 28 | 1 - 29 | 1 - 30 | 1 - 31 | 1 32 | 1 33 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 7 | 1 + 10 | 1 + 12 | 1 + 16 | 1 + 20 | 1 + 24 | 1 + 27 | 1 + 31 | 1 34 | 1 0 | 1 1 | 4 + 12 | 1 + 15 | 1 + 20 | 1 + 23 | 1 + 26 | 1 + 30 | 1 + 31 | 1 + 0 | 1 + 1 | 1 2 | 1 - 3 | 1 4 | 1 - 5 | 1 6 | 1 - 7 | 1 8 | 1 - 9 | 1 - 10 | 1 - 11 | 1 - 12 | 1 13 | 1 - 14 | 1 - 15 | 1 - 16 | 1 - 17 | 1 18 | 1 19 | 1 - 20 | 1 - 21 | 1 22 | 1 23 | 1 - 24 | 1 25 | 1 - 26 | 1 - 27 | 1 - 28 | 1 29 | 1 - 30 | 1 - 31 | 1 32 | 1 33 | 1 + 2 | 1 + 3 | 1 + 4 | 1 + 7 | 1 + 8 | 1 + 16 | 1 + 18 | 1 + 19 | 1 + 22 | 1 + 24 | 1 + 27 | 1 + 29 | 1 34 | 1 (73 rows) @@ -3970,123 +3974,123 @@ select a,count(*) from orca.m group by grouping sets ((a), (b)); a | count ----+------- | 1 + 5 | 1 + 6 | 1 + 9 | 1 + 10 | 1 + 11 | 1 + 13 | 1 + 14 | 1 + 17 | 1 + 21 | 1 + 25 | 1 + 28 | 1 + 32 | 1 + 33 | 1 | 17 | 19 - | 1 0 | 1 1 | 4 + 12 | 1 + 15 | 1 + 20 | 1 + 23 | 1 + 26 | 1 + 30 | 1 + 31 | 1 + | 1 2 | 1 3 | 1 4 | 1 - 5 | 1 - 6 | 1 7 | 1 8 | 1 - 9 | 1 - 10 | 1 - 11 | 1 - 12 | 1 - 13 | 1 - 14 | 1 - 15 | 1 16 | 1 - 17 | 1 18 | 1 19 | 1 - 20 | 1 - 21 | 1 22 | 1 - 23 | 1 24 | 1 - 25 | 1 - 26 | 1 27 | 1 - 28 | 1 29 | 1 - 30 | 1 - 31 | 1 - 32 | 1 - 33 | 1 34 | 1 (39 rows) select a,b,count(*) from orca.m group by rollup(a, b); a | b | count ----+----+------- - 0 | 1 | 1 1 | -1 | 1 - 1 | 0 | 1 1 | 1 | 1 1 | 2 | 1 - 2 | 1 | 1 - 3 | 0 | 1 - 4 | 1 | 1 - 5 | 0 | 1 - 6 | 1 | 1 7 | 0 | 1 - 8 | 1 | 1 - 9 | 0 | 1 10 | 1 | 1 - 11 | 0 | 1 12 | 1 | 1 - 13 | 0 | 1 - 14 | 1 | 1 - 15 | 0 | 1 16 | 1 | 1 - 17 | 0 | 1 - 18 | 1 | 1 - 19 | 0 | 1 20 | 1 | 1 - 21 | 0 | 1 - 22 | 1 | 1 - 23 | 0 | 1 24 | 1 | 1 - 25 | 0 | 1 - 26 | 1 | 1 27 | 0 | 1 - 28 | 1 | 1 - 29 | 0 | 1 - 30 | 1 | 1 31 | 0 | 1 - 32 | 1 | 1 - 33 | 0 | 1 34 | 1 | 1 0 | | 1 1 | | 4 - 2 | | 1 - 3 | | 1 - 4 | | 1 - 5 | | 1 - 6 | | 1 - 7 | | 1 - 8 | | 1 - 9 | | 1 - 10 | | 1 - 11 | | 1 12 | | 1 - 13 | | 1 - 14 | | 1 15 | | 1 - 16 | | 1 - 17 | | 1 - 18 | | 1 - 19 | | 1 20 | | 1 - 21 | | 1 - 22 | | 1 23 | | 1 - 24 | | 1 - 25 | | 1 26 | | 1 - 27 | | 1 - 28 | | 1 - 29 | | 1 30 | | 1 31 | | 1 + | | 38 + 0 | 1 | 1 + 1 | 0 | 1 + 2 | 1 | 1 + 4 | 1 | 1 + 6 | 1 | 1 + 8 | 1 | 1 + 13 | 0 | 1 + 18 | 1 | 1 + 19 | 0 | 1 + 22 | 1 | 1 + 23 | 0 | 1 + 25 | 0 | 1 + 29 | 0 | 1 + 32 | 1 | 1 + 33 | 0 | 1 + 2 | | 1 + 3 | | 1 + 4 | | 1 + 7 | | 1 + 8 | | 1 + 16 | | 1 + 18 | | 1 + 19 | | 1 + 22 | | 1 + 24 | | 1 + 27 | | 1 + 29 | | 1 + 34 | | 1 + 3 | 0 | 1 + 5 | 0 | 1 + 9 | 0 | 1 + 11 | 0 | 1 + 14 | 1 | 1 + 15 | 0 | 1 + 17 | 0 | 1 + 21 | 0 | 1 + 26 | 1 | 1 + 28 | 1 | 1 + 30 | 1 | 1 + 5 | | 1 + 6 | | 1 + 9 | | 1 + 10 | | 1 + 11 | | 1 + 13 | | 1 + 14 | | 1 + 17 | | 1 + 21 | | 1 + 25 | | 1 + 28 | | 1 32 | | 1 33 | | 1 - 34 | | 1 - | | 38 (74 rows) select a,b,count(*) from orca.m group by rollup((a),(a,b)) order by 1,2,3; @@ -4177,52 +4181,52 @@ select count(*) from orca.m group by (); select a, count(*) from orca.r group by (), a; a | count ----+------- - 1 | 1 - 3 | 1 5 | 1 - 7 | 1 + 6 | 1 9 | 1 + 10 | 1 11 | 1 13 | 1 - 15 | 1 + 14 | 1 17 | 1 - 19 | 1 - | 1 + 1 | 1 + 12 | 1 + 15 | 1 + 20 | 1 2 | 1 + 3 | 1 4 | 1 - 6 | 1 + 7 | 1 8 | 1 - 10 | 1 - 12 | 1 - 14 | 1 16 | 1 18 | 1 - 20 | 1 + 19 | 1 + | 1 (21 rows) select a, count(*) from orca.r group by grouping sets ((),(a)); a | count ----+------- - 2 | 1 - 4 | 1 + 5 | 1 6 | 1 - 8 | 1 + 9 | 1 10 | 1 - 12 | 1 + 11 | 1 + 13 | 1 14 | 1 - 16 | 1 - 18 | 1 - 20 | 1 + 17 | 1 | 21 1 | 1 + 12 | 1 + 15 | 1 + 20 | 1 + 2 | 1 3 | 1 - 5 | 1 + 4 | 1 7 | 1 - 9 | 1 - 11 | 1 - 13 | 1 - 15 | 1 - 17 | 1 + 8 | 1 + 16 | 1 + 18 | 1 19 | 1 | 1 (22 rows) @@ -4333,60 +4337,60 @@ select a,1 from orca.r group by rollup(a); a | ?column? ----+---------- 1 | 1 + 12 | 1 + 15 | 1 + 20 | 1 + 2 | 1 3 | 1 - 5 | 1 + 4 | 1 7 | 1 - 9 | 1 - 11 | 1 - 13 | 1 - 15 | 1 - 17 | 1 + 8 | 1 + 16 | 1 + 18 | 1 19 | 1 | 1 - | 1 - 2 | 1 - 4 | 1 + 5 | 1 6 | 1 - 8 | 1 + 9 | 1 10 | 1 - 12 | 1 + 11 | 1 + 13 | 1 14 | 1 - 16 | 1 - 18 | 1 - 20 | 1 + 17 | 1 + | 1 (22 rows) select distinct grouping(a) + grouping(b) from orca.m group by rollup(a,b); ?column? ---------- + 2 0 1 - 2 (3 rows) -- arrays select array[array[a,b]], array[b] from orca.r; array | array ------------+------- - {{2,2}} | {2} - {{4,1}} | {1} + {{5,2}} | {2} {{6,0}} | {0} - {{8,2}} | {2} + {{9,0}} | {0} {{10,1}} | {1} - {{12,0}} | {0} + {{11,2}} | {2} + {{13,1}} | {1} {{14,2}} | {2} - {{16,1}} | {1} - {{18,0}} | {0} - {{20,2}} | {2} + {{17,2}} | {2} {{1,1}} | {1} + {{12,0}} | {0} + {{15,0}} | {0} + {{20,2}} | {2} + {{2,2}} | {2} {{3,0}} | {0} - {{5,2}} | {2} + {{4,1}} | {1} {{7,1}} | {1} - {{9,0}} | {0} - {{11,2}} | {2} - {{13,1}} | {1} - {{15,0}} | {0} - {{17,2}} | {2} + {{8,2}} | {2} + {{16,1}} | {1} + {{18,0}} | {0} {{19,1}} | {1} {{NULL,1}} | {1} (21 rows) @@ -4395,177 +4399,177 @@ select array[array[a,b]], array[b] from orca.r; select a, b from orca.m union select b,a from orca.m; a | b ----+---- - 0 | 1 0 | 3 - 0 | 5 0 | 7 - 0 | 9 0 | 11 - 0 | 13 0 | 15 0 | 17 - 0 | 19 - 0 | 21 0 | 23 - 0 | 25 + 0 | 33 + 1 | 4 + 1 | 8 + 1 | 24 + 1 | 28 + 3 | 0 + 5 | 0 + 9 | 0 + 11 | 0 + 14 | 1 + 15 | 0 + 17 | 0 + 21 | 0 + 26 | 1 + 28 | 1 + 30 | 1 + -1 | 1 + 0 | 1 + 0 | 13 + 0 | 19 0 | 27 0 | 29 0 | 31 - 0 | 33 1 | 0 - 1 | 1 - 1 | 2 - 1 | 4 - 1 | 6 - 1 | 8 - 1 | -1 - 1 | 10 - 1 | 12 1 | 14 1 | 16 1 | 18 - 1 | 20 1 | 22 - 1 | 24 1 | 26 - 1 | 28 - 1 | 30 1 | 32 1 | 34 2 | 1 - 3 | 0 4 | 1 - 5 | 0 6 | 1 - 7 | 0 8 | 1 - 9 | 0 - -1 | 1 - 10 | 1 - 11 | 0 - 12 | 1 13 | 0 - 14 | 1 - 15 | 0 - 16 | 1 - 17 | 0 18 | 1 19 | 0 - 20 | 1 - 21 | 0 22 | 1 23 | 0 - 24 | 1 25 | 0 - 26 | 1 - 27 | 0 - 28 | 1 29 | 0 - 30 | 1 - 31 | 0 32 | 1 33 | 0 + 0 | 5 + 0 | 9 + 0 | 21 + 0 | 25 + 1 | -1 + 1 | 1 + 1 | 2 + 1 | 6 + 1 | 10 + 1 | 12 + 1 | 20 + 1 | 30 + 7 | 0 + 10 | 1 + 12 | 1 + 16 | 1 + 20 | 1 + 24 | 1 + 27 | 0 + 31 | 0 34 | 1 (71 rows) SELECT a from orca.m UNION ALL select b from orca.m UNION ALL select a+b from orca.m group by 1; a ---- + 1 + 3 + 9 + 14 + 17 + 22 + 24 + 26 + 28 + 29 + 30 + 32 + 34 + 1 0 0 0 + 1 0 + 1 + 1 + 1 + 1 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 1 1 1 1 - 1 - 1 - 2 - 2 2 3 - 3 - 4 - 5 + 7 + 19 + 27 + 29 5 6 7 - 7 - 8 - 9 - 9 - -1 10 11 + 16 + 23 + 25 + 31 + 1 + 0 + 1 + 0 + 1 + 0 + 1 + 0 + 0 + 0 + -1 + 5 + 9 11 - 12 13 + 17 + 21 + 25 + 33 + 0 + 2 + 4 + 8 + 12 13 - 14 15 - 15 - 16 - 17 - 17 18 19 - 19 20 21 - 21 - 22 - 23 - 23 - 24 - 25 - 25 - 26 - 27 27 - 28 - 29 - 29 - 30 - 31 - 31 - 32 - 33 33 - 34 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 1 + 0 + 0 + 0 + 2 + 0 + 1 + 15 + 23 + 31 35 (96 rows) @@ -4584,69 +4588,69 @@ insert into orca.bar select i, i%3, i%2 from generate_series(1,30)i; SELECT distinct a, b from orca.foo; a | b ----+--- - 2 | 0 - 4 | 0 - 6 | 0 - 8 | 0 - 10 | 0 + 1 | 1 12 | 0 - 14 | 0 - 16 | 0 - 18 | 0 + 15 | 1 20 | 0 - 22 | 0 - 24 | 0 + 23 | 1 26 | 0 - 28 | 0 30 | 0 - 32 | 0 - 34 | 0 + 31 | 1 + 35 | 1 36 | 0 38 | 0 40 | 0 - 1 | 1 + 2 | 0 3 | 1 - 5 | 1 + 4 | 0 7 | 1 + 8 | 0 + 16 | 0 + 18 | 0 + 19 | 1 + 22 | 0 + 24 | 0 + 27 | 1 + 29 | 1 + 34 | 0 + 37 | 1 + 39 | 1 + 5 | 1 + 6 | 0 9 | 1 + 10 | 0 11 | 1 13 | 1 - 15 | 1 + 14 | 0 17 | 1 - 19 | 1 21 | 1 - 23 | 1 25 | 1 - 27 | 1 - 29 | 1 - 31 | 1 + 28 | 0 + 32 | 0 33 | 1 - 35 | 1 - 37 | 1 - 39 | 1 (40 rows) SELECT distinct foo.a, bar.b from orca.foo, orca.bar where foo.b = bar.a; a | b ----+--- - 1 | 1 - 3 | 1 5 | 1 7 | 1 - 9 | 1 - 11 | 1 - 13 | 1 15 | 1 - 17 | 1 19 | 1 21 | 1 - 23 | 1 - 25 | 1 27 | 1 - 29 | 1 + 35 | 1 + 3 | 1 + 9 | 1 + 11 | 1 + 23 | 1 31 | 1 33 | 1 - 35 | 1 + 1 | 1 + 13 | 1 + 17 | 1 + 25 | 1 + 29 | 1 37 | 1 39 | 1 (20 rows) @@ -4654,351 +4658,351 @@ SELECT distinct foo.a, bar.b from orca.foo, orca.bar where foo.b = bar.a; SELECT distinct a, b from orca.foo; a | b ----+--- - 1 | 1 + 2 | 0 3 | 1 - 5 | 1 + 4 | 0 7 | 1 - 9 | 1 - 11 | 1 - 13 | 1 - 15 | 1 - 17 | 1 + 8 | 0 + 16 | 0 + 18 | 0 19 | 1 - 21 | 1 - 23 | 1 - 25 | 1 + 22 | 0 + 24 | 0 27 | 1 29 | 1 - 31 | 1 - 33 | 1 - 35 | 1 + 34 | 0 37 | 1 39 | 1 - 2 | 0 - 4 | 0 - 6 | 0 - 8 | 0 - 10 | 0 + 1 | 1 12 | 0 - 14 | 0 - 16 | 0 - 18 | 0 + 15 | 1 20 | 0 - 22 | 0 - 24 | 0 + 23 | 1 26 | 0 - 28 | 0 30 | 0 - 32 | 0 - 34 | 0 + 31 | 1 + 35 | 1 36 | 0 38 | 0 40 | 0 + 5 | 1 + 6 | 0 + 9 | 1 + 10 | 0 + 11 | 1 + 13 | 1 + 14 | 0 + 17 | 1 + 21 | 1 + 25 | 1 + 28 | 0 + 32 | 0 + 33 | 1 (40 rows) SELECT distinct a, count(*) from orca.foo group by a; a | count ----+------- - 1 | 1 2 | 1 3 | 1 4 | 1 - 5 | 1 - 6 | 1 7 | 1 8 | 1 - 9 | 1 - 10 | 1 - 11 | 1 - 12 | 1 - 13 | 1 - 14 | 1 - 15 | 1 16 | 1 - 17 | 1 18 | 1 19 | 1 - 20 | 1 - 21 | 1 22 | 1 - 23 | 1 24 | 1 - 25 | 1 - 26 | 1 27 | 1 - 28 | 1 29 | 1 + 34 | 1 + 37 | 1 + 39 | 1 + 1 | 1 + 12 | 1 + 15 | 1 + 20 | 1 + 23 | 1 + 26 | 1 30 | 1 31 | 1 - 32 | 1 - 33 | 1 - 34 | 1 35 | 1 36 | 1 - 37 | 1 38 | 1 - 39 | 1 40 | 1 + 5 | 1 + 6 | 1 + 9 | 1 + 10 | 1 + 11 | 1 + 13 | 1 + 14 | 1 + 17 | 1 + 21 | 1 + 25 | 1 + 28 | 1 + 32 | 1 + 33 | 1 (40 rows) SELECT distinct foo.a, bar.b, sum(bar.c+foo.c) from orca.foo, orca.bar where foo.b = bar.a group by foo.a, bar.b; a | b | sum ----+---+----- - 1 | 1 | 2 - 3 | 1 | 4 5 | 1 | 2 7 | 1 | 4 - 9 | 1 | 2 - 11 | 1 | 4 - 13 | 1 | 2 15 | 1 | 4 - 17 | 1 | 2 19 | 1 | 4 21 | 1 | 2 - 23 | 1 | 4 - 25 | 1 | 2 27 | 1 | 4 - 29 | 1 | 2 - 31 | 1 | 4 - 33 | 1 | 2 35 | 1 | 4 + 1 | 1 | 2 + 13 | 1 | 2 + 17 | 1 | 2 + 25 | 1 | 2 + 29 | 1 | 2 37 | 1 | 2 39 | 1 | 4 + 3 | 1 | 4 + 9 | 1 | 2 + 11 | 1 | 4 + 23 | 1 | 4 + 31 | 1 | 4 + 33 | 1 | 2 (20 rows) SELECT distinct a, count(*) from orca.foo group by a; a | count ----+------- - 1 | 1 2 | 1 3 | 1 4 | 1 - 5 | 1 - 6 | 1 7 | 1 8 | 1 - 9 | 1 - 10 | 1 - 11 | 1 - 12 | 1 - 13 | 1 - 14 | 1 - 15 | 1 16 | 1 - 17 | 1 18 | 1 19 | 1 - 20 | 1 - 21 | 1 22 | 1 - 23 | 1 24 | 1 - 25 | 1 - 26 | 1 27 | 1 - 28 | 1 29 | 1 + 34 | 1 + 37 | 1 + 39 | 1 + 1 | 1 + 12 | 1 + 15 | 1 + 20 | 1 + 23 | 1 + 26 | 1 30 | 1 31 | 1 - 32 | 1 - 33 | 1 - 34 | 1 35 | 1 36 | 1 - 37 | 1 38 | 1 - 39 | 1 40 | 1 + 5 | 1 + 6 | 1 + 9 | 1 + 10 | 1 + 11 | 1 + 13 | 1 + 14 | 1 + 17 | 1 + 21 | 1 + 25 | 1 + 28 | 1 + 32 | 1 + 33 | 1 (40 rows) SELECT distinct foo.a, bar.b from orca.foo, orca.bar where foo.b = bar.a; a | b ----+--- - 1 | 1 - 3 | 1 5 | 1 7 | 1 - 9 | 1 - 11 | 1 - 13 | 1 15 | 1 - 17 | 1 19 | 1 21 | 1 - 23 | 1 - 25 | 1 27 | 1 - 29 | 1 - 31 | 1 - 33 | 1 35 | 1 + 1 | 1 + 13 | 1 + 17 | 1 + 25 | 1 + 29 | 1 37 | 1 39 | 1 + 3 | 1 + 9 | 1 + 11 | 1 + 23 | 1 + 31 | 1 + 33 | 1 (20 rows) SELECT distinct foo.a, bar.b, sum(bar.c+foo.c) from orca.foo, orca.bar where foo.b = bar.a group by foo.a, bar.b; a | b | sum ----+---+----- - 1 | 1 | 2 - 3 | 1 | 4 5 | 1 | 2 7 | 1 | 4 - 9 | 1 | 2 - 11 | 1 | 4 - 13 | 1 | 2 15 | 1 | 4 - 17 | 1 | 2 19 | 1 | 4 21 | 1 | 2 - 23 | 1 | 4 - 25 | 1 | 2 27 | 1 | 4 - 29 | 1 | 2 - 31 | 1 | 4 - 33 | 1 | 2 35 | 1 | 4 + 1 | 1 | 2 + 13 | 1 | 2 + 17 | 1 | 2 + 25 | 1 | 2 + 29 | 1 | 2 37 | 1 | 2 39 | 1 | 4 + 3 | 1 | 4 + 9 | 1 | 2 + 11 | 1 | 4 + 23 | 1 | 4 + 31 | 1 | 4 + 33 | 1 | 2 (20 rows) SELECT distinct a, b from orca.foo; a | b ----+--- - 2 | 0 - 4 | 0 - 6 | 0 - 8 | 0 - 10 | 0 + 1 | 1 12 | 0 - 14 | 0 - 16 | 0 - 18 | 0 + 15 | 1 20 | 0 - 22 | 0 - 24 | 0 + 23 | 1 26 | 0 - 28 | 0 30 | 0 - 32 | 0 - 34 | 0 + 31 | 1 + 35 | 1 36 | 0 38 | 0 40 | 0 - 1 | 1 + 2 | 0 3 | 1 - 5 | 1 + 4 | 0 7 | 1 + 8 | 0 + 16 | 0 + 18 | 0 + 19 | 1 + 22 | 0 + 24 | 0 + 27 | 1 + 29 | 1 + 34 | 0 + 37 | 1 + 39 | 1 + 5 | 1 + 6 | 0 9 | 1 + 10 | 0 11 | 1 13 | 1 - 15 | 1 + 14 | 0 17 | 1 - 19 | 1 21 | 1 - 23 | 1 25 | 1 - 27 | 1 - 29 | 1 - 31 | 1 + 28 | 0 + 32 | 0 33 | 1 - 35 | 1 - 37 | 1 - 39 | 1 (40 rows) SELECT distinct a, count(*) from orca.foo group by a; a | count ----+------- - 1 | 1 2 | 1 3 | 1 4 | 1 - 5 | 1 - 6 | 1 7 | 1 8 | 1 - 9 | 1 - 10 | 1 - 11 | 1 - 12 | 1 - 13 | 1 - 14 | 1 - 15 | 1 16 | 1 - 17 | 1 18 | 1 19 | 1 - 20 | 1 - 21 | 1 22 | 1 - 23 | 1 24 | 1 - 25 | 1 - 26 | 1 27 | 1 - 28 | 1 29 | 1 + 34 | 1 + 37 | 1 + 39 | 1 + 1 | 1 + 12 | 1 + 15 | 1 + 20 | 1 + 23 | 1 + 26 | 1 30 | 1 31 | 1 - 32 | 1 - 33 | 1 - 34 | 1 35 | 1 36 | 1 - 37 | 1 38 | 1 - 39 | 1 40 | 1 + 5 | 1 + 6 | 1 + 9 | 1 + 10 | 1 + 11 | 1 + 13 | 1 + 14 | 1 + 17 | 1 + 21 | 1 + 25 | 1 + 28 | 1 + 32 | 1 + 33 | 1 (40 rows) SELECT distinct foo.a, bar.b from orca.foo, orca.bar where foo.b = bar.a; a | b ----+--- - 1 | 1 3 | 1 - 5 | 1 - 7 | 1 9 | 1 11 | 1 + 23 | 1 + 31 | 1 + 33 | 1 + 1 | 1 13 | 1 - 15 | 1 17 | 1 - 19 | 1 - 21 | 1 - 23 | 1 25 | 1 - 27 | 1 29 | 1 - 31 | 1 - 33 | 1 - 35 | 1 37 | 1 39 | 1 + 5 | 1 + 7 | 1 + 15 | 1 + 19 | 1 + 21 | 1 + 27 | 1 + 35 | 1 (20 rows) SELECT distinct foo.a, bar.b, sum(bar.c+foo.c) from orca.foo, orca.bar where foo.b = bar.a group by foo.a, bar.b; a | b | sum ----+---+----- - 1 | 1 | 2 - 3 | 1 | 4 5 | 1 | 2 7 | 1 | 4 - 9 | 1 | 2 - 11 | 1 | 4 - 13 | 1 | 2 15 | 1 | 4 - 17 | 1 | 2 19 | 1 | 4 21 | 1 | 2 - 23 | 1 | 4 - 25 | 1 | 2 27 | 1 | 4 - 29 | 1 | 2 - 31 | 1 | 4 - 33 | 1 | 2 35 | 1 | 4 + 1 | 1 | 2 + 13 | 1 | 2 + 17 | 1 | 2 + 25 | 1 | 2 + 29 | 1 | 2 37 | 1 | 2 39 | 1 | 4 + 3 | 1 | 4 + 9 | 1 | 2 + 11 | 1 | 4 + 23 | 1 | 4 + 31 | 1 | 4 + 33 | 1 | 2 (20 rows) -- window operations @@ -6641,9 +6645,9 @@ select (select a+1 from (select a from orca_w2 where orca_w1.a=orca_w2.a) sq(a)) select (select a+1 from (select a from orca_w2 where sq2.a=orca_w2.a) sq1(a)) as one, row_number() over(partition by sq2.a) as two from (select 1,1,1,a from orca_w1) sq2(x,y,z,a); one | two -----+----- - | 1 3 | 1 4 | 1 + | 1 (3 rows) -- cte in scalar subquery @@ -6721,46 +6725,46 @@ select rank() over(partition by a, case when b = 0 then a+b end order by b asc) select foo.d from orca.foo full join orca.bar on (foo.d = bar.a) group by d; d ---- + 0 1 - 3 + 12 + 15 + 20 + 23 + 26 + 30 + 31 + 35 + 36 + 38 5 - 7 + 6 9 + 10 11 13 - 15 + 14 17 - 19 21 - 23 25 - 27 - 29 - 31 + 28 + 32 33 - 35 - 37 - 39 - 0 2 + 3 4 - 6 + 7 8 - 10 - 12 - 14 16 18 - 20 + 19 22 24 - 26 - 28 - 30 - 32 + 27 + 29 34 - 36 - 38 + 37 + 39 (40 rows) select 1 as v from orca.foo full join orca.bar on (foo.d = bar.a) group by d; @@ -6848,87 +6852,87 @@ insert into orca.rcte select i, i%2, i%3 from generate_series(1,40)i; with x as (select * from orca.rcte where a < 10) select * from x x1, x x2; a | b | c | a | b | c ---+---+---+---+---+--- - 2 | 0 | 2 | 1 | 1 | 1 - 4 | 0 | 1 | 1 | 1 | 1 - 6 | 0 | 0 | 1 | 1 | 1 - 8 | 0 | 2 | 1 | 1 | 1 + 2 | 0 | 2 | 2 | 0 | 2 2 | 0 | 2 | 3 | 1 | 0 - 4 | 0 | 1 | 3 | 1 | 0 - 6 | 0 | 0 | 3 | 1 | 0 - 8 | 0 | 2 | 3 | 1 | 0 - 2 | 0 | 2 | 5 | 1 | 2 - 4 | 0 | 1 | 5 | 1 | 2 - 6 | 0 | 0 | 5 | 1 | 2 - 8 | 0 | 2 | 5 | 1 | 2 + 2 | 0 | 2 | 4 | 0 | 1 2 | 0 | 2 | 7 | 1 | 1 - 4 | 0 | 1 | 7 | 1 | 1 - 6 | 0 | 0 | 7 | 1 | 1 - 8 | 0 | 2 | 7 | 1 | 1 + 2 | 0 | 2 | 8 | 0 | 2 + 2 | 0 | 2 | 5 | 1 | 2 + 2 | 0 | 2 | 6 | 0 | 0 2 | 0 | 2 | 9 | 1 | 0 - 4 | 0 | 1 | 9 | 1 | 0 - 6 | 0 | 0 | 9 | 1 | 0 - 8 | 0 | 2 | 9 | 1 | 0 - 2 | 0 | 2 | 2 | 0 | 2 + 2 | 0 | 2 | 1 | 1 | 1 + 3 | 1 | 0 | 2 | 0 | 2 + 3 | 1 | 0 | 3 | 1 | 0 + 3 | 1 | 0 | 4 | 0 | 1 + 3 | 1 | 0 | 7 | 1 | 1 + 3 | 1 | 0 | 8 | 0 | 2 + 3 | 1 | 0 | 5 | 1 | 2 + 3 | 1 | 0 | 6 | 0 | 0 + 3 | 1 | 0 | 9 | 1 | 0 + 3 | 1 | 0 | 1 | 1 | 1 4 | 0 | 1 | 2 | 0 | 2 - 6 | 0 | 0 | 2 | 0 | 2 - 8 | 0 | 2 | 2 | 0 | 2 - 2 | 0 | 2 | 4 | 0 | 1 + 4 | 0 | 1 | 3 | 1 | 0 4 | 0 | 1 | 4 | 0 | 1 - 6 | 0 | 0 | 4 | 0 | 1 - 8 | 0 | 2 | 4 | 0 | 1 - 2 | 0 | 2 | 6 | 0 | 0 - 4 | 0 | 1 | 6 | 0 | 0 - 6 | 0 | 0 | 6 | 0 | 0 - 8 | 0 | 2 | 6 | 0 | 0 - 2 | 0 | 2 | 8 | 0 | 2 + 4 | 0 | 1 | 7 | 1 | 1 4 | 0 | 1 | 8 | 0 | 2 - 6 | 0 | 0 | 8 | 0 | 2 - 8 | 0 | 2 | 8 | 0 | 2 - 1 | 1 | 1 | 1 | 1 | 1 - 3 | 1 | 0 | 1 | 1 | 1 - 5 | 1 | 2 | 1 | 1 | 1 - 7 | 1 | 1 | 1 | 1 | 1 - 9 | 1 | 0 | 1 | 1 | 1 - 1 | 1 | 1 | 3 | 1 | 0 - 3 | 1 | 0 | 3 | 1 | 0 - 5 | 1 | 2 | 3 | 1 | 0 + 4 | 0 | 1 | 5 | 1 | 2 + 4 | 0 | 1 | 6 | 0 | 0 + 4 | 0 | 1 | 9 | 1 | 0 + 4 | 0 | 1 | 1 | 1 | 1 + 7 | 1 | 1 | 2 | 0 | 2 7 | 1 | 1 | 3 | 1 | 0 - 9 | 1 | 0 | 3 | 1 | 0 - 1 | 1 | 1 | 5 | 1 | 2 - 3 | 1 | 0 | 5 | 1 | 2 - 5 | 1 | 2 | 5 | 1 | 2 - 7 | 1 | 1 | 5 | 1 | 2 - 9 | 1 | 0 | 5 | 1 | 2 - 1 | 1 | 1 | 7 | 1 | 1 - 3 | 1 | 0 | 7 | 1 | 1 - 5 | 1 | 2 | 7 | 1 | 1 + 7 | 1 | 1 | 4 | 0 | 1 7 | 1 | 1 | 7 | 1 | 1 - 9 | 1 | 0 | 7 | 1 | 1 - 1 | 1 | 1 | 9 | 1 | 0 - 3 | 1 | 0 | 9 | 1 | 0 - 5 | 1 | 2 | 9 | 1 | 0 + 7 | 1 | 1 | 8 | 0 | 2 + 7 | 1 | 1 | 5 | 1 | 2 + 7 | 1 | 1 | 6 | 0 | 0 7 | 1 | 1 | 9 | 1 | 0 - 9 | 1 | 0 | 9 | 1 | 0 - 1 | 1 | 1 | 2 | 0 | 2 - 3 | 1 | 0 | 2 | 0 | 2 + 7 | 1 | 1 | 1 | 1 | 1 + 8 | 0 | 2 | 2 | 0 | 2 + 8 | 0 | 2 | 3 | 1 | 0 + 8 | 0 | 2 | 4 | 0 | 1 + 8 | 0 | 2 | 7 | 1 | 1 + 8 | 0 | 2 | 8 | 0 | 2 + 8 | 0 | 2 | 5 | 1 | 2 + 8 | 0 | 2 | 6 | 0 | 0 + 8 | 0 | 2 | 9 | 1 | 0 + 8 | 0 | 2 | 1 | 1 | 1 5 | 1 | 2 | 2 | 0 | 2 - 7 | 1 | 1 | 2 | 0 | 2 - 9 | 1 | 0 | 2 | 0 | 2 - 1 | 1 | 1 | 4 | 0 | 1 - 3 | 1 | 0 | 4 | 0 | 1 + 5 | 1 | 2 | 3 | 1 | 0 5 | 1 | 2 | 4 | 0 | 1 - 7 | 1 | 1 | 4 | 0 | 1 - 9 | 1 | 0 | 4 | 0 | 1 - 1 | 1 | 1 | 6 | 0 | 0 - 3 | 1 | 0 | 6 | 0 | 0 + 5 | 1 | 2 | 7 | 1 | 1 + 5 | 1 | 2 | 8 | 0 | 2 + 5 | 1 | 2 | 5 | 1 | 2 5 | 1 | 2 | 6 | 0 | 0 - 7 | 1 | 1 | 6 | 0 | 0 + 5 | 1 | 2 | 9 | 1 | 0 + 5 | 1 | 2 | 1 | 1 | 1 + 6 | 0 | 0 | 2 | 0 | 2 + 6 | 0 | 0 | 3 | 1 | 0 + 6 | 0 | 0 | 4 | 0 | 1 + 6 | 0 | 0 | 7 | 1 | 1 + 6 | 0 | 0 | 8 | 0 | 2 + 6 | 0 | 0 | 5 | 1 | 2 + 6 | 0 | 0 | 6 | 0 | 0 + 6 | 0 | 0 | 9 | 1 | 0 + 6 | 0 | 0 | 1 | 1 | 1 + 9 | 1 | 0 | 2 | 0 | 2 + 9 | 1 | 0 | 3 | 1 | 0 + 9 | 1 | 0 | 4 | 0 | 1 + 9 | 1 | 0 | 7 | 1 | 1 + 9 | 1 | 0 | 8 | 0 | 2 + 9 | 1 | 0 | 5 | 1 | 2 9 | 1 | 0 | 6 | 0 | 0 + 9 | 1 | 0 | 9 | 1 | 0 + 9 | 1 | 0 | 1 | 1 | 1 + 1 | 1 | 1 | 2 | 0 | 2 + 1 | 1 | 1 | 3 | 1 | 0 + 1 | 1 | 1 | 4 | 0 | 1 + 1 | 1 | 1 | 7 | 1 | 1 1 | 1 | 1 | 8 | 0 | 2 - 3 | 1 | 0 | 8 | 0 | 2 - 5 | 1 | 2 | 8 | 0 | 2 - 7 | 1 | 1 | 8 | 0 | 2 - 9 | 1 | 0 | 8 | 0 | 2 + 1 | 1 | 1 | 5 | 1 | 2 + 1 | 1 | 1 | 6 | 0 | 0 + 1 | 1 | 1 | 9 | 1 | 0 + 1 | 1 | 1 | 1 | 1 | 1 (81 rows) with x as (select * from orca.rcte where a < 10) select * from x x1, x x2 where x2.a = x1.b; @@ -6936,8 +6940,8 @@ with x as (select * from orca.rcte where a < 10) select * from x x1, x x2 where ---+---+---+---+---+--- 1 | 1 | 1 | 1 | 1 | 1 3 | 1 | 0 | 1 | 1 | 1 - 5 | 1 | 2 | 1 | 1 | 1 7 | 1 | 1 | 1 | 1 | 1 + 5 | 1 | 2 | 1 | 1 | 1 9 | 1 | 0 | 1 | 1 | 1 (5 rows) @@ -6945,20 +6949,20 @@ with x as (select * from orca.rcte where a < 10) select a from x union all selec a --- 2 + 3 4 - 6 + 7 8 0 - 0 - 0 + 1 0 1 - 3 + 0 5 - 7 + 6 9 1 - 1 + 0 1 1 1 @@ -6968,10 +6972,10 @@ with x as (select * from orca.rcte where a < 10) select * from x x1 where x1.b = a | b | c ---+---+--- 1 | 1 | 1 - 3 | 1 | 0 5 | 1 | 2 - 7 | 1 | 1 9 | 1 | 0 + 3 | 1 | 0 + 7 | 1 | 1 (5 rows) with x as (select * from orca.rcte where a < 10) select * from x x1 where x1.b = all (select x2.a from x x2 group by x2.a); @@ -6982,39 +6986,39 @@ with x as (select * from orca.rcte where a < 10) select * from x x1 where x1.b = with x as (select * from orca.rcte where a < 10) select * from x x1, x x2, x x3 where x2.a = x1.b and x3.b = x2.b ; a | b | c | a | b | c | a | b | c ---+---+---+---+---+---+---+---+--- - 1 | 1 | 1 | 1 | 1 | 1 | 9 | 1 | 0 - 1 | 1 | 1 | 1 | 1 | 1 | 7 | 1 | 1 - 1 | 1 | 1 | 1 | 1 | 1 | 5 | 1 | 2 - 1 | 1 | 1 | 1 | 1 | 1 | 3 | 1 | 0 - 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 - 3 | 1 | 0 | 1 | 1 | 1 | 9 | 1 | 0 - 3 | 1 | 0 | 1 | 1 | 1 | 7 | 1 | 1 - 3 | 1 | 0 | 1 | 1 | 1 | 5 | 1 | 2 - 3 | 1 | 0 | 1 | 1 | 1 | 3 | 1 | 0 - 3 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 - 5 | 1 | 2 | 1 | 1 | 1 | 9 | 1 | 0 5 | 1 | 2 | 1 | 1 | 1 | 7 | 1 | 1 - 5 | 1 | 2 | 1 | 1 | 1 | 5 | 1 | 2 5 | 1 | 2 | 1 | 1 | 1 | 3 | 1 | 0 + 5 | 1 | 2 | 1 | 1 | 1 | 9 | 1 | 0 + 5 | 1 | 2 | 1 | 1 | 1 | 5 | 1 | 2 5 | 1 | 2 | 1 | 1 | 1 | 1 | 1 | 1 - 7 | 1 | 1 | 1 | 1 | 1 | 9 | 1 | 0 - 7 | 1 | 1 | 1 | 1 | 1 | 7 | 1 | 1 - 7 | 1 | 1 | 1 | 1 | 1 | 5 | 1 | 2 - 7 | 1 | 1 | 1 | 1 | 1 | 3 | 1 | 0 - 7 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 - 9 | 1 | 0 | 1 | 1 | 1 | 9 | 1 | 0 9 | 1 | 0 | 1 | 1 | 1 | 7 | 1 | 1 - 9 | 1 | 0 | 1 | 1 | 1 | 5 | 1 | 2 9 | 1 | 0 | 1 | 1 | 1 | 3 | 1 | 0 + 9 | 1 | 0 | 1 | 1 | 1 | 9 | 1 | 0 + 9 | 1 | 0 | 1 | 1 | 1 | 5 | 1 | 2 9 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 + 3 | 1 | 0 | 1 | 1 | 1 | 7 | 1 | 1 + 3 | 1 | 0 | 1 | 1 | 1 | 3 | 1 | 0 + 3 | 1 | 0 | 1 | 1 | 1 | 9 | 1 | 0 + 3 | 1 | 0 | 1 | 1 | 1 | 5 | 1 | 2 + 3 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 + 7 | 1 | 1 | 1 | 1 | 1 | 7 | 1 | 1 + 7 | 1 | 1 | 1 | 1 | 1 | 3 | 1 | 0 + 7 | 1 | 1 | 1 | 1 | 1 | 9 | 1 | 0 + 7 | 1 | 1 | 1 | 1 | 1 | 5 | 1 | 2 + 7 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 + 1 | 1 | 1 | 1 | 1 | 1 | 7 | 1 | 1 + 1 | 1 | 1 | 1 | 1 | 1 | 3 | 1 | 0 + 1 | 1 | 1 | 1 | 1 | 1 | 9 | 1 | 0 + 1 | 1 | 1 | 1 | 1 | 1 | 5 | 1 | 2 + 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 (25 rows) with x as (select * from orca.rcte where a < 10) select * from x x2 where x2.b < (select avg(b) from x x1); a | b | c ---+---+--- + 6 | 0 | 0 2 | 0 | 2 4 | 0 | 1 - 6 | 0 | 0 8 | 0 | 2 (4 rows) @@ -7251,695 +7255,695 @@ with x as (select r.a from orca.r, orca.s where r.a < 10 and s.d < 10 and r.a = with x as (select r.a from orca.r, orca.s where r.a < 10 and s.c < 10 and r.a = s.c) select * from x x1, x x2; a | a ---+--- - 1 | 1 - 3 | 1 - 5 | 1 - 1 | 1 - 3 | 1 - 5 | 1 - 1 | 1 - 3 | 1 - 5 | 1 - 1 | 1 - 3 | 1 - 5 | 1 - 1 | 1 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 1 | 1 - 3 | 1 - 5 | 1 - 1 | 1 - 3 | 1 - 5 | 1 - 1 | 1 - 3 | 1 - 5 | 1 - 1 | 1 - 3 | 1 - 5 | 1 - 1 | 1 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 3 | 3 - 5 | 3 - 1 | 3 - 3 | 3 + 5 | 2 5 | 3 - 1 | 3 - 3 | 3 + 5 | 4 + 5 | 2 5 | 3 - 1 | 3 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 1 | 1 - 3 | 1 - 5 | 1 - 1 | 1 - 3 | 1 - 5 | 1 - 1 | 1 - 3 | 1 - 5 | 1 - 1 | 1 - 3 | 1 - 5 | 1 - 1 | 1 - 1 | 3 - 3 | 3 + 5 | 4 + 5 | 2 5 | 3 - 1 | 3 - 3 | 3 + 5 | 4 + 5 | 2 5 | 3 - 1 | 3 - 3 | 3 + 5 | 4 + 5 | 2 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 5 | 2 5 | 3 - 1 | 3 - 3 | 3 + 5 | 4 + 5 | 2 5 | 3 - 1 | 3 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 1 | 1 - 3 | 1 - 5 | 1 - 1 | 1 - 3 | 1 - 5 | 1 - 1 | 1 - 3 | 1 - 5 | 1 - 1 | 1 - 3 | 1 - 5 | 1 - 1 | 1 - 1 | 3 - 3 | 3 + 5 | 4 + 5 | 2 5 | 3 - 1 | 3 - 3 | 3 + 5 | 4 + 5 | 2 5 | 3 - 1 | 3 - 3 | 3 + 5 | 4 + 5 | 2 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 5 | 2 5 | 3 - 1 | 3 - 3 | 3 + 5 | 4 + 5 | 2 5 | 3 - 1 | 3 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 3 | 5 - 5 | 5 - 1 | 5 - 1 | 1 - 3 | 1 - 5 | 1 - 1 | 1 - 3 | 1 - 5 | 1 - 1 | 1 - 3 | 1 - 5 | 1 - 1 | 1 - 3 | 1 - 5 | 1 - 1 | 1 - 1 | 2 - 3 | 2 + 5 | 4 5 | 2 - 1 | 2 - 3 | 2 + 5 | 3 + 5 | 4 5 | 2 - 1 | 2 - 3 | 2 + 5 | 3 + 5 | 4 5 | 2 - 1 | 2 - 3 | 2 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 5 | 2 - 1 | 2 - 1 | 4 - 3 | 4 + 5 | 3 5 | 4 - 1 | 4 - 3 | 4 + 5 | 2 + 5 | 3 5 | 4 - 1 | 4 - 3 | 4 + 5 | 2 + 5 | 3 5 | 4 - 1 | 4 - 3 | 4 + 5 | 2 + 5 | 3 5 | 4 - 1 | 4 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 1 | 2 - 3 | 2 5 | 2 - 1 | 2 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 6 | 3 + 6 | 4 + 6 | 2 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 3 | 2 - 5 | 2 - 1 | 2 + 3 | 3 + 3 | 4 3 | 2 - 5 | 2 - 1 | 2 + 3 | 3 + 3 | 4 3 | 2 - 5 | 2 - 1 | 2 - 1 | 4 + 3 | 3 3 | 4 - 5 | 4 - 1 | 4 + 3 | 2 + 3 | 3 3 | 4 - 5 | 4 - 1 | 4 + 3 | 2 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 3 | 2 + 3 | 3 3 | 4 - 5 | 4 - 1 | 4 + 3 | 2 + 3 | 3 3 | 4 - 5 | 4 - 1 | 4 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 1 | 2 3 | 2 - 5 | 2 - 1 | 2 + 3 | 3 + 3 | 4 3 | 2 - 5 | 2 - 1 | 2 + 3 | 3 + 3 | 4 3 | 2 - 5 | 2 - 1 | 2 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 3 | 2 - 5 | 2 - 1 | 2 - 1 | 4 + 3 | 3 3 | 4 - 5 | 4 - 1 | 4 + 3 | 2 + 3 | 3 3 | 4 - 5 | 4 - 1 | 4 + 3 | 2 + 3 | 3 3 | 4 - 5 | 4 - 1 | 4 + 3 | 2 + 3 | 3 3 | 4 - 5 | 4 - 1 | 4 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 1 | 2 3 | 2 - 5 | 2 - 1 | 2 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 3 | 2 - 5 | 2 - 1 | 2 + 3 | 3 + 3 | 4 3 | 2 - 5 | 2 - 1 | 2 + 3 | 3 + 3 | 4 3 | 2 - 5 | 2 - 1 | 2 - 1 | 4 + 3 | 3 3 | 4 - 5 | 4 - 1 | 4 + 3 | 2 + 3 | 3 3 | 4 - 5 | 4 + 3 | 2 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 4 | 3 + 4 | 4 + 4 | 2 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 2 | 3 + 2 | 4 + 2 | 2 + 1 | 2 + 1 | 3 1 | 4 - 3 | 4 - 5 | 4 + 1 | 2 + 1 | 3 1 | 4 - 3 | 4 - 5 | 4 + 1 | 2 + 1 | 3 1 | 4 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 - 3 | 6 - 5 | 6 - 1 | 6 1 | 2 - 3 | 2 - 5 | 2 + 1 | 3 + 1 | 4 1 | 2 - 3 | 2 - 5 | 2 1 | 2 - 3 | 2 - 5 | 2 + 1 | 3 + 1 | 4 1 | 2 - 3 | 2 - 5 | 2 + 1 | 3 + 1 | 4 + 1 | 2 + 1 | 3 + 1 | 4 + 1 | 2 + 1 | 3 + 1 | 4 + 1 | 2 + 1 | 2 + 1 | 3 + 1 | 4 + 1 | 2 + 1 | 3 + 1 | 4 + 1 | 2 + 1 | 3 + 1 | 4 + 1 | 2 + 1 | 3 + 1 | 4 + 1 | 2 + 1 | 2 + 1 | 3 + 1 | 4 + 1 | 2 + 1 | 3 + 1 | 4 + 1 | 2 + 1 | 3 + 1 | 4 + 1 | 2 + 1 | 3 + 1 | 4 + 1 | 2 + 1 | 2 + 1 | 3 + 1 | 4 + 1 | 2 + 1 | 3 + 1 | 4 + 1 | 2 + 1 | 3 + 1 | 4 + 1 | 2 + 1 | 3 + 1 | 4 1 | 2 2 | 1 - 4 | 1 - 6 | 1 2 | 1 - 4 | 1 - 6 | 1 2 | 1 - 4 | 1 - 6 | 1 2 | 1 + 2 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 4 | 1 + 4 | 1 + 4 | 1 + 4 | 1 4 | 1 - 6 | 1 2 | 1 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 2 | 5 - 4 | 5 - 6 | 5 - 2 | 5 - 4 | 5 - 6 | 5 - 2 | 5 - 4 | 5 - 6 | 5 - 2 | 5 - 4 | 5 - 6 | 5 - 2 | 5 2 | 1 - 4 | 1 - 6 | 1 2 | 1 - 4 | 1 - 6 | 1 2 | 1 - 4 | 1 - 6 | 1 2 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 4 | 1 + 4 | 1 + 4 | 1 + 4 | 1 4 | 1 - 6 | 1 2 | 1 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 2 | 5 - 4 | 5 - 6 | 5 - 2 | 5 - 4 | 5 - 6 | 5 - 2 | 5 - 4 | 5 - 6 | 5 - 2 | 5 - 4 | 5 - 6 | 5 - 2 | 5 2 | 1 - 4 | 1 - 6 | 1 2 | 1 - 4 | 1 - 6 | 1 2 | 1 + 2 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 3 | 1 4 | 1 - 6 | 1 + 4 | 1 + 4 | 1 + 4 | 1 + 4 | 1 + 2 | 1 + 2 | 1 + 2 | 1 + 2 | 1 2 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 3 | 1 + 4 | 1 + 4 | 1 + 4 | 1 + 4 | 1 4 | 1 - 6 | 1 2 | 1 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 2 | 5 - 4 | 5 + 2 | 1 + 2 | 1 + 2 | 1 + 2 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 5 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 6 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 1 | 1 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 6 | 5 + 6 | 6 + 6 | 5 + 6 | 6 + 6 | 5 + 6 | 6 + 6 | 5 + 6 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 6 | 5 + 6 | 6 + 6 | 5 + 6 | 6 + 6 | 5 + 6 | 6 + 6 | 5 + 6 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 6 | 5 + 6 | 6 + 6 | 5 + 6 | 6 + 6 | 5 + 6 | 6 + 6 | 5 + 6 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 + 5 | 5 + 5 | 6 6 | 5 - 2 | 5 - 4 | 5 + 6 | 6 6 | 5 - 2 | 5 - 4 | 5 + 6 | 6 6 | 5 - 2 | 5 - 4 | 5 + 6 | 6 6 | 5 + 6 | 6 2 | 5 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 - 4 | 3 - 6 | 3 - 2 | 3 + 2 | 6 2 | 5 - 4 | 5 - 6 | 5 + 2 | 6 2 | 5 - 4 | 5 - 6 | 5 + 2 | 6 2 | 5 + 2 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 4 | 5 - 6 | 5 - 2 | 5 + 4 | 6 4 | 5 - 6 | 5 - 2 | 5 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 4 | 1 - 6 | 1 - 2 | 1 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 2 | 6 4 | 6 - 6 | 6 - 2 | 6 + 4 | 5 4 | 6 - 6 | 6 - 2 | 6 + 4 | 5 4 | 6 - 6 | 6 + 2 | 5 2 | 6 - 4 | 6 - 6 | 6 + 2 | 5 2 | 6 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 + 2 | 5 2 | 6 - 4 | 6 - 6 | 6 + 2 | 5 2 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 + 4 | 5 4 | 6 - 6 | 6 - 2 | 6 + 4 | 5 4 | 6 - 6 | 6 - 2 | 6 + 4 | 5 4 | 6 - 6 | 6 + 4 | 5 + 4 | 6 + 2 | 5 2 | 6 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 + 2 | 5 2 | 6 - 4 | 6 - 6 | 6 + 2 | 5 2 | 6 - 4 | 6 - 6 | 6 + 2 | 5 2 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 + 4 | 5 4 | 6 - 6 | 6 - 2 | 6 + 4 | 5 4 | 6 - 6 | 6 + 4 | 5 + 4 | 6 + 4 | 5 + 4 | 6 + 2 | 5 2 | 6 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 - 4 | 4 - 6 | 4 - 2 | 4 + 2 | 5 + 2 | 6 + 2 | 5 2 | 6 + 2 | 5 + 2 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 + 3 | 5 + 3 | 6 + 4 | 5 + 4 | 6 + 4 | 5 4 | 6 - 6 | 6 - 2 | 6 + 4 | 5 4 | 6 - 6 | 6 - 2 | 6 + 4 | 5 4 | 6 - 6 | 6 + 2 | 5 2 | 6 - 4 | 6 - 6 | 6 + 2 | 5 2 | 6 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 - 4 | 2 - 6 | 2 - 2 | 2 + 2 | 5 + 2 | 6 + 2 | 5 + 2 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 + 1 | 5 + 1 | 6 (676 rows) with x as (select * from orca.rcte where a < 10) (select a from x x2) union all (select max(a) from x x1); a --- 2 + 3 4 - 6 + 7 8 1 - 3 5 - 7 + 6 9 9 (10 rows) @@ -7979,7 +7983,7 @@ select (select generate_series(1,5)); ERROR: one or more assertions failed DETAIL: Expected no more than one row to be returned by expression select (select a from orca.foo inner1 where inner1.a=outer1.a union select b from orca.foo inner2 where inner2.b=outer1.b) from orca.foo outer1; -ERROR: more than one row returned by a subquery used as an expression +ERROR: more than one row returned by a subquery used as an expression (seg0 slice1 172.18.0.2:7002 pid=58796) select (select generate_series(1,1)) as series; series -------- @@ -8143,9 +8147,9 @@ having exists (select 1 from orca.onek b where sum(distinct a.four) = b.four); -----+----- 0 | 2 1 | 3 + 9 | 3 3 | 3 4 | 2 - 9 | 3 (5 rows) -- indexes on partitioned tables @@ -8164,6 +8168,8 @@ insert into orca.t select i, i::char(2), i, i, case when i%2 = 0 then 'a' else 'b' end, i from generate_series(1,100) i; select * from orca.t order by 1, 2, 3, 4, 5, 6 limit 4; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b | to_be_drop | c | d | e ---+----+------------+---+----+--- 1 | 1 | 1 | 1 | b | 1 @@ -8174,6 +8180,8 @@ select * from orca.t order by 1, 2, 3, 4, 5, 6 limit 4; alter table orca.t drop column to_be_drop; select * from orca.t order by 1, 2, 3, 4, 5 limit 4; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b | c | d | e ---+----+---+----+--- 1 | 1 | 1 | b | 1 @@ -8185,6 +8193,8 @@ select * from orca.t order by 1, 2, 3, 4, 5 limit 4; insert into orca.t (d, a) values('a', 0); insert into orca.t (a, d) values(0, 'b'); select * from orca.t order by 1, 2, 3, 4, 5 limit 4; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b | c | d | e ---+----+---+----+--- 0 | | | a | @@ -8226,6 +8236,8 @@ insert into orca.t select i, i::char(2), i, i, case when i%2 = 0 then 'a' else 'b' end, i from generate_series(1,100) i; select * from orca.t order by 1, 2, 3, 4, 5, 6 limit 4; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b | to_be_drop | c | d | e ---+----+------------+---+----+--- 1 | 1 | 1 | 1 | b | 1 @@ -8236,6 +8248,8 @@ select * from orca.t order by 1, 2, 3, 4, 5, 6 limit 4; alter table orca.t drop column to_be_drop; select * from orca.t order by 1, 2, 3, 4, 5 limit 4; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b | c | d | e ---+----+---+----+--- 1 | 1 | 1 | b | 1 @@ -8248,6 +8262,8 @@ insert into orca.t select i, i::char(2), i, case when i%2 = 0 then 'a' else 'b' end, i from generate_series(1,100) i; select * from orca.t order by 1, 2, 3, 4, 5 limit 4; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b | c | d | e ---+----+---+----+--- 1 | 1 | 1 | b | 1 @@ -8274,6 +8290,8 @@ insert into orca.t values('201207',1,'tag1','tag2'); insert into orca.t values('201208',2,'tag1','tag2'); -- test projections select * from orca.t order by 1,2; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. timest | user_id | tag1 | tag2 --------+---------+-------+------- 201203 | 0 | tag1 | tag2 @@ -8287,6 +8305,8 @@ select * from orca.t order by 1,2; -- test EXPLAIN support of partition selection nodes, while we're at it. explain select * from orca.t order by 1,2; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN ------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=24) @@ -8295,10 +8315,12 @@ explain select * from orca.t order by 1,2; Sort Key: timest, user_id -> Dynamic Seq Scan on t (cost=0.00..431.00 rows=1 width=24) Number of partitions to scan: 6 (out of 6) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) select tag2, tag1 from orca.t order by 1, 2;; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. tag2 | tag1 -------+------- tag2 | tag1 @@ -8311,6 +8333,8 @@ select tag2, tag1 from orca.t order by 1, 2;; (7 rows) select tag1, user_id from orca.t order by 1, 2; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. tag1 | user_id -------+--------- tag1 | 0 @@ -8324,6 +8348,8 @@ select tag1, user_id from orca.t order by 1, 2; insert into orca.t(user_id, timest, tag2) values(3, '201208','tag2'); select * from orca.t order by 1, 2; +NOTICE: One or more columns in the following table(s) do not have statistics: t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. timest | user_id | tag1 | tag2 --------+---------+-------+------- 201203 | 0 | tag1 | tag2 @@ -8363,6 +8389,9 @@ insert into orca.t_date values('01-03-2012'::date,8,'tag1','tag2'); insert into orca.t_date values('01-03-2012'::date,9,'tag1','tag2'); set optimizer_enable_space_pruning=off; set optimizer_enable_constant_expression_evaluation=on; +-- start_ignore +analyze orca.t_date; +-- end_ignore explain select * from orca.t_date where user_id=9; QUERY PLAN ------------------------------------------------------------------------------- @@ -8370,7 +8399,7 @@ explain select * from orca.t_date where user_id=9; -> Dynamic Seq Scan on t_date (cost=0.00..431.00 rows=1 width=20) Number of partitions to scan: 6 (out of 6) Filter: (user_id = '9'::numeric) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) select * from orca.t_date where user_id=9; @@ -8406,6 +8435,9 @@ insert into orca.t_text values('01-03-2012'::date,8,'bad','tag2'); insert into orca.t_text values('01-03-2012'::date,9,'ugly','tag2'); set optimizer_enable_space_pruning=off; set optimizer_enable_constant_expression_evaluation=on; +-- start_ignore +analyze orca.t_text; +-- end_ignore explain select * from orca.t_text where user_id=9; QUERY PLAN ------------------------------------------------------------------------------- @@ -8413,7 +8445,7 @@ explain select * from orca.t_text where user_id=9; -> Dynamic Seq Scan on t_text (cost=0.00..431.00 rows=1 width=20) Number of partitions to scan: 3 (out of 3) Filter: (user_id = '9'::numeric) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) select * from orca.t_text where user_id=9; @@ -8441,6 +8473,9 @@ insert into orca.t_ceeval_ints values(5, 102, 'tag1', 'tag2'); set optimizer_enable_space_pruning=off; set optimizer_enable_constant_expression_evaluation=on; set optimizer_use_external_constant_expression_evaluation_for_ints = on; +-- start_ignore +analyze orca.t_ceeval_ints; +-- end_ignore explain select * from orca.t_ceeval_ints where user_id=4; QUERY PLAN ------------------------------------------------------------------------------- @@ -8448,7 +8483,7 @@ explain select * from orca.t_ceeval_ints where user_id=4; -> Dynamic Seq Scan on t_ceeval_ints (cost=0.00..431.00 rows=1 width=21) Number of partitions to scan: 3 (out of 3) Filter: (user_id = '4'::numeric) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) select * from orca.t_ceeval_ints where user_id=4; @@ -8511,10 +8546,10 @@ insert into orca.fooh2 select i%3, i%2, i from generate_series(1,20) i; select sum(f1.b) from orca.fooh1 f1 group by f1.a; sum ----- - 4 6 - 5 6 + 5 + 4 (4 rows) select f1.a + 1 from fooh1 f1 group by f1.a+1 having sum(f1.a+1) + 1 > 20; @@ -8526,9 +8561,9 @@ select f1.a + 1 from fooh1 f1 group by f1.a+1 having sum(f1.a+1) + 1 > 20; select 1 as one, f1.a from orca.fooh1 f1 group by f1.a having sum(f1.b) > 4; one | a -----+--- - 1 | 2 1 | 0 1 | 1 + 1 | 2 (3 rows) select f1.a, 1 as one from orca.fooh1 f1 group by f1.a having 10 > (select f2.a from orca.fooh2 f2 group by f2.a having sum(f1.a) > count(*) order by f2.a limit 1) order by f1.a; @@ -8623,27 +8658,27 @@ select sum(f1.a+1)+1 from orca.fooh1 f1 group by f1.a+1; ?column? ---------- 11 + 16 21 6 - 16 (4 rows) select sum(f1.a+1)+sum(f1.a+1) from orca.fooh1 f1 group by f1.a+1; ?column? ---------- 20 + 30 40 10 - 30 (4 rows) select sum(f1.a+1)+avg(f1.a+1), sum(f1.a), sum(f1.a+1) from orca.fooh1 f1 group by f1.a+1; ?column? | sum | sum ------------------------+-----+----- 12.0000000000000000 | 5 | 10 + 18.0000000000000000 | 10 | 15 24.0000000000000000 | 15 | 20 6.00000000000000000000 | 0 | 5 - 18.0000000000000000 | 10 | 15 (4 rows) -- @@ -8674,27 +8709,27 @@ select a, (select sum(e) from bar where foo.b = bar.f), b, count(*) from foo, ja select foo.a, (select (foo.a + foo.b) * count(bar.e) from bar), b, count(*) from foo group by foo.a, foo.b, foo.a + foo.b; a | ?column? | b | count ---+----------+---+------- + 2 | 12 | 2 | 1 3 | 18 | 3 | 1 1 | 6 | 1 | 1 - 2 | 12 | 2 | 1 (3 rows) -- aggfunc over an outer reference in a subquery select (select sum(foo.a + bar.d) from bar) from foo group by a, b; sum ----- - 9 12 15 + 9 (3 rows) -- complex expression of aggfunc over an outer reference in a subquery select (select sum(foo.a + bar.d) + 1 from bar) from foo group by a, b; ?column? ---------- - 10 13 16 + 10 (3 rows) -- aggrefs with multiple agglevelsup @@ -8728,35 +8763,35 @@ select (select max(f) from bar where d = 1 group by a, e) from foo group by a; select a, count(*), (with cte as (select min(d) dd from bar group by e) select max(a * dd) from cte) from foo group by a; a | count | max ---+-------+----- - 1 | 1 | 3 2 | 1 | 6 3 | 1 | 9 + 1 | 1 | 3 (3 rows) -- cte with an aggfunc of outer ref in an complex expression select a, count(*), (with cte as (select e, min(d) as dd from bar group by e) select max(a) * sum(dd) from cte) from foo group by a; a | count | ?column? ---+-------+---------- + 2 | 1 | 12 3 | 1 | 18 1 | 1 | 6 - 2 | 1 | 12 (3 rows) -- subquery in group by select max(a) from foo group by (select e from bar where bar.e = foo.a); max ----- + 2 3 1 - 2 (3 rows) -- nested subquery in group by select max(a) from foo group by (select g from jazz where foo.a = (select max(a) from foo where c = 1 group by b)); max ----- - 3 1 + 3 (2 rows) -- group by inside groupby inside group by @@ -8771,9 +8806,9 @@ select max(a) from foo group by (select min(g) from jazz where foo.a = (select m select max(a) from foo group by b, (with cte as (select min(g) from jazz group by h) select a from cte); max ----- - 3 1 2 + 3 (3 rows) -- group by subquery in order by @@ -8807,17 +8842,17 @@ select b + (a+1) from foo group by b, a+1; SELECT foo.b+1, avg (( SELECT bar.f FROM bar WHERE bar.d = foo.b)) AS t FROM foo GROUP BY foo.b; ?column? | t ----------+------------------------ - 2 | 1.00000000000000000000 3 | 2.0000000000000000 4 | 3.0000000000000000 + 2 | 1.00000000000000000000 (3 rows) SELECT foo.b+1, sum( 1 + (SELECT bar.f FROM bar WHERE bar.d = ANY (SELECT jazz.g FROM jazz WHERE jazz.h = foo.b))) AS t FROM foo GROUP BY foo.b; ?column? | t ----------+--- - 2 | 3 | 3 4 | + 2 | (3 rows) select foo.b+1, sum((with cte as (select * from jazz) select 1 from cte where cte.h = foo.b)) as t FROM foo GROUP BY foo.b; @@ -8832,9 +8867,9 @@ select foo.b+1, sum((with cte as (select * from jazz) select 1 from cte where ct select foo.b+1, sum((with cte as (select * from jazz) select 1 from cte cte1, cte cte2 where cte1.h = foo.b)) as t FROM foo GROUP BY foo.b; ?column? | t ----------+--- + 2 | 3 | 1 4 | - 2 | (3 rows) drop table foo, bar, jazz; @@ -8848,9 +8883,9 @@ insert into orca.t77 select 'orange'::text; SELECT to_char(AVG( char_length(DT466.C952) ), '9999999.9999999'), MAX( char_length(DT466.C952) ) FROM orca.t77 DT466 GROUP BY char_length(DT466.C952); to_char | max ------------------+----- + 6.0000000 | 6 5.0000000 | 5 4.0000000 | 4 - 6.0000000 | 6 (3 rows) create table orca.prod9 (sale integer, prodnm varchar,price integer); @@ -8863,8 +8898,8 @@ insert into orca.prod9 values (300, 't-shirts', 300); select prodnm, price from orca.prod9 GROUP BY prodnm, price HAVING price !=300; prodnm | price --------+------- - shirts | 500 pants | 800 + shirts | 500 (2 rows) -- analyze on tables with dropped attributes @@ -8873,7 +8908,7 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into orca.toanalyze values (1,1), (2,2), (3,3); alter table orca.toanalyze drop column a; -NOTICE: dropping a column that is part of the distribution policy forces a random distribution policy +NOTICE: dropping a column that is part of the distribution policy forces a NULL distribution policy analyze orca.toanalyze; -- union create table orca.ur (a int, b int); @@ -8996,14 +9031,14 @@ select * from orca.tab1 where 0 < (select count(*) from generate_series(1,i)) or select * from orca.tab1 where i > (select b from orca.tab2); i | j ----+--- - 4 | 0 6 | 0 - 8 | 0 + 9 | 1 10 | 0 3 | 1 - 5 | 1 + 4 | 0 7 | 1 - 9 | 1 + 5 | 1 + 8 | 0 (8 rows) -- subqueries @@ -9115,6 +9150,8 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into mpp22791 values (1, 1), (2, 2), (3, 3); select * from mpp22791 where b > 1; +NOTICE: One or more columns in the following table(s) do not have statistics: mpp22791 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b ---+--- 2 | 2 @@ -9122,11 +9159,13 @@ select * from mpp22791 where b > 1; (2 rows) select * from mpp22791 where b <= 3; +NOTICE: One or more columns in the following table(s) do not have statistics: mpp22791 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b ---+--- 1 | 1 - 3 | 3 2 | 2 + 3 | 3 (3 rows) -- MPP-20713, MPP-20714, MPP-20738: Const table get with a filter @@ -9141,6 +9180,8 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into orca.p1 select * from generate_series(2,15); select count(*) from (select gp_segment_id,ctid,tableoid from orca.p1 group by gp_segment_id,ctid,tableoid) as foo; +NOTICE: One or more columns in the following table(s) do not have statistics: p1 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. count ------- 14 @@ -9902,7 +9943,7 @@ where c.cid = s.cid and s.date_sk = d.date_sk and -> Hash (cost=431.00..431.00 rows=1 width=12) -> Seq Scan on datedim d (cost=0.00..431.00 rows=1 width=12) Filter: ((year = 2001) OR (moy = 4)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (18 rows) -- Bitmap indexes @@ -9916,15 +9957,15 @@ analyze orca.bm_test; create index bm_test_idx on orca.bm_test using bitmap (i); set optimizer_enable_bitmapscan=on; explain select * from orca.bm_test where i=2 and t='2'; - QUERY PLAN + QUERY PLAN -------------------------------------------------------------------------------- - Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..204.39 rows=2 width=6) - -> Bitmap Heap Scan on bm_test (cost=0.00..204.39 rows=2 width=6) + Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..397.98 rows=2 width=6) + -> Bitmap Heap Scan on bm_test (cost=0.00..397.98 rows=1 width=6) Recheck Cond: (i = 2) Filter: (t = '2'::text) -> Bitmap Index Scan on bm_test_idx (cost=0.00..0.00 rows=0 width=0) Index Cond: (i = 2) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) select * from orca.bm_test where i=2 and t='2'; @@ -9957,6 +9998,9 @@ alter table orca.bm_dyn_test drop column to_be_dropped; alter table orca.bm_dyn_test add partition part5 values(5); insert into orca.bm_dyn_test values(2, 5, '2'); set optimizer_enable_dynamicbitmapscan=on; +-- start_ignore +analyze orca.bm_dyn_test; +-- end_ignore -- gather on 1 segment because of direct dispatch explain select * from orca.bm_dyn_test where i=2 and t='2'; QUERY PLAN @@ -9968,7 +10012,7 @@ explain select * from orca.bm_dyn_test where i=2 and t='2'; Filter: ((i = 2) AND (t = '2'::text)) -> Dynamic Bitmap Index Scan on bm_dyn_test_idx (cost=0.00..0.00 rows=0 width=0) Index Cond: (i = 2) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) select * from orca.bm_dyn_test where i=2 and t='2'; @@ -10004,6 +10048,9 @@ alter table orca.bm_dyn_test_onepart add partition part5 values(5); insert into orca.bm_dyn_test_onepart values(2, 5, '2'); set optimizer_enable_bitmapscan=on; set optimizer_enable_dynamictablescan = off; +-- start_ignore +analyze orca.bm_dyn_test_onepart; +-- end_ignore -- gather on 1 segment because of direct dispatch explain select * from orca.bm_dyn_test_onepart where i=2 and t='2'; INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner @@ -10067,10 +10114,10 @@ analyze orca.bm_dyn_test_multilvl_part; explain select * from orca.bm_dyn_test_multilvl_part where year = 2019; INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Multi-level partitioned tables - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..7.95 rows=53 width=18) - -> Append (cost=0.00..6.89 rows=18 width=18) + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..5.13 rows=59 width=18) + -> Append (cost=0.00..4.34 rows=20 width=18) -> Seq Scan on bm_dyn_test_multilvl_part_1_prt_2_2_prt_1_3_prt_usa bm_dyn_test_multilvl_part_1 (cost=0.00..1.01 rows=1 width=44) Filter: (year = 2019) -> Seq Scan on bm_dyn_test_multilvl_part_1_prt_2_2_prt_1_3_prt_other_regions bm_dyn_test_multilvl_part_2 (cost=0.00..1.01 rows=1 width=44) @@ -10309,8 +10356,8 @@ WHERE tq.sym = tt.symbol AND tt.event_ts < tq.end_ts GROUP BY 1 ORDER BY 1 asc ; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------- GroupAggregate (cost=0.00..862.00 rows=1 width=16) Group Key: ((((tt.event_ts / 100000) / 5) * 5)) -> Sort (cost=0.00..862.00 rows=1 width=8) @@ -10325,7 +10372,7 @@ ORDER BY 1 asc ; Number of partitions to scan: 2 (out of 2) -> Hash (cost=431.00..431.00 rows=1 width=24) -> Seq Scan on my_tt_agg_opt tt (cost=0.00..431.00 rows=1 width=24) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (15 rows) -- MPP-25661: IndexScan crashing for qual with reference to outer tuple @@ -10366,10 +10413,10 @@ analyze idxscan_inner; set optimizer_enable_hashjoin = off; explain select id, comment from idxscan_outer as o join idxscan_inner as i on o.id = i.productid where ordernum between 10 and 20; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..888833.21 rows=3 width=9) - -> Nested Loop (cost=0.00..888833.21 rows=1 width=9) + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..888833.23 rows=3 width=9) + -> Nested Loop (cost=0.00..888833.23 rows=1 width=9) Join Filter: (o.id = i.productid) -> Seq Scan on idxscan_outer o (cost=0.00..431.00 rows=3 width=4) -> Materialize (cost=0.00..6.00 rows=1 width=9) @@ -10377,15 +10424,15 @@ where ordernum between 10 and 20; Hash Key: i.productid -> Index Scan using idxscan_inner_ordernum_key on idxscan_inner i (cost=0.00..6.00 rows=1 width=9) Index Cond: ((ordernum >= 10) AND (ordernum <= 20)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) select id, comment from idxscan_outer as o join idxscan_inner as i on o.id = i.productid where ordernum between 10 and 20; id | comment ----+--------- - 1 | xxxx 3 | zzzz + 1 | xxxx (2 rows) reset optimizer_enable_hashjoin; @@ -10426,10 +10473,10 @@ analyze orca.index_test; explain select * from orca.index_test where a = 5; QUERY PLAN ----------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..6.00 rows=2 width=20) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..6.00 rows=1 width=20) -> Index Scan using index_test_pkey on index_test (cost=0.00..6.00 rows=1 width=20) Index Cond: (a = 5) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) -- force_explain @@ -10439,7 +10486,7 @@ explain select * from orca.index_test where c = 5; Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..6.00 rows=1 width=20) -> Index Scan using index_test_pkey on index_test (cost=0.00..6.00 rows=1 width=20) Index Cond: (c = 5) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) -- force_explain @@ -10449,7 +10496,7 @@ explain select * from orca.index_test where a = 5 and c = 5; Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..6.00 rows=1 width=20) -> Index Scan using index_test_pkey on index_test (cost=0.00..6.00 rows=1 width=20) Index Cond: ((a = 5) AND (c = 5)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) -- renaming columns @@ -10512,6 +10559,7 @@ drop table can_set_tag_target; drop table can_set_tag_audit; -- start_ignore create language plpython3u; +ERROR: extension "plpython3u" already exists -- end_ignore -- Checking if ORCA uses parser's canSetTag for CREATE TABLE AS SELECT create or replace function canSetTag_Func(x int) returns int as $$ @@ -10543,49 +10591,55 @@ select disable_xform('CXformSelect2IndexGet'); CXformSelect2IndexGet is disabled (1 row) +select disable_xform('CXformSelect2IndexOnlyGet'); + disable_xform +--------------------------------------- + CXformSelect2IndexOnlyGet is disabled +(1 row) + -- end_ignore EXPLAIN SELECT * FROM btree_test WHERE a in (1, 47); QUERY PLAN ------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..204.38 rows=3 width=8) - -> Bitmap Heap Scan on btree_test (cost=0.00..204.38 rows=1 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..387.97 rows=3 width=8) + -> Bitmap Heap Scan on btree_test (cost=0.00..387.97 rows=1 width=8) Recheck Cond: (a = ANY ('{1,47}'::integer[])) -> Bitmap Index Scan on btree_test_index (cost=0.00..0.00 rows=0 width=0) Index Cond: (a = ANY ('{1,47}'::integer[])) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (6 rows) EXPLAIN SELECT * FROM btree_test WHERE a in ('2', 47); QUERY PLAN ------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..204.38 rows=3 width=8) - -> Bitmap Heap Scan on btree_test (cost=0.00..204.38 rows=1 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..387.97 rows=3 width=8) + -> Bitmap Heap Scan on btree_test (cost=0.00..387.97 rows=1 width=8) Recheck Cond: (a = ANY ('{2,47}'::integer[])) -> Bitmap Index Scan on btree_test_index (cost=0.00..0.00 rows=0 width=0) Index Cond: (a = ANY ('{2,47}'::integer[])) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (6 rows) EXPLAIN SELECT * FROM btree_test WHERE a in ('1', '2'); QUERY PLAN ------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..204.38 rows=3 width=8) - -> Bitmap Heap Scan on btree_test (cost=0.00..204.38 rows=1 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..387.97 rows=3 width=8) + -> Bitmap Heap Scan on btree_test (cost=0.00..387.97 rows=1 width=8) Recheck Cond: (a = ANY ('{1,2}'::integer[])) -> Bitmap Index Scan on btree_test_index (cost=0.00..0.00 rows=0 width=0) Index Cond: (a = ANY ('{1,2}'::integer[])) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (6 rows) EXPLAIN SELECT * FROM btree_test WHERE a in ('1', '2', 47); QUERY PLAN ------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..613.15 rows=4 width=8) - -> Bitmap Heap Scan on btree_test (cost=0.00..613.15 rows=2 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..387.97 rows=4 width=8) + -> Bitmap Heap Scan on btree_test (cost=0.00..387.97 rows=2 width=8) Recheck Cond: (a = ANY ('{1,2,47}'::integer[])) -> Bitmap Index Scan on btree_test_index (cost=0.00..0.00 rows=0 width=0) Index Cond: (a = ANY ('{1,2,47}'::integer[])) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (6 rows) SELECT * FROM btree_test WHERE a in ('1', '2', 47); @@ -10605,14 +10659,14 @@ EXPLAIN SELECT * FROM btree_test WHERE a in (1, 2, 47) AND b > 1; Recheck Cond: ((a = ANY ('{1,2,47}'::integer[])) AND (b > 1)) -> Bitmap Index Scan on btree_test_index_ab (cost=0.00..0.00 rows=0 width=0) Index Cond: ((a = ANY ('{1,2,47}'::integer[])) AND (b > 1)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (6 rows) SELECT * FROM btree_test WHERE a in (1, 2, 47) AND b > 1; a | b ----+---- - 2 | 2 47 | 47 + 2 | 2 (2 rows) -- start_ignore @@ -10622,6 +10676,12 @@ select enable_xform('CXformSelect2IndexGet'); CXformSelect2IndexGet is enabled (1 row) +select enable_xform('CXformSelect2IndexOnlyGet'); + enable_xform +-------------------------------------- + CXformSelect2IndexOnlyGet is enabled +(1 row) + -- end_ignore reset optimizer_enable_tablescan; -- Test Bitmap index scan with in list @@ -10631,62 +10691,61 @@ CREATE INDEX bitmap_index ON bitmap_test USING BITMAP(a); EXPLAIN SELECT * FROM bitmap_test WHERE a in (1); QUERY PLAN --------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..68.82 rows=2 width=4) - -> Bitmap Heap Scan on bitmap_test (cost=0.00..68.82 rows=1 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..391.30 rows=1 width=4) + -> Bitmap Heap Scan on bitmap_test (cost=0.00..391.30 rows=1 width=4) Recheck Cond: (a = 1) -> Bitmap Index Scan on bitmap_index (cost=0.00..0.00 rows=0 width=0) Index Cond: (a = 1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (6 rows) EXPLAIN SELECT * FROM bitmap_test WHERE a in (1, 47); QUERY PLAN --------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..204.38 rows=3 width=4) - -> Bitmap Heap Scan on bitmap_test (cost=0.00..204.38 rows=1 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..407.97 rows=3 width=4) + -> Bitmap Heap Scan on bitmap_test (cost=0.00..407.97 rows=1 width=4) Recheck Cond: (a = ANY ('{1,47}'::integer[])) -> Bitmap Index Scan on bitmap_index (cost=0.00..0.00 rows=0 width=0) Index Cond: (a = ANY ('{1,47}'::integer[])) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (6 rows) EXPLAIN SELECT * FROM bitmap_test WHERE a in ('2', 47); QUERY PLAN --------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..204.38 rows=3 width=4) - -> Bitmap Heap Scan on bitmap_test (cost=0.00..204.38 rows=1 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..407.97 rows=3 width=4) + -> Bitmap Heap Scan on bitmap_test (cost=0.00..407.97 rows=1 width=4) Recheck Cond: (a = ANY ('{2,47}'::integer[])) -> Bitmap Index Scan on bitmap_index (cost=0.00..0.00 rows=0 width=0) Index Cond: (a = ANY ('{2,47}'::integer[])) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (6 rows) EXPLAIN SELECT * FROM bitmap_test WHERE a in ('1', '2'); - QUERY PLAN + QUERY PLAN --------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..204.38 rows=3 width=4) - -> Bitmap Heap Scan on bitmap_test (cost=0.00..204.38 rows=1 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..407.97 rows=3 width=4) + -> Bitmap Heap Scan on bitmap_test (cost=0.00..407.97 rows=1 width=4) Recheck Cond: (a = ANY ('{1,2}'::integer[])) -> Bitmap Index Scan on bitmap_index (cost=0.00..0.00 rows=0 width=0) Index Cond: (a = ANY ('{1,2}'::integer[])) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (6 rows) EXPLAIN SELECT * FROM bitmap_test WHERE a in ('1', '2', 47); - QUERY PLAN + QUERY PLAN --------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..417.97 rows=4 width=4) -> Bitmap Heap Scan on bitmap_test (cost=0.00..417.97 rows=2 width=4) Recheck Cond: (a = ANY ('{1,2,47}'::integer[])) -> Bitmap Index Scan on bitmap_index (cost=0.00..0.00 rows=0 width=0) Index Cond: (a = ANY ('{1,2,47}'::integer[])) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (6 rows) -- Test Logging for unsupported features in ORCA -- start_ignore drop table if exists foo; -NOTICE: table "foo" does not exist, skipping -- end_ignore create table foo(a int, b int) distributed by (a); -- The amount of log messages you get depends on a lot of options, but any @@ -10840,7 +10899,7 @@ explain select * from foo where b in ('1', '2'); Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=12) -> Seq Scan on foo (cost=0.00..431.00 rows=1 width=12) Filter: ((b)::text = ANY ('{1,2}'::text[])) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) set optimizer_enable_ctas = off; @@ -10848,7 +10907,7 @@ set log_statement='none'; set log_min_duration_statement=-1; set client_min_messages='log'; create table foo_ctas(a) as (select generate_series(1,10)) distributed by (a); -LOG: 2023-08-17 15:11:09:454388 PDT,THD000,NOTICE,"Falling back to Postgres-based planner because GPORCA does not support the following feature: CTAS. Set optimizer_enable_ctas to on to enable CTAS with GPORCA", +LOG: 2026-06-17 21:09:03:804528 PDT,THD000,NOTICE,"Falling back to Postgres-based planner because GPORCA does not support the following feature: CTAS. Set optimizer_enable_ctas to on to enable CTAS with GPORCA", INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: CTAS. Set optimizer_enable_ctas to on to enable CTAS with GPORCA reset client_min_messages; @@ -10870,8 +10929,8 @@ set optimizer_force_multistage_agg = off; set optimizer_force_three_stage_scalar_dqa = off; -- end_ignore explain (costs off) select count(*), t2.c from input_tab1 t1 left join input_tab2 t2 on t1.a = t2.c group by t2.c; - QUERY PLAN --------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> GroupAggregate Group Key: t2.c @@ -10884,7 +10943,7 @@ explain (costs off) select count(*), t2.c from input_tab1 t1 left join input_tab -> Seq Scan on input_tab1 t1 -> Hash -> Seq Scan on input_tab2 t2 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) select count(*), t2.c from input_tab1 t1 left join input_tab2 t2 on t1.a = t2.c group by t2.c; @@ -10938,7 +10997,7 @@ FROM (SELECT * -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=7) -> Seq Scan on tab_2 (cost=0.00..431.00 rows=1 width=7) -> Seq Scan on tab_3 (cost=0.00..431.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) SELECT Count(*) @@ -10976,14 +11035,14 @@ set optimizer_enable_streaming_material = on; select c1 from t_outer where not c1 =all (select c2 from t_inner); c1 ---- - 1 2 3 4 - 5 - 6 7 8 + 1 + 5 + 6 9 10 (10 rows) @@ -10992,16 +11051,16 @@ set optimizer_enable_streaming_material = off; select c1 from t_outer where not c1 =all (select c2 from t_inner); c1 ---- - 8 - 9 - 10 - 1 2 3 4 + 7 + 8 + 1 5 6 - 7 + 9 + 10 (10 rows) reset optimizer_enable_streaming_material; @@ -11130,7 +11189,6 @@ select * from x_tab; -- start_ignore drop table bar; -ERROR: table "bar" does not exist -- end_ignore -- TVF with a subplan that generates an RTABLE entry create table bar(name text); @@ -11173,15 +11231,15 @@ INSERT INTO csq_cast_param_inner VALUES EXPLAIN SELECT a FROM csq_cast_param_outer WHERE b in (SELECT CASE WHEN a > 1 THEN d ELSE '42' END FROM csq_cast_param_inner); QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.56 rows=2 width=4) - -> Seq Scan on csq_cast_param_outer (cost=0.00..1324032.56 rows=1 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.39 rows=1 width=4) + -> Seq Scan on csq_cast_param_outer (cost=0.00..1324032.39 rows=1 width=4) Filter: (SubPlan 1) SubPlan 1 - -> Result (cost=0.00..431.00 rows=2 width=4) - -> Materialize (cost=0.00..431.00 rows=2 width=4) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=2 width=4) + -> Result (cost=0.00..431.00 rows=1 width=4) + -> Materialize (cost=0.00..431.00 rows=1 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on csq_cast_param_inner (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) SELECT a FROM csq_cast_param_outer WHERE b in (SELECT CASE WHEN a > 1 THEN d ELSE '42' END FROM csq_cast_param_inner); @@ -11197,15 +11255,15 @@ CREATE CAST (myint AS numeric) WITH FUNCTION myint_numeric(myint) AS IMPLICIT; EXPLAIN SELECT a FROM csq_cast_param_outer WHERE b in (SELECT CASE WHEN a > 1 THEN d ELSE '42' END FROM csq_cast_param_inner); QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.56 rows=2 width=4) - -> Seq Scan on csq_cast_param_outer (cost=0.00..1324032.56 rows=1 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.39 rows=1 width=4) + -> Seq Scan on csq_cast_param_outer (cost=0.00..1324032.39 rows=1 width=4) Filter: (SubPlan 1) SubPlan 1 - -> Result (cost=0.00..431.00 rows=2 width=4) - -> Materialize (cost=0.00..431.00 rows=2 width=4) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=2 width=4) + -> Result (cost=0.00..431.00 rows=1 width=4) + -> Materialize (cost=0.00..431.00 rows=1 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on csq_cast_param_inner (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) SELECT a FROM csq_cast_param_outer WHERE b in (SELECT CASE WHEN a > 1 THEN d ELSE '42' END FROM csq_cast_param_inner); @@ -11226,19 +11284,19 @@ SELECT a FROM ggg WHERE a IN (NULL, 'x'); EXPLAIN SELECT a FROM ggg WHERE a NOT IN (NULL, ''); QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=2) - -> Seq Scan on ggg (cost=0.00..431.00 rows=1 width=2) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=8) + -> Seq Scan on ggg (cost=0.00..431.00 rows=1 width=8) Filter: (a <> ALL ('{NULL,""}'::bpchar[])) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) EXPLAIN SELECT a FROM ggg WHERE a IN (NULL, 'x'); QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..431.00 rows=1 width=2) - -> Seq Scan on ggg (cost=0.00..431.00 rows=1 width=2) + Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..431.00 rows=1 width=8) + -> Seq Scan on ggg (cost=0.00..431.00 rows=1 width=8) Filter: (a = ANY ('{NULL,x}'::bpchar[])) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) -- result node with one time filter and filter @@ -11303,15 +11361,15 @@ WITH abc AS (SELECT onetimefilter1.a, onetimefilter1.b FROM onetimefilter1, onet ?column? | coalesce | b ----------+----------+---- 1 | 0 | 1 - 1 | 0 | 3 - 1 | 0 | 4 - 1 | 0 | 7 - 1 | 0 | 8 - 1 | 0 | 2 1 | 0 | 5 1 | 0 | 6 1 | 0 | 9 1 | 0 | 10 + 1 | 0 | 2 + 1 | 0 | 3 + 1 | 0 | 4 + 1 | 0 | 7 + 1 | 0 | 8 (10 rows) -- full joins with predicates @@ -11343,16 +11401,16 @@ CREATE INDEX tinnerbtree_ix ON tinnerbtree USING btree(a); SELECT * FROM touter LEFT JOIN tinnerbitmap ON touter.a = tinnerbitmap.a; a | b | a | b ----+---+----+--- - 1 | 1 | 1 | 1 - 6 | 0 | 6 | 0 - 5 | 5 | 5 | 5 - 9 | 3 | 9 | 3 - 10 | 4 | 10 | 4 2 | 2 | 2 | 2 - 7 | 1 | 7 | 1 - 8 | 2 | 8 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 + 7 | 1 | 7 | 1 + 8 | 2 | 8 | 2 + 5 | 5 | 5 | 5 + 6 | 0 | 6 | 0 + 9 | 3 | 9 | 3 + 10 | 4 | 10 | 4 + 1 | 1 | 1 | 1 (10 rows) SELECT * FROM touter LEFT JOIN tinnerbitmap ON touter.a = tinnerbitmap.a AND tinnerbitmap.b=10; @@ -11369,26 +11427,25 @@ SELECT * FROM touter LEFT JOIN tinnerbitmap ON touter.a = tinnerbitmap.a AND tin 9 | 3 | | 10 | 4 | | (10 rows) - -SELECT * FROM touter LEFT JOIN tinnerbtree ON touter.a = tinnerbtree.a; - a | b | a | b -----+---+----+--- - 1 | 1 | 1 | 1 - 6 | 0 | 6 | 0 - 5 | 5 | 5 | 5 - 9 | 3 | 9 | 3 - 10 | 4 | 10 | 4 + +SELECT * FROM touter LEFT JOIN tinnerbtree ON touter.a = tinnerbtree.a; + a | b | a | b +----+---+----+--- 2 | 2 | 2 | 2 - 7 | 1 | 7 | 1 - 8 | 2 | 8 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 + 7 | 1 | 7 | 1 + 8 | 2 | 8 | 2 + 5 | 5 | 5 | 5 + 6 | 0 | 6 | 0 + 9 | 3 | 9 | 3 + 10 | 4 | 10 | 4 + 1 | 1 | 1 | 1 (10 rows) SELECT * FROM touter LEFT JOIN tinnerbtree ON touter.a = tinnerbtree.a AND tinnerbtree.b=10; a | b | a | b ----+---+---+--- - 1 | 1 | | 5 | 5 | | 6 | 0 | | 9 | 3 | | @@ -11398,6 +11455,7 @@ SELECT * FROM touter LEFT JOIN tinnerbtree ON touter.a = tinnerbtree.a AND tinne 4 | 4 | | 7 | 1 | | 8 | 2 | | + 1 | 1 | | (10 rows) -- test subplan in a qual under dynamic scan @@ -11423,28 +11481,39 @@ SELECT * FROM ds_part, non_part2 WHERE ds_part.c = non_part2.e AND non_part2.f = (0 rows) explain analyze SELECT * FROM ds_part, non_part2 WHERE ds_part.c = non_part2.e AND non_part2.f = 10 AND a IN ( SELECT b + 1 FROM non_part1); - QUERY PLAN --------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324481.18 rows=1 width=20) - -> Hash Join (cost=0.00..1324481.18 rows=1 width=20) + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324481.25 rows=1 width=20) (actual time=4.489..4.493 rows=0 loops=1) + -> Hash Join (cost=0.00..1324481.25 rows=1 width=20) (actual time=2.148..2.151 rows=0 loops=1) Hash Cond: (ds_part.c = non_part2.e) - -> Dynamic Seq Scan on ds_part (cost=0.00..1324050.11 rows=334 width=12) + -> Dynamic Seq Scan on ds_part (cost=0.00..1324050.19 rows=334 width=12) (actual time=0.051..0.051 rows=0 loops=1) Number of partitions to scan: 6 (out of 6) Filter: ((a = (b + 1)) AND (SubPlan 1)) + Partitions scanned: Avg 1.0 x 3 workers. Max 1 parts (seg0). SubPlan 1 - -> Materialize (cost=0.00..431.00 rows=1 width=4) - -> Broadcast Motion 1:3 (slice2) (cost=0.00..431.00 rows=1 width=4) - -> Limit (cost=0.00..431.00 rows=1 width=4) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=4) - -> Limit (cost=0.00..431.00 rows=1 width=4) - -> Seq Scan on non_part1 (cost=0.00..431.00 rows=34 width=4) - -> Hash (cost=431.00..431.00 rows=1 width=8) - -> Partition Selector (selector id: $0) (cost=0.00..431.00 rows=1 width=8) - -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..431.00 rows=1 width=8) - -> Seq Scan on non_part2 (cost=0.00..431.00 rows=1 width=8) + -> Materialize (cost=0.00..431.00 rows=1 width=4) (never executed) + -> Broadcast Motion 1:3 (slice2) (cost=0.00..431.00 rows=1 width=4) (never executed) + -> Limit (cost=0.00..431.00 rows=1 width=4) (actual time=2.442..2.444 rows=1 loops=1) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=4) (actual time=2.441..2.441 rows=1 loops=1) + -> Limit (cost=0.00..431.00 rows=1 width=4) (actual time=0.008..0.009 rows=1 loops=1) + -> Seq Scan on non_part1 (cost=0.00..431.00 rows=34 width=4) (actual time=0.008..0.008 rows=1 loops=1) + -> Hash (cost=431.00..431.00 rows=1 width=8) (actual time=1.590..1.592 rows=1 loops=1) + Buckets: 262144 Batches: 1 Memory Usage: 2049kB + -> Partition Selector (selector id: $0) (cost=0.00..431.00 rows=1 width=8) (actual time=1.585..1.587 rows=1 loops=1) + -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..431.00 rows=1 width=8) (actual time=1.580..1.582 rows=1 loops=1) + -> Seq Scan on non_part2 (cost=0.00..431.00 rows=1 width=8) (actual time=0.012..0.014 rows=1 loops=1) Filter: (f = 10) - Optimizer: Pivotal Optimizer (GPORCA) -(19 rows) + Rows Removed by Filter: 24 + Planning Time: 24.075 ms + (slice0) Executor memory: 69K bytes. + (slice1) Executor memory: 2119K bytes avg x 3x(0) workers, 2119K bytes max (seg0). Work_mem: 2049K bytes max. + (slice2) Executor memory: 18K bytes (entry db). + (slice3) Executor memory: 112K bytes avg x 3x(0) workers, 112K bytes max (seg0). + (slice4) Executor memory: 111K bytes avg x 3x(0) workers, 111K bytes max (seg0). + Memory used: 128000kB + Optimizer: GPORCA + Execution Time: 5.112 ms +(30 rows) SELECT *, a IN ( SELECT b + 1 FROM non_part1) FROM ds_part, non_part2 WHERE ds_part.c = non_part2.e AND non_part2.f = 10 AND a IN ( SELECT b FROM non_part1); a | b | c | e | f | ?column? @@ -11467,8 +11536,8 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO varchar_sc_array_cmp VALUES ('a'), ('b'), ('c'), ('d'); EXPLAIN SELECT * FROM varchar_sc_array_cmp t1, varchar_sc_array_cmp t2 where t1.a = t2.a and t1.a in ('b', 'c'); - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=1 width=16) -> Hash Join (cost=0.00..862.00 rows=1 width=16) Hash Cond: ((t1.a)::text = (t2.a)::text) @@ -11477,7 +11546,7 @@ EXPLAIN SELECT * FROM varchar_sc_array_cmp t1, varchar_sc_array_cmp t2 where t1. -> Hash (cost=431.00..431.00 rows=1 width=8) -> Seq Scan on varchar_sc_array_cmp t2 (cost=0.00..431.00 rows=1 width=8) Filter: (a = ANY ('{b,c}'::character varying[])) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) SELECT * FROM varchar_sc_array_cmp t1, varchar_sc_array_cmp t2 where t1.a = t2.a and t1.a in ('b', 'c'); @@ -11499,15 +11568,15 @@ EXPLAIN SELECT * FROM varchar_sc_array_cmp t1, varchar_sc_array_cmp t2 where t1. -> Hash (cost=431.00..431.00 rows=1 width=8) -> Seq Scan on varchar_sc_array_cmp t2 (cost=0.00..431.00 rows=1 width=8) Filter: (a = ANY ('{a,b,c}'::character varying[])) - Optimizer: Pivotal Optimizer (GPORCA) version 3.65.2 + Optimizer: GPORCA (9 rows) SELECT * FROM varchar_sc_array_cmp t1, varchar_sc_array_cmp t2 where t1.a = t2.a and (t1.a in ('b', 'c') OR t1.a = 'a'); a | a ---+--- + b | b a | a c | c - b | b (3 rows) DROP TABLE varchar_sc_array_cmp; @@ -11586,10 +11655,10 @@ insert into tt values (1, 'b'), (1, 'B'); select * from tc, tt where c = v; a | c | b | v ---+---+---+--- + 1 | b | 1 | b + 1 | B | 1 | B 1 | a | 1 | a 1 | A | 1 | A - 1 | B | 1 | B - 1 | b | 1 | b (4 rows) -- bitmap scan on bitmap index @@ -11609,7 +11678,7 @@ explain select * from tc where c='a'; Recheck Cond: (c = 'a'::citext) -> Bitmap Index Scan on tc_idx (cost=0.00..0.00 rows=0 width=0) Index Cond: (c = 'a'::citext) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (6 rows) -- test gpexpand phase 1 @@ -11636,12 +11705,12 @@ reset allow_system_table_mods; explain insert into gpexp_hash select i, i from generate_series(1,50) i; INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Unknown error: Partially Distributed Data - QUERY PLAN --------------------------------------------------------------------------------------------- - Insert on gpexp_hash (cost=0.00..30.00 rows=500 width=8) - -> Redistribute Motion 1:2 (slice1; segments: 1) (cost=0.00..30.00 rows=1000 width=8) + QUERY PLAN +----------------------------------------------------------------------------------------- + Insert on gpexp_hash (cost=0.00..1.25 rows=0 width=0) + -> Redistribute Motion 1:2 (slice1; segments: 1) (cost=0.00..1.25 rows=25 width=8) Hash Key: i.i - -> Function Scan on generate_series i (cost=0.00..10.00 rows=500 width=8) + -> Function Scan on generate_series i (cost=0.00..0.50 rows=50 width=8) Optimizer: Postgres query optimizer (5 rows) @@ -11731,14 +11800,14 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Unknown error: Partially Distributed Data QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Update on gpexp_rand (cost=0.00..216.00 rows=25 width=18) - -> Seq Scan on gpexp_rand (cost=0.00..215.00 rows=25 width=18) + Update on gpexp_rand (cost=0.00..70.00 rows=0 width=0) + -> Seq Scan on gpexp_rand (cost=0.00..70.00 rows=25 width=14) SubPlan 1 - -> Result (cost=0.00..4.25 rows=50 width=4) + -> Result (cost=0.00..2.75 rows=50 width=4) Filter: (gpexp_rand.a = gpexp_hash.a) - -> Materialize (cost=0.00..3.75 rows=50 width=8) - -> Broadcast Motion 2:2 (slice1; segments: 2) (cost=0.00..3.50 rows=25 width=8) - -> Seq Scan on gpexp_hash (cost=0.00..2.50 rows=25 width=8) + -> Materialize (cost=0.00..2.25 rows=50 width=8) + -> Broadcast Motion 2:2 (slice1; segments: 2) (cost=0.00..2.00 rows=50 width=8) + -> Seq Scan on gpexp_hash (cost=0.00..1.25 rows=25 width=8) Optimizer: Postgres query optimizer (9 rows) @@ -11772,7 +11841,7 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Unknown error: Partially Distributed Data QUERY PLAN -------------------------------------------------------- - Insert on gpexp_repl (cost=0.00..0.01 rows=1 width=8) + Insert on gpexp_repl (cost=0.00..0.01 rows=0 width=0) -> Result (cost=0.00..0.01 rows=1 width=8) Optimizer: Postgres query optimizer (3 rows) @@ -11848,24 +11917,37 @@ analyze part2_1_prt_2; -- the plan should contain a 2 stage limit. If we incorrectly estimate that the -- relation is empty, we would end up choosing a single stage limit. explain select * from part1, part2 where part1.b = part2.b limit 5; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ - Limit (cost=0.00..862.14 rows=5 width=16) + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------- + Limit (cost=0.00..862.13 rows=5 width=16) -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.13 rows=5 width=16) -> Limit (cost=0.00..862.13 rows=2 width=16) - -> Hash Join (cost=0.00..862.13 rows=334 width=16) + -> Hash Join (cost=0.00..862.13 rows=333 width=16) Hash Cond: (part1.b = part2.b) - -> Dynamic Seq Scan on part1 (cost=0.00..431.01 rows=334 width=8) + -> Dynamic Seq Scan on part1 (cost=0.00..431.01 rows=333 width=8) Number of partitions to scan: 4 (out of 4) - -> Hash (cost=431.02..431.02 rows=100 width=8) - -> Partition Selector (selector id: $0) (cost=0.00..431.02 rows=100 width=8) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.02 rows=100 width=8) - -> Dynamic Seq Scan on part2 (cost=0.00..431.00 rows=34 width=8) + -> Hash (cost=431.02..431.02 rows=97 width=8) + -> Partition Selector (selector id: $0) (cost=0.00..431.02 rows=97 width=8) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.02 rows=97 width=8) + -> Dynamic Seq Scan on part2 (cost=0.00..431.00 rows=33 width=8) Number of partitions to scan: 4 (out of 4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) -- test opfamily handling in ORCA +-- start_ignore +DROP FUNCTION abseq(int, int) CASCADE; +NOTICE: drop cascades to 4 other objects +DETAIL: drop cascades to operator |=|(integer,integer) +drop cascades to operator class abs_int_btree_ops for access method btree +drop cascades to operator class abs_int_hash_ops for access method hash +drop cascades to table abs_opclass_test +DROP FUNCTION abslt(int, int) CASCADE; +NOTICE: drop cascades to operator |<|(integer,integer) +DROP FUNCTION absgt(int, int) CASCADE; +NOTICE: drop cascades to operator |>|(integer,integer) +DROP FUNCTION abscmp(int, int) CASCADE; +-- end_ignore CREATE FUNCTION abseq(int, int) RETURNS BOOL AS $$ begin return abs($1) = abs($2); end; @@ -11914,22 +11996,22 @@ ANALYZE btab_old_hash; EXPLAIN SELECT a, b FROM atab_old_hash INNER JOIN btab_old_hash ON a |=| b; QUERY PLAN --------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1324032.87 rows=5 width=8) - -> Nested Loop (cost=0.00..1324032.87 rows=2 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.88 rows=5 width=8) + -> Nested Loop (cost=0.00..1324032.88 rows=2 width=8) Join Filter: (atab_old_hash.a |=| btab_old_hash.b) -> Seq Scan on btab_old_hash (cost=0.00..431.00 rows=2 width=4) -> Materialize (cost=0.00..431.00 rows=3 width=4) - -> Broadcast Motion 3:3 (slice1; segments: 3) (cost=0.00..431.00 rows=3 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=3 width=4) -> Seq Scan on atab_old_hash (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) version 3.93.0 + Optimizer: GPORCA (8 rows) SELECT a, b FROM atab_old_hash INNER JOIN btab_old_hash ON a |=| b; a | b ----+---- 0 | 0 - -1 | 1 1 | 1 + -1 | 1 -1 | -1 1 | -1 (5 rows) @@ -11958,7 +12040,7 @@ EXPLAIN SELECT a, b FROM atab_old_hash INNER JOIN btab_old_hash ON a |=| b; -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=4) Hash Key: atab_old_hash.a -> Seq Scan on atab_old_hash (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) SELECT a, b FROM atab_old_hash INNER JOIN btab_old_hash ON a |=| b; @@ -11984,7 +12066,7 @@ EXPLAIN SELECT a, b FROM btab_old_hash LEFT OUTER JOIN atab_old_hash ON a |=| b; -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=4) Hash Key: atab_old_hash.a -> Seq Scan on atab_old_hash (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) SELECT a, b FROM btab_old_hash LEFT OUTER JOIN atab_old_hash ON a |=| b; @@ -11992,10 +12074,10 @@ SELECT a, b FROM btab_old_hash LEFT OUTER JOIN atab_old_hash ON a |=| b; ----+---- | 2 0 | 0 - -1 | 1 1 | 1 - -1 | -1 + -1 | 1 1 | -1 + -1 | -1 (6 rows) set optimizer_expand_fulljoin = on; @@ -12026,27 +12108,27 @@ EXPLAIN SELECT a, b FROM atab_old_hash FULL JOIN btab_old_hash ON a |=| b; -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=4) Hash Key: share3_ref2.a -> Shared Scan (share slice:id 3:3) (cost=0.00..431.00 rows=1 width=4) - -> Hash Anti Join (cost=0.00..862.00 rows=1 width=4) + -> Hash Right Anti Join (cost=0.00..862.00 rows=1 width=4) Hash Cond: (share3_ref3.a |=| share2_ref3.b) - -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..431.00 rows=1 width=4) - Hash Key: share3_ref3.a - -> Shared Scan (share slice:id 4:3) (cost=0.00..431.00 rows=1 width=4) - -> Hash (cost=431.00..431.00 rows=2 width=4) - -> Redistribute Motion 3:3 (slice5; segments: 3) (cost=0.00..431.00 rows=2 width=4) - Hash Key: share2_ref3.b - -> Shared Scan (share slice:id 5:2) (cost=0.00..431.00 rows=2 width=4) + -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..431.00 rows=2 width=4) + Hash Key: share2_ref3.b + -> Shared Scan (share slice:id 4:2) (cost=0.00..431.00 rows=2 width=4) + -> Hash (cost=431.00..431.00 rows=1 width=4) + -> Redistribute Motion 3:3 (slice5; segments: 3) (cost=0.00..431.00 rows=1 width=4) + Hash Key: share3_ref3.a + -> Shared Scan (share slice:id 5:3) (cost=0.00..431.00 rows=1 width=4) Optimizer: GPORCA (28 rows) SELECT a, b FROM atab_old_hash FULL JOIN btab_old_hash ON a |=| b; a | b ----+---- - | 2 0 | 0 - 1 | -1 + -1 | 1 1 | 1 -1 | -1 - -1 | 1 + 1 | -1 + | 2 (6 rows) reset optimizer_expand_fulljoin; @@ -12107,7 +12189,7 @@ EXPLAIN SELECT 1 FROM foo1 left join foo2 on foo1.a = foo2.a AND foo2.c = 3 AND -> Hash (cost=431.00..431.00 rows=2 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=2 width=4) -> Seq Scan on foo3 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (16 rows) SELECT 1 FROM foo1 left join foo2 on foo1.a = foo2.a AND foo2.c = 3 AND foo2.b IN (SELECT b FROM foo3); @@ -12151,8 +12233,8 @@ SELECT DISTINCT L1.c, L1.lid FROM t55 L1 CROSS JOIN META WHERE L1.lid = int4in(textout(meta.load_id)); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause. Creating a NULL policy entry. - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------- Result (cost=0.00..431.09 rows=1 width=8) Output: c, lid -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..431.07 rows=1 width=8) @@ -12172,9 +12254,9 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause. Creating a NULL policy entr Output: ('2020-01-01'::text), ('99'::text) -> Result (cost=0.00..0.00 rows=1 width=1) Output: '2020-01-01'::text, '99'::text - Optimizer: Pivotal Optimizer (GPORCA) - Settings: optimizer_enable_coordinator_only_queries = 'on', optimizer_enable_master_only_queries = 'on', optimizer_join_order = 'query', optimizer_segments = '3' -(25 rows) + Settings: optimizer = 'on', enable_incremental_sort = 'on', optimizer_segments = '3', optimizer_enable_dynamicbitmapscan = 'on', optimizer_join_order = 'query' + Optimizer: GPORCA +(21 rows) CREATE TABLE TP AS WITH META AS (SELECT '2020-01-01' AS VALID_DT, '99' AS LOAD_ID) @@ -12193,10 +12275,6 @@ SELECT * from tp; create table lossycastrangepart(a float, b float) partition by range(b) (start(0) end(40) every(10)); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. -NOTICE: CREATE TABLE will create partition "lossycastrangepart_1_prt_1" for table "lossycastrangepart" -NOTICE: CREATE TABLE will create partition "lossycastrangepart_1_prt_2" for table "lossycastrangepart" -NOTICE: CREATE TABLE will create partition "lossycastrangepart_1_prt_3" for table "lossycastrangepart" -NOTICE: CREATE TABLE will create partition "lossycastrangepart_1_prt_4" for table "lossycastrangepart" insert into lossycastrangepart (values (5.1,5.1), (9.9,9.9), (10.1,10.1), (9.1,9.1), (10.9,10.9), (11.1,11.1), (21.0,21.0)); explain select * from lossycastrangepart where b::int = 10; QUERY PLAN @@ -12204,15 +12282,15 @@ explain select * from lossycastrangepart where b::int = 10; Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=16) -> Dynamic Seq Scan on lossycastrangepart (cost=0.00..431.00 rows=1 width=16) Number of partitions to scan: 4 (out of 4) - Filter: (int4(b) = 10) - Optimizer: Pivotal Optimizer (GPORCA) + Filter: ((b)::integer = 10) + Optimizer: GPORCA (5 rows) select * from lossycastrangepart where b::int = 10; a | b ------+------ - 10.1 | 10.1 9.9 | 9.9 + 10.1 | 10.1 (2 rows) explain select * from lossycastrangepart where b::int = 11; @@ -12221,8 +12299,8 @@ explain select * from lossycastrangepart where b::int = 11; Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=16) -> Dynamic Seq Scan on lossycastrangepart (cost=0.00..431.00 rows=1 width=16) Number of partitions to scan: 4 (out of 4) - Filter: (int4(b) = 11) - Optimizer: Pivotal Optimizer (GPORCA) + Filter: ((b)::integer = 11) + Optimizer: GPORCA (5 rows) select * from lossycastrangepart where b::int = 11; @@ -12238,15 +12316,15 @@ explain select * from lossycastrangepart where b::int < 10; Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=16) -> Dynamic Seq Scan on lossycastrangepart (cost=0.00..431.00 rows=1 width=16) Number of partitions to scan: 4 (out of 4) - Filter: (int4(b) < 10) - Optimizer: Pivotal Optimizer (GPORCA) + Filter: ((b)::integer < 10) + Optimizer: GPORCA (5 rows) select * from lossycastrangepart where b::int < 10; a | b -----+----- - 9.1 | 9.1 5.1 | 5.1 + 9.1 | 9.1 (2 rows) explain select * from lossycastrangepart where b::int < 11; @@ -12255,25 +12333,22 @@ explain select * from lossycastrangepart where b::int < 11; Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=16) -> Dynamic Seq Scan on lossycastrangepart (cost=0.00..431.00 rows=1 width=16) Number of partitions to scan: 4 (out of 4) - Filter: (int4(b) < 11) - Optimizer: Pivotal Optimizer (GPORCA) + Filter: ((b)::integer < 11) + Optimizer: GPORCA (5 rows) select * from lossycastrangepart where b::int < 11; a | b ------+------ + 9.9 | 9.9 9.1 | 9.1 - 10.1 | 10.1 5.1 | 5.1 - 9.9 | 9.9 + 10.1 | 10.1 (4 rows) create table lossycastlistpart( a int, b float) partition by list(b) (partition l1 values(1.7, 2.1), partition l2 values(1.3, 2.7), partition l3 values(1.8, 2.8)); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. -NOTICE: CREATE TABLE will create partition "lossycastlistpart_1_prt_l1" for table "lossycastlistpart" -NOTICE: CREATE TABLE will create partition "lossycastlistpart_1_prt_l2" for table "lossycastlistpart" -NOTICE: CREATE TABLE will create partition "lossycastlistpart_1_prt_l3" for table "lossycastlistpart" insert into lossycastlistpart (values (1.0,2.1), (1.0,1.3), (10.1,2.1), (9.1,2.7), (10.9,1.8), (11.1,2.8), (21.0,1.7)); explain select * from lossycastlistpart where b::int < 2; QUERY PLAN @@ -12281,8 +12356,8 @@ explain select * from lossycastlistpart where b::int < 2; Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=12) -> Dynamic Seq Scan on lossycastlistpart (cost=0.00..431.00 rows=1 width=12) Number of partitions to scan: 3 (out of 3) - Filter: (int4(b) < 2) - Optimizer: Pivotal Optimizer (GPORCA) + Filter: ((b)::integer < 2) + Optimizer: GPORCA (5 rows) select * from lossycastlistpart where b::int < 2; @@ -12297,16 +12372,16 @@ explain select * from lossycastlistpart where b::int = 2; Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=12) -> Dynamic Seq Scan on lossycastlistpart (cost=0.00..431.00 rows=1 width=12) Number of partitions to scan: 3 (out of 3) - Filter: (int4(b) = 2) - Optimizer: Pivotal Optimizer (GPORCA) + Filter: ((b)::integer = 2) + Optimizer: GPORCA (5 rows) select * from lossycastlistpart where b::int = 2; a | b ----+----- - 11 | 1.8 10 | 2.1 21 | 1.7 + 11 | 1.8 1 | 2.1 (4 rows) @@ -12317,39 +12392,6 @@ partition by range(sales_ts) (start (timestamp '2010-01-01 00:00:00') end(timest every (interval '1 day')); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. -NOTICE: CREATE TABLE will create partition "sales_1_prt_1" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_2" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_3" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_4" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_5" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_6" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_7" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_8" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_9" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_10" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_11" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_12" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_13" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_14" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_15" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_16" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_17" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_18" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_19" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_20" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_21" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_22" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_23" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_24" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_25" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_26" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_27" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_28" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_29" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_30" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_31" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_32" for table "sales" -NOTICE: CREATE TABLE will create partition "sales_1_prt_33" for table "sales" insert into sales select i, i%100, i%1000, timestamp '2010-01-01 00:00:00' + i * interval '1 day' from generate_series(1,20) i; select * from sales where sales_ts::date != '2010-01-05' order by sales_ts; id | prod_id | cust_id | sales_ts @@ -12422,7 +12464,7 @@ where out.b in (select coalesce(tcorr2.a, 99) -> Materialize (cost=0.00..431.00 rows=1 width=4) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on tcorr2 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (14 rows) -- expect 1 row @@ -12454,7 +12496,7 @@ where out.b in (select max(tcorr2.b + out.b - 1) -> Materialize (cost=0.00..431.00 rows=1 width=8) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on tcorr2 (cost=0.00..431.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) -- expect 1 row @@ -12497,7 +12539,7 @@ where out.b in (select coalesce(tcorr2_d.c, 99) -> Materialize (cost=0.00..431.00 rows=1 width=8) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on tcorr2 (cost=0.00..431.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (20 rows) -- expect 1 row @@ -12546,7 +12588,7 @@ where out.b in (select coalesce(tcorr2.a, 99) -> Materialize (cost=0.00..431.00 rows=1 width=4) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on tcorr2 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (14 rows) -- expect 1 row @@ -12578,7 +12620,7 @@ where out.b in (select max(tcorr2.b + out.b - 1) -> Materialize (cost=0.00..431.00 rows=1 width=8) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on tcorr2 (cost=0.00..431.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) -- expect 1 row @@ -12621,7 +12663,7 @@ where out.b in (select coalesce(tcorr2_d.c, 99) -> Materialize (cost=0.00..431.00 rows=1 width=8) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on tcorr2 (cost=0.00..431.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (20 rows) -- expect 1 row @@ -12718,7 +12760,7 @@ select * from foo join tbtree on foo.a=tbtree.a; -> Seq Scan on foo -> Index Scan using tbtreexa on tbtree Index Cond: (a = foo.a) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) select * from foo join tbtree on foo.a=tbtree.a; @@ -12750,7 +12792,7 @@ select * from foo join tbitmap on foo.a=tbitmap.a; Recheck Cond: (a = foo.a) -> Bitmap Index Scan on tbitmapxa Index Cond: (a = foo.a) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) select * from foo join tbitmap on foo.a=tbitmap.a; @@ -12781,17 +12823,17 @@ select * from foo join tbtree on foo.a=tbtree.a where tbtree.a < 5000; Filter: (a < 5000) -> Index Scan using tbtreexa on tbtree Index Cond: ((a = foo.a) AND (a < 5000)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) select * from foo join tbtree on foo.a=tbtree.a where tbtree.a < 5000; a | b | c | a | b | c ------+------+------+------+------+------ - 3000 | 3000 | 3000 | 3000 | 3000 | 3000 - 4000 | 4000 | 4000 | 4000 | 4000 | 4000 1000 | 1000 | 1000 | 1000 | 1000 | 1000 2000 | 2000 | 2000 | 2000 | 2000 | 2000 2000 | 2000 | 2000 | 2000 | -1 | -1 + 3000 | 3000 | 3000 | 3000 | 3000 | 3000 + 4000 | 4000 | 4000 | 4000 | 4000 | 4000 (5 rows) -- 4 bitmap with select pred @@ -12808,17 +12850,17 @@ select * from foo join tbitmap on foo.a=tbitmap.a where tbitmap.a < 5000; Recheck Cond: ((a = foo.a) AND (a < 5000)) -> Bitmap Index Scan on tbitmapxa Index Cond: ((a = foo.a) AND (a < 5000)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) select * from foo join tbitmap on foo.a=tbitmap.a where tbitmap.a < 5000; a | b | c | a | b | c ------+------+------+------+------+------ - 3000 | 3000 | 3000 | 3000 | 3000 | 3000 - 4000 | 4000 | 4000 | 4000 | 4000 | 4000 1000 | 1000 | 1000 | 1000 | 1000 | 1000 2000 | 2000 | 2000 | 2000 | 2000 | 2000 2000 | 2000 | 2000 | 2000 | -1 | -1 + 3000 | 3000 | 3000 | 3000 | 3000 | 3000 + 4000 | 4000 | 4000 | 4000 | 4000 | 4000 (5 rows) -- 5 btree with project @@ -12832,7 +12874,7 @@ select * from foo join (select a, b+c as bc from tbtree) proj on foo.a=proj.a; -> Seq Scan on foo -> Index Scan using tbtreexa on tbtree Index Cond: (a = foo.a) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) select * from foo join (select a, b+c as bc from tbtree) proj on foo.a=proj.a; @@ -12864,7 +12906,7 @@ select * from foo join (select a, b+c as bc from tbitmap) proj on foo.a=proj.a; Recheck Cond: (a = foo.a) -> Bitmap Index Scan on tbitmapxa Index Cond: (a = foo.a) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) select * from foo join (select a, b+c as bc from tbitmap) proj on foo.a=proj.a; @@ -12896,7 +12938,7 @@ select * from foo join (select a, count(*) as cnt from tbtree group by a,b) grby Group Key: tbtree.a, tbtree.b -> Index Scan using tbtreexa on tbtree Index Cond: (a = foo.a) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) select * from foo join (select a, count(*) as cnt from tbtree group by a,b) grby on foo.a=grby.a; @@ -12930,22 +12972,22 @@ select * from foo join (select a, count(*) as cnt from tbitmap group by a) grby Recheck Cond: (a = foo.a) -> Bitmap Index Scan on tbitmapxa Index Cond: (a = foo.a) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) select * from foo join (select a, count(*) as cnt from tbitmap group by a) grby on foo.a=grby.a; a | b | c | a | cnt -------+-------+-------+-------+----- - 5000 | 5000 | 5000 | 5000 | 1 + 3000 | 3000 | 3000 | 3000 | 1 + 4000 | 4000 | 4000 | 4000 | 1 + 9000 | 9000 | 9000 | 9000 | 1 + 10000 | 10000 | 10000 | 10000 | 1 1000 | 1000 | 1000 | 1000 | 1 2000 | 2000 | 2000 | 2000 | 2 6000 | 6000 | 6000 | 6000 | 1 7000 | 7000 | 7000 | 7000 | 1 8000 | 8000 | 8000 | 8000 | 1 - 3000 | 3000 | 3000 | 3000 | 1 - 4000 | 4000 | 4000 | 4000 | 1 - 9000 | 9000 | 9000 | 9000 | 1 - 10000 | 10000 | 10000 | 10000 | 1 + 5000 | 5000 | 5000 | 5000 | 1 (10 rows) -- 9 btree with proj select grby select @@ -12964,15 +13006,15 @@ select * from foo join (select a, count(*) + 5 as cnt from tbtree where tbtree.a Group Key: tbtree.a -> Index Scan using tbtreexa on tbtree Index Cond: ((a = foo.a) AND (a < 5000)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) select * from foo join (select a, count(*) + 5 as cnt from tbtree where tbtree.a < 5000 group by a having count(*) < 2) proj_sel_grby_sel on foo.a=proj_sel_grby_sel.a; a | b | c | a | cnt ------+------+------+------+----- - 1000 | 1000 | 1000 | 1000 | 6 3000 | 3000 | 3000 | 3000 | 6 4000 | 4000 | 4000 | 4000 | 6 + 1000 | 1000 | 1000 | 1000 | 6 (3 rows) -- 10 bitmap with proj select grby select @@ -12993,7 +13035,7 @@ select * from foo join (select a, count(*) + 5 as cnt from tbitmap where tbitmap Recheck Cond: ((a = foo.a) AND (a < 5000)) -> Bitmap Index Scan on tbitmapxa Index Cond: ((a = foo.a) AND (a < 5000)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (14 rows) select * from foo join (select a, count(*) + 5 as cnt from tbitmap where tbitmap.a < 5000 group by a having count(*) < 2) proj_sel_grby_sel on foo.a=proj_sel_grby_sel.a; @@ -13021,7 +13063,7 @@ select * from foo join (select a, count(*) as cnt from (select distinct a, b fro Recheck Cond: (a = foo.a) -> Bitmap Index Scan on tbitmapxa Index Cond: (a = foo.a) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) select * from foo join (select a, count(*) as cnt from (select distinct a, b from tbitmap) grby1 group by a) grby2 on foo.a=grby2.a; @@ -13059,7 +13101,7 @@ select * from foo join (select a, count(*) + cnt1 as cnt2 from (select a, count( Group Key: tbtree.a -> Index Scan using tbtreexa on tbtree Index Cond: ((a = foo.a) AND (a < 5000)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (14 rows) select * from foo join (select a, count(*) + cnt1 as cnt2 from (select a, count(*) as cnt1 from tbtree group by a) grby1 @@ -13084,14 +13126,14 @@ select * from foo join (select a, a::bigint*a::bigint as aa from tbtree) proj on -> Seq Scan on foo -> Materialize -> Seq Scan on tbtree - Optimizer: Pivotal Optimizer (GPORCA) -(6 rows) + Optimizer: GPORCA +(7 rows) -- 14 join pred accesses a projected column - no index scan explain (costs off) select * from foo join (select a, count(*) as cnt from tbitmap group by a) grby on foo.a=grby.a and foo.b=grby.cnt; - QUERY PLAN --------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: ((foo.a = tbitmap.a) AND (foo.b = (count(*)))) @@ -13099,7 +13141,7 @@ select * from foo join (select a, count(*) as cnt from tbitmap group by a) grby -> HashAggregate Group Key: tbitmap.a -> Seq Scan on tbitmap - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) -- 15 the potential index join itself contains outer refs - no index scan @@ -13128,7 +13170,7 @@ from foo l1 where b in (select ab -> Materialize -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on tbtree - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (17 rows) -- 16 group by columns are not a superset of the distribution columns - no index scan @@ -13147,7 +13189,7 @@ select * from foo join (select b, count(*) as cnt from tbtree group by b) grby o -> Redistribute Motion 3:3 (slice2; segments: 3) Hash Key: tbtree.b -> Seq Scan on tbtree - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) -- 17 group by columns don't intersect - no index scan @@ -13171,7 +13213,7 @@ select * from foo join (select min_a, count(*) as cnt from (select min(a) as min -> Redistribute Motion 3:3 (slice3; segments: 3) Hash Key: tbitmap.b -> Seq Scan on tbitmap - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (17 rows) reset optimizer_join_order; @@ -13210,7 +13252,7 @@ explain (costs off) select count(*), t2.c from roj1 t1 left join roj2 t2 on t1.a -> Hash -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on roj1 t1 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) -- check that ROJ can be disabled via GUC @@ -13269,8 +13311,8 @@ select * from tpart_ao_btree where a = 3 and b = 3; (1 row) explain (costs off) select * from tpart_dim d join t_ao_btree f on d.a=f.a where d.b=1; - QUERY PLAN ---------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -13278,12 +13320,12 @@ explain (costs off) select * from tpart_dim d join t_ao_btree f on d.a=f.a where Filter: (b = 1) -> Index Only Scan using t_ao_btree_ix on t_ao_btree f Index Cond: (a = d.a) - Optimizer: Pivotal Optimizer (GPORCA) -(9 rows) + Optimizer: GPORCA +(8 rows) explain (costs off) select * from tpart_dim d join tpart_ao_btree f on d.a=f.a where d.b=1; - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -13292,7 +13334,7 @@ explain (costs off) select * from tpart_dim d join tpart_ao_btree f on d.a=f.a w -> Dynamic Index Only Scan on tpart_ao_btree_ix on tpart_ao_btree f Index Cond: (a = d.a) Number of partitions to scan: 2 (out of 2) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) -- negative test, make sure we don't use a btree scan on an AO table @@ -13326,7 +13368,7 @@ explain (costs off) select * from t_ao_btree where a = 3 and b = 3; Gather Motion 1:1 (slice1; segments: 1) -> Index Only Scan using t_ao_btree_ix on t_ao_btree Index Cond: ((a = 3) AND (b = 3)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) explain (costs off) select * from tpart_ao_btree where a = 3 and b = 3; @@ -13336,7 +13378,7 @@ explain (costs off) select * from tpart_ao_btree where a = 3 and b = 3; -> Dynamic Index Only Scan on tpart_ao_btree_ix on tpart_ao_btree Index Cond: ((a = 3) AND (b = 3)) Number of partitions to scan: 1 (out of 2) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) select * from tpart_dim d join t_ao_btree f on d.a=f.a where d.b=1; @@ -13427,7 +13469,7 @@ group by asset_records.uid, asset_records.hostname, asset_records.asset_type, as -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on coverage Filter: (NOT (vendor_sla IS NULL)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (17 rows) -- IndexApply-PartResolverExpand.mdp @@ -13444,8 +13486,8 @@ create INDEX y_idx on y (j); set optimizer_enable_indexjoin=on; set optimizer_enable_dynamicindexscan=on; explain (costs off) select count(*) from x, y where (x.i > y.j AND x.j <= y.i); - QUERY PLAN ---------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------- Aggregate -> Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop @@ -13456,7 +13498,7 @@ explain (costs off) select count(*) from x, y where (x.i > y.j AND x.j <= y.i); Index Cond: (j < x.i) Filter: ((j < x.i) AND (x.j <= i)) Number of partitions to scan: 5 (out of 5) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) reset optimizer_enable_indexjoin; @@ -13489,7 +13531,7 @@ explain (costs off) select * from infer_part_vc inner join infer_txt on (infer_p -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on infer_txt Filter: (a = 'M'::text) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) -- NewBtreeIndexScanCost.mdp @@ -13535,7 +13577,7 @@ explain (costs off) select * from oip oip join ria a on ip=cidr and oip.oid=19 Hash Key: oip.cidr -> Seq Scan on oip Filter: (oid = 194073) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) -- PartTbl-ArrayCoerce.mdp @@ -13553,7 +13595,7 @@ explain (costs off) select * from pt where gender in ( 'F', 'FM'); -> Dynamic Seq Scan on pt Number of partitions to scan: 2 (out of 3) Filter: ((gender)::text = ANY ('{F,FM}'::text[])) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) -- PartTbl-List-DPE-Varchar-Predicates.mdp @@ -13580,7 +13622,7 @@ select * from pt where gender is null; -> Dynamic Seq Scan on pt pt_3 Number of partitions to scan: 1 (out of 3) Filter: (gender IS NULL) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (15 rows) -- PartTbl-RangeJoinPred.mdp @@ -13611,8 +13653,8 @@ where d.msisdn=f.subscriberaddress and f.sessioncreationtimestamp >= d.start_dtm and f.sessioncreationtimestamp Hash Join Hash Cond: ((d.msisdn)::text = (stg_xdr_crce_cdr.subscriberaddress)::text) @@ -13623,7 +13665,7 @@ where d.msisdn=f.subscriberaddress and -> Broadcast Motion 3:3 (slice2; segments: 3) -> Dynamic Seq Scan on stg_xdr_crce_cdr Number of partitions to scan: 2 (out of 2) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) -- PartTbl-Relabel-Equality.mdp @@ -13639,13 +13681,13 @@ explain (costs off) select month_id, cust_group_acc, mobile_no from ds_4 where month_id::text = 'Apr'; - QUERY PLAN --------------------------------------------------- + QUERY PLAN +---------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Dynamic Seq Scan on ds_4 Number of partitions to scan: 1 (out of 2) Filter: ((month_id)::text = 'Apr'::text) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) -- PartTbl-Relabel-Range.mdp @@ -13662,7 +13704,7 @@ where month_id::text >= 'Feb' and month_id::text < 'Mar'; -> Dynamic Seq Scan on ds_4 Number of partitions to scan: 2 (out of 2) Filter: (((month_id)::text >= 'Feb'::text) AND ((month_id)::text < 'Mar'::text)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) -- retail_28.mdp @@ -13687,8 +13729,8 @@ GROUP BY to_char(order_datetime,'YYYY-Q') ORDER BY to_char(order_datetime,'YYYY-Q') , item_shipment_status_code ; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Merge Key: (to_char(order_datetime, 'YYYY-Q'::text)), item_shipment_status_code -> GroupAggregate @@ -13700,7 +13742,7 @@ ORDER BY to_char(order_datetime,'YYYY-Q') -> Dynamic Seq Scan on order_lineitems Number of partitions to scan: 3 (out of 12) Filter: ((order_datetime >= 'Thu Apr 01 00:00:00 2010'::timestamp without time zone) AND (order_datetime <= '06-30-2010'::date)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) -- test partioned table with no partitions @@ -13812,16 +13854,16 @@ explain select r.a, r.b, r.c, l.c from left_outer_index_nl_foo r left outer join -> Materialize (cost=0.00..431.00 rows=5 width=8) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=5 width=8) -> Seq Scan on left_outer_index_nl_bar l (cost=0.00..431.00 rows=2 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) select r.a, r.b, r.c, l.c from left_outer_index_nl_foo r left outer join left_outer_index_nl_bar l on r.b=l.b; a | b | c | c ---+---+---+--- - 4 | 4 | 4 | 4 + 3 | 3 | 3 | 3 1 | 1 | 1 | + 4 | 4 | 4 | 4 2 | 2 | 2 | 2 - 3 | 3 | 3 | 3 (4 rows) create table left_outer_index_nl_foo_hash (a integer, b integer, c text); @@ -13839,14 +13881,14 @@ analyze left_outer_index_nl_bar_hash; explain select r.a, r.b, r.c, l.c from left_outer_index_nl_foo_hash r left outer join left_outer_index_nl_bar l on r.b=l.b; QUERY PLAN --------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324033.77 rows=7 width=14) - -> Nested Loop Left Join (cost=0.00..1324033.77 rows=3 width=14) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324033.78 rows=7 width=14) + -> Nested Loop Left Join (cost=0.00..1324033.78 rows=3 width=14) Join Filter: (r.b = l.b) -> Seq Scan on left_outer_index_nl_foo_hash r (cost=0.00..431.00 rows=2 width=10) -> Materialize (cost=0.00..431.00 rows=5 width=8) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=5 width=8) -> Seq Scan on left_outer_index_nl_bar l (cost=0.00..431.00 rows=2 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) select r.a, r.b, r.c, l.c from left_outer_index_nl_foo_hash r left outer join left_outer_index_nl_bar l on r.b=l.b; @@ -13860,8 +13902,8 @@ select r.a, r.b, r.c, l.c from left_outer_index_nl_foo_hash r left outer join le --- verify that a motion is introduced such that joins on each segment are internal to that segment (distributed by join key) explain select r.a, r.b, r.c, l.c from left_outer_index_nl_foo_hash r left outer join left_outer_index_nl_bar_hash l on r.b=l.b; - QUERY PLAN ------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324033.54 rows=7 width=12) -> Nested Loop Left Join (cost=0.00..1324033.54 rows=3 width=12) Join Filter: (r.b = l.b) @@ -13869,7 +13911,7 @@ explain select r.a, r.b, r.c, l.c from left_outer_index_nl_foo_hash r left outer -> Materialize (cost=0.00..431.00 rows=5 width=6) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=5 width=6) -> Seq Scan on left_outer_index_nl_bar_hash l (cost=0.00..431.00 rows=2 width=6) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) select r.a, r.b, r.c, l.c from left_outer_index_nl_foo_hash r left outer join left_outer_index_nl_bar_hash l on r.b=l.b; @@ -13890,15 +13932,15 @@ analyze left_outer_index_nl_foo_repl; analyze left_outer_index_nl_bar_repl; --- replicated on both sides shouldn't require a motion explain select r.a, r.b, r.c, l.c from left_outer_index_nl_foo_repl r left outer join left_outer_index_nl_bar_repl l on r.b=l.b; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------ Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..455.00 rows=7 width=16) -> Nested Loop Left Join (cost=0.00..455.00 rows=21 width=16) Join Filter: true -> Seq Scan on left_outer_index_nl_foo_repl r (cost=0.00..431.00 rows=12 width=12) -> Index Scan using left_outer_index_nl_bar_repl_idx on left_outer_index_nl_bar_repl l (cost=0.00..24.00 rows=3 width=4) Index Cond: (b = r.b) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) select r.a, r.b, r.c, l.c from left_outer_index_nl_foo_repl r left outer join left_outer_index_nl_bar_repl l on r.b=l.b; @@ -13912,16 +13954,16 @@ select r.a, r.b, r.c, l.c from left_outer_index_nl_foo_repl r left outer join le --- outer side replicated, inner side hashed can have interesting cases (gather + join on one segment of inner side and redistribute + join + gather are both valid) explain select r.a, r.b, r.c, l.c from left_outer_index_nl_foo_repl r left outer join left_outer_index_nl_bar_hash l on r.b=l.b; - QUERY PLAN ------------------------------------------------------------------------------------------------------- - Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..1324035.41 rows=7 width=14) - -> Nested Loop Left Join (cost=0.00..1324035.41 rows=21 width=14) + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..1324035.43 rows=7 width=14) + -> Nested Loop Left Join (cost=0.00..1324035.42 rows=21 width=14) Join Filter: (r.b = l.b) -> Seq Scan on left_outer_index_nl_foo_repl r (cost=0.00..431.00 rows=12 width=12) -> Materialize (cost=0.00..431.00 rows=15 width=6) -> Broadcast Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=15 width=6) -> Seq Scan on left_outer_index_nl_bar_hash l (cost=0.00..431.00 rows=2 width=6) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) select r.a, r.b, r.c, l.c from left_outer_index_nl_foo_repl r left outer join left_outer_index_nl_bar_hash l on r.b=l.b; @@ -13958,7 +14000,7 @@ EXPLAIN SELECT b FROM tt1 WHERE NOT EXISTS (SELECT * FROM tt2 WHERE (tt2.d = tt1 -> Materialize (cost=0.00..431.00 rows=4 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=4 width=4) -> Seq Scan on tt2 (cost=0.00..431.00 rows=2 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) SELECT b FROM tt1 WHERE NOT EXISTS (SELECT * FROM tt2 WHERE (tt2.d = tt1.b) IS DISTINCT FROM false); @@ -13976,7 +14018,7 @@ EXPLAIN SELECT b FROM tt1 WHERE NOT EXISTS (SELECT * FROM tt2 WHERE (tt2.d = tt1 -> Materialize (cost=0.00..431.00 rows=4 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=4 width=4) -> Seq Scan on tt2 (cost=0.00..431.00 rows=2 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) SELECT b FROM tt1 WHERE NOT EXISTS (SELECT * FROM tt2 WHERE (tt2.d = tt1.b) IS DISTINCT FROM true); @@ -13994,7 +14036,7 @@ EXPLAIN SELECT b FROM tt1 WHERE NOT EXISTS (SELECT * FROM tt2 WHERE (tt1.b = tt2 -> Materialize (cost=0.00..431.00 rows=4 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=4 width=4) -> Seq Scan on tt2 (cost=0.00..431.00 rows=2 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) SELECT b FROM tt1 WHERE NOT EXISTS (SELECT * FROM tt2 WHERE (tt1.b = tt2.d) IS DISTINCT FROM NULL); @@ -14106,17 +14148,17 @@ EXPLAIN (COSTS OFF) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.a Join Filter: (t1.a = t2.a) -> Seq Scan on tone t1 -> Seq Scan on tone t2 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (6 rows) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.a; a | b | c | a | b | c ----+----+----+----+----+---- - 1 | 1 | 1 | 1 | 1 | 1 5 | 5 | 5 | 5 | 5 | 5 6 | 6 | 6 | 6 | 6 | 6 9 | 9 | 9 | 9 | 9 | 9 10 | 10 | 10 | 10 | 10 | 10 + 1 | 1 | 1 | 1 | 1 | 1 2 | 2 | 2 | 2 | 2 | 2 3 | 3 | 3 | 3 | 3 | 3 4 | 4 | 4 | 4 | 4 | 4 @@ -14137,22 +14179,22 @@ EXPLAIN (COSTS OFF) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.b -> Redistribute Motion 3:3 (slice2; segments: 3) Hash Key: t2.b -> Seq Scan on tone t2 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.b; a | b | c | a | b | c ----+----+----+----+----+---- 1 | 1 | 1 | 1 | 1 | 1 + 5 | 5 | 5 | 5 | 5 | 5 + 6 | 6 | 6 | 6 | 6 | 6 + 9 | 9 | 9 | 9 | 9 | 9 + 10 | 10 | 10 | 10 | 10 | 10 2 | 2 | 2 | 2 | 2 | 2 3 | 3 | 3 | 3 | 3 | 3 4 | 4 | 4 | 4 | 4 | 4 7 | 7 | 7 | 7 | 7 | 7 8 | 8 | 8 | 8 | 8 | 8 - 5 | 5 | 5 | 5 | 5 | 5 - 6 | 6 | 6 | 6 | 6 | 6 - 9 | 9 | 9 | 9 | 9 | 9 - 10 | 10 | 10 | 10 | 10 | 10 (10 rows) EXPLAIN (COSTS OFF) SELECT * FROM tone t1 LEFT OUTER JOIN (SELECT 1+t2.b as b from tone t2) t2 ON t1.a = t2.b; @@ -14166,7 +14208,7 @@ EXPLAIN (COSTS OFF) SELECT * FROM tone t1 LEFT OUTER JOIN (SELECT 1+t2.b as b fr -> Redistribute Motion 3:3 (slice2; segments: 3) Hash Key: ((1 + t2.b)) -> Seq Scan on tone t2 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) SELECT * FROM tone t1 LEFT OUTER JOIN (SELECT 1+t2.b as b from tone t2) t2 ON t1.a = t2.b; @@ -14196,22 +14238,22 @@ EXPLAIN (COSTS OFF) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.b -> Materialize -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on tone t2 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.b-t1.a; a | b | c | a | b | c ----+----+----+----+----+---- 1 | 1 | 1 | 2 | 2 | 2 - 5 | 5 | 5 | 10 | 10 | 10 - 6 | 6 | 6 | | | - 9 | 9 | 9 | | | - 10 | 10 | 10 | | | 2 | 2 | 2 | 4 | 4 | 4 3 | 3 | 3 | 6 | 6 | 6 4 | 4 | 4 | 8 | 8 | 8 7 | 7 | 7 | | | 8 | 8 | 8 | | | + 5 | 5 | 5 | 10 | 10 | 10 + 6 | 6 | 6 | | | + 9 | 9 | 9 | | | + 10 | 10 | 10 | | | (10 rows) --- orca should broadcast the inner child if the guc is set off @@ -14226,22 +14268,22 @@ EXPLAIN (COSTS OFF) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.b -> Materialize -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on tone t2 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.b; a | b | c | a | b | c ----+----+----+----+----+---- - 1 | 1 | 1 | 1 | 1 | 1 - 5 | 5 | 5 | 5 | 5 | 5 - 6 | 6 | 6 | 6 | 6 | 6 - 9 | 9 | 9 | 9 | 9 | 9 - 10 | 10 | 10 | 10 | 10 | 10 2 | 2 | 2 | 2 | 2 | 2 3 | 3 | 3 | 3 | 3 | 3 4 | 4 | 4 | 4 | 4 | 4 7 | 7 | 7 | 7 | 7 | 7 8 | 8 | 8 | 8 | 8 | 8 + 5 | 5 | 5 | 5 | 5 | 5 + 6 | 6 | 6 | 6 | 6 | 6 + 9 | 9 | 9 | 9 | 9 | 9 + 10 | 10 | 10 | 10 | 10 | 10 + 1 | 1 | 1 | 1 | 1 | 1 (10 rows) EXPLAIN (COSTS OFF) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.a; @@ -14254,7 +14296,7 @@ EXPLAIN (COSTS OFF) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.a -> Materialize -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on tone t2 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.a; @@ -14264,12 +14306,12 @@ SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.a; 6 | 6 | 6 | 6 | 6 | 6 9 | 9 | 9 | 9 | 9 | 9 10 | 10 | 10 | 10 | 10 | 10 + 1 | 1 | 1 | 1 | 1 | 1 2 | 2 | 2 | 2 | 2 | 2 3 | 3 | 3 | 3 | 3 | 3 4 | 4 | 4 | 4 | 4 | 4 7 | 7 | 7 | 7 | 7 | 7 8 | 8 | 8 | 8 | 8 | 8 - 1 | 1 | 1 | 1 | 1 | 1 (10 rows) RESET optimizer_enable_redistribute_nestloop_loj_inner_child; @@ -14301,9 +14343,9 @@ CREATE TABLE result_tab AS SELECT gp_segment_id, * FROM result_tab; gp_segment_id | a | b ---------------+-------+--- - 0 | 3 | 3 - 1 | 2 | 2 2 | 1 | 1 + 1 | 2 | 2 + 0 | 3 | 3 (3 rows) DROP TABLE IF EXISTS dist_tab_a; @@ -14418,7 +14460,11 @@ DROP TABLE t_clientinstrumentind2, t_clientproductind2; -- eval_const_expressions() call for subplan. ORCA has only one call to -- fold_constants() at the very beginning and doesn't perform folding later. CREATE TABLE join_null_rej1(i int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TABLE join_null_rej2(i int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO join_null_rej1(i) VALUES (1), (2), (3); INSERT INTO join_null_rej2 SELECT i FROM join_null_rej1; CREATE OR REPLACE FUNCTION join_null_rej_func() RETURNS int AS $$ @@ -14432,8 +14478,8 @@ EXPLAIN (COSTS OFF) SELECT ( LEFT JOIN join_null_rej2 t2 ON t1.i = t2.i WHERE t2.i < join_null_rej_func() ); - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------- Nested Loop Left Join Join Filter: true -> Result @@ -14446,7 +14492,7 @@ EXPLAIN (COSTS OFF) SELECT ( -> Hash -> Seq Scan on join_null_rej2 t2 Filter: (i < join_null_rej_func()) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) -- Optional, but let's check we get same result for both, folded and @@ -14490,7 +14536,7 @@ where t.j = tt.j; -> Sort (cost=0.00..431.00 rows=1 width=8) Sort Key: window_agg_test.j -> Seq Scan on window_agg_test (cost=0.00..431.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (16 rows) ---------------------------------- @@ -14501,31 +14547,31 @@ create type complex_t as (r float8, i float8); create type quad as (c1 complex_t, c2 complex_t); create function quad_func_cast() returns quad immutable as $$ select ((1.1,null),(2.2,null))::quad $$ language sql; explain select c1 from quad_func_cast(); - QUERY PLAN + QUERY PLAN ------------------------------------------------------------------- Function Scan on quad_func_cast (cost=0.00..0.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (2 rows) explain select c2 from quad_func_cast(); - QUERY PLAN + QUERY PLAN ------------------------------------------------------------------- Function Scan on quad_func_cast (cost=0.00..0.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (2 rows) explain select (c1).r from quad_func_cast(); QUERY PLAN ------------------------------------------------------------------- Function Scan on quad_func_cast (cost=0.00..0.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (2 rows) explain select (c2).i from quad_func_cast(); QUERY PLAN ------------------------------------------------------------------- Function Scan on quad_func_cast (cost=0.00..0.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (2 rows) select c1 from quad_func_cast(); @@ -14555,24 +14601,24 @@ select (c2).i from quad_func_cast(); create type mix_type as (a text, b integer, c bool); create function mix_func_cast() returns mix_type immutable as $$ select ('column1', 1, true)::mix_type $$ language sql; explain select a from mix_func_cast(); - QUERY PLAN + QUERY PLAN ------------------------------------------------------------------ Function Scan on mix_func_cast (cost=0.00..0.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (2 rows) explain select b from mix_func_cast(); - QUERY PLAN + QUERY PLAN ------------------------------------------------------------------ Function Scan on mix_func_cast (cost=0.00..0.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (2 rows) explain select c from mix_func_cast(); - QUERY PLAN + QUERY PLAN ------------------------------------------------------------------ Function Scan on mix_func_cast (cost=0.00..0.00 rows=1 width=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (2 rows) select a from mix_func_cast(); @@ -14704,9 +14750,9 @@ explain (costs off) select (x.item).a from comp_table x join comp_table y on (x. select (x.item).a, (select count(*) from generate_series(1, (x.item).c)) from comp_table x; a | count ----+------- - GP | 10 VM | 20 DB | 10 + GP | 10 (3 rows) explain (costs off) select (x.item).a, (select count(*) from generate_series(1, (x.item).c)) from comp_table x; @@ -14763,11 +14809,11 @@ explain (costs off) select (item).a from comp_table where (item).c=10 and (item) select (x.item).a from comp_part x join comp_part y on (X.item).c=(Y.item).c; a ---- - GP - GP VM DB DB + GP + GP (5 rows) explain (costs off) select (x.item).a from comp_part x join comp_part y on (X.item).c=(Y.item).c; @@ -14821,10 +14867,10 @@ analyze ts_tbl; explain select * from ts_tbl where ts = to_timestamp('99991231'::text, 'YYYYMMDD'::text); QUERY PLAN ------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..6.01 rows=40 width=8) - -> Index Scan using ts_tbl_idx on ts_tbl (cost=0.00..6.00 rows=14 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..6.00 rows=1 width=8) + -> Index Scan using ts_tbl_idx on ts_tbl (cost=0.00..6.00 rows=1 width=8) Index Cond: (ts = 'Fri Dec 31 00:00:00 9999 PST'::timestamp with time zone) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) -- Test ORCA support for implicit array coerce cast @@ -14842,11 +14888,11 @@ explain insert into array_coerce_foo select * from array_coerce_bar; ------------------------------------------------------------------------- Insert on array_coerce_foo (cost=0.00..431.02 rows=1 width=12) -> Seq Scan on array_coerce_bar (cost=0.00..431.00 rows=1 width=12) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) insert into array_coerce_foo select * from array_coerce_bar; -ERROR: value too long for type character varying(2) (seg1 127.0.0.1:7003 pid=51460) +ERROR: value too long for type character varying(2) (seg1 172.18.0.2:7003 pid=58805) WITH conf AS ( SELECT setting FROM pg_catalog.pg_config @@ -14872,7 +14918,7 @@ baz.b = 11 OR baz.b = 12 OR baz.b = 13 OR baz.b = 14 OR baz.b = 15 OR baz.b = 16 Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on baz (cost=0.00..431.00 rows=1 width=8) Filter: ((a = 1) OR (b = 1) OR (b = 2) OR (b = 3) OR (b = 4) OR (b = 5) OR (b = 6) OR (b = 7) OR (b = 8) OR (b = 9) OR (b = 10) OR (b = 11) OR (b = 12) OR (b = 13) OR (b = 14) OR (b = 15) OR (b = 16) OR (b = 17) OR (b = 18) OR (b = 19) OR (b = 20)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) drop table baz; @@ -14885,7 +14931,7 @@ explain select * from baz where baz.a::bpchar='b' or baz.a='c'; Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on baz (cost=0.00..431.00 rows=1 width=8) Filter: (((a)::bpchar = 'b'::bpchar) OR ((a)::text = 'c'::text)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) drop table baz; @@ -14905,13 +14951,14 @@ explain (analyze, costs off, summary off, timing off) with cte as (select * from -> Append (actual rows=10 loops=1) -> Shared Scan (share slice:id 1:0) (actual rows=5 loops=1) -> Shared Scan (share slice:id 1:0) (actual rows=5 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) -- While retrieving the columns width in partitioned tables, inherited stats i.e. -- stats that cover all the child tables should be used -- start_ignore create language plpython3u; +ERROR: extension "plpython3u" already exists -- end_ignore create or replace function check_col_width(query text, operator text, width text) returns int as $$ @@ -14983,26 +15030,27 @@ SELECT CAST(a AS TEXT[]) FROM array_coerceviaio; --------------------------------------------------------------------------------- DROP TABLE IF EXISTS schema_test_table; +NOTICE: table "schema_test_table" does not exist, skipping CREATE TABLE schema_test_table(a numeric, b numeric(5,2), c char(10) NOT NULL) distributed by (a); -- In 7x, redundant Result nodes in planned_stmt are being removed by ORCA, -- which caused the loss of typmod info of column type in plan. -- Below query is used by external libraries to fetch schema of table. -- Test that the typmod of column type is correct in explain plan. EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM schema_test_table WHERE 1=0; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Result Output: NULL::numeric, NULL::numeric(5,2), NULL::character(10) One-Time Filter: false + Settings: optimizer = 'on', enable_incremental_sort = 'on', optimizer_segments = '3', optimizer_enable_dynamicbitmapscan = 'on', optimizer_enable_dynamicindexscan = 'on' Optimizer: GPORCA - Settings: optimizer_enable_coordinator_only_queries = 'on', optimizer_enable_master_only_queries = 'on', optimizer_segments = '3' (5 rows) --------------------------------------------------------------------------------- -- Test ALL NULL scalar array compare create table DatumSortedSet_core (a int, b character varying NOT NULL) distributed by (a); explain select * from DatumSortedSet_core where b in (NULL, NULL); - QUERY PLAN + QUERY PLAN ------------------------------------------- Result (cost=0.00..0.00 rows=0 width=12) One-Time Filter: false diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out index c1716225ac8..1d82a0f6f24 100644 --- a/src/test/regress/expected/join.out +++ b/src/test/regress/expected/join.out @@ -7,10 +7,14 @@ CREATE TABLE J1_TBL ( j integer, t text ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TABLE J2_TBL ( i integer, k integer ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO J1_TBL VALUES (1, 4, 'one'); INSERT INTO J1_TBL VALUES (2, 3, 'two'); INSERT INTO J1_TBL VALUES (3, 2, 'three'); @@ -33,6 +37,7 @@ INSERT INTO J2_TBL VALUES (NULL, NULL); INSERT INTO J2_TBL VALUES (NULL, 0); -- useful in some tests below create temp table onerow(); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause, and no column type is suitable for a distribution key. Creating a NULL policy entry. insert into onerow default values; analyze onerow; -- @@ -44,173 +49,173 @@ SELECT * FROM J1_TBL AS tx; i | j | t ---+---+------- - 1 | 4 | one 2 | 3 | two 3 | 2 | three 4 | 1 | four - 5 | 0 | five - 6 | 6 | six 7 | 7 | seven 8 | 8 | eight - 0 | | zero | | null | 0 | zero + 1 | 4 | one + 0 | | zero + 5 | 0 | five + 6 | 6 | six (11 rows) SELECT * FROM J1_TBL tx; i | j | t ---+---+------- - 1 | 4 | one + 5 | 0 | five + 6 | 6 | six 2 | 3 | two 3 | 2 | three 4 | 1 | four - 5 | 0 | five - 6 | 6 | six 7 | 7 | seven 8 | 8 | eight - 0 | | zero | | null | 0 | zero + 1 | 4 | one + 0 | | zero (11 rows) SELECT * FROM J1_TBL AS t1 (a, b, c); a | b | c ---+---+------- - 1 | 4 | one 2 | 3 | two 3 | 2 | three 4 | 1 | four - 5 | 0 | five - 6 | 6 | six 7 | 7 | seven 8 | 8 | eight - 0 | | zero | | null | 0 | zero + 1 | 4 | one + 0 | | zero + 5 | 0 | five + 6 | 6 | six (11 rows) SELECT * FROM J1_TBL t1 (a, b, c); a | b | c ---+---+------- - 1 | 4 | one 2 | 3 | two 3 | 2 | three 4 | 1 | four - 5 | 0 | five - 6 | 6 | six 7 | 7 | seven 8 | 8 | eight - 0 | | zero | | null | 0 | zero + 1 | 4 | one + 0 | | zero + 5 | 0 | five + 6 | 6 | six (11 rows) SELECT * FROM J1_TBL t1 (a, b, c), J2_TBL t2 (d, e); a | b | c | d | e ---+---+-------+---+---- - 1 | 4 | one | 1 | -1 2 | 3 | two | 1 | -1 3 | 2 | three | 1 | -1 4 | 1 | four | 1 | -1 - 5 | 0 | five | 1 | -1 - 6 | 6 | six | 1 | -1 7 | 7 | seven | 1 | -1 8 | 8 | eight | 1 | -1 - 0 | | zero | 1 | -1 | | null | 1 | -1 | 0 | zero | 1 | -1 - 1 | 4 | one | 2 | 2 + 2 | 3 | two | 0 | + 3 | 2 | three | 0 | + 4 | 1 | four | 0 | + 7 | 7 | seven | 0 | + 8 | 8 | eight | 0 | + | | null | 0 | + | 0 | zero | 0 | + 2 | 3 | two | 5 | -5 + 3 | 2 | three | 5 | -5 + 4 | 1 | four | 5 | -5 + 7 | 7 | seven | 5 | -5 + 8 | 8 | eight | 5 | -5 + | | null | 5 | -5 + | 0 | zero | 5 | -5 + 2 | 3 | two | 5 | -5 + 3 | 2 | three | 5 | -5 + 4 | 1 | four | 5 | -5 + 7 | 7 | seven | 5 | -5 + 8 | 8 | eight | 5 | -5 + | | null | 5 | -5 + | 0 | zero | 5 | -5 2 | 3 | two | 2 | 2 3 | 2 | three | 2 | 2 4 | 1 | four | 2 | 2 - 5 | 0 | five | 2 | 2 - 6 | 6 | six | 2 | 2 7 | 7 | seven | 2 | 2 8 | 8 | eight | 2 | 2 - 0 | | zero | 2 | 2 | | null | 2 | 2 | 0 | zero | 2 | 2 - 1 | 4 | one | 3 | -3 2 | 3 | two | 3 | -3 3 | 2 | three | 3 | -3 4 | 1 | four | 3 | -3 - 5 | 0 | five | 3 | -3 - 6 | 6 | six | 3 | -3 7 | 7 | seven | 3 | -3 8 | 8 | eight | 3 | -3 - 0 | | zero | 3 | -3 | | null | 3 | -3 | 0 | zero | 3 | -3 - 1 | 4 | one | 2 | 4 2 | 3 | two | 2 | 4 3 | 2 | three | 2 | 4 4 | 1 | four | 2 | 4 - 5 | 0 | five | 2 | 4 - 6 | 6 | six | 2 | 4 7 | 7 | seven | 2 | 4 8 | 8 | eight | 2 | 4 - 0 | | zero | 2 | 4 | | null | 2 | 4 | 0 | zero | 2 | 4 - 1 | 4 | one | 5 | -5 - 2 | 3 | two | 5 | -5 - 3 | 2 | three | 5 | -5 - 4 | 1 | four | 5 | -5 - 5 | 0 | five | 5 | -5 - 6 | 6 | six | 5 | -5 - 7 | 7 | seven | 5 | -5 - 8 | 8 | eight | 5 | -5 - 0 | | zero | 5 | -5 - | | null | 5 | -5 - | 0 | zero | 5 | -5 - 1 | 4 | one | 5 | -5 - 2 | 3 | two | 5 | -5 - 3 | 2 | three | 5 | -5 - 4 | 1 | four | 5 | -5 - 5 | 0 | five | 5 | -5 - 6 | 6 | six | 5 | -5 - 7 | 7 | seven | 5 | -5 - 8 | 8 | eight | 5 | -5 - 0 | | zero | 5 | -5 - | | null | 5 | -5 - | 0 | zero | 5 | -5 - 1 | 4 | one | 0 | - 2 | 3 | two | 0 | - 3 | 2 | three | 0 | - 4 | 1 | four | 0 | - 5 | 0 | five | 0 | - 6 | 6 | six | 0 | - 7 | 7 | seven | 0 | - 8 | 8 | eight | 0 | - 0 | | zero | 0 | - | | null | 0 | - | 0 | zero | 0 | - 1 | 4 | one | | 2 | 3 | two | | 3 | 2 | three | | 4 | 1 | four | | - 5 | 0 | five | | - 6 | 6 | six | | 7 | 7 | seven | | 8 | 8 | eight | | - 0 | | zero | | | | null | | | 0 | zero | | - 1 | 4 | one | | 0 2 | 3 | two | | 0 3 | 2 | three | | 0 4 | 1 | four | | 0 - 5 | 0 | five | | 0 - 6 | 6 | six | | 0 7 | 7 | seven | | 0 8 | 8 | eight | | 0 - 0 | | zero | | 0 | | null | | 0 | 0 | zero | | 0 + 5 | 0 | five | 1 | -1 + 6 | 6 | six | 1 | -1 + 5 | 0 | five | 0 | + 6 | 6 | six | 0 | + 5 | 0 | five | 5 | -5 + 6 | 6 | six | 5 | -5 + 5 | 0 | five | 5 | -5 + 6 | 6 | six | 5 | -5 + 5 | 0 | five | 2 | 2 + 6 | 6 | six | 2 | 2 + 5 | 0 | five | 3 | -3 + 6 | 6 | six | 3 | -3 + 5 | 0 | five | 2 | 4 + 6 | 6 | six | 2 | 4 + 5 | 0 | five | | + 6 | 6 | six | | + 5 | 0 | five | | 0 + 6 | 6 | six | | 0 + 1 | 4 | one | 1 | -1 + 0 | | zero | 1 | -1 + 1 | 4 | one | 0 | + 0 | | zero | 0 | + 1 | 4 | one | 5 | -5 + 0 | | zero | 5 | -5 + 1 | 4 | one | 5 | -5 + 0 | | zero | 5 | -5 + 1 | 4 | one | 2 | 2 + 0 | | zero | 2 | 2 + 1 | 4 | one | 3 | -3 + 0 | | zero | 3 | -3 + 1 | 4 | one | 2 | 4 + 0 | | zero | 2 | 4 + 1 | 4 | one | | + 0 | | zero | | + 1 | 4 | one | | 0 + 0 | | zero | | 0 (99 rows) SELECT t1.a, t2.e @@ -218,13 +223,13 @@ SELECT t1.a, t2.e WHERE t1.a = t2.d; a | e ---+---- - 0 | + 5 | -5 + 5 | -5 1 | -1 + 0 | 2 | 2 - 2 | 4 3 | -3 - 5 | -5 - 5 | -5 + 2 | 4 (7 rows) -- @@ -236,105 +241,105 @@ SELECT * FROM J1_TBL CROSS JOIN J2_TBL; i | j | t | i | k ---+---+-------+---+---- - 1 | 4 | one | 1 | -1 - 2 | 3 | two | 1 | -1 - 3 | 2 | three | 1 | -1 - 4 | 1 | four | 1 | -1 + 5 | 0 | five | 2 | 2 + 6 | 6 | six | 2 | 2 + 5 | 0 | five | 3 | -3 + 6 | 6 | six | 3 | -3 + 5 | 0 | five | 2 | 4 + 6 | 6 | six | 2 | 4 + 5 | 0 | five | | + 6 | 6 | six | | + 5 | 0 | five | | 0 + 6 | 6 | six | | 0 + 5 | 0 | five | 5 | -5 + 6 | 6 | six | 5 | -5 + 5 | 0 | five | 5 | -5 + 6 | 6 | six | 5 | -5 5 | 0 | five | 1 | -1 6 | 6 | six | 1 | -1 - 7 | 7 | seven | 1 | -1 - 8 | 8 | eight | 1 | -1 - 0 | | zero | 1 | -1 - | | null | 1 | -1 - | 0 | zero | 1 | -1 - 1 | 4 | one | 2 | 2 + 5 | 0 | five | 0 | + 6 | 6 | six | 0 | 2 | 3 | two | 2 | 2 3 | 2 | three | 2 | 2 4 | 1 | four | 2 | 2 - 5 | 0 | five | 2 | 2 - 6 | 6 | six | 2 | 2 7 | 7 | seven | 2 | 2 8 | 8 | eight | 2 | 2 - 0 | | zero | 2 | 2 | | null | 2 | 2 | 0 | zero | 2 | 2 - 1 | 4 | one | 3 | -3 2 | 3 | two | 3 | -3 3 | 2 | three | 3 | -3 4 | 1 | four | 3 | -3 - 5 | 0 | five | 3 | -3 - 6 | 6 | six | 3 | -3 7 | 7 | seven | 3 | -3 8 | 8 | eight | 3 | -3 - 0 | | zero | 3 | -3 | | null | 3 | -3 | 0 | zero | 3 | -3 - 1 | 4 | one | 2 | 4 2 | 3 | two | 2 | 4 3 | 2 | three | 2 | 4 4 | 1 | four | 2 | 4 - 5 | 0 | five | 2 | 4 - 6 | 6 | six | 2 | 4 7 | 7 | seven | 2 | 4 8 | 8 | eight | 2 | 4 - 0 | | zero | 2 | 4 | | null | 2 | 4 | 0 | zero | 2 | 4 - 1 | 4 | one | 5 | -5 + 2 | 3 | two | | + 3 | 2 | three | | + 4 | 1 | four | | + 7 | 7 | seven | | + 8 | 8 | eight | | + | | null | | + | 0 | zero | | + 2 | 3 | two | | 0 + 3 | 2 | three | | 0 + 4 | 1 | four | | 0 + 7 | 7 | seven | | 0 + 8 | 8 | eight | | 0 + | | null | | 0 + | 0 | zero | | 0 2 | 3 | two | 5 | -5 3 | 2 | three | 5 | -5 4 | 1 | four | 5 | -5 - 5 | 0 | five | 5 | -5 - 6 | 6 | six | 5 | -5 7 | 7 | seven | 5 | -5 8 | 8 | eight | 5 | -5 - 0 | | zero | 5 | -5 | | null | 5 | -5 | 0 | zero | 5 | -5 - 1 | 4 | one | 5 | -5 2 | 3 | two | 5 | -5 3 | 2 | three | 5 | -5 4 | 1 | four | 5 | -5 - 5 | 0 | five | 5 | -5 - 6 | 6 | six | 5 | -5 7 | 7 | seven | 5 | -5 8 | 8 | eight | 5 | -5 - 0 | | zero | 5 | -5 | | null | 5 | -5 | 0 | zero | 5 | -5 - 1 | 4 | one | 0 | + 2 | 3 | two | 1 | -1 + 3 | 2 | three | 1 | -1 + 4 | 1 | four | 1 | -1 + 7 | 7 | seven | 1 | -1 + 8 | 8 | eight | 1 | -1 + | | null | 1 | -1 + | 0 | zero | 1 | -1 2 | 3 | two | 0 | 3 | 2 | three | 0 | 4 | 1 | four | 0 | - 5 | 0 | five | 0 | - 6 | 6 | six | 0 | 7 | 7 | seven | 0 | 8 | 8 | eight | 0 | - 0 | | zero | 0 | | | null | 0 | | 0 | zero | 0 | + 1 | 4 | one | 2 | 2 + 0 | | zero | 2 | 2 + 1 | 4 | one | 3 | -3 + 0 | | zero | 3 | -3 + 1 | 4 | one | 2 | 4 + 0 | | zero | 2 | 4 1 | 4 | one | | - 2 | 3 | two | | - 3 | 2 | three | | - 4 | 1 | four | | - 5 | 0 | five | | - 6 | 6 | six | | - 7 | 7 | seven | | - 8 | 8 | eight | | 0 | | zero | | - | | null | | - | 0 | zero | | 1 | 4 | one | | 0 - 2 | 3 | two | | 0 - 3 | 2 | three | | 0 - 4 | 1 | four | | 0 - 5 | 0 | five | | 0 - 6 | 6 | six | | 0 - 7 | 7 | seven | | 0 - 8 | 8 | eight | | 0 0 | | zero | | 0 - | | null | | 0 - | 0 | zero | | 0 + 1 | 4 | one | 5 | -5 + 0 | | zero | 5 | -5 + 1 | 4 | one | 5 | -5 + 0 | | zero | 5 | -5 + 1 | 4 | one | 1 | -1 + 0 | | zero | 1 | -1 + 1 | 4 | one | 0 | + 0 | | zero | 0 | (99 rows) -- ambiguous column @@ -348,105 +353,105 @@ SELECT t1.i, k, t FROM J1_TBL t1 CROSS JOIN J2_TBL t2; i | k | t ---+----+------- - 1 | -1 | one - 2 | -1 | two - 3 | -1 | three - 4 | -1 | four 5 | -1 | five 6 | -1 | six - 7 | -1 | seven - 8 | -1 | eight - 0 | -1 | zero - | -1 | null - | -1 | zero - 1 | 2 | one + 5 | | five + 6 | | six + 5 | 2 | five + 6 | 2 | six + 5 | -3 | five + 6 | -3 | six + 5 | 4 | five + 6 | 4 | six + 5 | | five + 6 | | six + 5 | 0 | five + 6 | 0 | six + 5 | -5 | five + 6 | -5 | six + 5 | -5 | five + 6 | -5 | six 2 | 2 | two 3 | 2 | three 4 | 2 | four - 5 | 2 | five - 6 | 2 | six 7 | 2 | seven 8 | 2 | eight - 0 | 2 | zero | 2 | null | 2 | zero - 1 | -3 | one 2 | -3 | two 3 | -3 | three 4 | -3 | four - 5 | -3 | five - 6 | -3 | six 7 | -3 | seven 8 | -3 | eight - 0 | -3 | zero | -3 | null | -3 | zero - 1 | 4 | one 2 | 4 | two 3 | 4 | three 4 | 4 | four - 5 | 4 | five - 6 | 4 | six 7 | 4 | seven 8 | 4 | eight - 0 | 4 | zero | 4 | null | 4 | zero - 1 | -5 | one + 2 | | two + 3 | | three + 4 | | four + 7 | | seven + 8 | | eight + | | null + | | zero + 2 | 0 | two + 3 | 0 | three + 4 | 0 | four + 7 | 0 | seven + 8 | 0 | eight + | 0 | null + | 0 | zero + 2 | -1 | two + 3 | -1 | three + 4 | -1 | four + 7 | -1 | seven + 8 | -1 | eight + | -1 | null + | -1 | zero + 2 | | two + 3 | | three + 4 | | four + 7 | | seven + 8 | | eight + | | null + | | zero 2 | -5 | two 3 | -5 | three 4 | -5 | four - 5 | -5 | five - 6 | -5 | six 7 | -5 | seven 8 | -5 | eight - 0 | -5 | zero | -5 | null | -5 | zero - 1 | -5 | one 2 | -5 | two 3 | -5 | three 4 | -5 | four - 5 | -5 | five - 6 | -5 | six 7 | -5 | seven 8 | -5 | eight - 0 | -5 | zero | -5 | null | -5 | zero + 1 | -1 | one + 0 | -1 | zero 1 | | one - 2 | | two - 3 | | three - 4 | | four - 5 | | five - 6 | | six - 7 | | seven - 8 | | eight 0 | | zero - | | null - | | zero + 1 | -5 | one + 0 | -5 | zero + 1 | -5 | one + 0 | -5 | zero + 1 | 2 | one + 0 | 2 | zero + 1 | -3 | one + 0 | -3 | zero + 1 | 4 | one + 0 | 4 | zero 1 | | one - 2 | | two - 3 | | three - 4 | | four - 5 | | five - 6 | | six - 7 | | seven - 8 | | eight 0 | | zero - | | null - | | zero 1 | 0 | one - 2 | 0 | two - 3 | 0 | three - 4 | 0 | four - 5 | 0 | five - 6 | 0 | six - 7 | 0 | seven - 8 | 0 | eight 0 | 0 | zero - | 0 | null - | 0 | zero (99 rows) SELECT ii, tt, kk @@ -454,105 +459,105 @@ SELECT ii, tt, kk AS tx (ii, jj, tt, ii2, kk); ii | tt | kk ----+-------+---- - 1 | one | -1 - 2 | two | -1 - 3 | three | -1 - 4 | four | -1 - 5 | five | -1 - 6 | six | -1 - 7 | seven | -1 - 8 | eight | -1 - 0 | zero | -1 - | null | -1 - | zero | -1 - 1 | one | 2 2 | two | 2 3 | three | 2 4 | four | 2 - 5 | five | 2 - 6 | six | 2 7 | seven | 2 8 | eight | 2 - 0 | zero | 2 | null | 2 | zero | 2 - 1 | one | -3 2 | two | -3 3 | three | -3 4 | four | -3 - 5 | five | -3 - 6 | six | -3 7 | seven | -3 8 | eight | -3 - 0 | zero | -3 | null | -3 | zero | -3 - 1 | one | 4 2 | two | 4 3 | three | 4 4 | four | 4 - 5 | five | 4 - 6 | six | 4 7 | seven | 4 8 | eight | 4 - 0 | zero | 4 | null | 4 | zero | 4 - 1 | one | -5 + 2 | two | + 3 | three | + 4 | four | + 7 | seven | + 8 | eight | + | null | + | zero | + 2 | two | 0 + 3 | three | 0 + 4 | four | 0 + 7 | seven | 0 + 8 | eight | 0 + | null | 0 + | zero | 0 + 2 | two | -1 + 3 | three | -1 + 4 | four | -1 + 7 | seven | -1 + 8 | eight | -1 + | null | -1 + | zero | -1 + 2 | two | + 3 | three | + 4 | four | + 7 | seven | + 8 | eight | + | null | + | zero | 2 | two | -5 3 | three | -5 4 | four | -5 - 5 | five | -5 - 6 | six | -5 7 | seven | -5 8 | eight | -5 - 0 | zero | -5 | null | -5 | zero | -5 - 1 | one | -5 2 | two | -5 3 | three | -5 4 | four | -5 - 5 | five | -5 - 6 | six | -5 7 | seven | -5 8 | eight | -5 - 0 | zero | -5 | null | -5 | zero | -5 + 1 | one | 2 + 0 | zero | 2 + 1 | one | -3 + 0 | zero | -3 + 1 | one | 4 + 0 | zero | 4 1 | one | - 2 | two | - 3 | three | - 4 | four | - 5 | five | - 6 | six | - 7 | seven | - 8 | eight | 0 | zero | - | null | - | zero | + 1 | one | 0 + 0 | zero | 0 + 1 | one | -1 + 0 | zero | -1 1 | one | - 2 | two | - 3 | three | - 4 | four | + 0 | zero | + 1 | one | -5 + 0 | zero | -5 + 1 | one | -5 + 0 | zero | -5 + 5 | five | 2 + 6 | six | 2 + 5 | five | -3 + 6 | six | -3 + 5 | five | 4 + 6 | six | 4 5 | five | 6 | six | - 7 | seven | - 8 | eight | - 0 | zero | - | null | - | zero | - 1 | one | 0 - 2 | two | 0 - 3 | three | 0 - 4 | four | 0 5 | five | 0 6 | six | 0 - 7 | seven | 0 - 8 | eight | 0 - 0 | zero | 0 - | null | 0 - | zero | 0 + 5 | five | -1 + 6 | six | -1 + 5 | five | + 6 | six | + 5 | five | -5 + 6 | six | -5 + 5 | five | -5 + 6 | six | -5 (99 rows) SELECT tx.ii, tx.jj, tx.kk @@ -560,1002 +565,1002 @@ SELECT tx.ii, tx.jj, tx.kk AS tx (ii, jj, tt, ii2, kk); ii | jj | kk ----+----+---- - 1 | 4 | -1 - 2 | 3 | -1 - 3 | 2 | -1 - 4 | 1 | -1 - 5 | 0 | -1 - 6 | 6 | -1 - 7 | 7 | -1 - 8 | 8 | -1 - 0 | | -1 - | | -1 - | 0 | -1 1 | 4 | 2 - 2 | 3 | 2 - 3 | 2 | 2 - 4 | 1 | 2 - 5 | 0 | 2 - 6 | 6 | 2 - 7 | 7 | 2 - 8 | 8 | 2 0 | | 2 - | | 2 - | 0 | 2 1 | 4 | -3 - 2 | 3 | -3 - 3 | 2 | -3 - 4 | 1 | -3 - 5 | 0 | -3 - 6 | 6 | -3 - 7 | 7 | -3 - 8 | 8 | -3 0 | | -3 - | | -3 - | 0 | -3 1 | 4 | 4 - 2 | 3 | 4 - 3 | 2 | 4 - 4 | 1 | 4 - 5 | 0 | 4 - 6 | 6 | 4 - 7 | 7 | 4 - 8 | 8 | 4 0 | | 4 - | | 4 - | 0 | 4 + 1 | 4 | + 0 | | + 1 | 4 | 0 + 0 | | 0 1 | 4 | -5 + 0 | | -5 + 1 | 4 | -5 + 0 | | -5 + 1 | 4 | -1 + 0 | | -1 + 1 | 4 | + 0 | | 2 | 3 | -5 3 | 2 | -5 4 | 1 | -5 - 5 | 0 | -5 - 6 | 6 | -5 7 | 7 | -5 8 | 8 | -5 - 0 | | -5 | | -5 | 0 | -5 - 1 | 4 | -5 2 | 3 | -5 3 | 2 | -5 4 | 1 | -5 - 5 | 0 | -5 - 6 | 6 | -5 7 | 7 | -5 8 | 8 | -5 - 0 | | -5 | | -5 | 0 | -5 - 1 | 4 | + 2 | 3 | 2 + 3 | 2 | 2 + 4 | 1 | 2 + 7 | 7 | 2 + 8 | 8 | 2 + | | 2 + | 0 | 2 + 2 | 3 | -3 + 3 | 2 | -3 + 4 | 1 | -3 + 7 | 7 | -3 + 8 | 8 | -3 + | | -3 + | 0 | -3 + 2 | 3 | 4 + 3 | 2 | 4 + 4 | 1 | 4 + 7 | 7 | 4 + 8 | 8 | 4 + | | 4 + | 0 | 4 2 | 3 | 3 | 2 | 4 | 1 | - 5 | 0 | - 6 | 6 | 7 | 7 | 8 | 8 | - 0 | | | | | 0 | - 1 | 4 | + 2 | 3 | 0 + 3 | 2 | 0 + 4 | 1 | 0 + 7 | 7 | 0 + 8 | 8 | 0 + | | 0 + | 0 | 0 + 2 | 3 | -1 + 3 | 2 | -1 + 4 | 1 | -1 + 7 | 7 | -1 + 8 | 8 | -1 + | | -1 + | 0 | -1 2 | 3 | 3 | 2 | 4 | 1 | - 5 | 0 | - 6 | 6 | 7 | 7 | 8 | 8 | - 0 | | | | | 0 | - 1 | 4 | 0 - 2 | 3 | 0 - 3 | 2 | 0 - 4 | 1 | 0 + 5 | 0 | -5 + 6 | 6 | -5 + 5 | 0 | -5 + 6 | 6 | -5 + 5 | 0 | 2 + 6 | 6 | 2 + 5 | 0 | -3 + 6 | 6 | -3 + 5 | 0 | 4 + 6 | 6 | 4 + 5 | 0 | + 6 | 6 | 5 | 0 | 0 6 | 6 | 0 - 7 | 7 | 0 - 8 | 8 | 0 - 0 | | 0 - | | 0 - | 0 | 0 + 5 | 0 | -1 + 6 | 6 | -1 + 5 | 0 | + 6 | 6 | (99 rows) SELECT * FROM J1_TBL CROSS JOIN J2_TBL a CROSS JOIN J2_TBL b; i | j | t | i | k | i | k ---+---+-------+---+----+---+---- - 1 | 4 | one | 1 | -1 | 1 | -1 - 1 | 4 | one | 1 | -1 | 2 | 2 - 1 | 4 | one | 1 | -1 | 3 | -3 - 1 | 4 | one | 1 | -1 | 2 | 4 - 1 | 4 | one | 1 | -1 | 5 | -5 - 1 | 4 | one | 1 | -1 | 5 | -5 - 1 | 4 | one | 1 | -1 | 0 | - 1 | 4 | one | 1 | -1 | | - 1 | 4 | one | 1 | -1 | | 0 - 2 | 3 | two | 1 | -1 | 1 | -1 - 2 | 3 | two | 1 | -1 | 2 | 2 - 2 | 3 | two | 1 | -1 | 3 | -3 - 2 | 3 | two | 1 | -1 | 2 | 4 - 2 | 3 | two | 1 | -1 | 5 | -5 - 2 | 3 | two | 1 | -1 | 5 | -5 - 2 | 3 | two | 1 | -1 | 0 | - 2 | 3 | two | 1 | -1 | | - 2 | 3 | two | 1 | -1 | | 0 - 3 | 2 | three | 1 | -1 | 1 | -1 - 3 | 2 | three | 1 | -1 | 2 | 2 - 3 | 2 | three | 1 | -1 | 3 | -3 - 3 | 2 | three | 1 | -1 | 2 | 4 - 3 | 2 | three | 1 | -1 | 5 | -5 - 3 | 2 | three | 1 | -1 | 5 | -5 - 3 | 2 | three | 1 | -1 | 0 | - 3 | 2 | three | 1 | -1 | | - 3 | 2 | three | 1 | -1 | | 0 - 4 | 1 | four | 1 | -1 | 1 | -1 - 4 | 1 | four | 1 | -1 | 2 | 2 - 4 | 1 | four | 1 | -1 | 3 | -3 - 4 | 1 | four | 1 | -1 | 2 | 4 - 4 | 1 | four | 1 | -1 | 5 | -5 - 4 | 1 | four | 1 | -1 | 5 | -5 - 4 | 1 | four | 1 | -1 | 0 | - 4 | 1 | four | 1 | -1 | | - 4 | 1 | four | 1 | -1 | | 0 - 5 | 0 | five | 1 | -1 | 1 | -1 - 5 | 0 | five | 1 | -1 | 2 | 2 - 5 | 0 | five | 1 | -1 | 3 | -3 - 5 | 0 | five | 1 | -1 | 2 | 4 - 5 | 0 | five | 1 | -1 | 5 | -5 - 5 | 0 | five | 1 | -1 | 5 | -5 - 5 | 0 | five | 1 | -1 | 0 | - 5 | 0 | five | 1 | -1 | | - 5 | 0 | five | 1 | -1 | | 0 - 6 | 6 | six | 1 | -1 | 1 | -1 - 6 | 6 | six | 1 | -1 | 2 | 2 - 6 | 6 | six | 1 | -1 | 3 | -3 - 6 | 6 | six | 1 | -1 | 2 | 4 - 6 | 6 | six | 1 | -1 | 5 | -5 - 6 | 6 | six | 1 | -1 | 5 | -5 - 6 | 6 | six | 1 | -1 | 0 | - 6 | 6 | six | 1 | -1 | | - 6 | 6 | six | 1 | -1 | | 0 - 7 | 7 | seven | 1 | -1 | 1 | -1 - 7 | 7 | seven | 1 | -1 | 2 | 2 - 7 | 7 | seven | 1 | -1 | 3 | -3 - 7 | 7 | seven | 1 | -1 | 2 | 4 - 7 | 7 | seven | 1 | -1 | 5 | -5 - 7 | 7 | seven | 1 | -1 | 5 | -5 - 7 | 7 | seven | 1 | -1 | 0 | - 7 | 7 | seven | 1 | -1 | | - 7 | 7 | seven | 1 | -1 | | 0 - 8 | 8 | eight | 1 | -1 | 1 | -1 - 8 | 8 | eight | 1 | -1 | 2 | 2 - 8 | 8 | eight | 1 | -1 | 3 | -3 - 8 | 8 | eight | 1 | -1 | 2 | 4 - 8 | 8 | eight | 1 | -1 | 5 | -5 - 8 | 8 | eight | 1 | -1 | 5 | -5 - 8 | 8 | eight | 1 | -1 | 0 | - 8 | 8 | eight | 1 | -1 | | - 8 | 8 | eight | 1 | -1 | | 0 - 0 | | zero | 1 | -1 | 1 | -1 - 0 | | zero | 1 | -1 | 2 | 2 - 0 | | zero | 1 | -1 | 3 | -3 - 0 | | zero | 1 | -1 | 2 | 4 - 0 | | zero | 1 | -1 | 5 | -5 - 0 | | zero | 1 | -1 | 5 | -5 - 0 | | zero | 1 | -1 | 0 | - 0 | | zero | 1 | -1 | | - 0 | | zero | 1 | -1 | | 0 - | | null | 1 | -1 | 1 | -1 - | | null | 1 | -1 | 2 | 2 - | | null | 1 | -1 | 3 | -3 - | | null | 1 | -1 | 2 | 4 - | | null | 1 | -1 | 5 | -5 - | | null | 1 | -1 | 5 | -5 - | | null | 1 | -1 | 0 | - | | null | 1 | -1 | | - | | null | 1 | -1 | | 0 - | 0 | zero | 1 | -1 | 1 | -1 - | 0 | zero | 1 | -1 | 2 | 2 - | 0 | zero | 1 | -1 | 3 | -3 - | 0 | zero | 1 | -1 | 2 | 4 - | 0 | zero | 1 | -1 | 5 | -5 - | 0 | zero | 1 | -1 | 5 | -5 - | 0 | zero | 1 | -1 | 0 | - | 0 | zero | 1 | -1 | | - | 0 | zero | 1 | -1 | | 0 - 1 | 4 | one | 2 | 2 | 1 | -1 - 1 | 4 | one | 2 | 2 | 2 | 2 - 1 | 4 | one | 2 | 2 | 3 | -3 - 1 | 4 | one | 2 | 2 | 2 | 4 - 1 | 4 | one | 2 | 2 | 5 | -5 - 1 | 4 | one | 2 | 2 | 5 | -5 - 1 | 4 | one | 2 | 2 | 0 | - 1 | 4 | one | 2 | 2 | | - 1 | 4 | one | 2 | 2 | | 0 - 2 | 3 | two | 2 | 2 | 1 | -1 - 2 | 3 | two | 2 | 2 | 2 | 2 - 2 | 3 | two | 2 | 2 | 3 | -3 - 2 | 3 | two | 2 | 2 | 2 | 4 - 2 | 3 | two | 2 | 2 | 5 | -5 - 2 | 3 | two | 2 | 2 | 5 | -5 - 2 | 3 | two | 2 | 2 | 0 | - 2 | 3 | two | 2 | 2 | | - 2 | 3 | two | 2 | 2 | | 0 - 3 | 2 | three | 2 | 2 | 1 | -1 - 3 | 2 | three | 2 | 2 | 2 | 2 - 3 | 2 | three | 2 | 2 | 3 | -3 - 3 | 2 | three | 2 | 2 | 2 | 4 - 3 | 2 | three | 2 | 2 | 5 | -5 - 3 | 2 | three | 2 | 2 | 5 | -5 - 3 | 2 | three | 2 | 2 | 0 | - 3 | 2 | three | 2 | 2 | | - 3 | 2 | three | 2 | 2 | | 0 - 4 | 1 | four | 2 | 2 | 1 | -1 - 4 | 1 | four | 2 | 2 | 2 | 2 - 4 | 1 | four | 2 | 2 | 3 | -3 - 4 | 1 | four | 2 | 2 | 2 | 4 - 4 | 1 | four | 2 | 2 | 5 | -5 - 4 | 1 | four | 2 | 2 | 5 | -5 - 4 | 1 | four | 2 | 2 | 0 | - 4 | 1 | four | 2 | 2 | | - 4 | 1 | four | 2 | 2 | | 0 - 5 | 0 | five | 2 | 2 | 1 | -1 - 5 | 0 | five | 2 | 2 | 2 | 2 - 5 | 0 | five | 2 | 2 | 3 | -3 - 5 | 0 | five | 2 | 2 | 2 | 4 - 5 | 0 | five | 2 | 2 | 5 | -5 - 5 | 0 | five | 2 | 2 | 5 | -5 - 5 | 0 | five | 2 | 2 | 0 | - 5 | 0 | five | 2 | 2 | | - 5 | 0 | five | 2 | 2 | | 0 - 6 | 6 | six | 2 | 2 | 1 | -1 - 6 | 6 | six | 2 | 2 | 2 | 2 - 6 | 6 | six | 2 | 2 | 3 | -3 - 6 | 6 | six | 2 | 2 | 2 | 4 - 6 | 6 | six | 2 | 2 | 5 | -5 - 6 | 6 | six | 2 | 2 | 5 | -5 - 6 | 6 | six | 2 | 2 | 0 | - 6 | 6 | six | 2 | 2 | | - 6 | 6 | six | 2 | 2 | | 0 - 7 | 7 | seven | 2 | 2 | 1 | -1 - 7 | 7 | seven | 2 | 2 | 2 | 2 - 7 | 7 | seven | 2 | 2 | 3 | -3 - 7 | 7 | seven | 2 | 2 | 2 | 4 - 7 | 7 | seven | 2 | 2 | 5 | -5 - 7 | 7 | seven | 2 | 2 | 5 | -5 - 7 | 7 | seven | 2 | 2 | 0 | - 7 | 7 | seven | 2 | 2 | | - 7 | 7 | seven | 2 | 2 | | 0 - 8 | 8 | eight | 2 | 2 | 1 | -1 - 8 | 8 | eight | 2 | 2 | 2 | 2 - 8 | 8 | eight | 2 | 2 | 3 | -3 - 8 | 8 | eight | 2 | 2 | 2 | 4 - 8 | 8 | eight | 2 | 2 | 5 | -5 - 8 | 8 | eight | 2 | 2 | 5 | -5 - 8 | 8 | eight | 2 | 2 | 0 | - 8 | 8 | eight | 2 | 2 | | - 8 | 8 | eight | 2 | 2 | | 0 - 0 | | zero | 2 | 2 | 1 | -1 - 0 | | zero | 2 | 2 | 2 | 2 - 0 | | zero | 2 | 2 | 3 | -3 - 0 | | zero | 2 | 2 | 2 | 4 - 0 | | zero | 2 | 2 | 5 | -5 - 0 | | zero | 2 | 2 | 5 | -5 - 0 | | zero | 2 | 2 | 0 | - 0 | | zero | 2 | 2 | | - 0 | | zero | 2 | 2 | | 0 - | | null | 2 | 2 | 1 | -1 - | | null | 2 | 2 | 2 | 2 - | | null | 2 | 2 | 3 | -3 - | | null | 2 | 2 | 2 | 4 - | | null | 2 | 2 | 5 | -5 - | | null | 2 | 2 | 5 | -5 - | | null | 2 | 2 | 0 | - | | null | 2 | 2 | | - | | null | 2 | 2 | | 0 - | 0 | zero | 2 | 2 | 1 | -1 - | 0 | zero | 2 | 2 | 2 | 2 - | 0 | zero | 2 | 2 | 3 | -3 - | 0 | zero | 2 | 2 | 2 | 4 - | 0 | zero | 2 | 2 | 5 | -5 - | 0 | zero | 2 | 2 | 5 | -5 - | 0 | zero | 2 | 2 | 0 | - | 0 | zero | 2 | 2 | | - | 0 | zero | 2 | 2 | | 0 - 1 | 4 | one | 3 | -3 | 1 | -1 - 1 | 4 | one | 3 | -3 | 2 | 2 - 1 | 4 | one | 3 | -3 | 3 | -3 - 1 | 4 | one | 3 | -3 | 2 | 4 - 1 | 4 | one | 3 | -3 | 5 | -5 - 1 | 4 | one | 3 | -3 | 5 | -5 - 1 | 4 | one | 3 | -3 | 0 | - 1 | 4 | one | 3 | -3 | | - 1 | 4 | one | 3 | -3 | | 0 - 2 | 3 | two | 3 | -3 | 1 | -1 - 2 | 3 | two | 3 | -3 | 2 | 2 - 2 | 3 | two | 3 | -3 | 3 | -3 - 2 | 3 | two | 3 | -3 | 2 | 4 - 2 | 3 | two | 3 | -3 | 5 | -5 - 2 | 3 | two | 3 | -3 | 5 | -5 - 2 | 3 | two | 3 | -3 | 0 | - 2 | 3 | two | 3 | -3 | | - 2 | 3 | two | 3 | -3 | | 0 - 3 | 2 | three | 3 | -3 | 1 | -1 - 3 | 2 | three | 3 | -3 | 2 | 2 - 3 | 2 | three | 3 | -3 | 3 | -3 - 3 | 2 | three | 3 | -3 | 2 | 4 - 3 | 2 | three | 3 | -3 | 5 | -5 - 3 | 2 | three | 3 | -3 | 5 | -5 - 3 | 2 | three | 3 | -3 | 0 | - 3 | 2 | three | 3 | -3 | | - 3 | 2 | three | 3 | -3 | | 0 - 4 | 1 | four | 3 | -3 | 1 | -1 - 4 | 1 | four | 3 | -3 | 2 | 2 - 4 | 1 | four | 3 | -3 | 3 | -3 - 4 | 1 | four | 3 | -3 | 2 | 4 - 4 | 1 | four | 3 | -3 | 5 | -5 - 4 | 1 | four | 3 | -3 | 5 | -5 - 4 | 1 | four | 3 | -3 | 0 | - 4 | 1 | four | 3 | -3 | | - 4 | 1 | four | 3 | -3 | | 0 - 5 | 0 | five | 3 | -3 | 1 | -1 - 5 | 0 | five | 3 | -3 | 2 | 2 - 5 | 0 | five | 3 | -3 | 3 | -3 - 5 | 0 | five | 3 | -3 | 2 | 4 - 5 | 0 | five | 3 | -3 | 5 | -5 - 5 | 0 | five | 3 | -3 | 5 | -5 - 5 | 0 | five | 3 | -3 | 0 | - 5 | 0 | five | 3 | -3 | | - 5 | 0 | five | 3 | -3 | | 0 - 6 | 6 | six | 3 | -3 | 1 | -1 - 6 | 6 | six | 3 | -3 | 2 | 2 - 6 | 6 | six | 3 | -3 | 3 | -3 - 6 | 6 | six | 3 | -3 | 2 | 4 - 6 | 6 | six | 3 | -3 | 5 | -5 - 6 | 6 | six | 3 | -3 | 5 | -5 - 6 | 6 | six | 3 | -3 | 0 | - 6 | 6 | six | 3 | -3 | | - 6 | 6 | six | 3 | -3 | | 0 - 7 | 7 | seven | 3 | -3 | 1 | -1 - 7 | 7 | seven | 3 | -3 | 2 | 2 - 7 | 7 | seven | 3 | -3 | 3 | -3 - 7 | 7 | seven | 3 | -3 | 2 | 4 - 7 | 7 | seven | 3 | -3 | 5 | -5 - 7 | 7 | seven | 3 | -3 | 5 | -5 - 7 | 7 | seven | 3 | -3 | 0 | - 7 | 7 | seven | 3 | -3 | | - 7 | 7 | seven | 3 | -3 | | 0 - 8 | 8 | eight | 3 | -3 | 1 | -1 - 8 | 8 | eight | 3 | -3 | 2 | 2 - 8 | 8 | eight | 3 | -3 | 3 | -3 - 8 | 8 | eight | 3 | -3 | 2 | 4 - 8 | 8 | eight | 3 | -3 | 5 | -5 - 8 | 8 | eight | 3 | -3 | 5 | -5 - 8 | 8 | eight | 3 | -3 | 0 | - 8 | 8 | eight | 3 | -3 | | - 8 | 8 | eight | 3 | -3 | | 0 - 0 | | zero | 3 | -3 | 1 | -1 - 0 | | zero | 3 | -3 | 2 | 2 - 0 | | zero | 3 | -3 | 3 | -3 - 0 | | zero | 3 | -3 | 2 | 4 - 0 | | zero | 3 | -3 | 5 | -5 - 0 | | zero | 3 | -3 | 5 | -5 - 0 | | zero | 3 | -3 | 0 | - 0 | | zero | 3 | -3 | | - 0 | | zero | 3 | -3 | | 0 - | | null | 3 | -3 | 1 | -1 - | | null | 3 | -3 | 2 | 2 - | | null | 3 | -3 | 3 | -3 - | | null | 3 | -3 | 2 | 4 - | | null | 3 | -3 | 5 | -5 - | | null | 3 | -3 | 5 | -5 - | | null | 3 | -3 | 0 | - | | null | 3 | -3 | | - | | null | 3 | -3 | | 0 - | 0 | zero | 3 | -3 | 1 | -1 - | 0 | zero | 3 | -3 | 2 | 2 - | 0 | zero | 3 | -3 | 3 | -3 - | 0 | zero | 3 | -3 | 2 | 4 - | 0 | zero | 3 | -3 | 5 | -5 - | 0 | zero | 3 | -3 | 5 | -5 - | 0 | zero | 3 | -3 | 0 | - | 0 | zero | 3 | -3 | | - | 0 | zero | 3 | -3 | | 0 - 1 | 4 | one | 2 | 4 | 1 | -1 - 1 | 4 | one | 2 | 4 | 2 | 2 - 1 | 4 | one | 2 | 4 | 3 | -3 - 1 | 4 | one | 2 | 4 | 2 | 4 - 1 | 4 | one | 2 | 4 | 5 | -5 - 1 | 4 | one | 2 | 4 | 5 | -5 - 1 | 4 | one | 2 | 4 | 0 | - 1 | 4 | one | 2 | 4 | | - 1 | 4 | one | 2 | 4 | | 0 - 2 | 3 | two | 2 | 4 | 1 | -1 - 2 | 3 | two | 2 | 4 | 2 | 2 - 2 | 3 | two | 2 | 4 | 3 | -3 - 2 | 3 | two | 2 | 4 | 2 | 4 - 2 | 3 | two | 2 | 4 | 5 | -5 - 2 | 3 | two | 2 | 4 | 5 | -5 - 2 | 3 | two | 2 | 4 | 0 | - 2 | 3 | two | 2 | 4 | | - 2 | 3 | two | 2 | 4 | | 0 - 3 | 2 | three | 2 | 4 | 1 | -1 - 3 | 2 | three | 2 | 4 | 2 | 2 - 3 | 2 | three | 2 | 4 | 3 | -3 - 3 | 2 | three | 2 | 4 | 2 | 4 - 3 | 2 | three | 2 | 4 | 5 | -5 - 3 | 2 | three | 2 | 4 | 5 | -5 - 3 | 2 | three | 2 | 4 | 0 | - 3 | 2 | three | 2 | 4 | | - 3 | 2 | three | 2 | 4 | | 0 - 4 | 1 | four | 2 | 4 | 1 | -1 - 4 | 1 | four | 2 | 4 | 2 | 2 - 4 | 1 | four | 2 | 4 | 3 | -3 - 4 | 1 | four | 2 | 4 | 2 | 4 - 4 | 1 | four | 2 | 4 | 5 | -5 - 4 | 1 | four | 2 | 4 | 5 | -5 - 4 | 1 | four | 2 | 4 | 0 | - 4 | 1 | four | 2 | 4 | | - 4 | 1 | four | 2 | 4 | | 0 - 5 | 0 | five | 2 | 4 | 1 | -1 - 5 | 0 | five | 2 | 4 | 2 | 2 - 5 | 0 | five | 2 | 4 | 3 | -3 - 5 | 0 | five | 2 | 4 | 2 | 4 - 5 | 0 | five | 2 | 4 | 5 | -5 - 5 | 0 | five | 2 | 4 | 5 | -5 - 5 | 0 | five | 2 | 4 | 0 | - 5 | 0 | five | 2 | 4 | | - 5 | 0 | five | 2 | 4 | | 0 - 6 | 6 | six | 2 | 4 | 1 | -1 - 6 | 6 | six | 2 | 4 | 2 | 2 - 6 | 6 | six | 2 | 4 | 3 | -3 - 6 | 6 | six | 2 | 4 | 2 | 4 - 6 | 6 | six | 2 | 4 | 5 | -5 - 6 | 6 | six | 2 | 4 | 5 | -5 - 6 | 6 | six | 2 | 4 | 0 | - 6 | 6 | six | 2 | 4 | | - 6 | 6 | six | 2 | 4 | | 0 - 7 | 7 | seven | 2 | 4 | 1 | -1 - 7 | 7 | seven | 2 | 4 | 2 | 2 - 7 | 7 | seven | 2 | 4 | 3 | -3 - 7 | 7 | seven | 2 | 4 | 2 | 4 - 7 | 7 | seven | 2 | 4 | 5 | -5 - 7 | 7 | seven | 2 | 4 | 5 | -5 - 7 | 7 | seven | 2 | 4 | 0 | - 7 | 7 | seven | 2 | 4 | | - 7 | 7 | seven | 2 | 4 | | 0 - 8 | 8 | eight | 2 | 4 | 1 | -1 - 8 | 8 | eight | 2 | 4 | 2 | 2 - 8 | 8 | eight | 2 | 4 | 3 | -3 - 8 | 8 | eight | 2 | 4 | 2 | 4 - 8 | 8 | eight | 2 | 4 | 5 | -5 - 8 | 8 | eight | 2 | 4 | 5 | -5 - 8 | 8 | eight | 2 | 4 | 0 | - 8 | 8 | eight | 2 | 4 | | - 8 | 8 | eight | 2 | 4 | | 0 - 0 | | zero | 2 | 4 | 1 | -1 - 0 | | zero | 2 | 4 | 2 | 2 - 0 | | zero | 2 | 4 | 3 | -3 - 0 | | zero | 2 | 4 | 2 | 4 - 0 | | zero | 2 | 4 | 5 | -5 - 0 | | zero | 2 | 4 | 5 | -5 - 0 | | zero | 2 | 4 | 0 | - 0 | | zero | 2 | 4 | | - 0 | | zero | 2 | 4 | | 0 - | | null | 2 | 4 | 1 | -1 - | | null | 2 | 4 | 2 | 2 - | | null | 2 | 4 | 3 | -3 - | | null | 2 | 4 | 2 | 4 - | | null | 2 | 4 | 5 | -5 - | | null | 2 | 4 | 5 | -5 - | | null | 2 | 4 | 0 | - | | null | 2 | 4 | | - | | null | 2 | 4 | | 0 - | 0 | zero | 2 | 4 | 1 | -1 - | 0 | zero | 2 | 4 | 2 | 2 - | 0 | zero | 2 | 4 | 3 | -3 - | 0 | zero | 2 | 4 | 2 | 4 - | 0 | zero | 2 | 4 | 5 | -5 - | 0 | zero | 2 | 4 | 5 | -5 - | 0 | zero | 2 | 4 | 0 | - | 0 | zero | 2 | 4 | | - | 0 | zero | 2 | 4 | | 0 - 1 | 4 | one | 5 | -5 | 1 | -1 - 1 | 4 | one | 5 | -5 | 2 | 2 - 1 | 4 | one | 5 | -5 | 3 | -3 - 1 | 4 | one | 5 | -5 | 2 | 4 - 1 | 4 | one | 5 | -5 | 5 | -5 - 1 | 4 | one | 5 | -5 | 5 | -5 - 1 | 4 | one | 5 | -5 | 0 | - 1 | 4 | one | 5 | -5 | | - 1 | 4 | one | 5 | -5 | | 0 - 2 | 3 | two | 5 | -5 | 1 | -1 + 2 | 3 | two | 5 | -5 | 5 | -5 + 2 | 3 | two | 5 | -5 | 5 | -5 2 | 3 | two | 5 | -5 | 2 | 2 2 | 3 | two | 5 | -5 | 3 | -3 2 | 3 | two | 5 | -5 | 2 | 4 + 2 | 3 | two | 5 | -5 | | + 2 | 3 | two | 5 | -5 | | 0 + 2 | 3 | two | 5 | -5 | 1 | -1 + 2 | 3 | two | 5 | -5 | 0 | 2 | 3 | two | 5 | -5 | 5 | -5 2 | 3 | two | 5 | -5 | 5 | -5 - 2 | 3 | two | 5 | -5 | 0 | + 2 | 3 | two | 5 | -5 | 2 | 2 + 2 | 3 | two | 5 | -5 | 3 | -3 + 2 | 3 | two | 5 | -5 | 2 | 4 2 | 3 | two | 5 | -5 | | 2 | 3 | two | 5 | -5 | | 0 - 3 | 2 | three | 5 | -5 | 1 | -1 - 3 | 2 | three | 5 | -5 | 2 | 2 + 2 | 3 | two | 5 | -5 | 1 | -1 + 2 | 3 | two | 5 | -5 | 0 | + 3 | 2 | three | 5 | -5 | 5 | -5 + 3 | 2 | three | 5 | -5 | 5 | -5 + 3 | 2 | three | 5 | -5 | 2 | 2 3 | 2 | three | 5 | -5 | 3 | -3 3 | 2 | three | 5 | -5 | 2 | 4 + 3 | 2 | three | 5 | -5 | | + 3 | 2 | three | 5 | -5 | | 0 + 3 | 2 | three | 5 | -5 | 1 | -1 + 3 | 2 | three | 5 | -5 | 0 | 3 | 2 | three | 5 | -5 | 5 | -5 3 | 2 | three | 5 | -5 | 5 | -5 - 3 | 2 | three | 5 | -5 | 0 | + 3 | 2 | three | 5 | -5 | 2 | 2 + 3 | 2 | three | 5 | -5 | 3 | -3 + 3 | 2 | three | 5 | -5 | 2 | 4 3 | 2 | three | 5 | -5 | | 3 | 2 | three | 5 | -5 | | 0 - 4 | 1 | four | 5 | -5 | 1 | -1 + 3 | 2 | three | 5 | -5 | 1 | -1 + 3 | 2 | three | 5 | -5 | 0 | + 4 | 1 | four | 5 | -5 | 5 | -5 + 4 | 1 | four | 5 | -5 | 5 | -5 4 | 1 | four | 5 | -5 | 2 | 2 4 | 1 | four | 5 | -5 | 3 | -3 4 | 1 | four | 5 | -5 | 2 | 4 + 4 | 1 | four | 5 | -5 | | + 4 | 1 | four | 5 | -5 | | 0 + 4 | 1 | four | 5 | -5 | 1 | -1 + 4 | 1 | four | 5 | -5 | 0 | 4 | 1 | four | 5 | -5 | 5 | -5 4 | 1 | four | 5 | -5 | 5 | -5 - 4 | 1 | four | 5 | -5 | 0 | + 4 | 1 | four | 5 | -5 | 2 | 2 + 4 | 1 | four | 5 | -5 | 3 | -3 + 4 | 1 | four | 5 | -5 | 2 | 4 4 | 1 | four | 5 | -5 | | 4 | 1 | four | 5 | -5 | | 0 - 5 | 0 | five | 5 | -5 | 1 | -1 - 5 | 0 | five | 5 | -5 | 2 | 2 - 5 | 0 | five | 5 | -5 | 3 | -3 - 5 | 0 | five | 5 | -5 | 2 | 4 - 5 | 0 | five | 5 | -5 | 5 | -5 - 5 | 0 | five | 5 | -5 | 5 | -5 - 5 | 0 | five | 5 | -5 | 0 | - 5 | 0 | five | 5 | -5 | | - 5 | 0 | five | 5 | -5 | | 0 - 6 | 6 | six | 5 | -5 | 1 | -1 - 6 | 6 | six | 5 | -5 | 2 | 2 - 6 | 6 | six | 5 | -5 | 3 | -3 - 6 | 6 | six | 5 | -5 | 2 | 4 - 6 | 6 | six | 5 | -5 | 5 | -5 - 6 | 6 | six | 5 | -5 | 5 | -5 - 6 | 6 | six | 5 | -5 | 0 | - 6 | 6 | six | 5 | -5 | | - 6 | 6 | six | 5 | -5 | | 0 - 7 | 7 | seven | 5 | -5 | 1 | -1 + 4 | 1 | four | 5 | -5 | 1 | -1 + 4 | 1 | four | 5 | -5 | 0 | + 7 | 7 | seven | 5 | -5 | 5 | -5 + 7 | 7 | seven | 5 | -5 | 5 | -5 7 | 7 | seven | 5 | -5 | 2 | 2 7 | 7 | seven | 5 | -5 | 3 | -3 7 | 7 | seven | 5 | -5 | 2 | 4 + 7 | 7 | seven | 5 | -5 | | + 7 | 7 | seven | 5 | -5 | | 0 + 7 | 7 | seven | 5 | -5 | 1 | -1 + 7 | 7 | seven | 5 | -5 | 0 | 7 | 7 | seven | 5 | -5 | 5 | -5 7 | 7 | seven | 5 | -5 | 5 | -5 - 7 | 7 | seven | 5 | -5 | 0 | + 7 | 7 | seven | 5 | -5 | 2 | 2 + 7 | 7 | seven | 5 | -5 | 3 | -3 + 7 | 7 | seven | 5 | -5 | 2 | 4 7 | 7 | seven | 5 | -5 | | 7 | 7 | seven | 5 | -5 | | 0 - 8 | 8 | eight | 5 | -5 | 1 | -1 + 7 | 7 | seven | 5 | -5 | 1 | -1 + 7 | 7 | seven | 5 | -5 | 0 | + 8 | 8 | eight | 5 | -5 | 5 | -5 + 8 | 8 | eight | 5 | -5 | 5 | -5 8 | 8 | eight | 5 | -5 | 2 | 2 8 | 8 | eight | 5 | -5 | 3 | -3 8 | 8 | eight | 5 | -5 | 2 | 4 + 8 | 8 | eight | 5 | -5 | | + 8 | 8 | eight | 5 | -5 | | 0 + 8 | 8 | eight | 5 | -5 | 1 | -1 + 8 | 8 | eight | 5 | -5 | 0 | 8 | 8 | eight | 5 | -5 | 5 | -5 8 | 8 | eight | 5 | -5 | 5 | -5 - 8 | 8 | eight | 5 | -5 | 0 | + 8 | 8 | eight | 5 | -5 | 2 | 2 + 8 | 8 | eight | 5 | -5 | 3 | -3 + 8 | 8 | eight | 5 | -5 | 2 | 4 8 | 8 | eight | 5 | -5 | | 8 | 8 | eight | 5 | -5 | | 0 - 0 | | zero | 5 | -5 | 1 | -1 - 0 | | zero | 5 | -5 | 2 | 2 - 0 | | zero | 5 | -5 | 3 | -3 - 0 | | zero | 5 | -5 | 2 | 4 - 0 | | zero | 5 | -5 | 5 | -5 - 0 | | zero | 5 | -5 | 5 | -5 - 0 | | zero | 5 | -5 | 0 | - 0 | | zero | 5 | -5 | | - 0 | | zero | 5 | -5 | | 0 - | | null | 5 | -5 | 1 | -1 + 8 | 8 | eight | 5 | -5 | 1 | -1 + 8 | 8 | eight | 5 | -5 | 0 | + | | null | 5 | -5 | 5 | -5 + | | null | 5 | -5 | 5 | -5 | | null | 5 | -5 | 2 | 2 | | null | 5 | -5 | 3 | -3 | | null | 5 | -5 | 2 | 4 + | | null | 5 | -5 | | + | | null | 5 | -5 | | 0 + | | null | 5 | -5 | 1 | -1 + | | null | 5 | -5 | 0 | | | null | 5 | -5 | 5 | -5 | | null | 5 | -5 | 5 | -5 - | | null | 5 | -5 | 0 | + | | null | 5 | -5 | 2 | 2 + | | null | 5 | -5 | 3 | -3 + | | null | 5 | -5 | 2 | 4 | | null | 5 | -5 | | | | null | 5 | -5 | | 0 - | 0 | zero | 5 | -5 | 1 | -1 + | | null | 5 | -5 | 1 | -1 + | | null | 5 | -5 | 0 | + | 0 | zero | 5 | -5 | 5 | -5 + | 0 | zero | 5 | -5 | 5 | -5 | 0 | zero | 5 | -5 | 2 | 2 | 0 | zero | 5 | -5 | 3 | -3 | 0 | zero | 5 | -5 | 2 | 4 + | 0 | zero | 5 | -5 | | + | 0 | zero | 5 | -5 | | 0 + | 0 | zero | 5 | -5 | 1 | -1 + | 0 | zero | 5 | -5 | 0 | | 0 | zero | 5 | -5 | 5 | -5 | 0 | zero | 5 | -5 | 5 | -5 - | 0 | zero | 5 | -5 | 0 | + | 0 | zero | 5 | -5 | 2 | 2 + | 0 | zero | 5 | -5 | 3 | -3 + | 0 | zero | 5 | -5 | 2 | 4 | 0 | zero | 5 | -5 | | | 0 | zero | 5 | -5 | | 0 - 1 | 4 | one | 5 | -5 | 1 | -1 + | 0 | zero | 5 | -5 | 1 | -1 + | 0 | zero | 5 | -5 | 0 | + 1 | 4 | one | 5 | -5 | 5 | -5 + 1 | 4 | one | 5 | -5 | 5 | -5 1 | 4 | one | 5 | -5 | 2 | 2 1 | 4 | one | 5 | -5 | 3 | -3 1 | 4 | one | 5 | -5 | 2 | 4 + 1 | 4 | one | 5 | -5 | | + 1 | 4 | one | 5 | -5 | | 0 + 1 | 4 | one | 5 | -5 | 1 | -1 + 1 | 4 | one | 5 | -5 | 0 | 1 | 4 | one | 5 | -5 | 5 | -5 1 | 4 | one | 5 | -5 | 5 | -5 - 1 | 4 | one | 5 | -5 | 0 | + 1 | 4 | one | 5 | -5 | 2 | 2 + 1 | 4 | one | 5 | -5 | 3 | -3 + 1 | 4 | one | 5 | -5 | 2 | 4 1 | 4 | one | 5 | -5 | | 1 | 4 | one | 5 | -5 | | 0 - 2 | 3 | two | 5 | -5 | 1 | -1 - 2 | 3 | two | 5 | -5 | 2 | 2 - 2 | 3 | two | 5 | -5 | 3 | -3 - 2 | 3 | two | 5 | -5 | 2 | 4 - 2 | 3 | two | 5 | -5 | 5 | -5 - 2 | 3 | two | 5 | -5 | 5 | -5 - 2 | 3 | two | 5 | -5 | 0 | - 2 | 3 | two | 5 | -5 | | - 2 | 3 | two | 5 | -5 | | 0 - 3 | 2 | three | 5 | -5 | 1 | -1 - 3 | 2 | three | 5 | -5 | 2 | 2 - 3 | 2 | three | 5 | -5 | 3 | -3 - 3 | 2 | three | 5 | -5 | 2 | 4 - 3 | 2 | three | 5 | -5 | 5 | -5 - 3 | 2 | three | 5 | -5 | 5 | -5 - 3 | 2 | three | 5 | -5 | 0 | - 3 | 2 | three | 5 | -5 | | - 3 | 2 | three | 5 | -5 | | 0 - 4 | 1 | four | 5 | -5 | 1 | -1 - 4 | 1 | four | 5 | -5 | 2 | 2 - 4 | 1 | four | 5 | -5 | 3 | -3 - 4 | 1 | four | 5 | -5 | 2 | 4 - 4 | 1 | four | 5 | -5 | 5 | -5 - 4 | 1 | four | 5 | -5 | 5 | -5 - 4 | 1 | four | 5 | -5 | 0 | - 4 | 1 | four | 5 | -5 | | - 4 | 1 | four | 5 | -5 | | 0 - 5 | 0 | five | 5 | -5 | 1 | -1 + 1 | 4 | one | 5 | -5 | 1 | -1 + 1 | 4 | one | 5 | -5 | 0 | + 0 | | zero | 5 | -5 | 5 | -5 + 0 | | zero | 5 | -5 | 5 | -5 + 0 | | zero | 5 | -5 | 2 | 2 + 0 | | zero | 5 | -5 | 3 | -3 + 0 | | zero | 5 | -5 | 2 | 4 + 0 | | zero | 5 | -5 | | + 0 | | zero | 5 | -5 | | 0 + 0 | | zero | 5 | -5 | 1 | -1 + 0 | | zero | 5 | -5 | 0 | + 0 | | zero | 5 | -5 | 5 | -5 + 0 | | zero | 5 | -5 | 5 | -5 + 0 | | zero | 5 | -5 | 2 | 2 + 0 | | zero | 5 | -5 | 3 | -3 + 0 | | zero | 5 | -5 | 2 | 4 + 0 | | zero | 5 | -5 | | + 0 | | zero | 5 | -5 | | 0 + 0 | | zero | 5 | -5 | 1 | -1 + 0 | | zero | 5 | -5 | 0 | + 5 | 0 | five | 5 | -5 | 5 | -5 + 5 | 0 | five | 5 | -5 | 5 | -5 5 | 0 | five | 5 | -5 | 2 | 2 5 | 0 | five | 5 | -5 | 3 | -3 5 | 0 | five | 5 | -5 | 2 | 4 + 5 | 0 | five | 5 | -5 | | + 5 | 0 | five | 5 | -5 | | 0 + 5 | 0 | five | 5 | -5 | 1 | -1 + 5 | 0 | five | 5 | -5 | 0 | 5 | 0 | five | 5 | -5 | 5 | -5 5 | 0 | five | 5 | -5 | 5 | -5 - 5 | 0 | five | 5 | -5 | 0 | + 5 | 0 | five | 5 | -5 | 2 | 2 + 5 | 0 | five | 5 | -5 | 3 | -3 + 5 | 0 | five | 5 | -5 | 2 | 4 5 | 0 | five | 5 | -5 | | 5 | 0 | five | 5 | -5 | | 0 - 6 | 6 | six | 5 | -5 | 1 | -1 + 5 | 0 | five | 5 | -5 | 1 | -1 + 5 | 0 | five | 5 | -5 | 0 | + 6 | 6 | six | 5 | -5 | 5 | -5 + 6 | 6 | six | 5 | -5 | 5 | -5 6 | 6 | six | 5 | -5 | 2 | 2 6 | 6 | six | 5 | -5 | 3 | -3 6 | 6 | six | 5 | -5 | 2 | 4 + 6 | 6 | six | 5 | -5 | | + 6 | 6 | six | 5 | -5 | | 0 + 6 | 6 | six | 5 | -5 | 1 | -1 + 6 | 6 | six | 5 | -5 | 0 | 6 | 6 | six | 5 | -5 | 5 | -5 6 | 6 | six | 5 | -5 | 5 | -5 - 6 | 6 | six | 5 | -5 | 0 | + 6 | 6 | six | 5 | -5 | 2 | 2 + 6 | 6 | six | 5 | -5 | 3 | -3 + 6 | 6 | six | 5 | -5 | 2 | 4 6 | 6 | six | 5 | -5 | | 6 | 6 | six | 5 | -5 | | 0 - 7 | 7 | seven | 5 | -5 | 1 | -1 - 7 | 7 | seven | 5 | -5 | 2 | 2 - 7 | 7 | seven | 5 | -5 | 3 | -3 - 7 | 7 | seven | 5 | -5 | 2 | 4 - 7 | 7 | seven | 5 | -5 | 5 | -5 - 7 | 7 | seven | 5 | -5 | 5 | -5 - 7 | 7 | seven | 5 | -5 | 0 | - 7 | 7 | seven | 5 | -5 | | - 7 | 7 | seven | 5 | -5 | | 0 - 8 | 8 | eight | 5 | -5 | 1 | -1 - 8 | 8 | eight | 5 | -5 | 2 | 2 - 8 | 8 | eight | 5 | -5 | 3 | -3 - 8 | 8 | eight | 5 | -5 | 2 | 4 - 8 | 8 | eight | 5 | -5 | 5 | -5 - 8 | 8 | eight | 5 | -5 | 5 | -5 - 8 | 8 | eight | 5 | -5 | 0 | - 8 | 8 | eight | 5 | -5 | | - 8 | 8 | eight | 5 | -5 | | 0 - 0 | | zero | 5 | -5 | 1 | -1 - 0 | | zero | 5 | -5 | 2 | 2 - 0 | | zero | 5 | -5 | 3 | -3 - 0 | | zero | 5 | -5 | 2 | 4 - 0 | | zero | 5 | -5 | 5 | -5 - 0 | | zero | 5 | -5 | 5 | -5 - 0 | | zero | 5 | -5 | 0 | - 0 | | zero | 5 | -5 | | - 0 | | zero | 5 | -5 | | 0 - | | null | 5 | -5 | 1 | -1 - | | null | 5 | -5 | 2 | 2 - | | null | 5 | -5 | 3 | -3 - | | null | 5 | -5 | 2 | 4 - | | null | 5 | -5 | 5 | -5 - | | null | 5 | -5 | 5 | -5 - | | null | 5 | -5 | 0 | - | | null | 5 | -5 | | - | | null | 5 | -5 | | 0 - | 0 | zero | 5 | -5 | 1 | -1 - | 0 | zero | 5 | -5 | 2 | 2 - | 0 | zero | 5 | -5 | 3 | -3 - | 0 | zero | 5 | -5 | 2 | 4 - | 0 | zero | 5 | -5 | 5 | -5 - | 0 | zero | 5 | -5 | 5 | -5 - | 0 | zero | 5 | -5 | 0 | - | 0 | zero | 5 | -5 | | - | 0 | zero | 5 | -5 | | 0 - 1 | 4 | one | 0 | | 1 | -1 - 1 | 4 | one | 0 | | 2 | 2 - 1 | 4 | one | 0 | | 3 | -3 - 1 | 4 | one | 0 | | 2 | 4 - 1 | 4 | one | 0 | | 5 | -5 - 1 | 4 | one | 0 | | 5 | -5 - 1 | 4 | one | 0 | | 0 | - 1 | 4 | one | 0 | | | - 1 | 4 | one | 0 | | | 0 - 2 | 3 | two | 0 | | 1 | -1 + 6 | 6 | six | 5 | -5 | 1 | -1 + 6 | 6 | six | 5 | -5 | 0 | + 2 | 3 | two | 1 | -1 | 2 | 2 + 2 | 3 | two | 1 | -1 | 3 | -3 + 2 | 3 | two | 1 | -1 | 2 | 4 + 2 | 3 | two | 1 | -1 | | + 2 | 3 | two | 1 | -1 | | 0 + 2 | 3 | two | 1 | -1 | 5 | -5 + 2 | 3 | two | 1 | -1 | 5 | -5 + 2 | 3 | two | 1 | -1 | 1 | -1 + 2 | 3 | two | 1 | -1 | 0 | 2 | 3 | two | 0 | | 2 | 2 2 | 3 | two | 0 | | 3 | -3 2 | 3 | two | 0 | | 2 | 4 - 2 | 3 | two | 0 | | 5 | -5 - 2 | 3 | two | 0 | | 5 | -5 - 2 | 3 | two | 0 | | 0 | 2 | 3 | two | 0 | | | 2 | 3 | two | 0 | | | 0 - 3 | 2 | three | 0 | | 1 | -1 + 2 | 3 | two | 0 | | 5 | -5 + 2 | 3 | two | 0 | | 5 | -5 + 2 | 3 | two | 0 | | 1 | -1 + 2 | 3 | two | 0 | | 0 | + 3 | 2 | three | 1 | -1 | 2 | 2 + 3 | 2 | three | 1 | -1 | 3 | -3 + 3 | 2 | three | 1 | -1 | 2 | 4 + 3 | 2 | three | 1 | -1 | | + 3 | 2 | three | 1 | -1 | | 0 + 3 | 2 | three | 1 | -1 | 5 | -5 + 3 | 2 | three | 1 | -1 | 5 | -5 + 3 | 2 | three | 1 | -1 | 1 | -1 + 3 | 2 | three | 1 | -1 | 0 | 3 | 2 | three | 0 | | 2 | 2 3 | 2 | three | 0 | | 3 | -3 3 | 2 | three | 0 | | 2 | 4 + 3 | 2 | three | 0 | | | + 3 | 2 | three | 0 | | | 0 3 | 2 | three | 0 | | 5 | -5 3 | 2 | three | 0 | | 5 | -5 + 3 | 2 | three | 0 | | 1 | -1 3 | 2 | three | 0 | | 0 | - 3 | 2 | three | 0 | | | - 3 | 2 | three | 0 | | | 0 - 4 | 1 | four | 0 | | 1 | -1 + 4 | 1 | four | 1 | -1 | 2 | 2 + 4 | 1 | four | 1 | -1 | 3 | -3 + 4 | 1 | four | 1 | -1 | 2 | 4 + 4 | 1 | four | 1 | -1 | | + 4 | 1 | four | 1 | -1 | | 0 + 4 | 1 | four | 1 | -1 | 5 | -5 + 4 | 1 | four | 1 | -1 | 5 | -5 + 4 | 1 | four | 1 | -1 | 1 | -1 + 4 | 1 | four | 1 | -1 | 0 | 4 | 1 | four | 0 | | 2 | 2 4 | 1 | four | 0 | | 3 | -3 4 | 1 | four | 0 | | 2 | 4 + 4 | 1 | four | 0 | | | + 4 | 1 | four | 0 | | | 0 4 | 1 | four | 0 | | 5 | -5 4 | 1 | four | 0 | | 5 | -5 + 4 | 1 | four | 0 | | 1 | -1 4 | 1 | four | 0 | | 0 | - 4 | 1 | four | 0 | | | - 4 | 1 | four | 0 | | | 0 - 5 | 0 | five | 0 | | 1 | -1 - 5 | 0 | five | 0 | | 2 | 2 - 5 | 0 | five | 0 | | 3 | -3 - 5 | 0 | five | 0 | | 2 | 4 - 5 | 0 | five | 0 | | 5 | -5 - 5 | 0 | five | 0 | | 5 | -5 - 5 | 0 | five | 0 | | 0 | - 5 | 0 | five | 0 | | | - 5 | 0 | five | 0 | | | 0 - 6 | 6 | six | 0 | | 1 | -1 - 6 | 6 | six | 0 | | 2 | 2 - 6 | 6 | six | 0 | | 3 | -3 - 6 | 6 | six | 0 | | 2 | 4 - 6 | 6 | six | 0 | | 5 | -5 - 6 | 6 | six | 0 | | 5 | -5 - 6 | 6 | six | 0 | | 0 | - 6 | 6 | six | 0 | | | - 6 | 6 | six | 0 | | | 0 - 7 | 7 | seven | 0 | | 1 | -1 + 7 | 7 | seven | 1 | -1 | 2 | 2 + 7 | 7 | seven | 1 | -1 | 3 | -3 + 7 | 7 | seven | 1 | -1 | 2 | 4 + 7 | 7 | seven | 1 | -1 | | + 7 | 7 | seven | 1 | -1 | | 0 + 7 | 7 | seven | 1 | -1 | 5 | -5 + 7 | 7 | seven | 1 | -1 | 5 | -5 + 7 | 7 | seven | 1 | -1 | 1 | -1 + 7 | 7 | seven | 1 | -1 | 0 | 7 | 7 | seven | 0 | | 2 | 2 7 | 7 | seven | 0 | | 3 | -3 7 | 7 | seven | 0 | | 2 | 4 + 7 | 7 | seven | 0 | | | + 7 | 7 | seven | 0 | | | 0 7 | 7 | seven | 0 | | 5 | -5 7 | 7 | seven | 0 | | 5 | -5 + 7 | 7 | seven | 0 | | 1 | -1 7 | 7 | seven | 0 | | 0 | - 7 | 7 | seven | 0 | | | - 7 | 7 | seven | 0 | | | 0 - 8 | 8 | eight | 0 | | 1 | -1 + 8 | 8 | eight | 1 | -1 | 2 | 2 + 8 | 8 | eight | 1 | -1 | 3 | -3 + 8 | 8 | eight | 1 | -1 | 2 | 4 + 8 | 8 | eight | 1 | -1 | | + 8 | 8 | eight | 1 | -1 | | 0 + 8 | 8 | eight | 1 | -1 | 5 | -5 + 8 | 8 | eight | 1 | -1 | 5 | -5 + 8 | 8 | eight | 1 | -1 | 1 | -1 + 8 | 8 | eight | 1 | -1 | 0 | 8 | 8 | eight | 0 | | 2 | 2 8 | 8 | eight | 0 | | 3 | -3 8 | 8 | eight | 0 | | 2 | 4 + 8 | 8 | eight | 0 | | | + 8 | 8 | eight | 0 | | | 0 8 | 8 | eight | 0 | | 5 | -5 8 | 8 | eight | 0 | | 5 | -5 + 8 | 8 | eight | 0 | | 1 | -1 8 | 8 | eight | 0 | | 0 | - 8 | 8 | eight | 0 | | | - 8 | 8 | eight | 0 | | | 0 - 0 | | zero | 0 | | 1 | -1 - 0 | | zero | 0 | | 2 | 2 - 0 | | zero | 0 | | 3 | -3 - 0 | | zero | 0 | | 2 | 4 - 0 | | zero | 0 | | 5 | -5 - 0 | | zero | 0 | | 5 | -5 - 0 | | zero | 0 | | 0 | - 0 | | zero | 0 | | | - 0 | | zero | 0 | | | 0 - | | null | 0 | | 1 | -1 + | | null | 1 | -1 | 2 | 2 + | | null | 1 | -1 | 3 | -3 + | | null | 1 | -1 | 2 | 4 + | | null | 1 | -1 | | + | | null | 1 | -1 | | 0 + | | null | 1 | -1 | 5 | -5 + | | null | 1 | -1 | 5 | -5 + | | null | 1 | -1 | 1 | -1 + | | null | 1 | -1 | 0 | | | null | 0 | | 2 | 2 | | null | 0 | | 3 | -3 | | null | 0 | | 2 | 4 + | | null | 0 | | | + | | null | 0 | | | 0 | | null | 0 | | 5 | -5 | | null | 0 | | 5 | -5 + | | null | 0 | | 1 | -1 | | null | 0 | | 0 | - | | null | 0 | | | - | | null | 0 | | | 0 - | 0 | zero | 0 | | 1 | -1 + | 0 | zero | 1 | -1 | 2 | 2 + | 0 | zero | 1 | -1 | 3 | -3 + | 0 | zero | 1 | -1 | 2 | 4 + | 0 | zero | 1 | -1 | | + | 0 | zero | 1 | -1 | | 0 + | 0 | zero | 1 | -1 | 5 | -5 + | 0 | zero | 1 | -1 | 5 | -5 + | 0 | zero | 1 | -1 | 1 | -1 + | 0 | zero | 1 | -1 | 0 | | 0 | zero | 0 | | 2 | 2 | 0 | zero | 0 | | 3 | -3 | 0 | zero | 0 | | 2 | 4 + | 0 | zero | 0 | | | + | 0 | zero | 0 | | | 0 | 0 | zero | 0 | | 5 | -5 | 0 | zero | 0 | | 5 | -5 + | 0 | zero | 0 | | 1 | -1 | 0 | zero | 0 | | 0 | - | 0 | zero | 0 | | | - | 0 | zero | 0 | | | 0 - 1 | 4 | one | | | 1 | -1 - 1 | 4 | one | | | 2 | 2 - 1 | 4 | one | | | 3 | -3 - 1 | 4 | one | | | 2 | 4 - 1 | 4 | one | | | 5 | -5 - 1 | 4 | one | | | 5 | -5 - 1 | 4 | one | | | 0 | - 1 | 4 | one | | | | - 1 | 4 | one | | | | 0 - 2 | 3 | two | | | 1 | -1 + 1 | 4 | one | 1 | -1 | 2 | 2 + 1 | 4 | one | 1 | -1 | 3 | -3 + 1 | 4 | one | 1 | -1 | 2 | 4 + 1 | 4 | one | 1 | -1 | | + 1 | 4 | one | 1 | -1 | | 0 + 1 | 4 | one | 1 | -1 | 5 | -5 + 1 | 4 | one | 1 | -1 | 5 | -5 + 1 | 4 | one | 1 | -1 | 1 | -1 + 1 | 4 | one | 1 | -1 | 0 | + 1 | 4 | one | 0 | | 2 | 2 + 1 | 4 | one | 0 | | 3 | -3 + 1 | 4 | one | 0 | | 2 | 4 + 1 | 4 | one | 0 | | | + 1 | 4 | one | 0 | | | 0 + 1 | 4 | one | 0 | | 5 | -5 + 1 | 4 | one | 0 | | 5 | -5 + 1 | 4 | one | 0 | | 1 | -1 + 1 | 4 | one | 0 | | 0 | + 0 | | zero | 1 | -1 | 2 | 2 + 0 | | zero | 1 | -1 | 3 | -3 + 0 | | zero | 1 | -1 | 2 | 4 + 0 | | zero | 1 | -1 | | + 0 | | zero | 1 | -1 | | 0 + 0 | | zero | 1 | -1 | 5 | -5 + 0 | | zero | 1 | -1 | 5 | -5 + 0 | | zero | 1 | -1 | 1 | -1 + 0 | | zero | 1 | -1 | 0 | + 0 | | zero | 0 | | 2 | 2 + 0 | | zero | 0 | | 3 | -3 + 0 | | zero | 0 | | 2 | 4 + 0 | | zero | 0 | | | + 0 | | zero | 0 | | | 0 + 0 | | zero | 0 | | 5 | -5 + 0 | | zero | 0 | | 5 | -5 + 0 | | zero | 0 | | 1 | -1 + 0 | | zero | 0 | | 0 | + 5 | 0 | five | 1 | -1 | 2 | 2 + 5 | 0 | five | 1 | -1 | 3 | -3 + 5 | 0 | five | 1 | -1 | 2 | 4 + 5 | 0 | five | 1 | -1 | | + 5 | 0 | five | 1 | -1 | | 0 + 5 | 0 | five | 1 | -1 | 5 | -5 + 5 | 0 | five | 1 | -1 | 5 | -5 + 5 | 0 | five | 1 | -1 | 1 | -1 + 5 | 0 | five | 1 | -1 | 0 | + 5 | 0 | five | 0 | | 2 | 2 + 5 | 0 | five | 0 | | 3 | -3 + 5 | 0 | five | 0 | | 2 | 4 + 5 | 0 | five | 0 | | | + 5 | 0 | five | 0 | | | 0 + 5 | 0 | five | 0 | | 5 | -5 + 5 | 0 | five | 0 | | 5 | -5 + 5 | 0 | five | 0 | | 1 | -1 + 5 | 0 | five | 0 | | 0 | + 6 | 6 | six | 1 | -1 | 2 | 2 + 6 | 6 | six | 1 | -1 | 3 | -3 + 6 | 6 | six | 1 | -1 | 2 | 4 + 6 | 6 | six | 1 | -1 | | + 6 | 6 | six | 1 | -1 | | 0 + 6 | 6 | six | 1 | -1 | 5 | -5 + 6 | 6 | six | 1 | -1 | 5 | -5 + 6 | 6 | six | 1 | -1 | 1 | -1 + 6 | 6 | six | 1 | -1 | 0 | + 6 | 6 | six | 0 | | 2 | 2 + 6 | 6 | six | 0 | | 3 | -3 + 6 | 6 | six | 0 | | 2 | 4 + 6 | 6 | six | 0 | | | + 6 | 6 | six | 0 | | | 0 + 6 | 6 | six | 0 | | 5 | -5 + 6 | 6 | six | 0 | | 5 | -5 + 6 | 6 | six | 0 | | 1 | -1 + 6 | 6 | six | 0 | | 0 | + 2 | 3 | two | 2 | 2 | 5 | -5 + 2 | 3 | two | 2 | 2 | 5 | -5 + 2 | 3 | two | 2 | 2 | 2 | 2 + 2 | 3 | two | 2 | 2 | 3 | -3 + 2 | 3 | two | 2 | 2 | 2 | 4 + 2 | 3 | two | 2 | 2 | | + 2 | 3 | two | 2 | 2 | | 0 + 2 | 3 | two | 2 | 2 | 1 | -1 + 2 | 3 | two | 2 | 2 | 0 | + 2 | 3 | two | 3 | -3 | 5 | -5 + 2 | 3 | two | 3 | -3 | 5 | -5 + 2 | 3 | two | 3 | -3 | 2 | 2 + 2 | 3 | two | 3 | -3 | 3 | -3 + 2 | 3 | two | 3 | -3 | 2 | 4 + 2 | 3 | two | 3 | -3 | | + 2 | 3 | two | 3 | -3 | | 0 + 2 | 3 | two | 3 | -3 | 1 | -1 + 2 | 3 | two | 3 | -3 | 0 | + 2 | 3 | two | 2 | 4 | 5 | -5 + 2 | 3 | two | 2 | 4 | 5 | -5 + 2 | 3 | two | 2 | 4 | 2 | 2 + 2 | 3 | two | 2 | 4 | 3 | -3 + 2 | 3 | two | 2 | 4 | 2 | 4 + 2 | 3 | two | 2 | 4 | | + 2 | 3 | two | 2 | 4 | | 0 + 2 | 3 | two | 2 | 4 | 1 | -1 + 2 | 3 | two | 2 | 4 | 0 | + 2 | 3 | two | | | 5 | -5 + 2 | 3 | two | | | 5 | -5 2 | 3 | two | | | 2 | 2 2 | 3 | two | | | 3 | -3 2 | 3 | two | | | 2 | 4 - 2 | 3 | two | | | 5 | -5 - 2 | 3 | two | | | 5 | -5 - 2 | 3 | two | | | 0 | 2 | 3 | two | | | | 2 | 3 | two | | | | 0 - 3 | 2 | three | | | 1 | -1 - 3 | 2 | three | | | 2 | 2 - 3 | 2 | three | | | 3 | -3 - 3 | 2 | three | | | 2 | 4 - 3 | 2 | three | | | 5 | -5 - 3 | 2 | three | | | 5 | -5 - 3 | 2 | three | | | 0 | - 3 | 2 | three | | | | - 3 | 2 | three | | | | 0 - 4 | 1 | four | | | 1 | -1 - 4 | 1 | four | | | 2 | 2 - 4 | 1 | four | | | 3 | -3 - 4 | 1 | four | | | 2 | 4 - 4 | 1 | four | | | 5 | -5 - 4 | 1 | four | | | 5 | -5 - 4 | 1 | four | | | 0 | - 4 | 1 | four | | | | - 4 | 1 | four | | | | 0 - 5 | 0 | five | | | 1 | -1 + 2 | 3 | two | | | 1 | -1 + 2 | 3 | two | | | 0 | + 2 | 3 | two | | 0 | 5 | -5 + 2 | 3 | two | | 0 | 5 | -5 + 2 | 3 | two | | 0 | 2 | 2 + 2 | 3 | two | | 0 | 3 | -3 + 2 | 3 | two | | 0 | 2 | 4 + 2 | 3 | two | | 0 | | + 2 | 3 | two | | 0 | | 0 + 2 | 3 | two | | 0 | 1 | -1 + 2 | 3 | two | | 0 | 0 | + 3 | 2 | three | 2 | 2 | 5 | -5 + 3 | 2 | three | 2 | 2 | 5 | -5 + 3 | 2 | three | 2 | 2 | 2 | 2 + 3 | 2 | three | 2 | 2 | 3 | -3 + 3 | 2 | three | 2 | 2 | 2 | 4 + 3 | 2 | three | 2 | 2 | | + 3 | 2 | three | 2 | 2 | | 0 + 3 | 2 | three | 2 | 2 | 1 | -1 + 3 | 2 | three | 2 | 2 | 0 | + 3 | 2 | three | 3 | -3 | 5 | -5 + 3 | 2 | three | 3 | -3 | 5 | -5 + 3 | 2 | three | 3 | -3 | 2 | 2 + 3 | 2 | three | 3 | -3 | 3 | -3 + 3 | 2 | three | 3 | -3 | 2 | 4 + 3 | 2 | three | 3 | -3 | | + 3 | 2 | three | 3 | -3 | | 0 + 3 | 2 | three | 3 | -3 | 1 | -1 + 3 | 2 | three | 3 | -3 | 0 | + 3 | 2 | three | 2 | 4 | 5 | -5 + 3 | 2 | three | 2 | 4 | 5 | -5 + 3 | 2 | three | 2 | 4 | 2 | 2 + 3 | 2 | three | 2 | 4 | 3 | -3 + 3 | 2 | three | 2 | 4 | 2 | 4 + 3 | 2 | three | 2 | 4 | | + 3 | 2 | three | 2 | 4 | | 0 + 3 | 2 | three | 2 | 4 | 1 | -1 + 3 | 2 | three | 2 | 4 | 0 | + 3 | 2 | three | | | 5 | -5 + 3 | 2 | three | | | 5 | -5 + 3 | 2 | three | | | 2 | 2 + 3 | 2 | three | | | 3 | -3 + 3 | 2 | three | | | 2 | 4 + 3 | 2 | three | | | | + 3 | 2 | three | | | | 0 + 3 | 2 | three | | | 1 | -1 + 3 | 2 | three | | | 0 | + 3 | 2 | three | | 0 | 5 | -5 + 3 | 2 | three | | 0 | 5 | -5 + 3 | 2 | three | | 0 | 2 | 2 + 3 | 2 | three | | 0 | 3 | -3 + 3 | 2 | three | | 0 | 2 | 4 + 3 | 2 | three | | 0 | | + 3 | 2 | three | | 0 | | 0 + 3 | 2 | three | | 0 | 1 | -1 + 3 | 2 | three | | 0 | 0 | + 4 | 1 | four | 2 | 2 | 5 | -5 + 4 | 1 | four | 2 | 2 | 5 | -5 + 4 | 1 | four | 2 | 2 | 2 | 2 + 4 | 1 | four | 2 | 2 | 3 | -3 + 4 | 1 | four | 2 | 2 | 2 | 4 + 4 | 1 | four | 2 | 2 | | + 4 | 1 | four | 2 | 2 | | 0 + 4 | 1 | four | 2 | 2 | 1 | -1 + 4 | 1 | four | 2 | 2 | 0 | + 4 | 1 | four | 3 | -3 | 5 | -5 + 4 | 1 | four | 3 | -3 | 5 | -5 + 4 | 1 | four | 3 | -3 | 2 | 2 + 4 | 1 | four | 3 | -3 | 3 | -3 + 4 | 1 | four | 3 | -3 | 2 | 4 + 4 | 1 | four | 3 | -3 | | + 4 | 1 | four | 3 | -3 | | 0 + 4 | 1 | four | 3 | -3 | 1 | -1 + 4 | 1 | four | 3 | -3 | 0 | + 4 | 1 | four | 2 | 4 | 5 | -5 + 4 | 1 | four | 2 | 4 | 5 | -5 + 4 | 1 | four | 2 | 4 | 2 | 2 + 4 | 1 | four | 2 | 4 | 3 | -3 + 4 | 1 | four | 2 | 4 | 2 | 4 + 4 | 1 | four | 2 | 4 | | + 4 | 1 | four | 2 | 4 | | 0 + 4 | 1 | four | 2 | 4 | 1 | -1 + 4 | 1 | four | 2 | 4 | 0 | + 4 | 1 | four | | | 5 | -5 + 4 | 1 | four | | | 5 | -5 + 4 | 1 | four | | | 2 | 2 + 4 | 1 | four | | | 3 | -3 + 4 | 1 | four | | | 2 | 4 + 4 | 1 | four | | | | + 4 | 1 | four | | | | 0 + 4 | 1 | four | | | 1 | -1 + 4 | 1 | four | | | 0 | + 4 | 1 | four | | 0 | 5 | -5 + 4 | 1 | four | | 0 | 5 | -5 + 4 | 1 | four | | 0 | 2 | 2 + 4 | 1 | four | | 0 | 3 | -3 + 4 | 1 | four | | 0 | 2 | 4 + 4 | 1 | four | | 0 | | + 4 | 1 | four | | 0 | | 0 + 4 | 1 | four | | 0 | 1 | -1 + 4 | 1 | four | | 0 | 0 | + 7 | 7 | seven | 2 | 2 | 5 | -5 + 7 | 7 | seven | 2 | 2 | 5 | -5 + 7 | 7 | seven | 2 | 2 | 2 | 2 + 7 | 7 | seven | 2 | 2 | 3 | -3 + 7 | 7 | seven | 2 | 2 | 2 | 4 + 7 | 7 | seven | 2 | 2 | | + 7 | 7 | seven | 2 | 2 | | 0 + 7 | 7 | seven | 2 | 2 | 1 | -1 + 7 | 7 | seven | 2 | 2 | 0 | + 7 | 7 | seven | 3 | -3 | 5 | -5 + 7 | 7 | seven | 3 | -3 | 5 | -5 + 7 | 7 | seven | 3 | -3 | 2 | 2 + 7 | 7 | seven | 3 | -3 | 3 | -3 + 7 | 7 | seven | 3 | -3 | 2 | 4 + 7 | 7 | seven | 3 | -3 | | + 7 | 7 | seven | 3 | -3 | | 0 + 7 | 7 | seven | 3 | -3 | 1 | -1 + 7 | 7 | seven | 3 | -3 | 0 | + 7 | 7 | seven | 2 | 4 | 5 | -5 + 7 | 7 | seven | 2 | 4 | 5 | -5 + 7 | 7 | seven | 2 | 4 | 2 | 2 + 7 | 7 | seven | 2 | 4 | 3 | -3 + 7 | 7 | seven | 2 | 4 | 2 | 4 + 7 | 7 | seven | 2 | 4 | | + 7 | 7 | seven | 2 | 4 | | 0 + 7 | 7 | seven | 2 | 4 | 1 | -1 + 7 | 7 | seven | 2 | 4 | 0 | + 7 | 7 | seven | | | 5 | -5 + 7 | 7 | seven | | | 5 | -5 + 7 | 7 | seven | | | 2 | 2 + 7 | 7 | seven | | | 3 | -3 + 7 | 7 | seven | | | 2 | 4 + 7 | 7 | seven | | | | + 7 | 7 | seven | | | | 0 + 7 | 7 | seven | | | 1 | -1 + 7 | 7 | seven | | | 0 | + 7 | 7 | seven | | 0 | 5 | -5 + 7 | 7 | seven | | 0 | 5 | -5 + 7 | 7 | seven | | 0 | 2 | 2 + 7 | 7 | seven | | 0 | 3 | -3 + 7 | 7 | seven | | 0 | 2 | 4 + 7 | 7 | seven | | 0 | | + 7 | 7 | seven | | 0 | | 0 + 7 | 7 | seven | | 0 | 1 | -1 + 7 | 7 | seven | | 0 | 0 | + 8 | 8 | eight | 2 | 2 | 5 | -5 + 8 | 8 | eight | 2 | 2 | 5 | -5 + 8 | 8 | eight | 2 | 2 | 2 | 2 + 8 | 8 | eight | 2 | 2 | 3 | -3 + 8 | 8 | eight | 2 | 2 | 2 | 4 + 8 | 8 | eight | 2 | 2 | | + 8 | 8 | eight | 2 | 2 | | 0 + 8 | 8 | eight | 2 | 2 | 1 | -1 + 8 | 8 | eight | 2 | 2 | 0 | + 8 | 8 | eight | 3 | -3 | 5 | -5 + 8 | 8 | eight | 3 | -3 | 5 | -5 + 8 | 8 | eight | 3 | -3 | 2 | 2 + 8 | 8 | eight | 3 | -3 | 3 | -3 + 8 | 8 | eight | 3 | -3 | 2 | 4 + 8 | 8 | eight | 3 | -3 | | + 8 | 8 | eight | 3 | -3 | | 0 + 8 | 8 | eight | 3 | -3 | 1 | -1 + 8 | 8 | eight | 3 | -3 | 0 | + 8 | 8 | eight | 2 | 4 | 5 | -5 + 8 | 8 | eight | 2 | 4 | 5 | -5 + 8 | 8 | eight | 2 | 4 | 2 | 2 + 8 | 8 | eight | 2 | 4 | 3 | -3 + 8 | 8 | eight | 2 | 4 | 2 | 4 + 8 | 8 | eight | 2 | 4 | | + 8 | 8 | eight | 2 | 4 | | 0 + 8 | 8 | eight | 2 | 4 | 1 | -1 + 8 | 8 | eight | 2 | 4 | 0 | + 8 | 8 | eight | | | 5 | -5 + 8 | 8 | eight | | | 5 | -5 + 8 | 8 | eight | | | 2 | 2 + 8 | 8 | eight | | | 3 | -3 + 8 | 8 | eight | | | 2 | 4 + 8 | 8 | eight | | | | + 8 | 8 | eight | | | | 0 + 8 | 8 | eight | | | 1 | -1 + 8 | 8 | eight | | | 0 | + 8 | 8 | eight | | 0 | 5 | -5 + 8 | 8 | eight | | 0 | 5 | -5 + 8 | 8 | eight | | 0 | 2 | 2 + 8 | 8 | eight | | 0 | 3 | -3 + 8 | 8 | eight | | 0 | 2 | 4 + 8 | 8 | eight | | 0 | | + 8 | 8 | eight | | 0 | | 0 + 8 | 8 | eight | | 0 | 1 | -1 + 8 | 8 | eight | | 0 | 0 | + | | null | 2 | 2 | 5 | -5 + | | null | 2 | 2 | 5 | -5 + | | null | 2 | 2 | 2 | 2 + | | null | 2 | 2 | 3 | -3 + | | null | 2 | 2 | 2 | 4 + | | null | 2 | 2 | | + | | null | 2 | 2 | | 0 + | | null | 2 | 2 | 1 | -1 + | | null | 2 | 2 | 0 | + | | null | 3 | -3 | 5 | -5 + | | null | 3 | -3 | 5 | -5 + | | null | 3 | -3 | 2 | 2 + | | null | 3 | -3 | 3 | -3 + | | null | 3 | -3 | 2 | 4 + | | null | 3 | -3 | | + | | null | 3 | -3 | | 0 + | | null | 3 | -3 | 1 | -1 + | | null | 3 | -3 | 0 | + | | null | 2 | 4 | 5 | -5 + | | null | 2 | 4 | 5 | -5 + | | null | 2 | 4 | 2 | 2 + | | null | 2 | 4 | 3 | -3 + | | null | 2 | 4 | 2 | 4 + | | null | 2 | 4 | | + | | null | 2 | 4 | | 0 + | | null | 2 | 4 | 1 | -1 + | | null | 2 | 4 | 0 | + | | null | | | 5 | -5 + | | null | | | 5 | -5 + | | null | | | 2 | 2 + | | null | | | 3 | -3 + | | null | | | 2 | 4 + | | null | | | | + | | null | | | | 0 + | | null | | | 1 | -1 + | | null | | | 0 | + | | null | | 0 | 5 | -5 + | | null | | 0 | 5 | -5 + | | null | | 0 | 2 | 2 + | | null | | 0 | 3 | -3 + | | null | | 0 | 2 | 4 + | | null | | 0 | | + | | null | | 0 | | 0 + | | null | | 0 | 1 | -1 + | | null | | 0 | 0 | + | 0 | zero | 2 | 2 | 5 | -5 + | 0 | zero | 2 | 2 | 5 | -5 + | 0 | zero | 2 | 2 | 2 | 2 + | 0 | zero | 2 | 2 | 3 | -3 + | 0 | zero | 2 | 2 | 2 | 4 + | 0 | zero | 2 | 2 | | + | 0 | zero | 2 | 2 | | 0 + | 0 | zero | 2 | 2 | 1 | -1 + | 0 | zero | 2 | 2 | 0 | + | 0 | zero | 3 | -3 | 5 | -5 + | 0 | zero | 3 | -3 | 5 | -5 + | 0 | zero | 3 | -3 | 2 | 2 + | 0 | zero | 3 | -3 | 3 | -3 + | 0 | zero | 3 | -3 | 2 | 4 + | 0 | zero | 3 | -3 | | + | 0 | zero | 3 | -3 | | 0 + | 0 | zero | 3 | -3 | 1 | -1 + | 0 | zero | 3 | -3 | 0 | + | 0 | zero | 2 | 4 | 5 | -5 + | 0 | zero | 2 | 4 | 5 | -5 + | 0 | zero | 2 | 4 | 2 | 2 + | 0 | zero | 2 | 4 | 3 | -3 + | 0 | zero | 2 | 4 | 2 | 4 + | 0 | zero | 2 | 4 | | + | 0 | zero | 2 | 4 | | 0 + | 0 | zero | 2 | 4 | 1 | -1 + | 0 | zero | 2 | 4 | 0 | + | 0 | zero | | | 5 | -5 + | 0 | zero | | | 5 | -5 + | 0 | zero | | | 2 | 2 + | 0 | zero | | | 3 | -3 + | 0 | zero | | | 2 | 4 + | 0 | zero | | | | + | 0 | zero | | | | 0 + | 0 | zero | | | 1 | -1 + | 0 | zero | | | 0 | + | 0 | zero | | 0 | 5 | -5 + | 0 | zero | | 0 | 5 | -5 + | 0 | zero | | 0 | 2 | 2 + | 0 | zero | | 0 | 3 | -3 + | 0 | zero | | 0 | 2 | 4 + | 0 | zero | | 0 | | + | 0 | zero | | 0 | | 0 + | 0 | zero | | 0 | 1 | -1 + | 0 | zero | | 0 | 0 | + 1 | 4 | one | 2 | 2 | 5 | -5 + 1 | 4 | one | 2 | 2 | 5 | -5 + 1 | 4 | one | 2 | 2 | 2 | 2 + 1 | 4 | one | 2 | 2 | 3 | -3 + 1 | 4 | one | 2 | 2 | 2 | 4 + 1 | 4 | one | 2 | 2 | | + 1 | 4 | one | 2 | 2 | | 0 + 1 | 4 | one | 2 | 2 | 1 | -1 + 1 | 4 | one | 2 | 2 | 0 | + 1 | 4 | one | 3 | -3 | 5 | -5 + 1 | 4 | one | 3 | -3 | 5 | -5 + 1 | 4 | one | 3 | -3 | 2 | 2 + 1 | 4 | one | 3 | -3 | 3 | -3 + 1 | 4 | one | 3 | -3 | 2 | 4 + 1 | 4 | one | 3 | -3 | | + 1 | 4 | one | 3 | -3 | | 0 + 1 | 4 | one | 3 | -3 | 1 | -1 + 1 | 4 | one | 3 | -3 | 0 | + 1 | 4 | one | 2 | 4 | 5 | -5 + 1 | 4 | one | 2 | 4 | 5 | -5 + 1 | 4 | one | 2 | 4 | 2 | 2 + 1 | 4 | one | 2 | 4 | 3 | -3 + 1 | 4 | one | 2 | 4 | 2 | 4 + 1 | 4 | one | 2 | 4 | | + 1 | 4 | one | 2 | 4 | | 0 + 1 | 4 | one | 2 | 4 | 1 | -1 + 1 | 4 | one | 2 | 4 | 0 | + 1 | 4 | one | | | 5 | -5 + 1 | 4 | one | | | 5 | -5 + 1 | 4 | one | | | 2 | 2 + 1 | 4 | one | | | 3 | -3 + 1 | 4 | one | | | 2 | 4 + 1 | 4 | one | | | | + 1 | 4 | one | | | | 0 + 1 | 4 | one | | | 1 | -1 + 1 | 4 | one | | | 0 | + 1 | 4 | one | | 0 | 5 | -5 + 1 | 4 | one | | 0 | 5 | -5 + 1 | 4 | one | | 0 | 2 | 2 + 1 | 4 | one | | 0 | 3 | -3 + 1 | 4 | one | | 0 | 2 | 4 + 1 | 4 | one | | 0 | | + 1 | 4 | one | | 0 | | 0 + 1 | 4 | one | | 0 | 1 | -1 + 1 | 4 | one | | 0 | 0 | + 0 | | zero | 2 | 2 | 5 | -5 + 0 | | zero | 2 | 2 | 5 | -5 + 0 | | zero | 2 | 2 | 2 | 2 + 0 | | zero | 2 | 2 | 3 | -3 + 0 | | zero | 2 | 2 | 2 | 4 + 0 | | zero | 2 | 2 | | + 0 | | zero | 2 | 2 | | 0 + 0 | | zero | 2 | 2 | 1 | -1 + 0 | | zero | 2 | 2 | 0 | + 0 | | zero | 3 | -3 | 5 | -5 + 0 | | zero | 3 | -3 | 5 | -5 + 0 | | zero | 3 | -3 | 2 | 2 + 0 | | zero | 3 | -3 | 3 | -3 + 0 | | zero | 3 | -3 | 2 | 4 + 0 | | zero | 3 | -3 | | + 0 | | zero | 3 | -3 | | 0 + 0 | | zero | 3 | -3 | 1 | -1 + 0 | | zero | 3 | -3 | 0 | + 0 | | zero | 2 | 4 | 5 | -5 + 0 | | zero | 2 | 4 | 5 | -5 + 0 | | zero | 2 | 4 | 2 | 2 + 0 | | zero | 2 | 4 | 3 | -3 + 0 | | zero | 2 | 4 | 2 | 4 + 0 | | zero | 2 | 4 | | + 0 | | zero | 2 | 4 | | 0 + 0 | | zero | 2 | 4 | 1 | -1 + 0 | | zero | 2 | 4 | 0 | + 0 | | zero | | | 5 | -5 + 0 | | zero | | | 5 | -5 + 0 | | zero | | | 2 | 2 + 0 | | zero | | | 3 | -3 + 0 | | zero | | | 2 | 4 + 0 | | zero | | | | + 0 | | zero | | | | 0 + 0 | | zero | | | 1 | -1 + 0 | | zero | | | 0 | + 0 | | zero | | 0 | 5 | -5 + 0 | | zero | | 0 | 5 | -5 + 0 | | zero | | 0 | 2 | 2 + 0 | | zero | | 0 | 3 | -3 + 0 | | zero | | 0 | 2 | 4 + 0 | | zero | | 0 | | + 0 | | zero | | 0 | | 0 + 0 | | zero | | 0 | 1 | -1 + 0 | | zero | | 0 | 0 | + 5 | 0 | five | 2 | 2 | 5 | -5 + 5 | 0 | five | 2 | 2 | 5 | -5 + 5 | 0 | five | 2 | 2 | 2 | 2 + 5 | 0 | five | 2 | 2 | 3 | -3 + 5 | 0 | five | 2 | 2 | 2 | 4 + 5 | 0 | five | 2 | 2 | | + 5 | 0 | five | 2 | 2 | | 0 + 5 | 0 | five | 2 | 2 | 1 | -1 + 5 | 0 | five | 2 | 2 | 0 | + 5 | 0 | five | 3 | -3 | 5 | -5 + 5 | 0 | five | 3 | -3 | 5 | -5 + 5 | 0 | five | 3 | -3 | 2 | 2 + 5 | 0 | five | 3 | -3 | 3 | -3 + 5 | 0 | five | 3 | -3 | 2 | 4 + 5 | 0 | five | 3 | -3 | | + 5 | 0 | five | 3 | -3 | | 0 + 5 | 0 | five | 3 | -3 | 1 | -1 + 5 | 0 | five | 3 | -3 | 0 | + 5 | 0 | five | 2 | 4 | 5 | -5 + 5 | 0 | five | 2 | 4 | 5 | -5 + 5 | 0 | five | 2 | 4 | 2 | 2 + 5 | 0 | five | 2 | 4 | 3 | -3 + 5 | 0 | five | 2 | 4 | 2 | 4 + 5 | 0 | five | 2 | 4 | | + 5 | 0 | five | 2 | 4 | | 0 + 5 | 0 | five | 2 | 4 | 1 | -1 + 5 | 0 | five | 2 | 4 | 0 | + 5 | 0 | five | | | 5 | -5 + 5 | 0 | five | | | 5 | -5 5 | 0 | five | | | 2 | 2 5 | 0 | five | | | 3 | -3 5 | 0 | five | | | 2 | 4 - 5 | 0 | five | | | 5 | -5 - 5 | 0 | five | | | 5 | -5 - 5 | 0 | five | | | 0 | 5 | 0 | five | | | | 5 | 0 | five | | | | 0 - 6 | 6 | six | | | 1 | -1 - 6 | 6 | six | | | 2 | 2 - 6 | 6 | six | | | 3 | -3 - 6 | 6 | six | | | 2 | 4 - 6 | 6 | six | | | 5 | -5 - 6 | 6 | six | | | 5 | -5 - 6 | 6 | six | | | 0 | - 6 | 6 | six | | | | - 6 | 6 | six | | | | 0 - 7 | 7 | seven | | | 1 | -1 - 7 | 7 | seven | | | 2 | 2 - 7 | 7 | seven | | | 3 | -3 - 7 | 7 | seven | | | 2 | 4 - 7 | 7 | seven | | | 5 | -5 - 7 | 7 | seven | | | 5 | -5 - 7 | 7 | seven | | | 0 | - 7 | 7 | seven | | | | - 7 | 7 | seven | | | | 0 - 8 | 8 | eight | | | 1 | -1 - 8 | 8 | eight | | | 2 | 2 - 8 | 8 | eight | | | 3 | -3 - 8 | 8 | eight | | | 2 | 4 - 8 | 8 | eight | | | 5 | -5 - 8 | 8 | eight | | | 5 | -5 - 8 | 8 | eight | | | 0 | - 8 | 8 | eight | | | | - 8 | 8 | eight | | | | 0 - 0 | | zero | | | 1 | -1 - 0 | | zero | | | 2 | 2 - 0 | | zero | | | 3 | -3 - 0 | | zero | | | 2 | 4 - 0 | | zero | | | 5 | -5 - 0 | | zero | | | 5 | -5 - 0 | | zero | | | 0 | - 0 | | zero | | | | - 0 | | zero | | | | 0 - | | null | | | 1 | -1 - | | null | | | 2 | 2 - | | null | | | 3 | -3 - | | null | | | 2 | 4 - | | null | | | 5 | -5 - | | null | | | 5 | -5 - | | null | | | 0 | - | | null | | | | - | | null | | | | 0 - | 0 | zero | | | 1 | -1 - | 0 | zero | | | 2 | 2 - | 0 | zero | | | 3 | -3 - | 0 | zero | | | 2 | 4 - | 0 | zero | | | 5 | -5 - | 0 | zero | | | 5 | -5 - | 0 | zero | | | 0 | - | 0 | zero | | | | - | 0 | zero | | | | 0 - 1 | 4 | one | | 0 | 1 | -1 - 1 | 4 | one | | 0 | 2 | 2 - 1 | 4 | one | | 0 | 3 | -3 - 1 | 4 | one | | 0 | 2 | 4 - 1 | 4 | one | | 0 | 5 | -5 - 1 | 4 | one | | 0 | 5 | -5 - 1 | 4 | one | | 0 | 0 | - 1 | 4 | one | | 0 | | - 1 | 4 | one | | 0 | | 0 - 2 | 3 | two | | 0 | 1 | -1 - 2 | 3 | two | | 0 | 2 | 2 - 2 | 3 | two | | 0 | 3 | -3 - 2 | 3 | two | | 0 | 2 | 4 - 2 | 3 | two | | 0 | 5 | -5 - 2 | 3 | two | | 0 | 5 | -5 - 2 | 3 | two | | 0 | 0 | - 2 | 3 | two | | 0 | | - 2 | 3 | two | | 0 | | 0 - 3 | 2 | three | | 0 | 1 | -1 - 3 | 2 | three | | 0 | 2 | 2 - 3 | 2 | three | | 0 | 3 | -3 - 3 | 2 | three | | 0 | 2 | 4 - 3 | 2 | three | | 0 | 5 | -5 - 3 | 2 | three | | 0 | 5 | -5 - 3 | 2 | three | | 0 | 0 | - 3 | 2 | three | | 0 | | - 3 | 2 | three | | 0 | | 0 - 4 | 1 | four | | 0 | 1 | -1 - 4 | 1 | four | | 0 | 2 | 2 - 4 | 1 | four | | 0 | 3 | -3 - 4 | 1 | four | | 0 | 2 | 4 - 4 | 1 | four | | 0 | 5 | -5 - 4 | 1 | four | | 0 | 5 | -5 - 4 | 1 | four | | 0 | 0 | - 4 | 1 | four | | 0 | | - 4 | 1 | four | | 0 | | 0 - 5 | 0 | five | | 0 | 1 | -1 + 5 | 0 | five | | | 1 | -1 + 5 | 0 | five | | | 0 | + 5 | 0 | five | | 0 | 5 | -5 + 5 | 0 | five | | 0 | 5 | -5 5 | 0 | five | | 0 | 2 | 2 5 | 0 | five | | 0 | 3 | -3 5 | 0 | five | | 0 | 2 | 4 - 5 | 0 | five | | 0 | 5 | -5 - 5 | 0 | five | | 0 | 5 | -5 - 5 | 0 | five | | 0 | 0 | 5 | 0 | five | | 0 | | 5 | 0 | five | | 0 | | 0 - 6 | 6 | six | | 0 | 1 | -1 + 5 | 0 | five | | 0 | 1 | -1 + 5 | 0 | five | | 0 | 0 | + 6 | 6 | six | 2 | 2 | 5 | -5 + 6 | 6 | six | 2 | 2 | 5 | -5 + 6 | 6 | six | 2 | 2 | 2 | 2 + 6 | 6 | six | 2 | 2 | 3 | -3 + 6 | 6 | six | 2 | 2 | 2 | 4 + 6 | 6 | six | 2 | 2 | | + 6 | 6 | six | 2 | 2 | | 0 + 6 | 6 | six | 2 | 2 | 1 | -1 + 6 | 6 | six | 2 | 2 | 0 | + 6 | 6 | six | 3 | -3 | 5 | -5 + 6 | 6 | six | 3 | -3 | 5 | -5 + 6 | 6 | six | 3 | -3 | 2 | 2 + 6 | 6 | six | 3 | -3 | 3 | -3 + 6 | 6 | six | 3 | -3 | 2 | 4 + 6 | 6 | six | 3 | -3 | | + 6 | 6 | six | 3 | -3 | | 0 + 6 | 6 | six | 3 | -3 | 1 | -1 + 6 | 6 | six | 3 | -3 | 0 | + 6 | 6 | six | 2 | 4 | 5 | -5 + 6 | 6 | six | 2 | 4 | 5 | -5 + 6 | 6 | six | 2 | 4 | 2 | 2 + 6 | 6 | six | 2 | 4 | 3 | -3 + 6 | 6 | six | 2 | 4 | 2 | 4 + 6 | 6 | six | 2 | 4 | | + 6 | 6 | six | 2 | 4 | | 0 + 6 | 6 | six | 2 | 4 | 1 | -1 + 6 | 6 | six | 2 | 4 | 0 | + 6 | 6 | six | | | 5 | -5 + 6 | 6 | six | | | 5 | -5 + 6 | 6 | six | | | 2 | 2 + 6 | 6 | six | | | 3 | -3 + 6 | 6 | six | | | 2 | 4 + 6 | 6 | six | | | | + 6 | 6 | six | | | | 0 + 6 | 6 | six | | | 1 | -1 + 6 | 6 | six | | | 0 | + 6 | 6 | six | | 0 | 5 | -5 + 6 | 6 | six | | 0 | 5 | -5 6 | 6 | six | | 0 | 2 | 2 6 | 6 | six | | 0 | 3 | -3 6 | 6 | six | | 0 | 2 | 4 - 6 | 6 | six | | 0 | 5 | -5 - 6 | 6 | six | | 0 | 5 | -5 - 6 | 6 | six | | 0 | 0 | 6 | 6 | six | | 0 | | 6 | 6 | six | | 0 | | 0 - 7 | 7 | seven | | 0 | 1 | -1 - 7 | 7 | seven | | 0 | 2 | 2 - 7 | 7 | seven | | 0 | 3 | -3 - 7 | 7 | seven | | 0 | 2 | 4 - 7 | 7 | seven | | 0 | 5 | -5 - 7 | 7 | seven | | 0 | 5 | -5 - 7 | 7 | seven | | 0 | 0 | - 7 | 7 | seven | | 0 | | - 7 | 7 | seven | | 0 | | 0 - 8 | 8 | eight | | 0 | 1 | -1 - 8 | 8 | eight | | 0 | 2 | 2 - 8 | 8 | eight | | 0 | 3 | -3 - 8 | 8 | eight | | 0 | 2 | 4 - 8 | 8 | eight | | 0 | 5 | -5 - 8 | 8 | eight | | 0 | 5 | -5 - 8 | 8 | eight | | 0 | 0 | - 8 | 8 | eight | | 0 | | - 8 | 8 | eight | | 0 | | 0 - 0 | | zero | | 0 | 1 | -1 - 0 | | zero | | 0 | 2 | 2 - 0 | | zero | | 0 | 3 | -3 - 0 | | zero | | 0 | 2 | 4 - 0 | | zero | | 0 | 5 | -5 - 0 | | zero | | 0 | 5 | -5 - 0 | | zero | | 0 | 0 | - 0 | | zero | | 0 | | - 0 | | zero | | 0 | | 0 - | | null | | 0 | 1 | -1 - | | null | | 0 | 2 | 2 - | | null | | 0 | 3 | -3 - | | null | | 0 | 2 | 4 - | | null | | 0 | 5 | -5 - | | null | | 0 | 5 | -5 - | | null | | 0 | 0 | - | | null | | 0 | | - | | null | | 0 | | 0 - | 0 | zero | | 0 | 1 | -1 - | 0 | zero | | 0 | 2 | 2 - | 0 | zero | | 0 | 3 | -3 - | 0 | zero | | 0 | 2 | 4 - | 0 | zero | | 0 | 5 | -5 - | 0 | zero | | 0 | 5 | -5 - | 0 | zero | | 0 | 0 | - | 0 | zero | | 0 | | - | 0 | zero | | 0 | | 0 + 6 | 6 | six | | 0 | 1 | -1 + 6 | 6 | six | | 0 | 0 | (891 rows) -- @@ -1573,13 +1578,13 @@ SELECT * FROM J1_TBL INNER JOIN J2_TBL USING (i); i | j | t | k ---+---+-------+---- - 0 | | zero | - 1 | 4 | one | -1 2 | 3 | two | 2 - 2 | 3 | two | 4 3 | 2 | three | -3 + 2 | 3 | two | 4 5 | 0 | five | -5 5 | 0 | five | -5 + 1 | 4 | one | -1 + 0 | | zero | (7 rows) -- Same as above, slightly different syntax @@ -1587,13 +1592,13 @@ SELECT * FROM J1_TBL JOIN J2_TBL USING (i); i | j | t | k ---+---+-------+---- - 0 | | zero | - 1 | 4 | one | -1 2 | 3 | two | 2 - 2 | 3 | two | 4 3 | 2 | three | -3 + 2 | 3 | two | 4 5 | 0 | five | -5 5 | 0 | five | -5 + 1 | 4 | one | -1 + 0 | | zero | (7 rows) SELECT * @@ -1681,26 +1686,26 @@ SELECT * FROM J1_TBL NATURAL JOIN J2_TBL; i | j | t | k ---+---+-------+---- - 0 | | zero | + 5 | 0 | five | -5 + 5 | 0 | five | -5 1 | 4 | one | -1 + 0 | | zero | 2 | 3 | two | 2 - 2 | 3 | two | 4 3 | 2 | three | -3 - 5 | 0 | five | -5 - 5 | 0 | five | -5 + 2 | 3 | two | 4 (7 rows) SELECT * FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (a, d); a | b | c | d ---+---+-------+---- - 0 | | zero | - 1 | 4 | one | -1 - 2 | 3 | two | 2 - 2 | 3 | two | 4 - 3 | 2 | three | -3 5 | 0 | five | -5 5 | 0 | five | -5 + 2 | 3 | two | 2 + 3 | 2 | three | -3 + 2 | 3 | two | 4 + 1 | 4 | one | -1 + 0 | | zero | (7 rows) SELECT * @@ -1718,13 +1723,13 @@ SELECT * FROM J1_TBL t1 (a, b) NATURAL JOIN J2_TBL t2 (a); a | b | t | k ---+---+-------+---- - 0 | | zero | + 5 | 0 | five | -5 + 5 | 0 | five | -5 1 | 4 | one | -1 + 0 | | zero | 2 | 3 | two | 2 - 2 | 3 | two | 4 3 | 2 | three | -3 - 5 | 0 | five | -5 - 5 | 0 | five | -5 + 2 | 3 | two | 4 (7 rows) -- @@ -1734,13 +1739,13 @@ SELECT * FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.i); i | j | t | i | k ---+---+-------+---+---- - 0 | | zero | 0 | 1 | 4 | one | 1 | -1 - 2 | 3 | two | 2 | 2 - 2 | 3 | two | 2 | 4 - 3 | 2 | three | 3 | -3 + 0 | | zero | 0 | 5 | 0 | five | 5 | -5 5 | 0 | five | 5 | -5 + 2 | 3 | two | 2 | 2 + 3 | 2 | three | 3 | -3 + 2 | 3 | two | 2 | 4 (7 rows) SELECT * @@ -1759,13 +1764,13 @@ SELECT * FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i <= J2_TBL.k); i | j | t | i | k ---+---+-------+---+--- - 1 | 4 | one | 2 | 2 2 | 3 | two | 2 | 2 - 0 | | zero | 2 | 2 - 1 | 4 | one | 2 | 4 2 | 3 | two | 2 | 4 3 | 2 | three | 2 | 4 4 | 1 | four | 2 | 4 + 1 | 4 | one | 2 | 2 + 0 | | zero | 2 | 2 + 1 | 4 | one | 2 | 4 0 | | zero | 2 | 4 0 | | zero | | 0 (9 rows) @@ -1818,28 +1823,28 @@ SELECT * FROM J1_TBL RIGHT OUTER JOIN J2_TBL USING (i); i | j | t | k ---+---+-------+---- - 0 | | zero | 1 | 4 | one | -1 + 0 | | zero | 2 | 3 | two | 2 - 2 | 3 | two | 4 3 | 2 | three | -3 - 5 | 0 | five | -5 - 5 | 0 | five | -5 + 2 | 3 | two | 4 | | | | | | 0 + 5 | 0 | five | -5 + 5 | 0 | five | -5 (9 rows) SELECT * FROM J1_TBL RIGHT JOIN J2_TBL USING (i); i | j | t | k ---+---+-------+---- - 0 | | zero | 1 | 4 | one | -1 - 2 | 3 | two | 2 - 2 | 3 | two | 4 - 3 | 2 | three | -3 + 0 | | zero | 5 | 0 | five | -5 5 | 0 | five | -5 + 2 | 3 | two | 2 + 3 | 2 | three | -3 + 2 | 3 | two | 4 | | | | | | 0 (9 rows) @@ -1904,33 +1909,46 @@ SELECT * -- -- semijoin selectivity for <> -- +-- start_ignore +-- GPDB: the exact plan shape depends on the optimizer (Postgres planner vs +-- GPORCA) and on MPP motion placement, so the plan is ignored here; this +-- query is retained from upstream only to exercise neqjoinsel's path. explain (costs off) -select * from int4_tbl i4, tenk1 a -where exists(select * from tenk1 b - where a.twothousand = b.twothousand and a.fivethous <> b.fivethous) - and i4.f1 = a.tenthous; - QUERY PLAN ---------------------------------------------------------------------------------------------- +select * from tenk1 a, tenk1 b +where exists(select * from tenk1 c + where b.twothousand = c.twothousand and b.fivethous <> c.fivethous) + and a.tenthous = b.tenthous and a.tenthous < 5000; + QUERY PLAN +------------------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> HashAggregate Group Key: (RowIdExpr) -> Redistribute Motion 3:3 (slice2; segments: 3) Hash Key: (RowIdExpr) -> Hash Join - Hash Cond: (b.twothousand = a.twothousand) - Join Filter: (a.fivethous <> b.fivethous) - -> Seq Scan on tenk1 b + Hash Cond: (c.twothousand = b.twothousand) + Join Filter: (b.fivethous <> c.fivethous) + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: c.twothousand + -> Seq Scan on tenk1 c -> Hash - -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: b.twothousand -> Hash Join - Hash Cond: (a.tenthous = i4.f1) - -> Seq Scan on tenk1 a + Hash Cond: (a.tenthous = b.tenthous) + -> Redistribute Motion 3:3 (slice5; segments: 3) + Hash Key: a.tenthous + -> Seq Scan on tenk1 a + Filter: (tenthous < 5000) -> Hash - -> Broadcast Motion 3:3 (slice4; segments: 3) - -> Seq Scan on int4_tbl i4 + -> Redistribute Motion 3:3 (slice6; segments: 3) + Hash Key: b.tenthous + -> Seq Scan on tenk1 b + Filter: (tenthous < 5000) Optimizer: Postgres query optimizer -(18 rows) +(26 rows) +-- end_ignore -- -- More complicated constructs -- @@ -1938,8 +1956,14 @@ where exists(select * from tenk1 b -- Multiway full join -- CREATE TABLE t1 (name TEXT, n INTEGER); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'name' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TABLE t2 (name TEXT, n INTEGER); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'name' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TABLE t3 (name TEXT, n INTEGER); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'name' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO t1 VALUES ( 'bb', 11 ); INSERT INTO t2 VALUES ( 'bb', 12 ); INSERT INTO t2 VALUES ( 'cc', 22 ); @@ -1950,10 +1974,10 @@ INSERT INTO t3 VALUES ( 'dd', 33 ); SELECT * FROM t1 FULL JOIN t2 USING (name) FULL JOIN t3 USING (name); name | n | n | n ------+----+----+---- - bb | 11 | 12 | 13 cc | | 22 | 23 - dd | | | 33 ee | | 42 | + bb | 11 | 12 | 13 + dd | | | 33 (4 rows) -- @@ -1967,8 +1991,8 @@ INNER JOIN USING (name); name | n | n ------+----+---- - bb | 12 | 13 cc | 22 | 23 + bb | 12 | 13 (2 rows) SELECT * FROM @@ -1978,9 +2002,9 @@ LEFT JOIN USING (name); name | n | n ------+----+---- - bb | 12 | 13 - cc | 22 | 23 ee | 42 | + cc | 22 | 23 + bb | 12 | 13 (3 rows) SELECT * FROM @@ -1990,10 +2014,10 @@ FULL JOIN USING (name); name | n | n ------+----+---- - bb | 12 | 13 + ee | 42 | cc | 22 | 23 + bb | 12 | 13 dd | | 33 - ee | 42 | (4 rows) -- Cases with non-nullable expressions in subquery results; @@ -2014,9 +2038,9 @@ NATURAL LEFT JOIN (SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; name | s2_n | s2_2 | s3_n | s3_2 ------+------+------+------+------ - bb | 12 | 2 | 13 | 3 - cc | 22 | 2 | 23 | 3 ee | 42 | 2 | | + cc | 22 | 2 | 23 | 3 + bb | 12 | 2 | 13 | 3 (3 rows) SELECT * FROM @@ -2025,10 +2049,10 @@ NATURAL FULL JOIN (SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; name | s2_n | s2_2 | s3_n | s3_2 ------+------+------+------+------ - bb | 12 | 2 | 13 | 3 + ee | 42 | 2 | | cc | 22 | 2 | 23 | 3 + bb | 12 | 2 | 13 | 3 dd | | | 33 | 3 - ee | 42 | 2 | | (4 rows) SELECT * FROM @@ -2051,8 +2075,8 @@ NATURAL FULL JOIN name | s1_n | s1_1 | s2_n | s2_2 | s3_n | s3_2 ------+------+------+------+------+------+------ bb | 11 | 1 | 12 | 2 | 13 | 3 - cc | | | 22 | 2 | 23 | 3 dd | | | | | 33 | 3 + cc | | | 22 | 2 | 23 | 3 ee | | | 42 | 2 | | (4 rows) @@ -2066,10 +2090,10 @@ NATURAL FULL JOIN ) ss2; name | s1_n | s2_n | s3_n ------+------+------+------ + ee | | 42 | bb | 11 | 12 | 13 - cc | | 22 | 23 dd | | | 33 - ee | | 42 | + cc | | 22 | 23 (4 rows) SELECT * FROM @@ -2083,8 +2107,8 @@ NATURAL FULL JOIN name | s1_n | s2_n | s2_2 | s3_n ------+------+------+------+------ bb | 11 | 12 | 2 | 13 - cc | | 22 | 2 | 23 dd | | | | 33 + cc | | 22 | 2 | 23 ee | | 42 | 2 | (4 rows) @@ -2096,20 +2120,24 @@ FULL JOIN ON (s1_n = s2_n); name | s1_n | name | s2_n ------+------+------+------ + bb | 11 | | | | bb | 2 | | cc | 2 | | ee | 2 - bb | 11 | | (4 rows) -- Test for propagation of nullability constraints into sub-joins create temp table x (x1 int, x2 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'x1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into x values (1,11); insert into x values (2,22); insert into x values (3,null); insert into x values (4,44); insert into x values (5,null); create temp table y (y1 int, y2 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'y1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into y values (1,111); insert into y values (2,222); insert into y values (3,333); @@ -2117,11 +2145,11 @@ insert into y values (4,null); select * from x; x1 | x2 ----+---- + 5 | 1 | 11 2 | 22 3 | 4 | 44 - 5 | (5 rows) select * from y; @@ -2147,54 +2175,54 @@ select * from x left join y on (x1 = y1 and y2 is not null); x1 | x2 | y1 | y2 ----+----+----+----- 1 | 11 | 1 | 111 + 5 | | | 2 | 22 | 2 | 222 3 | | 3 | 333 4 | 44 | | - 5 | | | (5 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | 3 | 4 | 44 | 4 | | 4 | 44 5 | | | | 5 | + 1 | 11 | 1 | 111 | 1 | 11 (5 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1 and x2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | | 4 | 44 | 4 | | 4 | 44 5 | | | | | + 1 | 11 | 1 | 111 | 1 | 11 (5 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1 and y2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 + 5 | | | | | 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | 3 | 4 | 44 | 4 | | | - 5 | | | | | + 1 | 11 | 1 | 111 | 1 | 11 (5 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1 and xx2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | | 4 | 44 | 4 | | 4 | 44 5 | | | | | + 1 | 11 | 1 | 111 | 1 | 11 (5 rows) -- these should NOT give the same answers as above @@ -2202,9 +2230,9 @@ select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1) where (x2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 4 | 44 | 4 | | 4 | 44 + 1 | 11 | 1 | 111 | 1 | 11 (3 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) @@ -2273,11 +2301,12 @@ explain (costs off) select aa, bb, unique1, unique1 from tenk1 right join b_star on aa = unique1 where bb < bb and bb is null; - QUERY PLAN --------------------------- + QUERY PLAN +------------------------------------- Result One-Time Filter: false -(2 rows) + Optimizer: Postgres query optimizer +(3 rows) select aa, bb, unique1, unique1 from tenk1 right join b_star on aa = unique1 @@ -2806,16 +2835,16 @@ select * from on j1_tbl.i = j2_tbl.i and j1_tbl.i = j2_tbl.k; --order none i | j | t | i | k ---+---+-------+---+---- + 6 | 6 | six | | + | | | 5 | -5 + | | | 5 | -5 + 5 | 0 | five | | | | | | 0 | | | | | 0 | zero | | | | null | | 8 | 8 | eight | | 7 | 7 | seven | | - 6 | 6 | six | | - | | | 5 | -5 - | | | 5 | -5 - 5 | 0 | five | | 4 | 1 | four | | | | | 3 | -3 3 | 2 | three | | @@ -2922,9 +2951,17 @@ DROP TABLE J2_TBL; -- Both DELETE and UPDATE allow the specification of additional tables -- to "join" against to determine which rows should be modified. CREATE TEMP TABLE t1 (a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TEMP TABLE t2 (a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TEMP TABLE t3 (x int, y int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'x' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TEMP TABLE t4 (x int, y int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'x' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO t1 VALUES (5, 10); INSERT INTO t1 VALUES (15, 20); INSERT INTO t1 VALUES (100, 100); @@ -2961,15 +2998,16 @@ SELECT * FROM t3; -- Test join against inheritance tree create temp table t2a () inherits (t2); +NOTICE: table has parent, setting distribution columns to match parent table insert into t2a values (200, 2001); select * from t1 left join t2 on (t1.a = t2.a); a | b | a | b -----+------+-----+------ - 5 | 10 | | 15 | 20 | | - 100 | 100 | | 200 | 1000 | 200 | 2000 200 | 1000 | 200 | 2001 + 100 | 100 | | + 5 | 10 | | (5 rows) -- Test matching of column name with wrong alias @@ -3015,9 +3053,13 @@ LINE 3: for update of bar; -- regression test for 8.1 merge right join bug -- CREATE TEMP TABLE tt1 ( tt1_id int4, joincol int4 ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'tt1_id' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO tt1 VALUES (1, 11); INSERT INTO tt1 VALUES (2, NULL); CREATE TEMP TABLE tt2 ( tt2_id int4, joincol int4 ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'tt2_id' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO tt2 VALUES (21, 11); INSERT INTO tt2 VALUES (22, 11); set enable_hashjoin to off; @@ -3026,17 +3068,17 @@ set enable_nestloop to off; select tt1.*, tt2.* from tt1 left join tt2 on tt1.joincol = tt2.joincol; tt1_id | joincol | tt2_id | joincol --------+---------+--------+--------- + 2 | | | 1 | 11 | 21 | 11 1 | 11 | 22 | 11 - 2 | | | (3 rows) select tt1.*, tt2.* from tt2 right join tt1 on tt1.joincol = tt2.joincol; tt1_id | joincol | tt2_id | joincol --------+---------+--------+--------- + 2 | | | 1 | 11 | 21 | 11 1 | 11 | 22 | 11 - 2 | | | (3 rows) reset enable_hashjoin; @@ -3077,35 +3119,65 @@ where not exists (select 1 from tbl_ra t2 where t2.b = t1.a) and t1.b < 2; a | b ------+--- 100 | 0 - 101 | 1 200 | 0 + 600 | 0 + 601 | 1 + 701 | 1 + 901 | 1 201 | 1 300 | 0 - 301 | 1 400 | 0 401 | 1 + 900 | 0 + 101 | 1 + 301 | 1 500 | 0 501 | 1 - 600 | 0 - 601 | 1 700 | 0 - 701 | 1 800 | 0 801 | 1 - 900 | 0 - 901 | 1 1000 | 0 (19 rows) reset enable_hashjoin; reset enable_nestloop; -- --- regression test for bug #13908 (hash join with skew tuples & nbatch increase) +-- regression test for bug with hash-right-semi join -- +create temp table tbl_rs(a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into tbl_rs select i, i from generate_series(1,10)i; +analyze tbl_rs; +set enable_nestloop to off; +set enable_hashagg to off; +-- ensure we get a hash right semi join with SubPlan in hash clauses -- start_ignore --- GPDB_96_MERGE_FIXME: does the plan exercise the nbatch increase in GPDB --- like it does on PostgreSQL? +-- GPDB: the plan shape (and whether a right-semi join is chosen) depends on +-- the optimizer and MPP motions, so the plan is ignored; correctness of the +-- rescan match-flag reset is verified by the result of the query below. +explain (costs off) +select * from tbl_rs t1 +where (select a from tbl_rs t2 + where exists (select 1 from + (select (b in (select b from tbl_rs t3)) as c from tbl_rs t4 where t4.a = 1) s + where c in (select t1.a = 1 from tbl_rs t5 union all select true)) + order by a limit 1) >= 0; +ERROR: correlated subquery with skip-level correlations is not supported -- end_ignore +-- and check we get the expected results +select * from tbl_rs t1 +where (select a from tbl_rs t2 + where exists (select 1 from + (select (b in (select b from tbl_rs t3)) as c from tbl_rs t4 where t4.a = 1) s + where c in (select t1.a = 1 from tbl_rs t5 union all select true)) + order by a limit 1) >= 0; +ERROR: correlated subquery with skip-level correlations is not supported +reset enable_nestloop; +reset enable_hashagg; +-- +-- regression test for bug #13908 (hash join with skew tuples & nbatch increase) +-- set work_mem to '64kB'; set enable_mergejoin to off; set enable_memoize to off; @@ -3141,9 +3213,13 @@ reset enable_memoize; -- regression test for 8.2 bug with improper re-ordering of left joins -- create temp table tt3(f1 int, f2 text); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into tt3 select x, repeat('xyzzy', 100) from generate_series(1,10000) x; analyze tt3; create temp table tt4(f1 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into tt4 values (0),(1),(9999); analyze tt4; set enable_nestloop to off; @@ -3200,16 +3276,16 @@ reset enable_nestloop; explain (costs off) select a.* from tenk1 a where unique1 in (select unique2 from tenk1 b); - QUERY PLAN ------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join - Hash Cond: (a.unique1 = b.unique2) - -> Seq Scan on tenk1 a + -> Hash Right Semi Join + Hash Cond: (b.unique2 = a.unique1) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: b.unique2 + -> Seq Scan on tenk1 b -> Hash - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: b.unique2 - -> Seq Scan on tenk1 b + -> Seq Scan on tenk1 a Optimizer: Postgres query optimizer (9 rows) @@ -3232,16 +3308,16 @@ where unique1 not in (select unique2 from tenk1 b); explain (costs off) select a.* from tenk1 a where exists (select 1 from tenk1 b where a.unique1 = b.unique2); - QUERY PLAN ------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join - Hash Cond: (a.unique1 = b.unique2) - -> Seq Scan on tenk1 a + -> Hash Right Semi Join + Hash Cond: (b.unique2 = a.unique1) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: b.unique2 + -> Seq Scan on tenk1 b -> Hash - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: b.unique2 - -> Seq Scan on tenk1 b + -> Seq Scan on tenk1 a Optimizer: Postgres query optimizer (9 rows) @@ -3281,6 +3357,8 @@ where b.unique2 is null; -- regression test for proper handling of outer joins within antijoins -- create temp table tt4x(c1 int, c2 int, c3 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. explain (costs off) select * from tt4x t1 where not exists ( @@ -3326,7 +3404,11 @@ where not exists ( -- regression test for problems of the sort depicted in bug #3494 -- create temp table tt5(f1 int, f2 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp table tt6(f1 int, f2 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into tt5 values(1, 10); insert into tt5 values(1, 11); insert into tt6 values(1, 9); @@ -3342,7 +3424,11 @@ select * from tt5,tt6 where tt5.f1 = tt6.f1 and tt5.f1 = tt5.f2 - tt6.f2; -- regression test for problems of the sort depicted in bug #3588 -- create temp table xx (pkxx int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'pkxx' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp table yy (pkyy int, pkxx int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'pkyy' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into xx values (1); insert into xx values (2); insert into xx values (3); @@ -3358,8 +3444,8 @@ from yy yy_pkyy | yy_pkxx | yya_pkyy | xxa_pkxx | xxb_pkxx ---------+---------+----------+----------+---------- 101 | 1 | 101 | 1 | 1 - 201 | 2 | | | 1 301 | | | | 1 + 201 | 2 | | | 1 (3 rows) -- @@ -3429,7 +3515,11 @@ set enable_mergejoin = 1; set enable_hashjoin = 0; set enable_nestloop = 0; create temp table a (i integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp table b (x integer, y integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'x' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. select * from a left join b on i = x and i = y and x = i; i | x | y ---+---+--- @@ -3442,6 +3532,8 @@ rollback; begin; create type mycomptype as (id int, v bigint); create temp table tidv (idv mycomptype); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'idv' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create index on tidv (idv); analyze tidv; explain (costs off) @@ -3669,12 +3761,14 @@ create temp table nt2 ( b2 boolean, foreign key (nt1_id) references nt1(id) ); +WARNING: referential integrity (FOREIGN KEY) constraints are not supported in Apache Cloudberry, will not be enforced create temp table nt3 ( id int primary key, nt2_id int, c1 boolean, foreign key (nt2_id) references nt2(id) ); +WARNING: referential integrity (FOREIGN KEY) constraints are not supported in Apache Cloudberry, will not be enforced insert into nt1 values (1,true,true); ANALYZE nt1; insert into nt1 values (2,true,false); @@ -3807,26 +3901,7 @@ select * from right join int4_tbl as i43 on (i43.f1 > 1) where ss1.loc = ss1.lat) as ss2 where i41.f1 > 0; -ERROR: could not devise a query plan for the given query (pathnode.c:277) ---start_ignore ---GPDB_14_MERGE_FIXME: We need to make plan work. One idea is generate a gather ---motion for relations. Even it is not efficient, but better than error out here. - QUERY PLAN --------------------------------------------------- - Nested Loop - -> Nested Loop - -> Seq Scan on int4_tbl i41 - Filter: (f1 > 0) - -> Nested Loop - Join Filter: (i42.f1 = i41.f1) - -> Seq Scan on int8_tbl i81 - -> Materialize - -> Seq Scan on int4_tbl i42 - -> Materialize - -> Seq Scan on int4_tbl i43 - Filter: (f1 > 1) -(12 rows) ---end_ignore +ERROR: could not devise a query plan for the given query (pathnode.c:285) select * from int4_tbl as i41, lateral @@ -3837,34 +3912,7 @@ select * from right join int4_tbl as i43 on (i43.f1 > 1) where ss1.loc = ss1.lat) as ss2 where i41.f1 > 0; -ERROR: could not devise a query plan for the given query (pathnode.c:277) ---start_ignore ---GPDB_14_MERGE_FIXME: We need to make plan work. One idea is generate a gather ---motion for relations. Even it is not efficient, but better than error out here. - f1 | x -------------+--- - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 -(20 rows) ---end_ignore +ERROR: could not devise a query plan for the given query (pathnode.c:285) -- -- test the corner cases FULL JOIN ON TRUE and FULL JOIN ON FALSE -- @@ -3901,14 +3949,14 @@ select * from int4_tbl a full join int4_tbl b on true order by 1, 2; select * from int4_tbl a full join int4_tbl b on false; --order none f1 | f1 -------------+------------- - | 0 | 123456 | -123456 + | 0 | 2147483647 | -2147483647 - 0 | 123456 | -123456 | + 0 | 2147483647 | -2147483647 | (10 rows) @@ -3917,7 +3965,11 @@ select * from int4_tbl a full join int4_tbl b on false; --order none -- test for ability to use a cartesian join when necessary -- create temp table q1 as select 1 as q1; +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'q1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp table q2 as select 0 as q2; +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'q2' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. analyze q1; analyze q2; explain (costs off) @@ -3925,8 +3977,8 @@ select * from tenk1 join int4_tbl on f1 = twothousand, q1, q2 where q1 = thousand or q2 = thousand; - QUERY PLAN ------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Hash Join Hash Cond: (tenk1.twothousand = int4_tbl.f1) @@ -3956,8 +4008,8 @@ select * from tenk1 join int4_tbl on f1 = twothousand, q1, q2 where thousand = (q1 + q2); - QUERY PLAN ---------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Join Hash Cond: (tenk1.thousand = (q1.q1 + q2.q2)) @@ -4149,8 +4201,8 @@ explain (verbose, costs off) select * from (select 1 as x) ss1 left join (select 2 as y) ss2 on (true), lateral (select ss2.y as z limit 1) ss3; - QUERY PLAN ---------------------------- + QUERY PLAN +------------------------------------- Nested Loop Output: 1, (2), ((2)) -> Result @@ -4161,8 +4213,9 @@ select * from Output: ((2)) -> Result Output: (2) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(11 rows) +(12 rows) select * from (select 1 as x) ss1 left join (select 2 as y) ss2 on (true), @@ -4191,7 +4244,8 @@ where b; -> Result -> Result One-Time Filter: (true) -(6 rows) + Optimizer: Postgres query optimizer +(7 rows) select * from (select 0 as z) as t1 @@ -4230,8 +4284,9 @@ where f1 in ( select c3.f1 from ctetable c2 full join ctetable c3 on true ); Output: (1) -> Result Output: 1 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(16 rows) +(17 rows) with ctetable as not materialized ( select 1 as f1 ) select * from ctetable c1 @@ -4253,7 +4308,9 @@ from int4_tbl t1 Result Output: 'regression'::information_schema.sql_identifier, (c.relname)::information_schema.sql_identifier One-Time Filter: false -(3 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(5 rows) -- Test handling of qual pushdown to appendrel members with non-Var outputs explain (verbose, costs off) @@ -4275,7 +4332,9 @@ where ss.x is null; Output: 'foo'::text -> Result Output: 'bar'::text -(12 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(14 rows) -- -- test inlining of immutable functions @@ -4300,8 +4359,8 @@ explain (verbose, costs off) select unique1, x.* from tenk1, (select *, random() from f_immutable_int4(1) x) x where x = unique1; - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +----------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: tenk1.unique1, (1), (random()) -> Nested Loop @@ -4314,8 +4373,8 @@ where x = unique1; -> Index Only Scan using tenk1_unique1 on public.tenk1 Output: tenk1.unique1 Index Cond: (tenk1.unique1 = (1)) + Settings: optimizer = 'off', enable_nestloop = 'on' Optimizer: Postgres query optimizer - Settings: enable_nestloop = 'on' (14 rows) explain (costs off) @@ -4386,8 +4445,8 @@ select unique1, x from tenk1 right join f_immutable_int4(1) x on unique1 = x; explain (costs off) select unique1, x from tenk1 full join f_immutable_int4(1) x on unique1 = x; - QUERY PLAN ----------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Hash Full Join Hash Cond: (tenk1.unique1 = (1)) @@ -4402,8 +4461,8 @@ select unique1, x from tenk1 full join f_immutable_int4(1) x on unique1 = x; -- check that pullup of a const function allows further const-folding explain (costs off) select unique1 from tenk1, f_immutable_int4(1) x where x = 42; - QUERY PLAN --------------------------- + QUERY PLAN +------------------------------------- Result One-Time Filter: false Optimizer: Postgres query optimizer @@ -4423,8 +4482,8 @@ from nt3 as nt3 ) as ss2 on ss2.id = nt3.nt2_id where nt3.id = 1 and ss2.b3; - QUERY PLAN ----------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Hash Right Join Hash Cond: (nt2.id = nt3.nt2_id) @@ -4439,7 +4498,7 @@ where nt3.id = 1 and ss2.b3; -> Seq Scan on nt3 Filter: (id = 1) Optimizer: Postgres query optimizer -(15 rows) +(14 rows) drop function f_immutable_int4(int); -- test inlining when function returns composite @@ -4449,8 +4508,8 @@ create function mki4(int) returns int4_tbl as $$select row($1)::int4_tbl$$ language sql; explain (verbose, costs off) select * from mki8(1,2); - QUERY PLAN ------------------------------------- + QUERY PLAN +-------------------------------------------------- Subquery Scan on sirvf_sq Output: (sirvf_sq.mki8).q1, (sirvf_sq.mki8).q2 -> Result @@ -4458,8 +4517,9 @@ select * from mki8(1,2); InitPlan 1 (returns $0) -> Result Output: '(1,2)'::int8_tbl + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(8 rows) +(9 rows) select * from mki8(1,2); q1 | q2 @@ -4469,8 +4529,8 @@ select * from mki8(1,2); explain (verbose, costs off) select * from mki4(42); - QUERY PLAN ------------------------------------ + QUERY PLAN +------------------------------------------ Subquery Scan on sirvf_sq Output: (sirvf_sq.mki4).f1 -> Result @@ -4478,8 +4538,9 @@ select * from mki4(42); InitPlan 1 (returns $0) -> Result Output: '(42)'::int4_tbl + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(8 rows) +(9 rows) select * from mki4(42); f1 @@ -4515,8 +4576,9 @@ select (t2.*).unique1, f_field_select(t2) from tenk1 t1 -> Materialize -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on public.int8_tbl t3 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(17 rows) +(18 rows) drop function f_field_select(t onek); -- @@ -4769,8 +4831,8 @@ select * from ) ss where fault = 122 order by fault; - QUERY PLAN ------------------------------------------------------------------------ + QUERY PLAN +-------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Right Join Hash Cond: (tenk1.unique2 = int8_tbl.q2) @@ -4939,16 +5001,16 @@ select * from int8_tbl t1 left join int8_tbl t2 on t1.q2 = t2.q1, lateral (select * from int8_tbl t3 where t2.q1 = t2.q2) ss; q1 | q2 | q1 | q2 | q1 | q2 ------------------+------------------+------------------+------------------+------------------+------------------- - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 456 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 456 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 456 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 456 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 (10 rows) -- @@ -4993,8 +5055,9 @@ using (join_key); Hash Key: "*VALUES*".column1 -> Values Scan on "*VALUES*" Output: "*VALUES*".column1 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(25 rows) +(26 rows) select foo1.join_key as foo1_id, foo3.join_key AS foo3_id, bug_field from (values (0),(1)) foo1(join_key) @@ -5053,8 +5116,9 @@ order by i0.f1, x; Output: i0.f1 -> Seq Scan on public.int4_tbl i0 Output: i0.f1 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(25 rows) +(26 rows) select * from int4_tbl i0 left join @@ -5132,8 +5196,9 @@ select t1.* from Output: i4.f1 -> Seq Scan on public.int4_tbl i4 Output: i4.f1 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(43 rows) +(44 rows) select t1.* from text_tbl t1 @@ -5147,8 +5212,8 @@ select t1.* from on (i8.q2 = i4.f1); f1 ------------------- - doh! hi de ho neighbor + doh! (2 rows) explain (verbose, costs off) @@ -5211,8 +5276,8 @@ select t1.* from Output: i4.f1 -> Seq Scan on public.int4_tbl i4 Output: i4.f1 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (49 rows) select t1.* from @@ -5227,8 +5292,8 @@ select t1.* from on (i8.q2 = i4.f1); f1 ------------------- - doh! hi de ho neighbor + doh! (2 rows) explain (verbose, costs off) @@ -5243,8 +5308,8 @@ select t1.* from on (t1.f1 = b1.d1) left join int4_tbl i4 on (i8.q2 = i4.f1); - QUERY PLAN ----------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: t1.f1 -> Hash Left Join @@ -5294,8 +5359,9 @@ select t1.* from Output: i4.f1 -> Seq Scan on public.int4_tbl i4 Output: i4.f1 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(50 rows) +(51 rows) select t1.* from text_tbl t1 @@ -5354,8 +5420,9 @@ select * from -> Seq Scan on public.text_tbl t1 Output: t1.f1 Filter: (t1.f1 = 'doh!'::text) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(30 rows) +(31 rows) select * from text_tbl t1 @@ -5380,14 +5447,15 @@ left join from pg_class c left join pg_namespace n on n.oid = c.relnamespace where c.relkind = 'r' ) ss2 on false; - QUERY PLAN --------------------------------- + QUERY PLAN +------------------------------------- Nested Loop Left Join Join Filter: false -> Result -> Result One-Time Filter: false -(5 rows) + Optimizer: Postgres query optimizer +(6 rows) -- check handling of apparently-commutable outer joins with non-commutable -- joins between them @@ -5399,8 +5467,8 @@ select 1 from join int4_tbl i42 on ss1.a is null or i8.q1 <> i8.q2 right join (select 2 as b) ss2 on ss2.b < i4.f1; - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------------------------------------------- Nested Loop Left Join -> Result -> Materialize @@ -5428,36 +5496,17 @@ select 1 from -- test for appropriate join order in the presence of lateral references -- -- start_ignore +-- GPDB_94_STABLE_MERGE_FIXME: Currently LATERAL is not fully supported in GPDB +-- and the queries below are failing at the moment (The first one fails with +-- error and the other two fail with panic). Comment them off temporarily. +/* 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) - -> Memoize - Output: (i8.q1), t2.f1 - Cache Key: i8.q1 - Cache Mode: binary - -> Limit - Output: (i8.q1), t2.f1 - -> Seq Scan on public.text_tbl t2 - Output: i8.q1, t2.f1 -(20 rows) +where t1.f1 = ss.f1; select * from text_tbl t1 @@ -5465,10 +5514,6 @@ select * from 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 @@ -5478,39 +5523,6 @@ select * from 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) - -> Memoize - Output: (i8.q1), t2.f1 - Cache Key: i8.q1 - Cache Mode: binary - -> Limit - Output: (i8.q1), t2.f1 - -> Seq Scan on public.text_tbl t2 - Output: i8.q1, t2.f1 - -> Memoize - Output: ((i8.q1)), (t2.f1) - Cache Key: (i8.q1), t2.f1 - Cache Mode: binary - -> Limit - Output: ((i8.q1)), (t2.f1) - -> Seq Scan on public.text_tbl t3 - Output: (i8.q1), t2.f1 -(30 rows) select * from text_tbl t1 @@ -5519,10 +5531,6 @@ select * from 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 @@ -5532,41 +5540,6 @@ select 1 from 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 - -> 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) - -> Memoize - Output: ss1.c0 - Cache Key: tt4.f1 - Cache Mode: binary - -> 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 -(33 rows) select 1 from text_tbl as tt1 @@ -5575,10 +5548,7 @@ select 1 from 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) - +*/ --end_ignore explain (verbose, costs off) select 1 from @@ -5588,12 +5558,14 @@ select 1 from right join (select 1 as z) as ss2 on true) on false, lateral (select i4.f1, ss1.n from int8_tbl as i8 limit 1) as ss3; - QUERY PLAN --------------------------- + QUERY PLAN +------------------------------------- Result Output: 1 One-Time Filter: false -(3 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(5 rows) select 1 from int4_tbl as i4 @@ -5622,11 +5594,12 @@ select 1 from t t1 on false where t3.a = coalesce(t5.a,1)) as s2 on true; - QUERY PLAN --------------------------- + QUERY PLAN +------------------------------------- Result One-Time Filter: false -(2 rows) + Optimizer: Postgres query optimizer +(3 rows) rollback; -- @@ -5683,8 +5656,9 @@ where ss1.c2 = 0; -> Materialize -> Gather Motion 3:1 (slice3; segments: 3) -> Seq Scan on public.text_tbl + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(36 rows) +(37 rows) --end_ignore select ss2.* from @@ -5782,8 +5756,8 @@ explain (verbose, costs off) select a.q2, b.q1 from int8_tbl a left join int8_tbl b on a.q2 = coalesce(b.q1, 1) where coalesce(b.q1, 1) > 0; - QUERY PLAN -------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: a.q2, b.q1 -> Merge Left Join @@ -5808,8 +5782,8 @@ explain (verbose, costs off) Hash Key: COALESCE(b.q1, '1'::bigint) -> Seq Scan on public.int8_tbl b Output: b.q1 + Settings: optimizer = 'off', enable_hashjoin = 'off', enable_nestloop = 'off', enable_mergejoin = 'on' Optimizer: Postgres query optimizer - Settings: enable_hashjoin=off, enable_mergejoin=on, enable_nestloop=off (26 rows) select a.q2, b.q1 @@ -5818,8 +5792,6 @@ select a.q2, b.q1 q2 | q1 -------------------+------------------ -4567890123456789 | - 123 | 123 - 123 | 123 456 | 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 @@ -5827,6 +5799,8 @@ select a.q2, b.q1 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 + 123 | 123 + 123 | 123 (10 rows) reset enable_hashjoin; @@ -5986,6 +5960,8 @@ CREATE TEMP TABLE a (id int PRIMARY KEY, b_id int); CREATE TEMP TABLE b (id int PRIMARY KEY, c_id int); CREATE TEMP TABLE c (id int PRIMARY KEY); CREATE TEMP TABLE d (a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO a VALUES (0, 0), (1, NULL); INSERT INTO b VALUES (0, 0), (1, NULL); INSERT INTO c VALUES (0), (1); @@ -6405,6 +6381,7 @@ select c.id, ss.a from c CREATE TEMP TABLE parted_b (id int PRIMARY KEY) partition by range(id); CREATE TEMP TABLE parted_b1 partition of parted_b for values from (0) to (10); +NOTICE: table has parent, setting distribution columns to match parent table -- test join removals on a partitioned table explain (costs off) select a.* from a left join parted_b pb on a.b_id = pb.id; @@ -6431,9 +6408,9 @@ insert into child values (1, 100), (4, 400); select p.* from parent p left join child c on (p.k = c.k); k | pd ---+---- - 1 | 10 2 | 20 3 | 30 + 1 | 10 (3 rows) explain (costs off) @@ -6451,9 +6428,9 @@ select p.*, linked from parent p on (p.k = ss.k); k | pd | linked ---+----+-------- - 1 | 10 | t 2 | 20 | 3 | 30 | + 1 | 10 | t (3 rows) explain (costs off) @@ -6501,8 +6478,8 @@ explain (costs off) select p.* from (parent p left join child c on (p.k = c.k)) join parent x on p.k = x.k where p.k = 1 and p.k = 2; - QUERY PLAN ------------------------------------ + QUERY PLAN +------------------------------------- Result One-Time Filter: false Optimizer: Postgres query optimizer @@ -6539,11 +6516,11 @@ SELECT * FROM ON true; x | q1 | q2 | y ---+------------------+-------------------+------------------ - 1 | 123 | 456 | 123 - 1 | 123 | 4567890123456789 | 123 1 | 4567890123456789 | 123 | 42 1 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 1 | 123 | 4567890123456789 | 123 1 | 4567890123456789 | -4567890123456789 | 4567890123456789 + 1 | 123 | 456 | 123 (5 rows) -- join removal bug #17769: can't remove if there's a pushed-down reference @@ -6586,8 +6563,9 @@ SELECT q2 FROM -> Result Output: q2, 'constant'::text One-Time Filter: false + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(12 rows) +(13 rows) -- join removal bug #17786: check that OR conditions are cleaned up EXPLAIN (COSTS OFF) @@ -6814,8 +6792,9 @@ where q2 = 456; -> Seq Scan on public.int4_tbl i4 Output: i4.f1 Filter: (i4.f1 = 1) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(28 rows) +(29 rows) select i8.*, ss.v, t.unique2 from int8_tbl i8 @@ -6832,6 +6811,7 @@ where q2 = 456; -- a PHV that's been translated to a child rel create temp table parttbl (a integer primary key) partition by range (a); create temp table parttbl1 partition of parttbl for values from (1) to (100); +NOTICE: table has parent, setting distribution columns to match parent table insert into parttbl values (11), (12); set optimizer_enable_dynamicindexonlyscan=off; explain (costs off) @@ -6923,12 +6903,14 @@ explain (verbose, costs off) select 1 from (select * from int8_tbl where q1 <> (select 42) offset 0) ss where false; - QUERY PLAN --------------------------- + QUERY PLAN +------------------------------------- Result Output: 1 One-Time Filter: false -(3 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(5 rows) -- -- Test LATERAL @@ -6964,7 +6946,7 @@ from int4_tbl x, lateral (select unique2 from tenk1 where f1 = unique1) ss; explain (costs off) select unique2, x.* from int4_tbl x, lateral (select unique2 from tenk1 where f1 = unique1) ss; - QUERY PLAN + QUERY PLAN ------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Join @@ -6993,17 +6975,17 @@ select unique2, x.* from int4_tbl x left join lateral (select unique1, unique2 from tenk1 where f1 = unique1) ss on true; unique2 | f1 ---------+------------- - 9998 | 0 | 123456 | -123456 - | 2147483647 + 9998 | 0 | -2147483647 + | 2147483647 (5 rows) explain (costs off) select unique2, x.* from int4_tbl x left join lateral (select unique1, unique2 from tenk1 where f1 = unique1) ss on true; - QUERY PLAN + QUERY PLAN ------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Right Join @@ -7029,11 +7011,11 @@ select *, (select r from (select q1 as q2) x, (select q2 as r) y) from int8_tbl; select *, (select r from (select q1 as q2) x, lateral (select q2 as r) y) from int8_tbl; q1 | q2 | r ------------------+-------------------+------------------ - 123 | 456 | 123 - 123 | 4567890123456789 | 123 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 4567890123456789 | -4567890123456789 | 4567890123456789 + 123 | 456 | 123 + 123 | 4567890123456789 | 123 (5 rows) -- lateral with function in FROM @@ -7093,11 +7075,6 @@ explain (costs off) (10 rows) -- lateral with UNION ALL subselect --- start_ignore --- GPDB_96_MERGE_FIXME: we used to get a better plan here, with --- the Nested Loop join being done on segments, and just a single --- Gather Motion at the top. Can we improve? --- end_ignore explain (costs off) select * from generate_series(100,200) g, lateral (select * from int8_tbl a where g = q1 union all @@ -7194,6 +7171,7 @@ select count(*) from tenk1 a, -- these will get fixed once we catch up to those. Or if not, at least it will be -- nicer to work on the code, knowing that there aren't going to be a dozen commits -- coming up, touching the same area. +-- FAIL with ERROR: could not devise a query plan for the given query (pathnode.c:416) explain (costs off) select * from int8_tbl a, int8_tbl x left join lateral (select a.q1 from int4_tbl y) ss(z) @@ -7218,9 +7196,9 @@ select * from (select f1 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1, lateral (values(x)) ss2(y); x | f1 | y -------------+-------------+------------- - 0 | 0 | 0 123456 | 123456 | 123456 -123456 | -123456 | -123456 + 0 | 0 | 0 2147483647 | 2147483647 | 2147483647 -2147483647 | -2147483647 | -2147483647 (5 rows) @@ -7247,16 +7225,6 @@ select * from (select f1/1000000000 from int4_tbl) x(lb), lateral generate_series(lb,4) x4; lb | x4 ----+---- - 0 | 0 - 0 | 1 - 0 | 2 - 0 | 3 - 0 | 4 - 0 | 0 - 0 | 1 - 0 | 2 - 0 | 3 - 0 | 4 0 | 0 0 | 1 0 | 2 @@ -7272,6 +7240,16 @@ select * from (select f1/1000000000 from int4_tbl) x(lb), -2 | 2 -2 | 3 -2 | 4 + 0 | 0 + 0 | 1 + 0 | 2 + 0 | 3 + 0 | 4 + 0 | 0 + 0 | 1 + 0 | 2 + 0 | 3 + 0 | 4 (25 rows) select * from (values(1)) x(lb), @@ -7297,12 +7275,12 @@ select * from lateral (values(x.q1,y.q1,y.q2)) v(xq1,yq1,yq2); q1 | q2 | q1 | q2 | xq1 | yq1 | yq2 ------------------+-------------------+------------------+-------------------+------------------+------------------+------------------- + 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 + 4567890123456789 | 123 | 123 | 456 | 4567890123456789 | 123 | 456 123 | 456 | | | 123 | | 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | -4567890123456789 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 123 | 4567890123456789 | 4567890123456789 | 123 | 123 | 4567890123456789 | 123 - 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 - 4567890123456789 | 123 | 123 | 456 | 4567890123456789 | 123 | 456 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 123 @@ -7314,16 +7292,16 @@ select * from lateral (select x.q1,y.q1,y.q2) v(xq1,yq1,yq2); q1 | q2 | q1 | q2 | xq1 | yq1 | yq2 ------------------+-------------------+------------------+-------------------+------------------+------------------+------------------- + 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 123 + 4567890123456789 | -4567890123456789 | | | 4567890123456789 | | 123 | 456 | | | 123 | | 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | -4567890123456789 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 123 | 4567890123456789 | 4567890123456789 | 123 | 123 | 4567890123456789 | 123 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 123 | 123 | 456 | 4567890123456789 | 123 | 456 - 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 123 - 4567890123456789 | -4567890123456789 | | | 4567890123456789 | | (10 rows) select x.* from @@ -7331,16 +7309,16 @@ select x.* from lateral (select x.q1,y.q1,y.q2) v(xq1,yq1,yq2); q1 | q2 ------------------+------------------- + 4567890123456789 | 4567890123456789 + 4567890123456789 | 4567890123456789 + 4567890123456789 | 4567890123456789 + 4567890123456789 | -4567890123456789 123 | 456 123 | 4567890123456789 123 | 4567890123456789 123 | 4567890123456789 4567890123456789 | 123 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 (10 rows) select v.* from @@ -7349,14 +7327,6 @@ select v.* from lateral (select x.q1,y.q1 union all select x.q2,y.q2) v(vx,vy); vx | vy -------------------+------------------- - 123 | - 456 | - 123 | 4567890123456789 - 4567890123456789 | -4567890123456789 - 123 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 - 4567890123456789 | 123 4567890123456789 | 123 123 | 4567890123456789 4567890123456789 | 123 @@ -7369,6 +7339,14 @@ select v.* from 4567890123456789 | 123 4567890123456789 | -4567890123456789 | + 123 | + 456 | + 123 | 4567890123456789 + 4567890123456789 | -4567890123456789 + 123 | 4567890123456789 + 4567890123456789 | 4567890123456789 + 123 | 4567890123456789 + 4567890123456789 | 123 (20 rows) select v.* from @@ -7377,26 +7355,26 @@ select v.* from lateral (select x.q1,y.q1 union all select x.q2,y.q2) v(vx,vy); vx | vy -------------------+------------------- - 4567890123456789 | 123 - 123 | 456 - 4567890123456789 | 123 + 123 | + 456 | + 123 | 4567890123456789 + 4567890123456789 | -4567890123456789 123 | 4567890123456789 4567890123456789 | 4567890123456789 - 4567890123456789 | 123 123 | 4567890123456789 4567890123456789 | 123 4567890123456789 | 4567890123456789 + 4567890123456789 | -4567890123456789 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 - 123 | 4567890123456789 - 4567890123456789 | -4567890123456789 - 123 | - 456 | + 4567890123456789 | 123 4567890123456789 | -4567890123456789 | + 4567890123456789 | 123 + 123 | 4567890123456789 + 4567890123456789 | 123 + 123 | 456 (20 rows) select v.* from @@ -7405,26 +7383,26 @@ select v.* from lateral (select x.q1,y.q1 from onerow union all select x.q2,y.q2 from onerow) v(vx,vy); vx | vy -------------------+------------------- - 4567890123456789 | 123 - 123 | 456 - 4567890123456789 | 123 - 123 | 4567890123456789 - 4567890123456789 | 4567890123456789 4567890123456789 | 123 123 | 4567890123456789 4567890123456789 | 123 + 123 | 456 4567890123456789 | 4567890123456789 + 4567890123456789 | -4567890123456789 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 - 123 | 4567890123456789 - 4567890123456789 | -4567890123456789 - 123 | - 456 | + 4567890123456789 | 123 4567890123456789 | -4567890123456789 | + 123 | + 456 | + 123 | 4567890123456789 + 4567890123456789 | -4567890123456789 + 123 | 4567890123456789 + 4567890123456789 | 4567890123456789 + 123 | 4567890123456789 + 4567890123456789 | 123 (20 rows) explain (verbose, costs off) @@ -7445,8 +7423,8 @@ select * from -> Seq Scan on public.int8_tbl b Output: b.q1, b.q2, a.q2 Filter: (a.q2 = b.q1) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (14 rows) select * from @@ -7454,24 +7432,24 @@ select * from lateral (select *, a.q2 as x from int8_tbl b) ss on a.q2 = ss.q1; q1 | q2 | q1 | q2 | x ------------------+-------------------+------------------+-------------------+------------------ + 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 + 4567890123456789 | -4567890123456789 | | | 123 | 456 | | | 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 4567890123456789 | 123 | 123 | 456 | 123 4567890123456789 | 123 | 123 | 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 | | | (10 rows) explain (verbose, costs off) select * from int8_tbl a left join lateral (select *, coalesce(a.q2, 42) as x from int8_tbl b) ss on a.q2 = ss.q1; - QUERY PLAN ----------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Output: a.q1, a.q2, b.q1, b.q2, (COALESCE(a.q2, '42'::bigint)) -> Nested Loop Left Join @@ -7484,8 +7462,8 @@ select * from -> Seq Scan on public.int8_tbl b Output: b.q1, b.q2, COALESCE(a.q2, '42'::bigint) Filter: (a.q2 = b.q1) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (14 rows) select * from @@ -7493,16 +7471,16 @@ select * from lateral (select *, coalesce(a.q2, 42) as x from int8_tbl b) ss on a.q2 = ss.q1; q1 | q2 | q1 | q2 | x ------------------+-------------------+------------------+-------------------+------------------ - 123 | 456 | | | - 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 4567890123456789 | 123 | 123 | 456 | 123 4567890123456789 | 123 | 123 | 4567890123456789 | 123 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 4567890123456789 | -4567890123456789 | | | + 123 | 456 | | | + 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 (10 rows) -- lateral can result in join conditions appearing below their @@ -7523,8 +7501,8 @@ select * from int4_tbl i left join Output: j.f1 -> Seq Scan on public.int2_tbl j Output: j.f1 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (13 rows) select * from int4_tbl i left join @@ -7532,10 +7510,10 @@ select * from int4_tbl i left join f1 | f1 -------------+---- 0 | 0 - 123456 | - -123456 | 2147483647 | -2147483647 | + 123456 | + -123456 | (5 rows) explain (verbose, costs off) @@ -7552,8 +7530,8 @@ select * from int4_tbl i left join -> Seq Scan on public.int2_tbl j Output: j.f1, COALESCE(i.*) Filter: (i.f1 = j.f1) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (11 rows) select * from int4_tbl i left join @@ -7561,10 +7539,10 @@ select * from int4_tbl i left join f1 | coalesce -------------+---------- 0 | (0) - 123456 | - -123456 | 2147483647 | -2147483647 | + 123456 | + -123456 | (5 rows) explain (verbose, costs off) @@ -7602,8 +7580,9 @@ select * from int4_tbl a, Output: b.f1 -> Seq Scan on public.int4_tbl b Output: b.f1 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(29 rows) +(30 rows) select * from int4_tbl a, lateral ( @@ -7611,31 +7590,31 @@ select * from int4_tbl a, ) ss; f1 | f1 | q1 | q2 -------------+-------------+----+---- - 0 | 0 | | - 0 | 123456 | | 0 | -123456 | | + 0 | 123456 | | + 0 | 0 | | 0 | 2147483647 | | 0 | -2147483647 | | - 123456 | 0 | | - 123456 | 123456 | | - 123456 | -123456 | | - 123456 | 2147483647 | | - 123456 | -2147483647 | | - -123456 | 0 | | - -123456 | 123456 | | - -123456 | -123456 | | - -123456 | 2147483647 | | - -123456 | -2147483647 | | - 2147483647 | 0 | | - 2147483647 | 123456 | | 2147483647 | -123456 | | + 2147483647 | 123456 | | + 2147483647 | 0 | | 2147483647 | 2147483647 | | 2147483647 | -2147483647 | | - -2147483647 | 0 | | - -2147483647 | 123456 | | -2147483647 | -123456 | | + -2147483647 | 123456 | | + -2147483647 | 0 | | -2147483647 | 2147483647 | | -2147483647 | -2147483647 | | + 123456 | -123456 | | + 123456 | 123456 | | + 123456 | 0 | | + 123456 | 2147483647 | | + 123456 | -2147483647 | | + -123456 | -123456 | | + -123456 | 123456 | | + -123456 | 0 | | + -123456 | 2147483647 | | + -123456 | -2147483647 | | (25 rows) -- lateral reference in a PlaceHolderVar evaluated at join level @@ -7648,13 +7627,13 @@ select * from (select b.q1 as bq1, c.q1 as cq1, least(a.q1,b.q1,c.q1) from int8_tbl b cross join int8_tbl c) ss on a.q2 = ss.bq1; -ERROR: could not devise a query plan for the given query (pathnode.c:485) +ERROR: could not devise a query plan for the given query (pathnode.c:285) select * from int8_tbl a left join lateral (select b.q1 as bq1, c.q1 as cq1, least(a.q1,b.q1,c.q1) from int8_tbl b cross join int8_tbl c) ss on a.q2 = ss.bq1; -ERROR: could not devise a query plan for the given query (pathnode.c:485) +ERROR: could not devise a query plan for the given query (pathnode.c:285) -- case requiring nested PlaceHolderVars explain (verbose, costs off) select * from @@ -7703,8 +7682,8 @@ select * from Output: ((COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2))) -> Result Output: (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (38 rows) -- another case requiring nested PlaceHolderVars @@ -7713,8 +7692,8 @@ select * from (select 0 as val0) as ss0 left join (select 1 as val) as ss1 on true left join lateral (select ss1.val as val_filtered where false) as ss2 on true; - QUERY PLAN --------------------------------- + QUERY PLAN +------------------------------------- Nested Loop Left Join Output: 0, (1), ((1)) Join Filter: false @@ -7723,7 +7702,9 @@ select * from -> Result Output: (1) One-Time Filter: false -(8 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(10 rows) select * from (select 0 as val0) as ss0 @@ -7796,8 +7777,8 @@ select c.*,a.*,ss1.q1,ss2.q1,ss3.* from Hash Key: c.q2 -> Seq Scan on public.int8_tbl c Output: c.q1, c.q2 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (50 rows) -- check processing of postponed quals (bug #9041) @@ -7824,8 +7805,8 @@ select * from Output: (3) -> Result Output: 3 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (17 rows) -- a new postponed-quals issue (bug #17768) @@ -7877,9 +7858,9 @@ select * from int8_tbl i8 left join lateral -> Result Output: f1, i8.q2 One-Time Filter: false + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off -(11 rows) +(12 rows) explain (verbose, costs off) select * from int8_tbl i8 left join lateral @@ -7895,8 +7876,8 @@ select * from int8_tbl i8 left join lateral -> Result Output: f1, f1, i8.q2 One-Time Filter: false + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (11 rows) -- check handling of nested appendrels inside LATERAL @@ -7949,8 +7930,8 @@ select * from Output: tenk1.unique1, tenk1.unique2 -> Seq Scan on public.tenk1 Output: tenk1.unique1, tenk1.unique2 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (21 rows) select * from @@ -8033,6 +8014,8 @@ LINE 1: select 1 from tenk1 a, lateral (select max(a.unique1) from i... ^ -- check behavior of LATERAL in UPDATE/DELETE create temp table xx1 as select f1 as x1, -f1 as x2 from int4_tbl; +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'x1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. -- error, can't do this: update xx1 set x2 = f1 from (select * from int4_tbl where f1 = x1) ss; ERROR: column "x1" does not exist @@ -8074,11 +8057,18 @@ HINT: There is an entry for table "xx1", but it cannot be referenced from this -- produced for a multi-level partitioned table hierarchy. -- create table join_pt1 (a int, b int, c varchar) partition by range(a); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create table join_pt1p1 partition of join_pt1 for values from (0) to (100) partition by range(b); +NOTICE: table has parent, setting distribution columns to match parent table create table join_pt1p2 partition of join_pt1 for values from (100) to (200); +NOTICE: table has parent, setting distribution columns to match parent table create table join_pt1p1p1 partition of join_pt1p1 for values from (0) to (100); +NOTICE: table has parent, setting distribution columns to match parent table insert into join_pt1 values (1, 1, 'x'), (101, 101, 'y'); create table join_ut1 (a int, b int, c varchar); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into join_ut1 values (101, 101, 'y'), (2, 2, 'z'); -- GPDB_12_MERGE_FIXME: The query fails. This test query is new with v12, -- but a corresponding query fails on GPDB master, too. I think this is @@ -8105,6 +8095,8 @@ drop table join_ut1; -- begin; create table fkest (x integer, x10 integer, x10b integer, x100 integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'x' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into fkest select x, x/10, x/10, x/100 from generate_series(1,1000) x; create unique index on fkest(x, x10, x100); analyze fkest; @@ -8113,8 +8105,8 @@ select * from fkest f1 join fkest f2 on (f1.x = f2.x and f1.x10 = f2.x10b and f1.x100 = f2.x100) join fkest f3 on f1.x = f3.x where f1.x100 = 2; - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +----------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Join Hash Cond: (f3.x = f1.x) @@ -8132,13 +8124,14 @@ select * from fkest f1 alter table fkest add constraint fk foreign key (x, x10b, x100) references fkest (x, x10, x100); +WARNING: referential integrity (FOREIGN KEY) constraints are not supported in Apache Cloudberry, will not be enforced explain (costs off) select * from fkest f1 join fkest f2 on (f1.x = f2.x and f1.x10 = f2.x10b and f1.x100 = f2.x100) join fkest f3 on f1.x = f3.x where f1.x100 = 2; - QUERY PLAN ------------------------------------------------------ + QUERY PLAN +----------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Join Hash Cond: ((f1.x = f2.x) AND (f1.x10 = f2.x10b)) @@ -8174,6 +8167,7 @@ insert into fkest select x/10, x%10, x from generate_series(1,1000*10) x; insert into fkest1 select x/10, x%10 from generate_series(1,1000*10) x; alter table fkest1 add constraint fkest1_a_b_fkey foreign key (a,b) references fkest; +WARNING: referential integrity (FOREIGN KEY) constraints are not supported in Apache Cloudberry, will not be enforced analyze fkest; analyze fkest1; explain (costs off) @@ -8204,7 +8198,7 @@ where f.c = 1; -> Index Only Scan using fkest1_pkey on fkest1 f3 Index Cond: ((a = f.a) AND (b = f.b)) Optimizer: Postgres query optimizer -(13 rows) +(19 rows) rollback; -- @@ -8213,6 +8207,8 @@ rollback; create table j1 (id int primary key); create table j2 (id int primary key); create table j3 (id int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into j1 values(1),(2),(3); insert into j2 values(1),(2),(3); insert into j3 values(1),(1); @@ -8246,8 +8242,8 @@ select * from j1 inner join j2 on j1.id = j2.id; Output: j2.id -> Seq Scan on public.j2 Output: j2.id + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (14 rows) -- ensure join is not unique when not an equi-join @@ -8266,8 +8262,8 @@ select * from j1 inner join j2 on j1.id > j2.id; -> Index Only Scan using j2_pkey on public.j2 Output: j2.id Index Cond: (j2.id < j1.id) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (13 rows) -- ensure non-unique rel is not chosen as inner @@ -8287,8 +8283,8 @@ select * from j1 inner join j3 on j1.id = j3.id; Output: j1.id -> Seq Scan on public.j1 Output: j1.id + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (14 rows) -- ensure left join is marked as unique @@ -8308,8 +8304,8 @@ select * from j1 left join j2 on j1.id = j2.id; Output: j2.id -> Seq Scan on public.j2 Output: j2.id + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (14 rows) -- ensure right join is marked as unique @@ -8329,8 +8325,8 @@ select * from j1 right join j2 on j1.id = j2.id; Output: j1.id -> Seq Scan on public.j1 Output: j1.id + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (14 rows) -- ensure full join is marked as unique @@ -8350,8 +8346,8 @@ select * from j1 full join j2 on j1.id = j2.id; Output: j2.id -> Seq Scan on public.j2 Output: j2.id + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (14 rows) -- a clauseless (cross) join can't be unique @@ -8371,8 +8367,8 @@ select * from j1 cross join j2; Output: j2.id -> Seq Scan on public.j2 Output: j2.id + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (14 rows) -- ensure a natural join is marked as unique @@ -8392,8 +8388,8 @@ select * from j1 natural join j2; Output: j2.id -> Seq Scan on public.j2 Output: j2.id + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (14 rows) -- ensure a distinct clause allows the inner to become unique @@ -8417,8 +8413,8 @@ inner join (select distinct id from j3) j3 on j1.id = j3.id; Group Key: j3.id -> Seq Scan on public.j3 Output: j3.id + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (17 rows) -- ensure group by clause allows the inner to become unique @@ -8442,8 +8438,8 @@ inner join (select id from j3 group by id) j3 on j1.id = j3.id; Group Key: j3.id -> Seq Scan on public.j3 Output: j3.id + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (17 rows) drop table j1; @@ -8483,8 +8479,8 @@ inner join j2 on j1.id1 = j2.id1; Hash Key: j2.id1 -> Seq Scan on public.j2 Output: j2.id1, j2.id2 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (19 rows) -- ensure proper unique detection with multiple join quals @@ -8505,8 +8501,8 @@ inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2; Output: j2.id1, j2.id2 -> Seq Scan on public.j2 Output: j2.id1, j2.id2 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (14 rows) -- ensure we don't detect the join to be unique when quals are not part of the @@ -8532,8 +8528,8 @@ inner join j2 on j1.id1 = j2.id1 where j1.id2 = 1; Hash Key: j2.id1, 1 -> Seq Scan on public.j2 Output: j2.id1, j2.id2 + Settings: optimizer = 'off', enable_nestloop = 'on' Optimizer: Postgres query optimizer - Settings: enable_nestloop=on, optimizer=off (17 rows) -- as above, but for left joins. @@ -8557,8 +8553,8 @@ left join j2 on j1.id1 = j2.id1 where j1.id2 = 1; Hash Key: j2.id1, 1 -> Seq Scan on public.j2 Output: j2.id1, j2.id2 + Settings: optimizer = 'off', enable_nestloop = 'on' Optimizer: Postgres query optimizer - Settings: enable_nestloop=on, optimizer=off (17 rows) create unique index j1_id2_idx on j1(id2) where id2 is not null; @@ -8587,7 +8583,7 @@ inner join j2 on j1.id2 = j2.id2; Hash Key: j2.id2 -> Seq Scan on public.j2 Output: j2.id1, j2.id2 - Settings: enable_nestloop = 'on' + Settings: optimizer = 'off', enable_nestloop = 'on' Optimizer: Postgres query optimizer (19 rows) @@ -8701,8 +8697,8 @@ from onek t1, tenk1 t2 where exists (select 1 from tenk1 t3 where t3.thousand = t1.unique1 and t3.tenthous = t2.hundred) and t1.unique1 < 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: t1.unique1, t2.hundred -> Nested Loop @@ -8731,12 +8727,14 @@ where exists (select 1 from tenk1 t3 -> Index Only Scan using tenk1_hundred on public.tenk1 t2 Output: t2.hundred Index Cond: (t2.hundred = t3.tenthous) + Settings: optimizer = 'off', enable_mergejoin = 'on', enable_hashjoin = 'off', enable_nestloop = 'on', enable_seqscan = 'off', enable_bitmapscan = 'off' Optimizer: Postgres query optimizer - Settings: enable_bitmapscan=off, enable_mergejoin=on, enable_nestloop=on, enable_seqscan=off, jit=off, optimizer=off (30 rows) -- ... unless it actually is unique create table j3 as select unique1, tenthous from onek; +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'unique1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. vacuum analyze j3; create unique index on j3(unique1, tenthous); explain (verbose, costs off) @@ -8745,8 +8743,8 @@ from onek t1, tenk1 t2 where exists (select 1 from j3 where j3.unique1 = t1.unique1 and j3.tenthous = t2.hundred) and t1.unique1 < 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: t1.unique1, t2.hundred -> Nested Loop @@ -8769,13 +8767,15 @@ where exists (select 1 from j3 -> Index Only Scan using tenk1_hundred on public.tenk1 t2 Output: t2.hundred Index Cond: (t2.hundred = j3.tenthous) + Settings: optimizer = 'off', enable_mergejoin = 'on', enable_hashjoin = 'off', enable_nestloop = 'on', enable_seqscan = 'off', enable_bitmapscan = 'off' Optimizer: Postgres query optimizer - Settings: enable_bitmapscan=off, enable_mergejoin=on, enable_nestloop=on, enable_seqscan=off, jit=off, optimizer=off (24 rows) drop table j3; -- Test that we do not account for nullingrels when looking up statistics CREATE TABLE group_tbl (a INT, b INT); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO group_tbl SELECT 1, 1; CREATE STATISTICS group_tbl_stat (ndistinct) ON a, b FROM group_tbl; ANALYZE group_tbl; diff --git a/src/test/regress/expected/join_gp.out b/src/test/regress/expected/join_gp.out index e459d425fff..5225be48d04 100644 --- a/src/test/regress/expected/join_gp.out +++ b/src/test/regress/expected/join_gp.out @@ -15,15 +15,15 @@ create table nhtest (i numeric(10, 2)) distributed by (i); insert into nhtest values(100000.22); insert into nhtest values(300000.19); explain select * from nhtest a join nhtest b using (i); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=1.02..2.07 rows=2 width=11) - -> Hash Join (cost=1.02..2.07 rows=2 width=11) + QUERY PLAN +------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=567.25..155362.25 rows=5055210 width=16) + -> Hash Join (cost=567.25..87959.45 rows=1685070 width=16) Hash Cond: (a.i = b.i) - -> Seq Scan on nhtest a (cost=0.00..1.01 rows=1 width=11) - -> Hash (cost=1.01..1.01 rows=1 width=11) - -> Seq Scan on nhtest b (cost=0.00..1.01 rows=1 width=11) - Settings: enable_hashjoin=on; enable_mergejoin=off; enable_nestloop=off + -> Seq Scan on nhtest a (cost=0.00..271.00 rows=23700 width=16) + -> Hash (cost=271.00..271.00 rows=23700 width=16) + -> Seq Scan on nhtest b (cost=0.00..271.00 rows=23700 width=16) + Optimizer: Postgres query optimizer (7 rows) select * from nhtest a join nhtest b using (i); @@ -98,6 +98,7 @@ set enable_mergejoin to on; set enable_nestloop to off; DROP TABLE IF EXISTS alpha; DROP TABLE IF EXISTS theta; +NOTICE: table "theta" does not exist, skipping CREATE TABLE alpha (i int, j int) distributed by (i); CREATE TABLE theta (i int, j char(10000000)) distributed by (i); INSERT INTO alpha values (1, 1), (2, 2); @@ -132,14 +133,14 @@ analyze t2; explain select count(*) from t1,t2 where t1.x = 100 and t1.x = t2.x; QUERY PLAN ------------------------------------------------------------------------------------------------------ - Aggregate (cost=10000000008.60..10000000008.61 rows=1 width=8) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10000000008.60 rows=4 width=0) - -> Nested Loop (cost=10000000000.00..10000000008.53 rows=2 width=0) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..4.27 rows=1 width=4) + Aggregate (cost=10000000002.92..10000000002.93 rows=1 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10000000002.91 rows=3 width=0) + -> Nested Loop (cost=10000000000.00..10000000002.86 rows=1 width=0) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.44 rows=1 width=4) Hash Key: t1.x - -> Seq Scan on t1 (cost=0.00..4.25 rows=1 width=4) + -> Seq Scan on t1 (cost=0.00..1.42 rows=1 width=4) Filter: (x = 100) - -> Seq Scan on t2 (cost=0.00..4.25 rows=1 width=4) + -> Seq Scan on t2 (cost=0.00..1.42 rows=1 width=4) Filter: (x = 100) Optimizer: Postgres query optimizer (10 rows) @@ -156,13 +157,13 @@ select count(*) from t1,t2 where t1.x = 100 and t1.x = t2.x; explain select * from t1,t2 where t1.x = 100 and t2.x >= t1.x; QUERY PLAN -------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10000000002.97 rows=3 width=24) - -> Nested Loop (cost=10000000000.00..10000000002.93 rows=1 width=24) + Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10000000002.91 rows=3 width=24) + -> Nested Loop (cost=10000000000.00..10000000002.87 rows=1 width=24) Join Filter: (t2.x >= t1.x) -> Seq Scan on t1 (cost=0.00..1.42 rows=1 width=12) Filter: (x = 100) - -> Materialize (cost=0.00..1.47 rows=3 width=12) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.46 rows=3 width=12) + -> Materialize (cost=0.00..1.44 rows=1 width=12) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.44 rows=1 width=12) -> Seq Scan on t2 (cost=0.00..1.42 rows=1 width=12) Filter: (x >= 100) Optimizer: Postgres query optimizer @@ -181,18 +182,17 @@ set optimizer_segments=2; explain select * from t1,t2 where t1.x = 100 and t1.x = t2.y and t1.x <= t2.x; QUERY PLAN -------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..9.14 rows=4 width=24) - -> Nested Loop (cost=0.00..9.14 rows=2 width=24) + Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10000000003.08 rows=3 width=24) + -> Nested Loop (cost=10000000000.00..10000000003.03 rows=1 width=24) Join Filter: (t1.x <= t2.x) - -> Seq Scan on t1 (cost=0.00..4.25 rows=1 width=12) - Filter: x = 100 - -> Materialize (cost=0.00..4.85 rows=1 width=12) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..4.79 rows=1 width=12) - -> Seq Scan on t2 (cost=0.00..4.75 rows=1 width=12) + -> Seq Scan on t1 (cost=0.00..1.42 rows=1 width=12) + Filter: (x = 100) + -> Materialize (cost=0.00..1.61 rows=1 width=12) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.60 rows=1 width=12) + -> Seq Scan on t2 (cost=0.00..1.58 rows=1 width=12) Filter: ((100 <= x) AND (y <= x) AND (y = 100)) - Settings: optimizer=off; optimizer_segments=2 - Optimizer status: Postgres query optimizer -(11 rows) + Optimizer: Postgres query optimizer +(10 rows) reset optimizer_segments; select * from t1,t2 where t1.x = 100 and t1.x = t2.y and t1.x <= t2.x; @@ -236,10 +236,10 @@ select * from int4_tbl a join int4_tbl b on (a.f1 = (select f1 from int4_tbl c w f1 | f1 -------------+------------- -2147483647 | -2147483647 - 123456 | 123456 - -123456 | -123456 0 | 0 2147483647 | 2147483647 + 123456 | 123456 + -123456 | -123456 (5 rows) -- Same as the last query, but with a partitioned table (which requires a @@ -255,9 +255,9 @@ insert into part4_tbl values select * from part4_tbl a join part4_tbl b on (a.f1 = (select f1 from int4_tbl c where c.f1=b.f1)); f1 | f1 ---------+--------- - 123456 | 123456 - -123456 | -123456 0 | 0 + -123456 | -123456 + 123456 | 123456 (3 rows) -- @@ -278,18 +278,18 @@ from tjoin1 left outer join (tjoin2 left outer join tjoin3 on tjoin2.id=tjoin3.id) on tjoin1.id=tjoin3.id; id | t | t ----+-----+----- - 1 | 2-1 | 2-1 - 1 | 2-1 | 1-1 - 1 | 1-1 | 2-1 1 | 1-1 | 1-1 - 3 | | - 1 | 2-1 | 2-1 - 1 | 2-1 | 1-1 - 1 | 1-1 | 2-1 1 | 1-1 | 1-1 - 3 | | + 1 | 1-1 | 2-1 + 1 | 1-1 | 2-1 + 1 | 2-1 | 1-1 + 1 | 2-1 | 1-1 + 1 | 2-1 | 2-1 + 1 | 2-1 | 2-1 2 | | 2 | | + 3 | | + 3 | | (12 rows) set enable_hashjoin to off; @@ -321,9 +321,9 @@ select count(*) from hjn_test, (select 3 as bar) foo where hjn_test.i = least (f select * from int4_tbl a join int4_tbl b on (a.f1 = (select f1 from int4_tbl c where c.f1=b.f1)); f1 | f1 -------------+------------- - -2147483647 | -2147483647 - 123456 | 123456 -123456 | -123456 + 123456 | 123456 + -2147483647 | -2147483647 0 | 0 2147483647 | 2147483647 (5 rows) @@ -365,8 +365,8 @@ select * from foo where a not in (select c from bar where c <= 5); ----+--- 6 | 7 | - 8 | 9 | + 8 | 10 | (5 rows) @@ -499,8 +499,8 @@ insert into test_float2 values(3, 10), (4, 20); select t1.id, t1.data, t2.id, t2.data from test_float1 t1, test_float2 t2 where t1.data = t2.data; id | data | id | data ----+------+----+------ - 2 | 20 | 4 | 20 1 | 10 | 3 | 10 + 2 | 20 | 4 | 20 (2 rows) -- test int type @@ -511,8 +511,8 @@ insert into test_int2 values(3, 10), (4, 20); select t1.id, t1.data, t2.id, t2.data from test_int1 t1, test_int2 t2 where t1.data = t2.data; id | data | id | data ----+------+----+------ - 1 | 10 | 3 | 10 2 | 20 | 4 | 20 + 1 | 10 | 3 | 10 (2 rows) -- Test to ensure that for full outer join on varchar columns, planner is successful in finding a sort operator in the catalog @@ -540,9 +540,7 @@ drop schema pred cascade; reset search_path; -- github issue 5370 cases drop table if exists t5370; -NOTICE: table "t5370" does not exist, skipping drop table if exists t5370_2; -NOTICE: table "t5370_2" does not exist, skipping create table t5370(id int,name text) distributed by(id); insert into t5370 select i,i from generate_series(1,1000) i; create table t5370_2 as select * from t5370 distributed by (id); @@ -551,16 +549,16 @@ analyze t5370; explain select * from t5370 a , t5370_2 b where a.name=b.name; QUERY PLAN ------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=45.50..92.25 rows=1000 width=14) - -> Hash Join (cost=45.50..92.25 rows=334 width=14) + Gather Motion 3:1 (slice1; segments: 3) (cost=15.17..44.08 rows=1000 width=14) + -> Hash Join (cost=15.17..30.75 rows=333 width=14) Hash Cond: (a.name = b.name) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..33.00 rows=334 width=7) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..11.00 rows=333 width=7) Hash Key: a.name - -> Seq Scan on t5370 a (cost=0.00..13.00 rows=334 width=7) - -> Hash (cost=33.00..33.00 rows=334 width=7) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..33.00 rows=334 width=7) + -> Seq Scan on t5370 a (cost=0.00..4.33 rows=333 width=7) + -> Hash (cost=11.00..11.00 rows=333 width=7) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..11.00 rows=333 width=7) Hash Key: b.name - -> Seq Scan on t5370_2 b (cost=0.00..13.00 rows=334 width=7) + -> Seq Scan on t5370_2 b (cost=0.00..4.33 rows=333 width=7) Optimizer: Postgres query optimizer (11 rows) @@ -706,25 +704,25 @@ explain (costs off) select * from t1 left join t2 on (t1.a = t2.a) join t3 on (t select * from t1 left join t2 on (t1.a = t2.a) join t3 on (t1.b = t3.b) where (t2.a is distinct from t3.a); a | b | c | a | b | c | a | b | c ---+---+---+---+---+---+---+---+--- - 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 + 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 (2 rows) -- ensure plan has a filter over left outer join explain select * from t3 join (select t1.a t1a, t1.b t1b, t1.c t1c, t2.a t2a, t2.b t2b, t2.c t2c from t1 left join t2 on (t1.a = t2.a)) t on (t1a = t3.a) WHERE (t2a IS NULL OR (t1c = t3.a)); QUERY PLAN --------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=20.27..37.13 rows=10 width=36) - -> Hash Right Join (cost=20.27..37.13 rows=4 width=36) + Gather Motion 3:1 (slice1; segments: 3) (cost=6.26..12.01 rows=10 width=36) + -> Hash Right Join (cost=6.26..11.88 rows=3 width=36) Hash Cond: (t2.a = t1.a) Filter: ((t2.a IS NULL) OR (t1.c = t3.a)) - -> Seq Scan on t2 (cost=0.00..12.99 rows=333 width=12) - -> Hash (cost=20.14..20.14 rows=4 width=24) - -> Hash Join (cost=2.04..20.14 rows=4 width=24) + -> Seq Scan on t2 (cost=0.00..4.33 rows=333 width=12) + -> Hash (cost=6.22..6.22 rows=3 width=24) + -> Hash Join (cost=1.02..6.22 rows=3 width=24) Hash Cond: (t1.a = t3.a) - -> Seq Scan on t1 (cost=0.00..13.00 rows=334 width=12) - -> Hash (cost=2.02..2.02 rows=1 width=12) - -> Seq Scan on t3 (cost=0.00..2.02 rows=1 width=12) + -> Seq Scan on t1 (cost=0.00..4.33 rows=333 width=12) + -> Hash (cost=1.01..1.01 rows=1 width=12) + -> Seq Scan on t3 (cost=0.00..1.01 rows=1 width=12) Optimizer: Postgres query optimizer (12 rows) @@ -741,38 +739,38 @@ explain select * from (select t1.a t1a, t1.b t1b, t2.a t2a, t2.b t2b from t1 lef join t3 t3_1 on tt1.t1b = t3_1.b and (tt1.t2a is NULL OR tt1.t1b = t3.b); QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=18.43..24.07 rows=3 width=56) - -> Hash Right Join (cost=18.43..24.03 rows=1 width=56) + Gather Motion 3:1 (slice1; segments: 3) (cost=18.39..24.02 rows=3 width=56) + -> Hash Right Join (cost=18.39..23.98 rows=1 width=56) Hash Cond: (t2_1.a = t1_1.a) Filter: ((t2_1.a IS NULL) OR (t1_1.b = t3.b)) -> Seq Scan on t2 t2_1 (cost=0.00..4.33 rows=333 width=8) - -> Hash (cost=18.42..18.42 rows=1 width=48) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=12.81..18.42 rows=1 width=48) + -> Hash (cost=18.37..18.37 rows=1 width=48) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=12.76..18.37 rows=1 width=48) Hash Key: t1_1.a - -> Hash Right Join (cost=12.81..18.40 rows=1 width=48) + -> Hash Right Join (cost=12.76..18.35 rows=1 width=48) Hash Cond: (t2.a = t1.a) -> Seq Scan on t2 (cost=0.00..4.33 rows=333 width=8) - -> Hash (cost=12.79..12.79 rows=1 width=40) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=7.48..12.79 rows=1 width=40) + -> Hash (cost=12.75..12.75 rows=1 width=40) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=7.44..12.75 rows=1 width=40) Hash Key: t1.a - -> Hash Join (cost=7.48..12.77 rows=1 width=40) + -> Hash Join (cost=7.44..12.73 rows=1 width=40) Hash Cond: (t1.b = t3.b) - -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=1.09..6.36 rows=3 width=20) + -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=1.06..6.33 rows=3 width=20) Hash Key: t1.b - -> Hash Join (cost=1.09..6.29 rows=3 width=20) + -> Hash Join (cost=1.06..6.27 rows=3 width=20) Hash Cond: (t1.b = t3_1.b) -> Seq Scan on t1 (cost=0.00..4.33 rows=333 width=8) - -> Hash (cost=1.05..1.05 rows=3 width=12) - -> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..1.05 rows=3 width=12) + -> Hash (cost=1.04..1.04 rows=2 width=12) + -> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..1.04 rows=2 width=12) -> Seq Scan on t3 t3_1 (cost=0.00..1.01 rows=1 width=12) - -> Hash (cost=6.36..6.36 rows=3 width=20) - -> Redistribute Motion 3:3 (slice6; segments: 3) (cost=1.09..6.36 rows=3 width=20) + -> Hash (cost=6.33..6.33 rows=3 width=20) + -> Redistribute Motion 3:3 (slice6; segments: 3) (cost=1.06..6.33 rows=3 width=20) Hash Key: t3.b - -> Hash Join (cost=1.09..6.29 rows=3 width=20) + -> Hash Join (cost=1.06..6.27 rows=3 width=20) Hash Cond: (t1_1.b = t3.b) -> Seq Scan on t1 t1_1 (cost=0.00..4.33 rows=333 width=8) - -> Hash (cost=1.05..1.05 rows=3 width=12) - -> Broadcast Motion 3:3 (slice7; segments: 3) (cost=0.00..1.05 rows=3 width=12) + -> Hash (cost=1.04..1.04 rows=2 width=12) + -> Broadcast Motion 3:3 (slice7; segments: 3) (cost=0.00..1.04 rows=2 width=12) -> Seq Scan on t3 (cost=0.00..1.01 rows=1 width=12) Optimizer: Postgres query optimizer (34 rows) @@ -783,10 +781,10 @@ select * from (select t1.a t1a, t1.b t1b, t2.a t2a, t2.b t2b from t1 left join t join t3 t3_1 on tt1.t1b = t3_1.b and (tt1.t2a is NULL OR tt1.t1b = t3.b); t1a | t1b | t2a | t2b | a | b | c | t1a | t1b | t2a | t2b | a | b | c -----+-----+-----+-----+---+---+---+-----+-----+-----+-----+---+---+--- - 2 | 2 | 2 | 2 | | 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 + 2 | 2 | 2 | 2 | 1 | 2 | 3 | 2 | 2 | 2 | 2 | 1 | 2 | 3 2 | 2 | 2 | 2 | | 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 2 | 2 | 2 | 2 | 1 | 2 | 3 | 2 | 2 | 2 | 2 | | 2 | 2 - 2 | 2 | 2 | 2 | 1 | 2 | 3 | 2 | 2 | 2 | 2 | 1 | 2 | 3 + 2 | 2 | 2 | 2 | | 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 (4 rows) -- test different join order enumeration methods @@ -794,32 +792,32 @@ set optimizer_join_order = query; select * from t1 join t2 on t1.a = t2.a join t3 on t1.b = t3.b; a | b | c | a | b | c | a | b | c ---+---+---+---+---+---+---+---+--- - 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 + 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 (2 rows) set optimizer_join_order = greedy; select * from t1 join t2 on t1.a = t2.a join t3 on t1.b = t3.b; a | b | c | a | b | c | a | b | c ---+---+---+---+---+---+---+---+--- - 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 + 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 (2 rows) set optimizer_join_order = exhaustive; select * from t1 join t2 on t1.a = t2.a join t3 on t1.b = t3.b; a | b | c | a | b | c | a | b | c ---+---+---+---+---+---+---+---+--- - 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 + 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 (2 rows) set optimizer_join_order = exhaustive2; select * from t1 join t2 on t1.a = t2.a join t3 on t1.b = t3.b; a | b | c | a | b | c | a | b | c ---+---+---+---+---+---+---+---+--- - 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 + 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 (2 rows) reset optimizer_join_order; @@ -853,16 +851,16 @@ set enable_bitmapscan = 0; -- m/Index Only Scan using tenk2_\w+ on tenk2/ -- end_matchignore explain select tenk1.unique2 >= 0 from tenk1 left join tenk2 on true limit 1; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------- - Limit (cost=0.32..0.38 rows=1 width=4) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.32..0.38 rows=1 width=4) - -> Limit (cost=0.32..0.36 rows=1 width=4) - -> Nested Loop Left Join (cost=0.32..3520104.27 rows=33333334 width=4) - -> Index Only Scan using tenk1_unique2 on tenk1 (cost=0.16..1650.16 rows=3334 width=4) - -> Materialize (cost=0.16..18479.11 rows=10000 width=0) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.16..18329.11 rows=10000 width=0) - -> Index Only Scan using tenk2_hundred on tenk2 (cost=0.16..223.47 rows=3333 width=0) + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- + Limit (cost=0.32..0.35 rows=1 width=1) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.32..0.40 rows=3 width=1) + -> Limit (cost=0.32..0.36 rows=1 width=1) + -> Nested Loop Left Join (cost=0.32..1219565.72 rows=33333333 width=1) + -> Index Only Scan using tenk1_unique2 on tenk1 (cost=0.16..143.49 rows=3333 width=4) + -> Materialize (cost=0.16..290.83 rows=10000 width=0) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.16..240.83 rows=10000 width=0) + -> Index Only Scan using tenk2_hundred on tenk2 (cost=0.16..107.49 rows=3333 width=0) Optimizer: Postgres query optimizer (9 rows) @@ -924,16 +922,16 @@ explain select * from generate_series(1, 5) g left join trep_join_gp on g = trep select * from generate_series(1, 5) g left join trep_join_gp on g = trep_join_gp.c1 join thash_join_gp on true; g | c1 | c2 | c1 | c2 ---+----+----+----+---- - 1 | 1 | 1 | 1 | 1 - 2 | 2 | 2 | 1 | 1 - 3 | | | 1 | 1 - 4 | | | 1 | 1 - 5 | | | 1 | 1 1 | 1 | 1 | 2 | 2 2 | 2 | 2 | 2 | 2 3 | | | 2 | 2 4 | | | 2 | 2 5 | | | 2 | 2 + 1 | 1 | 1 | 1 | 1 + 2 | 2 | 2 | 1 | 1 + 3 | | | 1 | 1 + 4 | | | 1 | 1 + 5 | | | 1 | 1 (10 rows) -- The following 4 tests are to check that general left join partition, we could redistribute the @@ -957,10 +955,10 @@ select * from generate_series(1, 5) g left join thash_join_gp on g = thash_join_ g | c1 | c2 ---+----+---- 2 | 2 | 2 - 3 | | 4 | | - 1 | 1 | 1 + 3 | | 5 | | + 1 | 1 | 1 (5 rows) explain select * from generate_series(1, 5) g left join thash_join_gp on g = thash_join_gp.c2; @@ -982,10 +980,10 @@ explain select * from generate_series(1, 5) g left join thash_join_gp on g = tha select * from generate_series(1, 5) g left join thash_join_gp on g = thash_join_gp.c2; g | c1 | c2 ---+----+---- - 5 | | 2 | 2 | 2 - 3 | | 4 | | + 3 | | + 5 | | 1 | 1 | 1 (5 rows) @@ -1008,11 +1006,11 @@ explain select * from generate_series(1, 5) g left join trand_join_gp on g = tra select * from generate_series(1, 5) g left join trand_join_gp on g = trand_join_gp.c1; g | c1 | c2 ---+----+---- + 5 | | + 1 | | + 4 | | 2 | | 3 | | - 4 | | - 1 | | - 5 | | (5 rows) explain select * from generate_series(1, 5) g full join trand_join_gp on g = trand_join_gp.c1; @@ -1034,11 +1032,11 @@ explain select * from generate_series(1, 5) g full join trand_join_gp on g = tra select * from generate_series(1, 5) g full join trand_join_gp on g = trand_join_gp.c1; g | c1 | c2 ---+----+---- + 4 | | 2 | | 3 | | - 4 | | - 1 | | 5 | | + 1 | | (5 rows) -- The following 3 tests are to check that segmentGeneral left join partition @@ -1062,23 +1060,23 @@ explain select * from trep_join_gp left join thash_join_gp using (c1); select * from trep_join_gp left join thash_join_gp using (c1); c1 | c2 | c2 ----+----+---- - 1 | 1 | 1 2 | 2 | 2 + 1 | 1 | 1 (2 rows) explain select * from trep_join_gp left join trand_join_gp using (c1); QUERY PLAN ---------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=1.03..2.20 rows=4 width=12) - -> Hash Left Join (cost=1.03..2.13 rows=2 width=12) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.04..2.15 rows=3 width=12) + -> Hash Left Join (cost=1.04..2.11 rows=1 width=12) Hash Cond: (trep_join_gp.c1 = trand_join_gp.c1) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=0.00..1.06 rows=2 width=8) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=0.00..1.05 rows=1 width=8) Hash Key: trep_join_gp.c1 -> Seq Scan on trep_join_gp (cost=0.00..1.02 rows=2 width=8) - -> Hash (cost=1.02..1.02 rows=1 width=8) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.02 rows=1 width=8) + -> Hash (cost=1.03..1.03 rows=1 width=8) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.03 rows=1 width=8) Hash Key: trand_join_gp.c1 - -> Seq Scan on trand_join_gp (cost=0.00..1.00 rows=1 width=8) + -> Seq Scan on trand_join_gp (cost=0.00..1.01 rows=1 width=8) Optimizer: Postgres query optimizer (11 rows) @@ -1146,19 +1144,19 @@ analyze t_joinsize_2; analyze t_joinsize_3; -- the following query should not broadcast the join result of t_joinsize_1, t_joinsize_2. explain select * from (t_joinsize_1 join t_joinsize_2 on t_joinsize_1.c2 = t_joinsize_2.c2) join t_joinsize_3 on t_joinsize_3.c = t_joinsize_1.c1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=24.17..386.00 rows=20000 width=20) -> Hash Join (cost=24.17..119.33 rows=6667 width=20) - Hash Cond: (t_joinsize_2.c2 = t_joinsize_1_1_prt_2.c2) + Hash Cond: (t_joinsize_2.c2 = t_joinsize_1.c2) -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..11.00 rows=333 width=8) Hash Key: t_joinsize_2.c2 -> Seq Scan on t_joinsize_2 (cost=0.00..4.33 rows=333 width=8) -> Hash (cost=21.67..21.67 rows=200 width=12) -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=2.42..21.67 rows=200 width=12) - Hash Key: t_joinsize_1_1_prt_2.c2 + Hash Key: t_joinsize_1.c2 -> Hash Join (cost=2.42..17.67 rows=200 width=12) - Hash Cond: (t_joinsize_1_1_prt_2.c1 = t_joinsize_3.c) + Hash Cond: (t_joinsize_1.c1 = t_joinsize_3.c) -> Append (cost=0.00..12.00 rows=400 width=8) -> Seq Scan on t_joinsize_1_1_prt_2 t_joinsize_1_1 (cost=0.00..1.13 rows=13 width=8) -> Seq Scan on t_joinsize_1_1_prt_3 t_joinsize_1_2 (cost=0.00..1.13 rows=13 width=8) @@ -1221,19 +1219,19 @@ insert into t2_lateral_limit values (2, 2); insert into t2_lateral_limit values (3, 3); explain select * from t1_lateral_limit as t1 cross join lateral (select ((c).x+t2.b) as n from t2_lateral_limit as t2 order by n limit 1)s; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Nested Loop (cost=10000000001.06..10000000002.12 rows=4 width=41) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=37) - -> Seq Scan on t1_lateral_limit t1 (cost=0.00..1.01 rows=1 width=37) - -> Materialize (cost=1.06..1.08 rows=1 width=4) - -> Limit (cost=1.06..1.06 rows=1 width=4) - -> Sort (cost=1.06..1.06 rows=1 width=4) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------- + Nested Loop (cost=10000003406.25..10159073271.08 rows=46700 width=44) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..812.33 rows=46700 width=40) + -> Seq Scan on t1_lateral_limit t1 (cost=0.00..189.67 rows=15567 width=40) + -> Materialize (cost=3406.25..3406.26 rows=1 width=4) + -> Limit (cost=3406.25..3406.25 rows=1 width=4) + -> Sort (cost=3406.25..3621.50 rows=86100 width=4) Sort Key: (((t1.c).x + t2.b)) - -> Result (cost=0.00..1.05 rows=1 width=4) - -> Materialize (cost=0.00..1.03 rows=1 width=4) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=4) - -> Seq Scan on t2_lateral_limit t2 (cost=0.00..1.01 rows=1 width=4) + -> Result (cost=0.00..2975.75 rows=86100 width=4) + -> Materialize (cost=0.00..1899.50 rows=86100 width=4) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1469.00 rows=86100 width=4) + -> Seq Scan on t2_lateral_limit t2 (cost=0.00..321.00 rows=28700 width=4) Optimizer: Postgres query optimizer (12 rows) @@ -1286,18 +1284,18 @@ select * from t1_lateral_limit as t1 cross join lateral -- may add motions in the subquery's plan). explain select * from t1_lateral_limit t1 cross join lateral (select (c).x+t2.a, sum(t2.a+t2.b) from t2_lateral_limit t2 group by (c).x+t2.a)x; - QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Nested Loop (cost=10000000001.06..10000000002.12 rows=4 width=49) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=37) - -> Seq Scan on t1_lateral_limit t1 (cost=0.00..1.01 rows=1 width=37) - -> Materialize (cost=1.05..1.08 rows=1 width=12) - -> HashAggregate (cost=1.05..1.07 rows=1 width=12) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Nested Loop (cost=10000003621.50..10170175612.33 rows=46700000 width=52) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..812.33 rows=46700 width=40) + -> Seq Scan on t1_lateral_limit t1 (cost=0.00..189.67 rows=15567 width=40) + -> Materialize (cost=3621.50..3639.00 rows=1000 width=12) + -> HashAggregate (cost=3621.50..3634.00 rows=1000 width=12) Group Key: ((t1.c).x + t2.a) - -> Result (cost=0.00..1.05 rows=1 width=12) - -> Materialize (cost=0.00..1.03 rows=1 width=8) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=8) - -> Seq Scan on t2_lateral_limit t2 (cost=0.00..1.01 rows=1 width=8) + -> Result (cost=0.00..2975.75 rows=86100 width=12) + -> Materialize (cost=0.00..1899.50 rows=86100 width=8) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1469.00 rows=86100 width=8) + -> Seq Scan on t2_lateral_limit t2 (cost=0.00..321.00 rows=28700 width=8) Optimizer: Postgres query optimizer (11 rows) @@ -1305,8 +1303,8 @@ select * from t1_lateral_limit t1 cross join lateral (select (c).x+t2.a, sum(t2.a+t2.b) from t2_lateral_limit t2 group by (c).x+t2.a)x; a | b | c | ?column? | sum ---+---+-------+----------+----- - 1 | 1 | (1,1) | 4 | 6 1 | 1 | (1,1) | 3 | 4 + 1 | 1 | (1,1) | 4 | 6 1 | 2 | (2,2) | 5 | 6 1 | 2 | (2,2) | 4 | 4 (4 rows) @@ -1324,18 +1322,18 @@ inner join lateral on true; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------- - Nested Loop (cost=10000000001.08..10000000003.25 rows=3 width=20) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.04 rows=2 width=12) - -> Seq Scan on t_mylog_issue_8860 ml1 (cost=0.00..1.01 rows=1 width=12) - -> Materialize (cost=1.08..1.10 rows=1 width=8) - -> Limit (cost=1.08..1.08 rows=1 width=12) - -> Sort (cost=1.08..1.08 rows=2 width=12) + Nested Loop (cost=10000002890.33..10225160051.75 rows=77900 width=20) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1332.33 rows=77900 width=12) + -> Seq Scan on t_mylog_issue_8860 ml1 (cost=0.00..293.67 rows=25967 width=12) + -> Materialize (cost=2890.33..2890.35 rows=1 width=8) + -> Limit (cost=2890.33..2890.34 rows=1 width=12) + -> Sort (cost=2890.33..3085.08 rows=77900 width=12) Sort Key: t_mylog_issue_8860.log_date - -> Result (cost=0.00..1.07 rows=2 width=12) + -> Result (cost=0.00..2500.83 rows=77900 width=12) Filter: ((t_mylog_issue_8860.log_date > ml1.log_date) AND (t_mylog_issue_8860.myid = ml1.myid)) - -> Materialize (cost=0.00..1.05 rows=2 width=12) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.04 rows=2 width=12) - -> Seq Scan on t_mylog_issue_8860 (cost=0.00..1.01 rows=1 width=12) + -> Materialize (cost=0.00..1721.83 rows=77900 width=12) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1332.33 rows=77900 width=12) + -> Seq Scan on t_mylog_issue_8860 (cost=0.00..293.67 rows=25967 width=12) Optimizer: Postgres query optimizer (13 rows) @@ -1346,8 +1344,8 @@ inner join lateral on true; myid | first_date | next_date ------+------------------------------+------------------------------ - 2 | Sun Jan 02 01:04:00 2000 PST | Sun Jan 02 03:04:00 2000 PST 1 | Sun Jan 02 02:04:00 2000 PST | Sun Jan 02 03:04:00 2000 PST + 2 | Sun Jan 02 01:04:00 2000 PST | Sun Jan 02 03:04:00 2000 PST (2 rows) -- test prefetch join qual @@ -1503,7 +1501,9 @@ reset enable_bitmapscan; --- Test that GUC enable_hashagg takes effect for SEMI join --- drop table if exists foo; +NOTICE: table "foo" does not exist, skipping drop table if exists bar; +NOTICE: table "bar" does not exist, skipping create table foo(a int) distributed by (a); create table bar(b int) distributed by (b); insert into foo select i from generate_series(1,10)i; @@ -1513,70 +1513,59 @@ analyze bar; set enable_hashagg to on; explain (costs off) select * from foo where exists (select 1 from bar where foo.a = bar.b); - QUERY PLAN ------------------------------------------------------------- + QUERY PLAN +------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> HashAggregate - Group Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: (bar.b = foo.a) - -> Seq Scan on bar - -> Hash - -> Seq Scan on foo + -> Hash Right Semi Join + Hash Cond: (bar.b = foo.a) + -> Seq Scan on bar + -> Hash + -> Seq Scan on foo Optimizer: Postgres query optimizer -(11 rows) +(7 rows) select * from foo where exists (select 1 from bar where foo.a = bar.b); a ---- - 10 + 1 + 5 + 6 9 + 10 + 2 3 - 7 4 - 5 + 7 8 - 1 - 2 - 6 (10 rows) set enable_hashagg to off; explain (costs off) select * from foo where exists (select 1 from bar where foo.a = bar.b); - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: (bar.b = foo.a) - -> Seq Scan on bar - -> Hash - -> Seq Scan on foo + -> Hash Right Semi Join + Hash Cond: (bar.b = foo.a) + -> Seq Scan on bar + -> Hash + -> Seq Scan on foo Optimizer: Postgres query optimizer -(14 rows) +(7 rows) select * from foo where exists (select 1 from bar where foo.a = bar.b); a ---- + 5 + 6 + 9 + 10 1 2 3 4 - 5 - 6 7 8 - 9 - 10 (10 rows) reset enable_hashagg; @@ -1671,20 +1660,20 @@ full join ( select r.id1, r.id2 from t_issue_10315 r group by r.id1, r.id2 ) tq_ on (coalesce(t.id1) = tq_all.id1 and t.id2 = tq_all.id2) ; id1 | id2 | id1 | id2 | id1 | id2 -----+-----+-----+-----+-----+----- - 2 | 2 | 2 | 2 | 2 | 2 + 1 | 1 | 1 | 1 | 1 | 1 + 1 | | | | | + | | | | 1 | + | | 1 | | | + | 2 | | | | 2 | | | | | + 2 | 2 | 2 | 2 | 2 | 2 | 1 | | | | - | 2 | | | | | | | 2 | | | | | 1 | | | | 2 | | | - | | 1 | | | | | | | | 2 | | | | | 1 | | | | 2 | - 1 | 1 | 1 | 1 | 1 | 1 - 1 | | | | | - | | | | 1 | (14 rows) drop table t_issue_10315; @@ -1717,8 +1706,8 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on fooJoinPruning.c=barJoinPruning.p where fooJoinPruning.b>300 and fooJoinPruning.c in (select barJoinPruning.q from barJoinPruning ); QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=958.75..1562.82 rows=12983 width=12) - -> Hash Join (cost=958.75..1389.71 rows=4328 width=12) + Gather Motion 3:1 (slice1; segments: 3) (cost=958.75..1562.80 rows=12983 width=12) + -> Hash Join (cost=958.75..1389.69 rows=4328 width=12) Hash Cond: (foojoinpruning.c = barjoinpruning.q) -> Seq Scan on foojoinpruning (cost=0.00..358.58 rows=8656 width=12) Filter: (b > 300) @@ -1887,7 +1876,7 @@ drop table barJoinPruning; drop table t1JoinPruning; drop table t2JoinPruning; create table t1 (a int); -NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table. +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create table t2 (a int primary key, b int); create table t3 (a int primary key, b int); @@ -2017,8 +2006,8 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on fooJoinPruning.c=barJoinPruning.p where fooJoinPruning.b in (select barJoinPruning.q from fooJoinPruning where fooJoinPruning.a=barJoinPruning.r); QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=1633.60..1994.88 rows=78 width=12) - -> Hash Join (cost=1633.60..1993.84 rows=26 width=12) + Gather Motion 3:1 (slice1; segments: 3) (cost=1633.60..1994.56 rows=78 width=12) + -> Hash Join (cost=1633.60..1993.52 rows=26 width=12) Hash Cond: (foojoinpruning_1.a = barjoinpruning.r) -> Seq Scan on foojoinpruning foojoinpruning_1 (cost=0.00..293.67 rows=25967 width=4) -> Hash (cost=1633.27..1633.27 rows=26 width=16) @@ -2140,7 +2129,7 @@ union select foo.a, bar.b from foo join bar on foo.a = bar.a; -> Seq Scan on foo foo_1 -> Hash -> Seq Scan on bar bar_1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (17 rows) ------------------------------------- @@ -2163,19 +2152,19 @@ select bar.b,bar.c from bar left join foo on foo.a=bar.a; -> Append -> Seq Scan on foo -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (9 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a union select bar.b,bar.c from bar left join foo on foo.a=bar.a; b | c ---+---- + 1 | 10 + 2 | 20 + 3 | | 2 | 30 | 3 - 2 | 20 - 3 | - 1 | 10 (6 rows) -------------------------------------------------------------------------------- @@ -2191,17 +2180,17 @@ select bar.b,bar.c from bar left join foo on foo.a=bar.a; -> Append -> Seq Scan on foo -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (5 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a union all select bar.b,bar.c from bar left join foo on foo.a=bar.a; b | c ---+---- - 2 | 30 - | 1 | 10 1 | 10 + 2 | 30 + | 1 | 10 1 | 10 2 | 20 @@ -2232,16 +2221,16 @@ select bar.b,bar.c from bar left join foo on foo.a=bar.a; Hash Key: "*SELECT* 1".b, "*SELECT* 1".c -> Subquery Scan on "*SELECT* 1" -> Seq Scan on foo - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (12 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a intersect select bar.b,bar.c from bar left join foo on foo.a=bar.a; b | c ---+---- - | 1 | 10 2 | 20 + | (3 rows) -------------------------------------------------------------------------------- @@ -2264,7 +2253,7 @@ select bar.b,bar.c from bar left join foo on foo.a=bar.a; Hash Key: "*SELECT* 1".b, "*SELECT* 1".c -> Subquery Scan on "*SELECT* 1" -> Seq Scan on foo - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (12 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a intersect all @@ -2297,7 +2286,7 @@ select bar.b,bar.c from bar left join foo on foo.a=bar.a; Hash Key: "*SELECT* 2".b, "*SELECT* 2".c -> Subquery Scan on "*SELECT* 2" -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (12 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a except @@ -2328,7 +2317,7 @@ select bar.b,bar.c from bar left join foo on foo.a=bar.a; Hash Key: "*SELECT* 2".b, "*SELECT* 2".c -> Subquery Scan on "*SELECT* 2" -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (12 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a except all @@ -2366,14 +2355,13 @@ select bar.b,foo.c from bar left join foo on foo.a=bar.a; -> Seq Scan on foo foo_1 -> Hash -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (13 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a union select bar.b,foo.c from bar left join foo on foo.a=bar.a; b | c ---+---- - 2 | 10 | 2 | 30 | 3 @@ -2382,6 +2370,7 @@ select bar.b,foo.c from bar left join foo on foo.a=bar.a; 1 | 30 2 | 20 | 20 + 2 | 10 (9 rows) -------------------------------------------------------------------------------- @@ -2403,13 +2392,16 @@ select bar.b,foo.c from bar left join foo on foo.a=bar.a; -> Seq Scan on foo foo_1 -> Hash -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (9 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a union all select bar.b,foo.c from bar left join foo on foo.a=bar.a; b | c ---+---- + 2 | 30 + | + 1 | 30 1 | 10 2 | 20 2 | 30 @@ -2417,9 +2409,6 @@ select bar.b,foo.c from bar left join foo on foo.a=bar.a; 2 | 10 | 20 3 | 30 - 2 | 30 - | - 1 | 30 1 | 10 1 | 10 (12 rows) @@ -2450,7 +2439,7 @@ select bar.b,foo.c from bar left join foo on foo.a=bar.a; Hash Key: "*SELECT* 1".b, "*SELECT* 1".c -> Subquery Scan on "*SELECT* 1" -> Seq Scan on foo foo_1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (16 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a intersect @@ -2486,7 +2475,7 @@ select bar.b,foo.c from bar left join foo on foo.a=bar.a; Hash Key: "*SELECT* 1".b, "*SELECT* 1".c -> Subquery Scan on "*SELECT* 1" -> Seq Scan on foo foo_1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (16 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a intersect all @@ -2522,17 +2511,17 @@ select bar.b,foo.c from bar left join foo on foo.a=bar.a; -> Seq Scan on foo foo_1 -> Hash -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (16 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a except select bar.b,foo.c from bar left join foo on foo.a=bar.a; b | c ---+---- + 2 | 20 | 3 | 2 | 30 - 2 | 20 (4 rows) -------------------------------------------------------------------------------- @@ -2561,19 +2550,19 @@ select bar.b,foo.c from bar left join foo on foo.a=bar.a; -> Seq Scan on foo foo_1 -> Hash -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (16 rows) select foo.b,foo.c from foo left join bar on foo.a=bar.a except all select bar.b,foo.c from bar left join foo on foo.a=bar.a; b | c ---+---- + 2 | 20 + 1 | 10 | 3 | 2 | 30 2 | 30 - 2 | 20 - 1 | 10 (6 rows) drop table foo; @@ -2656,11 +2645,11 @@ explain (costs off) select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a; a1_pc | b1 | a | b -------+----+---+--- + 5 | 5 | 5 | 5 1 | 1 | 1 | 1 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 - 5 | 5 | 5 | 5 (5 rows) -- Outer table: Partitioned table, Join Condition on Partition key: No, Result: DPE - No @@ -2688,10 +2677,10 @@ select * from bar_PT1 right join foo on bar_PT1.b1 =foo.a; a1_pc | b1 | a | b -------+----+---+--- 5 | 5 | 5 | 5 - 1 | 1 | 1 | 1 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 + 1 | 1 | 1 | 1 (5 rows) -- Outer,Inner table: Partitioned table, Join Condition on Partition key: Yes, Result: DPE - Yes @@ -2721,11 +2710,11 @@ explain (costs off) select * from bar_PT1 right join bar_PT3 on bar_PT1.a1_PC =b select * from bar_PT1 right join bar_PT3 on bar_PT1.a1_PC =bar_PT3.a3_PC; a1_pc | b1 | a3_pc | b3 -------+----+-------+---- + 1 | 1 | 1 | 1 5 | 5 | 5 | 5 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 - 1 | 1 | 1 | 1 (5 rows) -- Outer table: Not a Partitioned table, Join Condition on Partition key: Yes, Result: DPE - No @@ -2750,17 +2739,17 @@ explain (costs off) select * from foo right join bar_PT1 on foo.a=bar_PT1.a1_PC; select * from foo right join bar_PT1 on foo.a=bar_PT1.a1_PC; a | b | a1_pc | b1 ---+---+-------+---- - 5 | 5 | 5 | 5 - | | 6 | 6 - | | 9 | 9 - | | 10 | 10 - | | 11 | 11 + 1 | 1 | 1 | 1 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 | | 7 | 7 | | 8 | 8 - 1 | 1 | 1 | 1 + 5 | 5 | 5 | 5 + | | 6 | 6 + | | 9 | 9 + | | 10 | 10 + | | 11 | 11 (11 rows) -- Right join with predicate on the column of non partitioned table in 'where clause'. @@ -2789,9 +2778,9 @@ explain (costs off) select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a where foo.a>2; a1_pc | b1 | a | b -------+----+---+--- + 5 | 5 | 5 | 5 3 | 3 | 3 | 3 4 | 4 | 4 | 4 - 5 | 5 | 5 | 5 (3 rows) --Conjunction in join condition, Result: DPE - Yes @@ -2850,10 +2839,10 @@ select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a and foo.b>2; a1_pc | b1 | a | b -------+----+---+--- | | 1 | 1 - 5 | 5 | 5 | 5 3 | 3 | 3 | 3 4 | 4 | 4 | 4 | | 2 | 2 + 5 | 5 | 5 | 5 (5 rows) -- Multiple Right Joins, DPE- Yes @@ -2892,17 +2881,17 @@ explain (costs off) select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a right join bar_PT2 on bar_PT1.a1_PC =bar_PT2.b2_PC; a1_pc | b1 | a | b | a2 | b2_pc -------+----+---+---+----+------- + 5 | 5 | 5 | 5 | 5 | 5 + | | | | 6 | 6 + | | | | 9 | 9 + | | | | 10 | 10 + | | | | 11 | 11 2 | 2 | 2 | 2 | 2 | 2 3 | 3 | 3 | 3 | 3 | 3 4 | 4 | 4 | 4 | 4 | 4 | | | | 7 | 7 | | | | 8 | 8 1 | 1 | 1 | 1 | 1 | 1 - 5 | 5 | 5 | 5 | 5 | 5 - | | | | 6 | 6 - | | | | 9 | 9 - | | | | 10 | 10 - | | | | 11 | 11 (11 rows) -- FOR LIST PARTITIONED TABLE @@ -2938,10 +2927,10 @@ select * from bar_List_PT1 right join foo on bar_List_PT1.a1_PC =foo.a; a1_pc | b1 | a | b -------+----+---+--- 1 | 1 | 1 | 1 + 5 | 5 | 5 | 5 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 - 5 | 5 | 5 | 5 (5 rows) -- Outer,Inner table: Partitioned table, Join Condition on Partition key: Yes, Result: DPE - Yes @@ -2982,13 +2971,13 @@ explain (costs off) select * from bar_List_PT1 right join bar_List_PT2 on bar_Li select * from bar_List_PT1 right join bar_List_PT2 on bar_List_PT1.a1_PC =bar_List_PT2.a2_PC; a1_pc | b1 | a2_pc | b2 -------+----+-------+---- - 1 | 1 | 1 | 1 - 12 | 12 | 12 | 12 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 7 | 7 | 7 | 7 8 | 8 | 8 | 8 + 1 | 1 | 1 | 1 + 12 | 12 | 12 | 12 5 | 5 | 5 | 5 6 | 6 | 6 | 6 9 | 9 | 9 | 9 @@ -3021,11 +3010,11 @@ explain (costs off) select * from bar_PT2 right join foo on bar_PT2.b2_PC =foo.a select * from bar_PT2 right join foo on bar_PT2.b2_PC =foo.a; a2 | b2_pc | a | b ----+-------+---+--- - 5 | 5 | 5 | 5 + 1 | 1 | 1 | 1 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 - 1 | 1 | 1 | 1 + 5 | 5 | 5 | 5 (5 rows) -- Outer,Inner table: Partitioned table, Join Condition on Partition key: Yes, Result: DPE - No @@ -3065,12 +3054,12 @@ select * from bar_PT2 right join bar_PT1 on bar_PT2.b2_PC =bar_PT1.b1; 9 | 9 | 9 | 9 10 | 10 | 10 | 10 11 | 11 | 11 | 11 - 1 | 1 | 1 | 1 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 7 | 7 | 7 | 7 8 | 8 | 8 | 8 + 1 | 1 | 1 | 1 (11 rows) drop table if exists foo; @@ -3085,10 +3074,10 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'cidr' HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO inverse values ('192.168.100.199'); explain SELECT 1 FROM inverse WHERE NOT (cidr <<= ANY(SELECT * FROM inverse)); - QUERY PLAN --------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10027702610.21 rows=16 width=4) - -> Nested Loop Left Anti Semi (Not-In) Join (cost=10000000000.00..10027702610.00 rows=5 width=4) + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=10000000000.00..10027703310.48 rows=52536 width=4) + -> Nested Loop Left Anti Semi (Not-In) Join (cost=10000000000.00..10027702610.00 rows=17512 width=4) Join Filter: (inverse.cidr <<= inverse_1.cidr) -> Seq Scan on inverse (cost=0.00..210.00 rows=17600 width=32) -> Materialize (cost=0.00..1178.00 rows=52800 width=32) @@ -3160,9 +3149,9 @@ explain select * from foo_varchar left join random_dis_char on foo_varchar.a=ran select * from foo_varchar left join random_dis_char on foo_varchar.a=random_dis_char.y; a | y ------+------- - 1 | 1 2 | 2 3 | 3 + 1 | 1 (3 rows) explain select * from bar_char left join random_dis_varchar on bar_char.p=random_dis_varchar.x; @@ -3235,8 +3224,8 @@ select * from foo_varchar inner join random_dis_char on foo_varchar.a=random_dis a | y ------+------- 1 | 1 - 2 | 2 3 | 3 + 2 | 2 (3 rows) explain select * from bar_char inner join random_dis_varchar on bar_char.p=random_dis_varchar.x; @@ -3257,8 +3246,8 @@ select * from bar_char inner join random_dis_varchar on bar_char.p=random_dis_va p | x -------+------ 1 | 1 - 2 | 2 3 | 3 + 2 | 2 (3 rows) drop table foo_varchar; @@ -3273,7 +3262,9 @@ reset enable_nestloop; -- for "Left Semi Join with replicated outer table" ----------------------------------------------------------------- drop table if exists repli_t1; +NOTICE: table "repli_t1" does not exist, skipping drop table if exists dist_t1; +NOTICE: table "dist_t1" does not exist, skipping create table repli_t1 (a int) distributed replicated; insert into repli_t1 values(1); analyze repli_t1; @@ -3296,7 +3287,7 @@ explain (costs off) select * from repli_t1 where exists ( select 1 from dist_t1 -> Broadcast Motion 1:3 (slice3; segments: 1) -> Seq Scan on repli_t1 -> Seq Scan on dist_t1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (11 rows) select * from repli_t1 where exists ( select 1 from dist_t1 where repli_t1.a >= dist_t1.b); @@ -3324,7 +3315,7 @@ where exists (select 1 from dist_t1 as t4 where t3.aVal1 >= t4.b); -> Seq Scan on dist_t1 t4 -> Hash -> Seq Scan on repli_t1 t2 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (16 rows) select * from (select t1.a as aVal1, t2.a as aVal2 from repli_t1 as t1 , repli_t1 as t2 where t1.a = t2.a) as t3 @@ -3349,7 +3340,7 @@ explain (costs off) select * from repli_t1 where exists ( select 1 from dist_t1 -> Broadcast Motion 1:3 (slice3; segments: 1) -> Seq Scan on repli_t1 -> Seq Scan on dist_t1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (11 rows) select * from repli_t1 where exists ( select 1 from dist_t1 where repli_t1.a >= dist_t1.b); @@ -3368,17 +3359,17 @@ explain (costs off) select * from dist_t1 where exists ( select 1 from repli_t1 Join Filter: (repli_t1.a >= dist_t1.b) -> Seq Scan on dist_t1 -> Seq Scan on repli_t1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (6 rows) select * from dist_t1 where exists ( select 1 from repli_t1 where repli_t1.a >= dist_t1.b); a | b ---+--- + 5 | 1 + 1 | 1 2 | 1 3 | 1 4 | 1 - 1 | 1 - 5 | 1 (5 rows) -- Both replicated table @@ -3390,7 +3381,7 @@ explain (costs off) select * from repli_t1 as t1 where exists ( select 1 from r Join Filter: (t1.a >= t2.a) -> Seq Scan on repli_t1 t1 -> Seq Scan on repli_t1 t2 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (6 rows) select * from repli_t1 as t1 where exists ( select 1 from repli_t1 as t2 where t1.a >= t2.a); @@ -3411,7 +3402,7 @@ explain (costs off) select * from generate_series(1, 5) univ_t where exists ( se -> Seq Scan on dist_t1 -> Materialize -> Function Scan on generate_series univ_t - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (9 rows) select * from generate_series(1, 5) univ_t where exists ( select 1 from dist_t1 where univ_t >= dist_t1.b); @@ -3433,17 +3424,17 @@ explain (costs off) select * from dist_t1 where exists ( select 1 from generate_ Join Filter: (univ_t.univ_t >= dist_t1.b) -> Seq Scan on dist_t1 -> Function Scan on generate_series univ_t - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (6 rows) select * from dist_t1 where exists ( select 1 from generate_series(1, 5) univ_t where univ_t >= dist_t1.b); a | b ---+--- + 5 | 1 + 1 | 1 2 | 1 3 | 1 4 | 1 - 1 | 1 - 5 | 1 (5 rows) -- Outer - replicated, Inner - universal table @@ -3455,7 +3446,7 @@ explain (costs off)select * from repli_t1 where exists ( select 1 from generate_ Join Filter: (univ_t.univ_t >= repli_t1.a) -> Seq Scan on repli_t1 -> Function Scan on generate_series univ_t - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (6 rows) select * from repli_t1 where exists ( select 1 from generate_series(1, 5) univ_t where univ_t >= repli_t1.a); @@ -3474,7 +3465,7 @@ explain (costs off) select * from generate_series(1, 5) univ_t where exists ( se -> Function Scan on generate_series univ_t -> Materialize -> Seq Scan on repli_t1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (7 rows) select * from generate_series(1, 5) univ_t where exists ( select 1 from repli_t1 where univ_t >= repli_t1.a); @@ -3490,9 +3481,13 @@ select * from generate_series(1, 5) univ_t where exists ( select 1 from repli_t1 -- Explicitly defined primary key for replicated table --------------------------------------------------------- drop table if exists repli_t1_pk; +NOTICE: table "repli_t1_pk" does not exist, skipping drop table if exists repli_t2_pk; +NOTICE: table "repli_t2_pk" does not exist, skipping drop table if exists repli_t3_pk; +NOTICE: table "repli_t3_pk" does not exist, skipping drop table if exists repli_t4_pk; +NOTICE: table "repli_t4_pk" does not exist, skipping -- Outer - replicated, Inner - distributed table create table repli_t1_pk (a int, PRIMARY KEY(a)) distributed replicated; insert into repli_t1_pk values(1); @@ -3519,7 +3514,7 @@ explain (costs off) select * from repli_t1_pk where exists ( select 1 from dist_ -> Broadcast Motion 1:3 (slice3; segments: 1) -> Seq Scan on repli_t1_pk -> Seq Scan on dist_t1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (11 rows) select * from repli_t1_pk where exists ( select 1 from dist_t1 where repli_t1_pk.a >= dist_t1.b); @@ -3543,7 +3538,7 @@ explain (costs off) select * from repli_t1_pk where exists ( select 1 from dist_ -> Broadcast Motion 1:3 (slice3; segments: 1) -> Seq Scan on repli_t1_pk -> Seq Scan on dist_t1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (11 rows) select * from repli_t1_pk where exists ( select 1 from dist_t1 where repli_t1_pk.a >= dist_t1.b); @@ -3566,7 +3561,7 @@ explain (costs off) select * from repli_t2_pk where exists ( select 1 from dist_ -> Broadcast Motion 1:3 (slice3; segments: 1) -> Seq Scan on repli_t2_pk -> Seq Scan on dist_t1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (11 rows) select * from repli_t2_pk where exists ( select 1 from dist_t1 where repli_t2_pk.a >= dist_t1.b); @@ -3585,7 +3580,7 @@ explain (costs off) select * from repli_t3_pk where exists ( select 1 from dist_ -> Materialize -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on dist_t1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (8 rows) select * from repli_t3_pk where exists ( select 1 from dist_t1 where repli_t3_pk.a >= dist_t1.b); @@ -3604,7 +3599,7 @@ explain (costs off) select * from repli_t4_pk where exists ( select 1 from dist_ -> Materialize -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on dist_t1 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (8 rows) select * from repli_t4_pk where exists ( select 1 from dist_t1 where repli_t4_pk.a >= dist_t1.b); diff --git a/src/test/regress/expected/join_gp_optimizer.out b/src/test/regress/expected/join_gp_optimizer.out index 2c80ee0add7..5b6bcbe1d9d 100644 --- a/src/test/regress/expected/join_gp_optimizer.out +++ b/src/test/regress/expected/join_gp_optimizer.out @@ -15,22 +15,22 @@ create table nhtest (i numeric(10, 2)) distributed by (i); insert into nhtest values(100000.22); insert into nhtest values(300000.19); explain select * from nhtest a join nhtest b using (i); - QUERY PLAN ------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=1 width=9) - -> Hash Join (cost=0.00..862.00 rows=1 width=9) + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=1 width=8) + -> Hash Join (cost=0.00..862.00 rows=1 width=8) Hash Cond: (a.i = b.i) - -> Seq Scan on nhtest a (cost=0.00..431.00 rows=1 width=9) - -> Hash (cost=431.00..431.00 rows=1 width=9) - -> Seq Scan on nhtest b (cost=0.00..431.00 rows=1 width=9) - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 + -> Seq Scan on nhtest a (cost=0.00..431.00 rows=1 width=8) + -> Hash (cost=431.00..431.00 rows=1 width=8) + -> Seq Scan on nhtest b (cost=0.00..431.00 rows=1 width=8) + Optimizer: GPORCA (7 rows) select * from nhtest a join nhtest b using (i); i ----------- - 100000.22 300000.19 + 100000.22 (2 rows) create temp table l(a int); @@ -94,7 +94,6 @@ set enable_hashjoin to off; set enable_mergejoin to on; set enable_nestloop to off; DROP TABLE IF EXISTS alpha; -NOTICE: table "alpha" does not exist, skipping DROP TABLE IF EXISTS theta; NOTICE: table "theta" does not exist, skipping CREATE TABLE alpha (i int, j int) distributed by (i); @@ -129,8 +128,8 @@ analyze t2; -- infer over equalities -- explain select count(*) from t1,t2 where t1.x = 100 and t1.x = t2.x; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------ Aggregate (cost=0.00..862.00 rows=1 width=8) -> Hash Join (cost=0.00..862.00 rows=1 width=1) Hash Cond: (t1.x = t2.x) @@ -141,7 +140,7 @@ explain select count(*) from t1,t2 where t1.x = 100 and t1.x = t2.x; -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on t2 (cost=0.00..431.00 rows=1 width=4) Filter: (x = 100) - Optimizer: Pivotal Optimizer (GPORCA) version 3.64.0 + Optimizer: GPORCA (11 rows) select count(*) from t1,t2 where t1.x = 100 and t1.x = t2.x; @@ -156,16 +155,15 @@ select count(*) from t1,t2 where t1.x = 100 and t1.x = t2.x; explain select * from t1,t2 where t1.x = 100 and t2.x >= t1.x; QUERY PLAN ---------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324039.56 rows=34 width=24) - -> Nested Loop (cost=0.00..1324039.56 rows=12 width=24) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324039.71 rows=34 width=24) + -> Nested Loop (cost=0.00..1324039.71 rows=12 width=24) Join Filter: (t2.x >= t1.x) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=12) -> Seq Scan on t1 (cost=0.00..431.00 rows=1 width=12) Filter: (x = 100) -> Seq Scan on t2 (cost=0.00..431.00 rows=34 width=12) - Settings: optimizer=on - Optimizer status: Pivotal Optimizer (GPORCA) version 2.39.2 -(9 rows) + Optimizer: GPORCA +(8 rows) select * from t1,t2 where t1.x = 100 and t2.x >= t1.x; x | y | z | x | y | z @@ -190,7 +188,7 @@ explain select * from t1,t2 where t1.x = 100 and t1.x = t2.y and t1.x <= t2.x; -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=12) -> Seq Scan on t2 (cost=0.00..431.00 rows=1 width=12) Filter: (y = 100) - Optimizer: Pivotal Optimizer (GPORCA) version 3.64.0 + Optimizer: GPORCA (11 rows) reset optimizer_segments; @@ -234,10 +232,10 @@ select count(*) from hjn_test, (select 3 as bar) foo where hjn_test.i = least (f select * from int4_tbl a join int4_tbl b on (a.f1 = (select f1 from int4_tbl c where c.f1=b.f1)); f1 | f1 -------------+------------- - 2147483647 | 2147483647 - 123456 | 123456 -2147483647 | -2147483647 0 | 0 + 2147483647 | 2147483647 + 123456 | 123456 -123456 | -123456 (5 rows) @@ -252,11 +250,13 @@ insert into part4_tbl values (-1), (0), (1), (123455), (123456), (123457); select * from part4_tbl a join part4_tbl b on (a.f1 = (select f1 from int4_tbl c where c.f1=b.f1)); +NOTICE: One or more columns in the following table(s) do not have statistics: part4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. f1 | f1 ---------+--------- - 0 | 0 - 123456 | 123456 -123456 | -123456 + 123456 | 123456 + 0 | 0 (3 rows) -- @@ -277,18 +277,18 @@ from tjoin1 left outer join (tjoin2 left outer join tjoin3 on tjoin2.id=tjoin3.id) on tjoin1.id=tjoin3.id; id | t | t ----+-----+----- - 3 | | - 3 | | 1 | 2-1 | 1-1 - 1 | 2-1 | 2-1 - 1 | 1-1 | 1-1 - 1 | 1-1 | 2-1 - 2 | | 1 | 2-1 | 1-1 1 | 2-1 | 2-1 + 1 | 2-1 | 2-1 + 1 | 1-1 | 1-1 1 | 1-1 | 1-1 1 | 1-1 | 2-1 + 1 | 1-1 | 2-1 + 2 | | 2 | | + 3 | | + 3 | | (12 rows) set enable_hashjoin to off; @@ -320,11 +320,11 @@ select count(*) from hjn_test, (select 3 as bar) foo where hjn_test.i = least (f select * from int4_tbl a join int4_tbl b on (a.f1 = (select f1 from int4_tbl c where c.f1=b.f1)); f1 | f1 -------------+------------- - 2147483647 | 2147483647 123456 | 123456 + -123456 | -123456 -2147483647 | -2147483647 0 | 0 - -123456 | -123456 + 2147483647 | 2147483647 (5 rows) reset enable_hashjoin; @@ -340,11 +340,11 @@ create table bar (c int, d int) distributed randomly; insert into foo select generate_series(1,10); insert into bar select generate_series(1,10); explain select a from foo where a<1 and a>1 and not exists (select c from bar where c=a); - QUERY PLAN ------------------------------------------------------- + QUERY PLAN +------------------------------------------ Result (cost=0.00..0.00 rows=0 width=4) One-Time Filter: false - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (3 rows) select a from foo where a<1 and a>1 and not exists (select c from bar where c=a); @@ -363,10 +363,10 @@ select * from foo where a not in (select c from bar where c <= 5); a | b ----+--- 7 | + 10 | + 9 | 6 | 8 | - 9 | - 10 | (5 rows) set enable_nestloop to off; @@ -483,8 +483,8 @@ insert into test_timestamp_t2 values(11 ,'2018-1-11'::timestamp); select * from test_timestamp_t1 t1 full outer join test_timestamp_t2 t2 on T1.id = T2.id and T1.field_dt = t2.field_tms; id | field_dt | id | field_tms ----+------------+----+-------------------------- - 10 | 01-10-2018 | 10 | Wed Jan 10 00:00:00 2018 11 | 01-11-2018 | 11 | Thu Jan 11 00:00:00 2018 + 10 | 01-10-2018 | 10 | Wed Jan 10 00:00:00 2018 (2 rows) -- test float type @@ -498,8 +498,8 @@ insert into test_float2 values(3, 10), (4, 20); select t1.id, t1.data, t2.id, t2.data from test_float1 t1, test_float2 t2 where t1.data = t2.data; id | data | id | data ----+------+----+------ - 2 | 20 | 4 | 20 1 | 10 | 3 | 10 + 2 | 20 | 4 | 20 (2 rows) -- test int type @@ -510,16 +510,16 @@ insert into test_int2 values(3, 10), (4, 20); select t1.id, t1.data, t2.id, t2.data from test_int1 t1, test_int2 t2 where t1.data = t2.data; id | data | id | data ----+------+----+------ - 1 | 10 | 3 | 10 2 | 20 | 4 | 20 + 1 | 10 | 3 | 10 (2 rows) -- Test to ensure that for full outer join on varchar columns, planner is successful in finding a sort operator in the catalog create table input_table(a varchar(30), b varchar(30)) distributed by (a); set enable_hashjoin = off; explain (costs off) select X.a from input_table X full join (select a from input_table) Y ON X.a = Y.a; - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +---------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Full Join Hash Cond: ((x.a)::text = (input_table.a)::text) @@ -536,9 +536,7 @@ drop schema pred cascade; reset search_path; -- github issue 5370 cases drop table if exists t5370; -NOTICE: table "t5370" does not exist, skipping drop table if exists t5370_2; -NOTICE: table "t5370_2" does not exist, skipping create table t5370(id int,name text) distributed by(id); insert into t5370 select i,i from generate_series(1,1000) i; create table t5370_2 as select * from t5370 distributed by (id); @@ -557,7 +555,7 @@ explain select * from t5370 a , t5370_2 b where a.name=b.name; -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..431.02 rows=334 width=7) Hash Key: b.name -> Seq Scan on t5370_2 b (cost=0.00..431.01 rows=334 width=7) - Optimizer: Pivotal Optimizer (GPORCA) version 2.70.2 + Optimizer: GPORCA (11 rows) drop table t5370; @@ -650,7 +648,7 @@ explain (costs off) select * from t1 left join t2 on (t1.a = t2.a) join t3 on (t -> Hash -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on t3 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (14 rows) select * from t1 left join t2 on (t1.a = t2.a) join t3 on (t1.b = t3.b) where (t2.a IS NULL OR (t1.c = t3.c)); @@ -673,7 +671,7 @@ explain (costs off) select * from t1 left join t2 on (t1.a = t2.a) join t3 on (t -> Seq Scan on t2 -> Hash -> Seq Scan on t3 - Optimizer: Pivotal Optimizer (GPORCA) version 3.75.0 + Optimizer: GPORCA (11 rows) select * from t1 left join t2 on (t1.a = t2.a) join t3 on (t1.b = t3.b) where (t2.a = t3.a); @@ -698,22 +696,22 @@ explain (costs off) select * from t1 left join t2 on (t1.a = t2.a) join t3 on (t -> Hash -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on t3 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (14 rows) select * from t1 left join t2 on (t1.a = t2.a) join t3 on (t1.b = t3.b) where (t2.a is distinct from t3.a); a | b | c | a | b | c | a | b | c ---+---+---+---+---+---+---+---+--- - 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 + 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 (2 rows) -- ensure plan has a filter over left outer join explain select * from t3 join (select t1.a t1a, t1.b t1b, t1.c t1c, t2.a t2a, t2.b t2b, t2.c t2c from t1 left join t2 on (t1.a = t2.a)) t on (t1a = t3.a) WHERE (t2a IS NULL OR (t1c = t3.a)); QUERY PLAN ----------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1293.15 rows=4 width=36) - -> Result (cost=0.00..1293.15 rows=2 width=36) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1293.16 rows=4 width=36) + -> Result (cost=0.00..1293.16 rows=2 width=36) Filter: ((t2.a IS NULL) OR (t1.c = t3.a)) -> Hash Right Join (cost=0.00..1293.15 rows=2 width=36) Hash Cond: (t2.a = t1.a) @@ -724,7 +722,7 @@ explain select * from t3 join (select t1.a t1a, t1.b t1b, t1.c t1c, t2.a t2a, t2 -> Seq Scan on t1 (cost=0.00..431.01 rows=334 width=12) -> Hash (cost=431.00..431.00 rows=1 width=12) -> Seq Scan on t3 (cost=0.00..431.00 rows=1 width=12) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) select * from t3 join (select t1.a t1a, t1.b t1b, t1.c t1c, t2.a t2a, t2.b t2b, t2.c t2c from t1 left join t2 on (t1.a = t2.a)) t on (t1a = t3.a) WHERE (t2a IS NULL OR (t1c = t3.a)); @@ -767,7 +765,7 @@ explain select * from (select t1.a t1a, t1.b t1b, t2.a t2a, t2.b t2b from t1 lef -> Hash (cost=431.00..431.00 rows=2 width=12) -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..431.00 rows=2 width=12) -> Seq Scan on t3 (cost=0.00..431.00 rows=1 width=12) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (28 rows) select * from (select t1.a t1a, t1.b t1b, t2.a t2a, t2.b t2b from t1 left join t2 on t1.a = t2.a) tt @@ -776,10 +774,10 @@ select * from (select t1.a t1a, t1.b t1b, t2.a t2a, t2.b t2b from t1 left join t join t3 t3_1 on tt1.t1b = t3_1.b and (tt1.t2a is NULL OR tt1.t1b = t3.b); t1a | t1b | t2a | t2b | a | b | c | t1a | t1b | t2a | t2b | a | b | c -----+-----+-----+-----+---+---+---+-----+-----+-----+-----+---+---+--- - 2 | 2 | 2 | 2 | | 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 - 2 | 2 | 2 | 2 | | 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 2 | 2 | 2 | 2 | 1 | 2 | 3 | 2 | 2 | 2 | 2 | 1 | 2 | 3 + 2 | 2 | 2 | 2 | | 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 2 | 2 | 2 | 2 | 1 | 2 | 3 | 2 | 2 | 2 | 2 | | 2 | 2 + 2 | 2 | 2 | 2 | | 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 (4 rows) -- test different join order enumeration methods @@ -795,8 +793,8 @@ set optimizer_join_order = greedy; select * from t1 join t2 on t1.a = t2.a join t3 on t1.b = t3.b; a | b | c | a | b | c | a | b | c ---+---+---+---+---+---+---+---+--- - 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 + 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 (2 rows) set optimizer_join_order = exhaustive; @@ -811,8 +809,8 @@ set optimizer_join_order = exhaustive2; select * from t1 join t2 on t1.a = t2.a join t3 on t1.b = t3.b; a | b | c | a | b | c | a | b | c ---+---+---+---+---+---+---+---+--- - 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 + 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 (2 rows) reset optimizer_join_order; @@ -848,16 +846,16 @@ set enable_bitmapscan = 0; explain select tenk1.unique2 >= 0 from tenk1 left join tenk2 on true limit 1; QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Limit (cost=0.00..1885517.36 rows=1 width=1) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1885517.36 rows=1 width=1) - -> Limit (cost=0.00..1885517.36 rows=1 width=1) - -> Nested Loop Left Join (cost=0.00..1885484.02 rows=33336667 width=4) + Limit (cost=0.00..1885524.86 rows=1 width=1) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1885524.86 rows=1 width=1) + -> Limit (cost=0.00..1885524.86 rows=1 width=1) + -> Nested Loop Left Join (cost=0.00..1885491.53 rows=33336667 width=4) Join Filter: true -> Seq Scan on tenk1 (cost=0.00..431.51 rows=3334 width=4) -> Materialize (cost=0.00..431.70 rows=10000 width=1) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.69 rows=10000 width=1) - -> Seq Scan on tenk2 (cost=0.00..431.50 rows=3334 width=1) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + -> Seq Scan on tenk2 (cost=0.00..431.51 rows=3334 width=1) + Optimizer: GPORCA (10 rows) select tenk1.unique2 >= 0 from tenk1 left join tenk2 on true limit 1; @@ -913,7 +911,7 @@ explain select * from generate_series(1, 5) g left join trep_join_gp on g = trep -> Materialize (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on thash_join_gp (cost=0.00..1.01 rows=1 width=8) Optimizer: Postgres query optimizer -(9 rows) +(10 rows) select * from generate_series(1, 5) g left join trep_join_gp on g = trep_join_gp.c1 join thash_join_gp on true; g | c1 | c2 | c1 | c2 @@ -951,8 +949,8 @@ select * from generate_series(1, 5) g left join thash_join_gp on g = thash_join_ g | c1 | c2 ---+----+---- 2 | 2 | 2 - 3 | | 4 | | + 3 | | 5 | | 1 | 1 | 1 (5 rows) @@ -976,10 +974,10 @@ explain select * from generate_series(1, 5) g left join thash_join_gp on g = tha select * from generate_series(1, 5) g left join thash_join_gp on g = thash_join_gp.c2; g | c1 | c2 ---+----+---- + 1 | 1 | 1 2 | 2 | 2 - 3 | | 4 | | - 1 | 1 | 1 + 3 | | 5 | | (5 rows) @@ -1003,9 +1001,9 @@ select * from generate_series(1, 5) g left join trand_join_gp on g = trand_join_ g | c1 | c2 ---+----+---- 1 | | + 4 | | 2 | | 3 | | - 4 | | 5 | | (5 rows) @@ -1028,10 +1026,10 @@ explain select * from generate_series(1, 5) g full join trand_join_gp on g = tra select * from generate_series(1, 5) g full join trand_join_gp on g = trand_join_gp.c1; g | c1 | c2 ---+----+---- - 1 | | + 4 | | 2 | | 3 | | - 4 | | + 1 | | 5 | | (5 rows) @@ -1063,24 +1061,24 @@ select * from trep_join_gp left join thash_join_gp using (c1); explain select * from trep_join_gp left join trand_join_gp using (c1); QUERY PLAN ---------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=1.03..2.13 rows=4 width=12) - -> Hash Left Join (cost=1.03..2.13 rows=2 width=12) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.04..2.15 rows=3 width=12) + -> Hash Left Join (cost=1.04..2.11 rows=1 width=12) Hash Cond: (trep_join_gp.c1 = trand_join_gp.c1) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=0.00..1.06 rows=2 width=8) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=0.00..1.05 rows=1 width=8) Hash Key: trep_join_gp.c1 -> Seq Scan on trep_join_gp (cost=0.00..1.02 rows=2 width=8) - -> Hash (cost=1.02..1.02 rows=1 width=8) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.02 rows=1 width=8) + -> Hash (cost=1.03..1.03 rows=1 width=8) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.03 rows=1 width=8) Hash Key: trand_join_gp.c1 - -> Seq Scan on trand_join_gp (cost=0.00..1.00 rows=1 width=8) + -> Seq Scan on trand_join_gp (cost=0.00..1.01 rows=1 width=8) Optimizer: Postgres query optimizer (11 rows) select * from trep_join_gp left join trand_join_gp using (c1); c1 | c2 | c2 ----+----+---- - 2 | 2 | 1 | 1 | + 2 | 2 | (2 rows) explain select * from trep1_join_gp join thash_join_gp using (c1); @@ -1151,12 +1149,12 @@ explain select * from (t_joinsize_1 join t_joinsize_2 on t_joinsize_1.c2 = t_joi -> Hash Join (cost=0.00..862.10 rows=200 width=12) Hash Cond: (t_joinsize_1.c1 = t_joinsize_3.c) -> Dynamic Seq Scan on t_joinsize_1 (cost=0.00..431.01 rows=400 width=8) - Number of partitions to scan: 6 + Number of partitions to scan: 6 (out of 6) -> Hash (cost=431.00..431.00 rows=34 width=4) -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..431.00 rows=34 width=4) Hash Key: t_joinsize_3.c -> Seq Scan on t_joinsize_3 (cost=0.00..431.00 rows=34 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (15 rows) drop table t_joinsize_1; @@ -1188,7 +1186,7 @@ join t_randomly_dist_table on t_subquery_general.a = t_randomly_dist_table.c; -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) Hash Key: t_randomly_dist_table.c -> Seq Scan on t_randomly_dist_table (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) version 3.77.0 + Optimizer: GPORCA (13 rows) drop table t_randomly_dist_table; @@ -1211,19 +1209,19 @@ insert into t2_lateral_limit values (2, 2); insert into t2_lateral_limit values (3, 3); explain select * from t1_lateral_limit as t1 cross join lateral (select ((c).x+t2.b) as n from t2_lateral_limit as t2 order by n limit 1)s; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Nested Loop (cost=10000000001.06..10000000002.12 rows=4 width=41) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=37) - -> Seq Scan on t1_lateral_limit t1 (cost=0.00..1.01 rows=1 width=37) - -> Materialize (cost=1.06..1.08 rows=1 width=4) - -> Limit (cost=1.06..1.06 rows=1 width=4) - -> Sort (cost=1.06..1.06 rows=1 width=4) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------- + Nested Loop (cost=10000003406.25..10159073271.08 rows=46700 width=44) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..812.33 rows=46700 width=40) + -> Seq Scan on t1_lateral_limit t1 (cost=0.00..189.67 rows=15567 width=40) + -> Materialize (cost=3406.25..3406.26 rows=1 width=4) + -> Limit (cost=3406.25..3406.25 rows=1 width=4) + -> Sort (cost=3406.25..3621.50 rows=86100 width=4) Sort Key: (((t1.c).x + t2.b)) - -> Result (cost=0.00..1.05 rows=1 width=4) - -> Materialize (cost=0.00..1.03 rows=1 width=4) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=4) - -> Seq Scan on t2_lateral_limit t2 (cost=0.00..1.01 rows=1 width=4) + -> Result (cost=0.00..2975.75 rows=86100 width=4) + -> Materialize (cost=0.00..1899.50 rows=86100 width=4) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1469.00 rows=86100 width=4) + -> Seq Scan on t2_lateral_limit t2 (cost=0.00..321.00 rows=28700 width=4) Optimizer: Postgres query optimizer (12 rows) @@ -1276,18 +1274,18 @@ select * from t1_lateral_limit as t1 cross join lateral -- may add motions in the subquery's plan). explain select * from t1_lateral_limit t1 cross join lateral (select (c).x+t2.a, sum(t2.a+t2.b) from t2_lateral_limit t2 group by (c).x+t2.a)x; - QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Nested Loop (cost=10000000001.06..10000000002.12 rows=4 width=49) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=37) - -> Seq Scan on t1_lateral_limit t1 (cost=0.00..1.01 rows=1 width=37) - -> Materialize (cost=1.05..1.08 rows=1 width=12) - -> HashAggregate (cost=1.05..1.07 rows=1 width=12) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Nested Loop (cost=10000003621.50..10170175612.33 rows=46700000 width=52) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..812.33 rows=46700 width=40) + -> Seq Scan on t1_lateral_limit t1 (cost=0.00..189.67 rows=15567 width=40) + -> Materialize (cost=3621.50..3639.00 rows=1000 width=12) + -> HashAggregate (cost=3621.50..3634.00 rows=1000 width=12) Group Key: ((t1.c).x + t2.a) - -> Result (cost=0.00..1.05 rows=1 width=12) - -> Materialize (cost=0.00..1.03 rows=1 width=8) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=8) - -> Seq Scan on t2_lateral_limit t2 (cost=0.00..1.01 rows=1 width=8) + -> Result (cost=0.00..2975.75 rows=86100 width=12) + -> Materialize (cost=0.00..1899.50 rows=86100 width=8) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1469.00 rows=86100 width=8) + -> Seq Scan on t2_lateral_limit t2 (cost=0.00..321.00 rows=28700 width=8) Optimizer: Postgres query optimizer (11 rows) @@ -1295,8 +1293,8 @@ select * from t1_lateral_limit t1 cross join lateral (select (c).x+t2.a, sum(t2.a+t2.b) from t2_lateral_limit t2 group by (c).x+t2.a)x; a | b | c | ?column? | sum ---+---+-------+----------+----- - 1 | 1 | (1,1) | 4 | 6 1 | 1 | (1,1) | 3 | 4 + 1 | 1 | (1,1) | 4 | 6 1 | 2 | (2,2) | 5 | 6 1 | 2 | (2,2) | 4 | 4 (4 rows) @@ -1493,7 +1491,9 @@ reset enable_bitmapscan; --- Test that GUC enable_hashagg takes effect for SEMI join --- drop table if exists foo; +NOTICE: table "foo" does not exist, skipping drop table if exists bar; +NOTICE: table "bar" does not exist, skipping create table foo(a int) distributed by (a); create table bar(b int) distributed by (b); insert into foo select i from generate_series(1,10)i; @@ -1503,59 +1503,59 @@ analyze bar; set enable_hashagg to on; explain (costs off) select * from foo where exists (select 1 from bar where foo.a = bar.b); - QUERY PLAN ------------------------------------------- + QUERY PLAN +----------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join + -> Hash Right Semi Join Hash Cond: (foo.a = bar.b) - -> Seq Scan on foo - Filter: (NOT (a IS NULL)) + -> Seq Scan on bar -> Hash - -> Seq Scan on bar - Optimizer: Pivotal Optimizer (GPORCA) + -> Seq Scan on foo + Filter: (NOT (a IS NULL)) + Optimizer: GPORCA (8 rows) select * from foo where exists (select 1 from bar where foo.a = bar.b); a ---- - 10 - 9 + 2 3 - 7 4 - 5 + 7 8 1 - 2 + 5 6 + 9 + 10 (10 rows) set enable_hashagg to off; explain (costs off) select * from foo where exists (select 1 from bar where foo.a = bar.b); - QUERY PLAN ------------------------------------------- + QUERY PLAN +----------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join + -> Hash Right Semi Join Hash Cond: (foo.a = bar.b) - -> Seq Scan on foo - Filter: (NOT (a IS NULL)) + -> Seq Scan on bar -> Hash - -> Seq Scan on bar - Optimizer: Pivotal Optimizer (GPORCA) + -> Seq Scan on foo + Filter: (NOT (a IS NULL)) + Optimizer: GPORCA (8 rows) select * from foo where exists (select 1 from bar where foo.a = bar.b); a ---- - 1 2 3 4 - 5 - 6 7 8 + 1 + 5 + 6 9 10 (10 rows) @@ -1655,18 +1655,18 @@ on (coalesce(t.id1) = tq_all.id1 and t.id2 = tq_all.id2) ; -----+-----+-----+-----+-----+----- 2 | 2 | 2 | 2 | 2 | 2 2 | | | | | - | 1 | | | | | 2 | | | | - | | | 2 | | - | | | 1 | | - | | 2 | | | + 1 | | | | | | | 1 | | | - | | | | | 2 - | | | | | 1 + | | 2 | | | + | | | 2 | | + | | | | 1 | | | | | 2 | + | | | | | 2 + | 1 | | | | 1 | 1 | 1 | 1 | 1 | 1 - 1 | | | | | - | | | | 1 | + | | | 1 | | + | | | | | 1 (14 rows) drop table t_issue_10315; @@ -1683,7 +1683,7 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=12) -> Seq Scan on foojoinpruning (cost=0.00..431.00 rows=1 width=12) Filter: (b > 300) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on fooJoinPruning.c=barJoinPruning.p where fooJoinPruning.b>300; @@ -1692,7 +1692,7 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=12) -> Seq Scan on foojoinpruning (cost=0.00..431.00 rows=1 width=12) Filter: (b > 300) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) -- Unique key of inner relation ie 'p' is present in the join condition and is equal to a column from outer relation and filter contains subquery-- @@ -1707,7 +1707,7 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on -> Hash (cost=431.00..431.00 rows=1 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on barjoinpruning (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on fooJoinPruning.c=barJoinPruning.p where fooJoinPruning.b>300 and fooJoinPruning.c > ANY (select barJoinPruning.q from barJoinPruning ); @@ -1720,7 +1720,7 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on -> Materialize (cost=0.00..431.00 rows=1 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on barjoinpruning (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) -- Unique key of inner relation ie 'p' is present in the join condition and is equal to a column from outer relation and filter contains corelated subquery referencing outer relation column-- @@ -1737,7 +1737,7 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on -> Limit (cost=0.00..431.00 rows=1 width=1) -> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=1) -> Seq Scan on barjoinpruning (cost=0.00..431.00 rows=1 width=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) drop table fooJoinPruning; @@ -1754,7 +1754,7 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=28) -> Seq Scan on foojoinpruning (cost=0.00..431.00 rows=1 width=28) Filter: ((e > 300) AND (f <> 10)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on fooJoinPruning.g=barJoinPruning.p and fooJoinPruning.a=barJoinPruning.q where fooJoinPruning.e >300 and fooJoinPruning.f<>10; @@ -1763,7 +1763,7 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=28) -> Seq Scan on foojoinpruning (cost=0.00..431.00 rows=1 width=28) Filter: ((e > 300) AND (f <> 10)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on fooJoinPruning.g=barJoinPruning.p and barJoinPruning.q=100 where fooJoinPruning.e >300 and fooJoinPruning.f<>10; @@ -1772,7 +1772,7 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=28) -> Seq Scan on foojoinpruning (cost=0.00..431.00 rows=1 width=28) Filter: ((e > 300) AND (f <> 10)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) -- Unique key set of inner relation ie 'p,r,s' is present in the join condition and is equal to a column from outer relation or is a constant -- @@ -1782,7 +1782,7 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=28) -> Seq Scan on foojoinpruning (cost=0.00..431.00 rows=1 width=28) Filter: (f <> 10) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on fooJoinPruning.a=barJoinPruning.p and fooJoinPruning.b=barJoinPruning.r and fooJoinPruning.c=barJoinPruning.s and barJoinPruning.s=barJoinPruning.t where fooJoinPruning.b>300; @@ -1791,7 +1791,7 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..6.00 rows=1 width=28) -> Index Scan using idx1 on foojoinpruning (cost=0.00..6.00 rows=1 width=28) Index Cond: (b > 300) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (4 rows) -- Unique key of inner relation ie 'p' is present in the join condition and is equal to a column from outer relation and filter contains subquery -- @@ -1811,7 +1811,7 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on -> Seq Scan on barjoinpruning (cost=0.00..431.00 rows=1 width=4) -> Index Scan using idx2 on foojoinpruning (cost=0.00..6.00 rows=1 width=28) Index Cond: (c = barjoinpruning.t) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (14 rows) explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on fooJoinPruning.g=barJoinPruning.p and fooJoinPruning.a=barJoinPruning.q where fooJoinPruning.c > ANY (select barJoinPruning.t from barJoinPruning ); @@ -1828,15 +1828,15 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on -> Seq Scan on barjoinpruning (cost=0.00..431.00 rows=1 width=4) -> Index Scan using idx2 on foojoinpruning (cost=0.00..6.00 rows=1 width=28) Index Cond: (c > barjoinpruning.t) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) -- Unique key of inner relation ie 'p' is present in the join condition and is equal to a column from outer relation and filter contains corelated subquery referencing outer relation column -- explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on fooJoinPruning.g=barJoinPruning.p and fooJoinPruning.a=barJoinPruning.q where fooJoinPruning.e in (select fooJoinPruning.f from barJoinPruning); QUERY PLAN ------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.16 rows=1 width=28) - -> Nested Loop Semi Join (cost=0.00..1324032.16 rows=1 width=28) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.17 rows=1 width=28) + -> Nested Loop Semi Join (cost=0.00..1324032.17 rows=1 width=28) Join Filter: true -> Seq Scan on foojoinpruning (cost=0.00..431.00 rows=1 width=28) Filter: (e = f) @@ -1845,7 +1845,7 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on -> Limit (cost=0.00..431.00 rows=1 width=1) -> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=1) -> Seq Scan on barjoinpruning (cost=0.00..431.00 rows=1 width=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) -- Prunable Left join present in subquery -- @@ -1862,7 +1862,7 @@ explain select t1JoinPruning.n from t1JoinPruning where t1JoinPruning.m in (sele -> Seq Scan on foojoinpruning (cost=0.00..431.00 rows=1 width=4) -> Index Scan using t1joinpruning_pkey on t1joinpruning (cost=0.00..6.00 rows=1 width=4) Index Cond: (m = foojoinpruning.a) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) drop table fooJoinPruning; @@ -1880,7 +1880,7 @@ EXPLAIN select t1.a from t1 left join (t2 join t3 on true) on t2.a=t1.a and t3.a ------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on t1 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) -- inner table has new left join @@ -1889,7 +1889,7 @@ EXPLAIN select t1.* from t1 left join (t2 left join t3 on t3.a=t2.b) on t2.a=t1. ------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on t1 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) -- inner table is a derived table @@ -1905,7 +1905,7 @@ select t1.* from t1 left join ------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on t1 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) drop table t1; @@ -1930,7 +1930,7 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on -> Index Scan using idx2 on barjoinpruning (cost=0.00..6.00 rows=1 width=1) Index Cond: (p = foojoinpruning.b) Filter: (q <> 10) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) -- Unique key of inner relation ie 'p' is present in the join condition and is equal to a column from outer relation but output columns are from inner relation -- @@ -1946,15 +1946,15 @@ explain select barJoinPruning.* from fooJoinPruning left join barJoinPruning on Filter: (b > 1000) -> Index Scan using idx2 on barjoinpruning (cost=0.00..6.00 rows=1 width=12) Index Cond: ((p = foojoinpruning.b) AND (p > 1000)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) -- Subquery present in join condition explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on barJoinPruning.p in (select fooJoinPruning.b from fooJoinPruning ) where fooJoinPruning.c>100; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1330176.22 rows=2 width=12) - -> Nested Loop Left Join (cost=0.00..1330176.22 rows=1 width=12) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1330176.27 rows=2 width=12) + -> Nested Loop Left Join (cost=0.00..1330176.27 rows=1 width=12) Join Filter: true -> Seq Scan on foojoinpruning foojoinpruning_1 (cost=0.00..431.00 rows=1 width=12) Filter: (c > 100) @@ -1971,7 +1971,7 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on -> Seq Scan on foojoinpruning (cost=0.00..431.00 rows=1 width=4) -> Index Scan using idx2 on barjoinpruning (cost=0.00..6.00 rows=1 width=1) Index Cond: (p = foojoinpruning.b) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (19 rows) -- Unique key of inner relation ie 'p' is present in the join condition and is equal to a column from outer relation and filter contains corelated subquery referencing inner relation column-- @@ -1994,7 +1994,7 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on -> Index Scan using idx2 on barjoinpruning (cost=0.00..6.00 rows=1 width=1) Index Cond: (p = foojoinpruning_1.c) Filter: (foojoinpruning_1.b = q) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (17 rows) explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on fooJoinPruning.c=barJoinPruning.p where fooJoinPruning.b in (select barJoinPruning.q from fooJoinPruning where fooJoinPruning.a=barJoinPruning.r); @@ -2015,7 +2015,7 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on Filter: ((foojoinpruning.b = q) AND (NOT (r IS NULL))) -> Hash (cost=431.00..431.00 rows=1 width=4) -> Seq Scan on foojoinpruning foojoinpruning_1 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (16 rows) drop table fooJoinPruning; @@ -2027,8 +2027,8 @@ create table barJoinPruning (p int, q int, r int,s int,t int,u int,v int,constra explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on barJoinPruning.p>100 and barJoinPruning.q>200 where fooJoinPruning.b>300; QUERY PLAN --------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..453632.48 rows=2 width=28) - -> Nested Loop Left Join (cost=0.00..453632.48 rows=1 width=28) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..453632.49 rows=2 width=28) + -> Nested Loop Left Join (cost=0.00..453632.49 rows=1 width=28) Join Filter: true -> Index Scan using idx1 on foojoinpruning (cost=0.00..6.00 rows=1 width=28) Index Cond: (b > 300) @@ -2036,7 +2036,7 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..6.00 rows=1 width=1) -> Index Scan using idx3 on barjoinpruning (cost=0.00..6.00 rows=1 width=1) Index Cond: ((p > 100) AND (q > 200)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) -- OR operator is present in join condition -- @@ -2050,21 +2050,21 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on -> Materialize (cost=0.00..431.00 rows=1 width=12) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=12) -> Seq Scan on barjoinpruning (cost=0.00..431.00 rows=1 width=12) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on fooJoinPruning.a=barJoinPruning.p or fooJoinPruning.b=barJoinPruning.q where fooJoinPruning.b>300; QUERY PLAN ------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..888833.66 rows=1 width=28) - -> Nested Loop Left Join (cost=0.00..888833.66 rows=1 width=28) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..888833.67 rows=1 width=28) + -> Nested Loop Left Join (cost=0.00..888833.67 rows=1 width=28) Join Filter: ((foojoinpruning.a = barjoinpruning.p) OR (foojoinpruning.b = barjoinpruning.q)) -> Index Scan using idx1 on foojoinpruning (cost=0.00..6.00 rows=1 width=28) Index Cond: (b > 300) -> Materialize (cost=0.00..431.00 rows=1 width=8) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on barjoinpruning (cost=0.00..431.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) -- Not all unique keys of inner relation are equal to a constant or column from outer relation @@ -2078,12 +2078,12 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on -> Index Scan using idx4 on barjoinpruning (cost=0.00..6.00 rows=1 width=1) Index Cond: (p = foojoinpruning.a) Filter: (r = s) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on fooJoinPruning.a=barJoinPruning.p and fooJoinPruning.b=barJoinPruning.r and barJoinPruning.s=barJoinPruning.t where fooJoinPruning.b>300; - QUERY PLAN ----------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..12.00 rows=2 width=28) -> Nested Loop Left Join (cost=0.00..12.00 rows=1 width=28) Join Filter: true @@ -2092,7 +2092,7 @@ explain select fooJoinPruning.* from fooJoinPruning left join barJoinPruning on -> Index Scan using idx4 on barjoinpruning (cost=0.00..6.00 rows=1 width=1) Index Cond: ((p = foojoinpruning.a) AND (r = foojoinpruning.b) AND (r > 300)) Filter: (s = t) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) drop table fooJoinPruning; @@ -2189,8 +2189,6 @@ select foo.b,foo.c from foo left join bar on foo.a=bar.a union all select bar.b,bar.c from bar left join foo on foo.a=bar.a; b | c ---+---- - 1 | 10 - 1 | 10 1 | 10 2 | 20 2 | 30 @@ -2198,6 +2196,8 @@ select bar.b,bar.c from bar left join foo on foo.a=bar.a; 2 | 20 | 3 | + 1 | 10 + 1 | 10 2 | 30 | 1 | 10 @@ -2296,15 +2296,15 @@ select bar.b,bar.c from bar left join foo on foo.a=bar.a; Group Key: foo.b, foo.c -> Sort Sort Key: foo.b, foo.c - -> Hash Anti Join + -> Hash Right Anti Join Hash Cond: ((NOT (foo.b IS DISTINCT FROM bar.b)) AND (NOT (foo.c IS DISTINCT FROM bar.c))) -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: foo.b, foo.c - -> Seq Scan on foo + Hash Key: bar.b, bar.c + -> Seq Scan on bar -> Hash -> Redistribute Motion 3:3 (slice3; segments: 3) - Hash Key: bar.b, bar.c - -> Seq Scan on bar + Hash Key: foo.b, foo.c + -> Seq Scan on foo Optimizer: GPORCA (15 rows) @@ -2392,11 +2392,11 @@ select foo.b,foo.c from foo left join bar on foo.a=bar.a union select bar.b,foo.c from bar left join foo on foo.a=bar.a; b | c ---+---- + 2 | 10 1 | 10 1 | 30 2 | 20 | 20 - 2 | 10 2 | 30 3 | 30 | 3 @@ -2429,6 +2429,8 @@ select foo.b,foo.c from foo left join bar on foo.a=bar.a union all select bar.b,foo.c from bar left join foo on foo.a=bar.a; b | c ---+---- + 1 | 10 + 1 | 10 2 | 30 | 1 | 30 @@ -2439,8 +2441,6 @@ select bar.b,foo.c from bar left join foo on foo.a=bar.a; 2 | 10 | 20 3 | 30 - 1 | 10 - 1 | 10 (12 rows) -------------------------------------------------------------------------------- @@ -2565,10 +2565,10 @@ select foo.b,foo.c from foo left join bar on foo.a=bar.a except select bar.b,foo.c from bar left join foo on foo.a=bar.a; b | c ---+---- - 2 | 20 2 | 30 | 3 | + 2 | 20 (4 rows) -------------------------------------------------------------------------------- @@ -2611,12 +2611,12 @@ select foo.b,foo.c from foo left join bar on foo.a=bar.a except all select bar.b,foo.c from bar left join foo on foo.a=bar.a; b | c ---+---- + 1 | 10 + 2 | 20 2 | 30 2 | 30 | 3 | - 1 | 10 - 2 | 20 (6 rows) drop table foo; @@ -2687,14 +2687,14 @@ explain (costs off) select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a -> Hash -> Partition Selector (selector id: $0) -> Seq Scan on foo - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a; a1_pc | b1 | a | b -------+----+---+--- - 5 | 5 | 5 | 5 1 | 1 | 1 | 1 + 5 | 5 | 5 | 5 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 @@ -2713,7 +2713,7 @@ explain (costs off) select * from bar_PT1 right join foo on bar_PT1.b1 =foo.a; Number of partitions to scan: 6 (out of 6) -> Hash -> Seq Scan on foo - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) select * from bar_PT1 right join foo on bar_PT1.b1 =foo.a; @@ -2739,17 +2739,17 @@ explain (costs off) select * from bar_PT1 right join bar_PT3 on bar_PT1.a1_PC =b -> Partition Selector (selector id: $0) -> Dynamic Seq Scan on bar_pt3 Number of partitions to scan: 3 (out of 3) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) select * from bar_PT1 right join bar_PT3 on bar_PT1.a1_PC =bar_PT3.a3_PC; a1_pc | b1 | a3_pc | b3 -------+----+-------+---- 1 | 1 | 1 | 1 - 5 | 5 | 5 | 5 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 + 5 | 5 | 5 | 5 (5 rows) -- Outer table: Not a Partitioned table, Join Condition on Partition key: Yes, Result: DPE - No @@ -2763,23 +2763,23 @@ explain (costs off) select * from foo right join bar_PT1 on foo.a=bar_PT1.a1_PC; Number of partitions to scan: 6 (out of 6) -> Hash -> Seq Scan on foo - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) select * from foo right join bar_PT1 on foo.a=bar_PT1.a1_PC; a | b | a1_pc | b1 ---+---+-------+---- + 2 | 2 | 2 | 2 + 3 | 3 | 3 | 3 + 4 | 4 | 4 | 4 + | | 7 | 7 + | | 8 | 8 5 | 5 | 5 | 5 | | 6 | 6 | | 9 | 9 | | 10 | 10 | | 11 | 11 1 | 1 | 1 | 1 - 2 | 2 | 2 | 2 - 3 | 3 | 3 | 3 - 4 | 4 | 4 | 4 - | | 7 | 7 - | | 8 | 8 (11 rows) -- Right join with predicate on the column of non partitioned table in 'where clause'. @@ -2797,15 +2797,15 @@ explain (costs off) select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a -> Partition Selector (selector id: $0) -> Seq Scan on foo Filter: (a > 2) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a where foo.a>2; a1_pc | b1 | a | b -------+----+---+--- - 5 | 5 | 5 | 5 3 | 3 | 3 | 3 4 | 4 | 4 | 4 + 5 | 5 | 5 | 5 (3 rows) --Conjunction in join condition, Result: DPE - Yes @@ -2820,17 +2820,17 @@ explain (costs off) select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a -> Hash -> Partition Selector (selector id: $0) -> Seq Scan on foo - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a and bar_PT1.b1 =foo.b; a1_pc | b1 | a | b -------+----+---+--- + 5 | 5 | 5 | 5 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 1 | 1 | 1 | 1 - 5 | 5 | 5 | 5 (5 rows) explain (costs off) select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a and foo.b>2; @@ -2845,17 +2845,17 @@ explain (costs off) select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a -> Hash -> Partition Selector (selector id: $0) -> Seq Scan on foo - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a and foo.b>2; a1_pc | b1 | a | b -------+----+---+--- + 5 | 5 | 5 | 5 + | | 1 | 1 3 | 3 | 3 | 3 4 | 4 | 4 | 4 | | 2 | 2 - | | 1 | 1 - 5 | 5 | 5 | 5 (5 rows) -- Multiple Right Joins, DPE- Yes @@ -2879,7 +2879,7 @@ explain (costs off) select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a -> Hash -> Partition Selector (selector id: $0) -> Seq Scan on foo - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (18 rows) select * from bar_PT1 right join foo on bar_PT1.a1_PC =foo.a right join bar_PT2 on bar_PT1.a1_PC =bar_PT2.b2_PC; @@ -2911,7 +2911,7 @@ explain (costs off) select * from bar_List_PT1 right join foo on bar_List_PT1.a1 -> Hash -> Partition Selector (selector id: $0) -> Seq Scan on foo - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) select * from bar_List_PT1 right join foo on bar_List_PT1.a1_PC =foo.a; @@ -2937,7 +2937,7 @@ explain (costs off) select * from bar_List_PT1 right join bar_List_PT2 on bar_Li -> Partition Selector (selector id: $0) -> Dynamic Seq Scan on bar_list_pt2 Number of partitions to scan: 7 (out of 7) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) select * from bar_List_PT1 right join bar_List_PT2 on bar_List_PT1.a1_PC =bar_List_PT2.a2_PC; @@ -2945,16 +2945,16 @@ select * from bar_List_PT1 right join bar_List_PT2 on bar_List_PT1.a1_PC =bar_Li -------+----+-------+---- 1 | 1 | 1 | 1 12 | 12 | 12 | 12 - 2 | 2 | 2 | 2 - 3 | 3 | 3 | 3 - 4 | 4 | 4 | 4 - 7 | 7 | 7 | 7 - 8 | 8 | 8 | 8 5 | 5 | 5 | 5 6 | 6 | 6 | 6 9 | 9 | 9 | 9 10 | 10 | 10 | 10 11 | 11 | 11 | 11 + 2 | 2 | 2 | 2 + 3 | 3 | 3 | 3 + 4 | 4 | 4 | 4 + 7 | 7 | 7 | 7 + 8 | 8 | 8 | 8 (12 rows) -- Case-2 : Distribution colm <> Partition Key. @@ -2971,17 +2971,17 @@ explain (costs off) select * from bar_PT2 right join foo on bar_PT2.b2_PC =foo.a Number of partitions to scan: 6 (out of 6) -> Hash -> Seq Scan on foo - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) select * from bar_PT2 right join foo on bar_PT2.b2_PC =foo.a; a2 | b2_pc | a | b ----+-------+---+--- - 5 | 5 | 5 | 5 1 | 1 | 1 | 1 2 | 2 | 2 | 2 3 | 3 | 3 | 3 4 | 4 | 4 | 4 + 5 | 5 | 5 | 5 (5 rows) -- Outer,Inner table: Partitioned table, Join Condition on Partition key: Yes, Result: DPE - No @@ -3000,23 +3000,23 @@ explain (costs off) select * from bar_PT2 right join bar_PT1 on bar_PT2.b2_PC =b Hash Key: bar_pt2.b2_pc -> Dynamic Seq Scan on bar_pt2 Number of partitions to scan: 6 (out of 6) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) select * from bar_PT2 right join bar_PT1 on bar_PT2.b2_PC =bar_PT1.b1; a2 | b2_pc | a1_pc | b1 ----+-------+-------+---- + 2 | 2 | 2 | 2 + 3 | 3 | 3 | 3 + 4 | 4 | 4 | 4 + 7 | 7 | 7 | 7 + 8 | 8 | 8 | 8 1 | 1 | 1 | 1 5 | 5 | 5 | 5 6 | 6 | 6 | 6 9 | 9 | 9 | 9 10 | 10 | 10 | 10 11 | 11 | 11 | 11 - 2 | 2 | 2 | 2 - 3 | 3 | 3 | 3 - 4 | 4 | 4 | 4 - 7 | 7 | 7 | 7 - 8 | 8 | 8 | 8 (11 rows) drop table if exists foo; @@ -3048,7 +3048,7 @@ explain SELECT 1 FROM inverse WHERE NOT (cidr <<= ANY(SELECT * FROM inverse)); -> Result (cost=0.00..431.00 rows=1 width=9) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on inverse (cost=0.00..431.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (16 rows) SELECT 1 FROM inverse WHERE NOT (cidr <<= ANY(SELECT * FROM inverse)); @@ -3073,21 +3073,21 @@ set enable_nestloop to on; explain select * from foo_varchar left join bar_char on foo_varchar.a=bar_char.p; QUERY PLAN --------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.82 rows=2 width=16) - -> Nested Loop Left Join (cost=0.00..1324032.82 rows=1 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.83 rows=2 width=16) + -> Nested Loop Left Join (cost=0.00..1324032.83 rows=1 width=16) Join Filter: ((foo_varchar.a)::bpchar = bar_char.p) -> Seq Scan on foo_varchar (cost=0.00..431.00 rows=1 width=8) -> Materialize (cost=0.00..431.00 rows=1 width=8) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on bar_char (cost=0.00..431.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) select * from foo_varchar left join bar_char on foo_varchar.a=bar_char.p; a | p ------+------- - 1 | 1 2 | 2 + 1 | 1 3 | 3 (3 rows) @@ -3097,43 +3097,43 @@ select * from foo_varchar left join bar_char on foo_varchar.a=bar_char.p; explain select * from foo_varchar left join random_dis_char on foo_varchar.a=random_dis_char.y; QUERY PLAN --------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.50 rows=2 width=16) - -> Nested Loop Left Join (cost=0.00..1324032.50 rows=1 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.51 rows=2 width=16) + -> Nested Loop Left Join (cost=0.00..1324032.51 rows=1 width=16) Join Filter: ((foo_varchar.a)::bpchar = random_dis_char.y) -> Seq Scan on foo_varchar (cost=0.00..431.00 rows=1 width=8) -> Materialize (cost=0.00..431.00 rows=1 width=8) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on random_dis_char (cost=0.00..431.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) select * from foo_varchar left join random_dis_char on foo_varchar.a=random_dis_char.y; a | y ------+------- - 1 | 1 2 | 2 + 1 | 1 3 | 3 (3 rows) explain select * from bar_char left join random_dis_varchar on bar_char.p=random_dis_varchar.x; QUERY PLAN --------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.50 rows=2 width=16) - -> Nested Loop Left Join (cost=0.00..1324032.50 rows=1 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.51 rows=2 width=16) + -> Nested Loop Left Join (cost=0.00..1324032.51 rows=1 width=16) Join Filter: (bar_char.p = (random_dis_varchar.x)::bpchar) -> Seq Scan on bar_char (cost=0.00..431.00 rows=1 width=8) -> Materialize (cost=0.00..431.00 rows=1 width=8) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on random_dis_varchar (cost=0.00..431.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) select * from bar_char left join random_dis_varchar on bar_char.p=random_dis_varchar.x; p | x -------+------ - 1 | 1 2 | 2 3 | 3 + 1 | 1 (3 rows) -- check motion is added when performing a NL Inner Join between relations when @@ -3148,7 +3148,7 @@ explain select * from foo_varchar inner join bar_char on foo_varchar.a=bar_char. -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on foo_varchar (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on bar_char (cost=0.00..431.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) select * from foo_varchar inner join bar_char on foo_varchar.a=bar_char.p; @@ -3165,41 +3165,41 @@ select * from foo_varchar inner join bar_char on foo_varchar.a=bar_char.p; explain select * from foo_varchar inner join random_dis_char on foo_varchar.a=random_dis_char.y; QUERY PLAN --------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.47 rows=1 width=16) - -> Nested Loop (cost=0.00..1324032.47 rows=1 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.48 rows=1 width=16) + -> Nested Loop (cost=0.00..1324032.48 rows=1 width=16) Join Filter: ((foo_varchar.a)::bpchar = random_dis_char.y) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on random_dis_char (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on foo_varchar (cost=0.00..431.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) select * from foo_varchar inner join random_dis_char on foo_varchar.a=random_dis_char.y; a | y ------+------- - 1 | 1 2 | 2 + 1 | 1 3 | 3 (3 rows) explain select * from bar_char inner join random_dis_varchar on bar_char.p=random_dis_varchar.x; QUERY PLAN --------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.47 rows=1 width=16) - -> Nested Loop (cost=0.00..1324032.47 rows=1 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324032.48 rows=1 width=16) + -> Nested Loop (cost=0.00..1324032.48 rows=1 width=16) Join Filter: (bar_char.p = (random_dis_varchar.x)::bpchar) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on random_dis_varchar (cost=0.00..431.00 rows=1 width=8) -> Seq Scan on bar_char (cost=0.00..431.00 rows=1 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) select * from bar_char inner join random_dis_varchar on bar_char.p=random_dis_varchar.x; p | x -------+------ - 1 | 1 - 2 | 2 3 | 3 + 2 | 2 + 1 | 1 (3 rows) drop table foo_varchar; @@ -3214,7 +3214,9 @@ reset enable_nestloop; -- for "Left Semi Join with replicated outer table" ----------------------------------------------------------------- drop table if exists repli_t1; +NOTICE: table "repli_t1" does not exist, skipping drop table if exists dist_t1; +NOTICE: table "dist_t1" does not exist, skipping create table repli_t1 (a int) distributed replicated; insert into repli_t1 values(1); analyze repli_t1; @@ -3316,17 +3318,17 @@ explain (costs off) select * from dist_t1 where exists ( select 1 from repli_t1 select * from dist_t1 where exists ( select 1 from repli_t1 where repli_t1.a >= dist_t1.b); a | b ---+--- + 5 | 1 2 | 1 3 | 1 4 | 1 1 | 1 - 5 | 1 (5 rows) -- Both replicated table explain (costs off) select * from repli_t1 as t1 where exists ( select 1 from repli_t1 as t2 where t1.a >= t2.a); - QUERY PLAN ------------------------------------------------ + QUERY PLAN +------------------------------------------ Gather Motion 1:1 (slice1; segments: 1) -> Seq Scan on repli_t1 t1 Filter: (SubPlan 1) @@ -3384,11 +3386,11 @@ explain (costs off) select * from dist_t1 where exists ( select 1 from generate_ select * from dist_t1 where exists ( select 1 from generate_series(1, 5) univ_t where univ_t >= dist_t1.b); a | b ---+--- + 5 | 1 + 1 | 1 2 | 1 3 | 1 4 | 1 - 1 | 1 - 5 | 1 (5 rows) -- Outer - replicated, Inner - universal table @@ -3440,9 +3442,13 @@ select * from generate_series(1, 5) univ_t where exists ( select 1 from repli_t1 -- Explicitly defined primary key for replicated table --------------------------------------------------------- drop table if exists repli_t1_pk; +NOTICE: table "repli_t1_pk" does not exist, skipping drop table if exists repli_t2_pk; +NOTICE: table "repli_t2_pk" does not exist, skipping drop table if exists repli_t3_pk; +NOTICE: table "repli_t3_pk" does not exist, skipping drop table if exists repli_t4_pk; +NOTICE: table "repli_t4_pk" does not exist, skipping -- Outer - replicated, Inner - distributed table create table repli_t1_pk (a int, PRIMARY KEY(a)) distributed replicated; insert into repli_t1_pk values(1); diff --git a/src/test/regress/expected/join_optimizer.out b/src/test/regress/expected/join_optimizer.out index fd987628b10..d467fb1a189 100644 --- a/src/test/regress/expected/join_optimizer.out +++ b/src/test/regress/expected/join_optimizer.out @@ -49,66 +49,66 @@ SELECT * FROM J1_TBL AS tx; i | j | t ---+---+------- - 1 | 4 | one 2 | 3 | two 3 | 2 | three 4 | 1 | four - 5 | 0 | five - 6 | 6 | six 7 | 7 | seven 8 | 8 | eight - 0 | | zero | | null | 0 | zero + 5 | 0 | five + 6 | 6 | six + 1 | 4 | one + 0 | | zero (11 rows) SELECT * FROM J1_TBL tx; i | j | t ---+---+------- - 1 | 4 | one 2 | 3 | two 3 | 2 | three 4 | 1 | four - 5 | 0 | five - 6 | 6 | six 7 | 7 | seven 8 | 8 | eight - 0 | | zero | | null | 0 | zero + 5 | 0 | five + 6 | 6 | six + 1 | 4 | one + 0 | | zero (11 rows) SELECT * FROM J1_TBL AS t1 (a, b, c); a | b | c ---+---+------- - 1 | 4 | one + 5 | 0 | five + 6 | 6 | six 2 | 3 | two 3 | 2 | three 4 | 1 | four - 5 | 0 | five - 6 | 6 | six 7 | 7 | seven 8 | 8 | eight - 0 | | zero | | null | 0 | zero + 1 | 4 | one + 0 | | zero (11 rows) SELECT * FROM J1_TBL t1 (a, b, c); a | b | c ---+---+------- + 5 | 0 | five + 6 | 6 | six 1 | 4 | one + 0 | | zero 2 | 3 | two 3 | 2 | three 4 | 1 | four - 5 | 0 | five - 6 | 6 | six 7 | 7 | seven 8 | 8 | eight - 0 | | zero | | null | 0 | zero (11 rows) @@ -117,105 +117,105 @@ SELECT * FROM J1_TBL t1 (a, b, c), J2_TBL t2 (d, e); a | b | c | d | e ---+---+-------+---+---- - 1 | 4 | one | 1 | -1 + 2 | 3 | two | 5 | -5 + 2 | 3 | two | 5 | -5 + 2 | 3 | two | 2 | 2 + 2 | 3 | two | 3 | -3 + 2 | 3 | two | 2 | 4 + 2 | 3 | two | | + 2 | 3 | two | | 0 2 | 3 | two | 1 | -1 + 2 | 3 | two | 0 | + 3 | 2 | three | 5 | -5 + 3 | 2 | three | 5 | -5 + 3 | 2 | three | 2 | 2 + 3 | 2 | three | 3 | -3 + 3 | 2 | three | 2 | 4 + 3 | 2 | three | | + 3 | 2 | three | | 0 3 | 2 | three | 1 | -1 + 3 | 2 | three | 0 | + 4 | 1 | four | 5 | -5 + 4 | 1 | four | 5 | -5 + 4 | 1 | four | 2 | 2 + 4 | 1 | four | 3 | -3 + 4 | 1 | four | 2 | 4 + 4 | 1 | four | | + 4 | 1 | four | | 0 4 | 1 | four | 1 | -1 - 5 | 0 | five | 1 | -1 - 6 | 6 | six | 1 | -1 + 4 | 1 | four | 0 | + 7 | 7 | seven | 5 | -5 + 7 | 7 | seven | 5 | -5 + 7 | 7 | seven | 2 | 2 + 7 | 7 | seven | 3 | -3 + 7 | 7 | seven | 2 | 4 + 7 | 7 | seven | | + 7 | 7 | seven | | 0 7 | 7 | seven | 1 | -1 + 7 | 7 | seven | 0 | + 8 | 8 | eight | 5 | -5 + 8 | 8 | eight | 5 | -5 + 8 | 8 | eight | 2 | 2 + 8 | 8 | eight | 3 | -3 + 8 | 8 | eight | 2 | 4 + 8 | 8 | eight | | + 8 | 8 | eight | | 0 8 | 8 | eight | 1 | -1 - 0 | | zero | 1 | -1 + 8 | 8 | eight | 0 | + | | null | 5 | -5 + | | null | 5 | -5 + | | null | 2 | 2 + | | null | 3 | -3 + | | null | 2 | 4 + | | null | | + | | null | | 0 | | null | 1 | -1 + | | null | 0 | + | 0 | zero | 5 | -5 + | 0 | zero | 5 | -5 + | 0 | zero | 2 | 2 + | 0 | zero | 3 | -3 + | 0 | zero | 2 | 4 + | 0 | zero | | + | 0 | zero | | 0 | 0 | zero | 1 | -1 - 1 | 4 | one | 2 | 2 - 2 | 3 | two | 2 | 2 - 3 | 2 | three | 2 | 2 - 4 | 1 | four | 2 | 2 + | 0 | zero | 0 | 5 | 0 | five | 2 | 2 - 6 | 6 | six | 2 | 2 - 7 | 7 | seven | 2 | 2 - 8 | 8 | eight | 2 | 2 - 0 | | zero | 2 | 2 - | | null | 2 | 2 - | 0 | zero | 2 | 2 - 1 | 4 | one | 3 | -3 - 2 | 3 | two | 3 | -3 - 3 | 2 | three | 3 | -3 - 4 | 1 | four | 3 | -3 5 | 0 | five | 3 | -3 - 6 | 6 | six | 3 | -3 - 7 | 7 | seven | 3 | -3 - 8 | 8 | eight | 3 | -3 - 0 | | zero | 3 | -3 - | | null | 3 | -3 - | 0 | zero | 3 | -3 - 1 | 4 | one | 2 | 4 - 2 | 3 | two | 2 | 4 - 3 | 2 | three | 2 | 4 - 4 | 1 | four | 2 | 4 5 | 0 | five | 2 | 4 - 6 | 6 | six | 2 | 4 - 7 | 7 | seven | 2 | 4 - 8 | 8 | eight | 2 | 4 - 0 | | zero | 2 | 4 - | | null | 2 | 4 - | 0 | zero | 2 | 4 - 1 | 4 | one | 5 | -5 - 2 | 3 | two | 5 | -5 - 3 | 2 | three | 5 | -5 - 4 | 1 | four | 5 | -5 + 5 | 0 | five | | + 5 | 0 | five | | 0 + 5 | 0 | five | 1 | -1 + 5 | 0 | five | 0 | 5 | 0 | five | 5 | -5 - 6 | 6 | six | 5 | -5 - 7 | 7 | seven | 5 | -5 - 8 | 8 | eight | 5 | -5 - 0 | | zero | 5 | -5 - | | null | 5 | -5 - | 0 | zero | 5 | -5 - 1 | 4 | one | 5 | -5 - 2 | 3 | two | 5 | -5 - 3 | 2 | three | 5 | -5 - 4 | 1 | four | 5 | -5 5 | 0 | five | 5 | -5 - 6 | 6 | six | 5 | -5 - 7 | 7 | seven | 5 | -5 - 8 | 8 | eight | 5 | -5 - 0 | | zero | 5 | -5 - | | null | 5 | -5 - | 0 | zero | 5 | -5 - 1 | 4 | one | 0 | - 2 | 3 | two | 0 | - 3 | 2 | three | 0 | - 4 | 1 | four | 0 | - 5 | 0 | five | 0 | + 6 | 6 | six | 2 | 2 + 6 | 6 | six | 3 | -3 + 6 | 6 | six | 2 | 4 + 6 | 6 | six | | + 6 | 6 | six | | 0 + 6 | 6 | six | 1 | -1 6 | 6 | six | 0 | - 7 | 7 | seven | 0 | - 8 | 8 | eight | 0 | - 0 | | zero | 0 | - | | null | 0 | - | 0 | zero | 0 | + 6 | 6 | six | 5 | -5 + 6 | 6 | six | 5 | -5 + 1 | 4 | one | 2 | 2 + 1 | 4 | one | 3 | -3 + 1 | 4 | one | 2 | 4 1 | 4 | one | | - 2 | 3 | two | | - 3 | 2 | three | | - 4 | 1 | four | | - 5 | 0 | five | | - 6 | 6 | six | | - 7 | 7 | seven | | - 8 | 8 | eight | | - 0 | | zero | | - | | null | | - | 0 | zero | | 1 | 4 | one | | 0 - 2 | 3 | two | | 0 - 3 | 2 | three | | 0 - 4 | 1 | four | | 0 - 5 | 0 | five | | 0 - 6 | 6 | six | | 0 - 7 | 7 | seven | | 0 - 8 | 8 | eight | | 0 + 1 | 4 | one | 5 | -5 + 1 | 4 | one | 5 | -5 + 1 | 4 | one | 1 | -1 + 1 | 4 | one | 0 | + 0 | | zero | 2 | 2 + 0 | | zero | 3 | -3 + 0 | | zero | 2 | 4 + 0 | | zero | | 0 | | zero | | 0 - | | null | | 0 - | 0 | zero | | 0 + 0 | | zero | 5 | -5 + 0 | | zero | 5 | -5 + 0 | | zero | 1 | -1 + 0 | | zero | 0 | (99 rows) SELECT t1.a, t2.e @@ -223,13 +223,13 @@ SELECT t1.a, t2.e WHERE t1.a = t2.d; a | e ---+---- - 0 | 1 | -1 - 2 | 2 - 2 | 4 - 3 | -3 + 0 | 5 | -5 5 | -5 + 2 | 2 + 3 | -3 + 2 | 4 (7 rows) -- @@ -241,105 +241,105 @@ SELECT * FROM J1_TBL CROSS JOIN J2_TBL; i | j | t | i | k ---+---+-------+---+---- - 1 | 4 | one | 1 | -1 - 2 | 3 | two | 1 | -1 - 3 | 2 | three | 1 | -1 - 4 | 1 | four | 1 | -1 5 | 0 | five | 1 | -1 - 6 | 6 | six | 1 | -1 - 7 | 7 | seven | 1 | -1 - 8 | 8 | eight | 1 | -1 - 0 | | zero | 1 | -1 - | | null | 1 | -1 - | 0 | zero | 1 | -1 - 1 | 4 | one | 2 | 2 - 2 | 3 | two | 2 | 2 - 3 | 2 | three | 2 | 2 - 4 | 1 | four | 2 | 2 + 5 | 0 | five | 0 | + 5 | 0 | five | 5 | -5 + 5 | 0 | five | 5 | -5 5 | 0 | five | 2 | 2 - 6 | 6 | six | 2 | 2 - 7 | 7 | seven | 2 | 2 - 8 | 8 | eight | 2 | 2 - 0 | | zero | 2 | 2 - | | null | 2 | 2 - | 0 | zero | 2 | 2 - 1 | 4 | one | 3 | -3 - 2 | 3 | two | 3 | -3 - 3 | 2 | three | 3 | -3 - 4 | 1 | four | 3 | -3 5 | 0 | five | 3 | -3 - 6 | 6 | six | 3 | -3 - 7 | 7 | seven | 3 | -3 - 8 | 8 | eight | 3 | -3 - 0 | | zero | 3 | -3 - | | null | 3 | -3 - | 0 | zero | 3 | -3 - 1 | 4 | one | 2 | 4 - 2 | 3 | two | 2 | 4 - 3 | 2 | three | 2 | 4 - 4 | 1 | four | 2 | 4 5 | 0 | five | 2 | 4 - 6 | 6 | six | 2 | 4 - 7 | 7 | seven | 2 | 4 - 8 | 8 | eight | 2 | 4 - 0 | | zero | 2 | 4 - | | null | 2 | 4 - | 0 | zero | 2 | 4 - 1 | 4 | one | 5 | -5 - 2 | 3 | two | 5 | -5 - 3 | 2 | three | 5 | -5 - 4 | 1 | four | 5 | -5 - 5 | 0 | five | 5 | -5 + 5 | 0 | five | | + 5 | 0 | five | | 0 + 6 | 6 | six | 1 | -1 + 6 | 6 | six | 0 | 6 | 6 | six | 5 | -5 - 7 | 7 | seven | 5 | -5 - 8 | 8 | eight | 5 | -5 - 0 | | zero | 5 | -5 - | | null | 5 | -5 - | 0 | zero | 5 | -5 - 1 | 4 | one | 5 | -5 - 2 | 3 | two | 5 | -5 - 3 | 2 | three | 5 | -5 - 4 | 1 | four | 5 | -5 - 5 | 0 | five | 5 | -5 6 | 6 | six | 5 | -5 - 7 | 7 | seven | 5 | -5 - 8 | 8 | eight | 5 | -5 - 0 | | zero | 5 | -5 - | | null | 5 | -5 - | 0 | zero | 5 | -5 - 1 | 4 | one | 0 | + 6 | 6 | six | 2 | 2 + 6 | 6 | six | 3 | -3 + 6 | 6 | six | 2 | 4 + 6 | 6 | six | | + 6 | 6 | six | | 0 + 2 | 3 | two | 1 | -1 2 | 3 | two | 0 | - 3 | 2 | three | 0 | - 4 | 1 | four | 0 | - 5 | 0 | five | 0 | - 6 | 6 | six | 0 | - 7 | 7 | seven | 0 | - 8 | 8 | eight | 0 | - 0 | | zero | 0 | - | | null | 0 | - | 0 | zero | 0 | - 1 | 4 | one | | + 2 | 3 | two | 5 | -5 + 2 | 3 | two | 5 | -5 + 2 | 3 | two | 2 | 2 + 2 | 3 | two | 3 | -3 + 2 | 3 | two | 2 | 4 2 | 3 | two | | + 2 | 3 | two | | 0 + 3 | 2 | three | 1 | -1 + 3 | 2 | three | 0 | + 3 | 2 | three | 5 | -5 + 3 | 2 | three | 5 | -5 + 3 | 2 | three | 2 | 2 + 3 | 2 | three | 3 | -3 + 3 | 2 | three | 2 | 4 3 | 2 | three | | + 3 | 2 | three | | 0 + 4 | 1 | four | 1 | -1 + 4 | 1 | four | 0 | + 4 | 1 | four | 5 | -5 + 4 | 1 | four | 5 | -5 + 4 | 1 | four | 2 | 2 + 4 | 1 | four | 3 | -3 + 4 | 1 | four | 2 | 4 4 | 1 | four | | - 5 | 0 | five | | - 6 | 6 | six | | + 4 | 1 | four | | 0 + 7 | 7 | seven | 1 | -1 + 7 | 7 | seven | 0 | + 7 | 7 | seven | 5 | -5 + 7 | 7 | seven | 5 | -5 + 7 | 7 | seven | 2 | 2 + 7 | 7 | seven | 3 | -3 + 7 | 7 | seven | 2 | 4 7 | 7 | seven | | + 7 | 7 | seven | | 0 + 8 | 8 | eight | 1 | -1 + 8 | 8 | eight | 0 | + 8 | 8 | eight | 5 | -5 + 8 | 8 | eight | 5 | -5 + 8 | 8 | eight | 2 | 2 + 8 | 8 | eight | 3 | -3 + 8 | 8 | eight | 2 | 4 8 | 8 | eight | | - 0 | | zero | | + 8 | 8 | eight | | 0 + | | null | 1 | -1 + | | null | 0 | + | | null | 5 | -5 + | | null | 5 | -5 + | | null | 2 | 2 + | | null | 3 | -3 + | | null | 2 | 4 | | null | | + | | null | | 0 + | 0 | zero | 1 | -1 + | 0 | zero | 0 | + | 0 | zero | 5 | -5 + | 0 | zero | 5 | -5 + | 0 | zero | 2 | 2 + | 0 | zero | 3 | -3 + | 0 | zero | 2 | 4 | 0 | zero | | + | 0 | zero | | 0 + 1 | 4 | one | 1 | -1 + 1 | 4 | one | 0 | + 1 | 4 | one | 5 | -5 + 1 | 4 | one | 5 | -5 + 1 | 4 | one | 2 | 2 + 1 | 4 | one | 3 | -3 + 1 | 4 | one | 2 | 4 + 1 | 4 | one | | 1 | 4 | one | | 0 - 2 | 3 | two | | 0 - 3 | 2 | three | | 0 - 4 | 1 | four | | 0 - 5 | 0 | five | | 0 - 6 | 6 | six | | 0 - 7 | 7 | seven | | 0 - 8 | 8 | eight | | 0 + 0 | | zero | 1 | -1 + 0 | | zero | 0 | + 0 | | zero | 5 | -5 + 0 | | zero | 5 | -5 + 0 | | zero | 2 | 2 + 0 | | zero | 3 | -3 + 0 | | zero | 2 | 4 + 0 | | zero | | 0 | | zero | | 0 - | | null | | 0 - | 0 | zero | | 0 (99 rows) -- ambiguous column @@ -353,211 +353,211 @@ SELECT t1.i, k, t FROM J1_TBL t1 CROSS JOIN J2_TBL t2; i | k | t ---+----+------- - 1 | -1 | one - 2 | -1 | two - 3 | -1 | three - 4 | -1 | four 5 | -1 | five - 6 | -1 | six - 7 | -1 | seven - 8 | -1 | eight - 0 | -1 | zero - | -1 | null - | -1 | zero - 1 | 2 | one - 2 | 2 | two - 3 | 2 | three - 4 | 2 | four + 5 | | five + 5 | -5 | five + 5 | -5 | five 5 | 2 | five - 6 | 2 | six - 7 | 2 | seven - 8 | 2 | eight - 0 | 2 | zero - | 2 | null - | 2 | zero - 1 | -3 | one - 2 | -3 | two - 3 | -3 | three - 4 | -3 | four 5 | -3 | five - 6 | -3 | six - 7 | -3 | seven - 8 | -3 | eight - 0 | -3 | zero - | -3 | null - | -3 | zero - 1 | 4 | one - 2 | 4 | two - 3 | 4 | three - 4 | 4 | four 5 | 4 | five + 5 | | five + 5 | 0 | five + 6 | -1 | six + 6 | | six + 6 | -5 | six + 6 | -5 | six + 6 | 2 | six + 6 | -3 | six 6 | 4 | six - 7 | 4 | seven - 8 | 4 | eight - 0 | 4 | zero - | 4 | null - | 4 | zero - 1 | -5 | one + 6 | | six + 6 | 0 | six + 2 | -1 | two + 2 | | two 2 | -5 | two - 3 | -5 | three - 4 | -5 | four - 5 | -5 | five - 6 | -5 | six - 7 | -5 | seven - 8 | -5 | eight - 0 | -5 | zero - | -5 | null - | -5 | zero - 1 | -5 | one 2 | -5 | two - 3 | -5 | three - 4 | -5 | four - 5 | -5 | five - 6 | -5 | six - 7 | -5 | seven - 8 | -5 | eight - 0 | -5 | zero - | -5 | null - | -5 | zero - 1 | | one + 2 | 2 | two + 2 | -3 | two + 2 | 4 | two 2 | | two + 2 | 0 | two + 3 | -1 | three 3 | | three - 4 | | four - 5 | | five - 6 | | six - 7 | | seven - 8 | | eight - 0 | | zero - | | null - | | zero - 1 | | one - 2 | | two + 3 | -5 | three + 3 | -5 | three + 3 | 2 | three + 3 | -3 | three + 3 | 4 | three 3 | | three - 4 | | four - 5 | | five - 6 | | six - 7 | | seven - 8 | | eight - 0 | | zero - | | null - | | zero - 1 | 0 | one - 2 | 0 | two 3 | 0 | three + 4 | -1 | four + 4 | | four + 4 | -5 | four + 4 | -5 | four + 4 | 2 | four + 4 | -3 | four + 4 | 4 | four + 4 | | four 4 | 0 | four - 5 | 0 | five - 6 | 0 | six + 7 | -1 | seven + 7 | | seven + 7 | -5 | seven + 7 | -5 | seven + 7 | 2 | seven + 7 | -3 | seven + 7 | 4 | seven + 7 | | seven 7 | 0 | seven + 8 | -1 | eight + 8 | | eight + 8 | -5 | eight + 8 | -5 | eight + 8 | 2 | eight + 8 | -3 | eight + 8 | 4 | eight + 8 | | eight 8 | 0 | eight - 0 | 0 | zero + | -1 | null + | | null + | -5 | null + | -5 | null + | 2 | null + | -3 | null + | 4 | null + | | null | 0 | null - | 0 | zero -(99 rows) + | -1 | zero + | | zero + | -5 | zero + | -5 | zero + | 2 | zero + | -3 | zero + | 4 | zero + | | zero + | 0 | zero + 1 | -1 | one + 1 | | one + 1 | -5 | one + 1 | -5 | one + 1 | 2 | one + 1 | -3 | one + 1 | 4 | one + 1 | | one + 1 | 0 | one + 0 | -1 | zero + 0 | | zero + 0 | -5 | zero + 0 | -5 | zero + 0 | 2 | zero + 0 | -3 | zero + 0 | 4 | zero + 0 | | zero + 0 | 0 | zero +(99 rows) SELECT ii, tt, kk FROM (J1_TBL CROSS JOIN J2_TBL) AS tx (ii, jj, tt, ii2, kk); ii | tt | kk ----+-------+---- + 1 | one | -5 + 1 | one | -5 1 | one | -1 - 2 | two | -1 - 3 | three | -1 - 4 | four | -1 - 5 | five | -1 - 6 | six | -1 - 7 | seven | -1 - 8 | eight | -1 - 0 | zero | -1 - | null | -1 - | zero | -1 + 1 | one | 1 | one | 2 - 2 | two | 2 - 3 | three | 2 - 4 | four | 2 - 5 | five | 2 - 6 | six | 2 - 7 | seven | 2 - 8 | eight | 2 - 0 | zero | 2 - | null | 2 - | zero | 2 1 | one | -3 - 2 | two | -3 - 3 | three | -3 - 4 | four | -3 - 5 | five | -3 - 6 | six | -3 - 7 | seven | -3 - 8 | eight | -3 - 0 | zero | -3 - | null | -3 - | zero | -3 1 | one | 4 - 2 | two | 4 - 3 | three | 4 - 4 | four | 4 - 5 | five | 4 - 6 | six | 4 - 7 | seven | 4 - 8 | eight | 4 + 1 | one | + 1 | one | 0 + 0 | zero | -5 + 0 | zero | -5 + 0 | zero | -1 + 0 | zero | + 0 | zero | 2 + 0 | zero | -3 0 | zero | 4 - | null | 4 - | zero | 4 - 1 | one | -5 + 0 | zero | + 0 | zero | 0 2 | two | -5 - 3 | three | -5 - 4 | four | -5 - 5 | five | -5 - 6 | six | -5 - 7 | seven | -5 - 8 | eight | -5 - 0 | zero | -5 - | null | -5 - | zero | -5 - 1 | one | -5 2 | two | -5 - 3 | three | -5 - 4 | four | -5 - 5 | five | -5 - 6 | six | -5 - 7 | seven | -5 - 8 | eight | -5 - 0 | zero | -5 - | null | -5 - | zero | -5 - 1 | one | + 2 | two | -1 2 | two | - 3 | three | - 4 | four | - 5 | five | - 6 | six | - 7 | seven | - 8 | eight | - 0 | zero | - | null | - | zero | - 1 | one | + 2 | two | 2 + 2 | two | -3 + 2 | two | 4 2 | two | + 2 | two | 0 + 3 | three | -5 + 3 | three | -5 + 3 | three | -1 + 3 | three | + 3 | three | 2 + 3 | three | -3 + 3 | three | 4 3 | three | + 3 | three | 0 + 4 | four | -5 + 4 | four | -5 + 4 | four | -1 4 | four | - 5 | five | - 6 | six | + 4 | four | 2 + 4 | four | -3 + 4 | four | 4 + 4 | four | + 4 | four | 0 + 7 | seven | -5 + 7 | seven | -5 + 7 | seven | -1 + 7 | seven | + 7 | seven | 2 + 7 | seven | -3 + 7 | seven | 4 7 | seven | + 7 | seven | 0 + 8 | eight | -5 + 8 | eight | -5 + 8 | eight | -1 8 | eight | - 0 | zero | + 8 | eight | 2 + 8 | eight | -3 + 8 | eight | 4 + 8 | eight | + 8 | eight | 0 + | null | -5 + | null | -5 + | null | -1 + | null | + | null | 2 + | null | -3 + | null | 4 | null | + | null | 0 + | zero | -5 + | zero | -5 + | zero | -1 | zero | - 1 | one | 0 - 2 | two | 0 - 3 | three | 0 - 4 | four | 0 + | zero | 2 + | zero | -3 + | zero | 4 + | zero | + | zero | 0 + 5 | five | -5 + 5 | five | -5 + 5 | five | -1 + 5 | five | + 5 | five | 2 + 5 | five | -3 + 5 | five | 4 + 5 | five | 5 | five | 0 + 6 | six | -5 + 6 | six | -5 + 6 | six | -1 + 6 | six | + 6 | six | 2 + 6 | six | -3 + 6 | six | 4 + 6 | six | 6 | six | 0 - 7 | seven | 0 - 8 | eight | 0 - 0 | zero | 0 - | null | 0 - | zero | 0 (99 rows) SELECT tx.ii, tx.jj, tx.kk @@ -565,1002 +565,1002 @@ SELECT tx.ii, tx.jj, tx.kk AS tx (ii, jj, tt, ii2, kk); ii | jj | kk ----+----+---- - 1 | 4 | -1 - 2 | 3 | -1 - 3 | 2 | -1 - 4 | 1 | -1 + 5 | 0 | 2 + 5 | 0 | -3 + 5 | 0 | 4 + 5 | 0 | + 5 | 0 | 0 5 | 0 | -1 + 5 | 0 | + 5 | 0 | -5 + 5 | 0 | -5 + 6 | 6 | 2 + 6 | 6 | -3 + 6 | 6 | 4 + 6 | 6 | + 6 | 6 | 0 6 | 6 | -1 - 7 | 7 | -1 - 8 | 8 | -1 - 0 | | -1 - | | -1 - | 0 | -1 + 6 | 6 | + 6 | 6 | -5 + 6 | 6 | -5 1 | 4 | 2 - 2 | 3 | 2 - 3 | 2 | 2 - 4 | 1 | 2 - 5 | 0 | 2 - 6 | 6 | 2 - 7 | 7 | 2 - 8 | 8 | 2 - 0 | | 2 - | | 2 - | 0 | 2 1 | 4 | -3 - 2 | 3 | -3 - 3 | 2 | -3 - 4 | 1 | -3 - 5 | 0 | -3 - 6 | 6 | -3 - 7 | 7 | -3 - 8 | 8 | -3 - 0 | | -3 - | | -3 - | 0 | -3 1 | 4 | 4 - 2 | 3 | 4 - 3 | 2 | 4 - 4 | 1 | 4 - 5 | 0 | 4 - 6 | 6 | 4 - 7 | 7 | 4 - 8 | 8 | 4 - 0 | | 4 - | | 4 - | 0 | 4 + 1 | 4 | + 1 | 4 | 0 + 1 | 4 | -1 + 1 | 4 | 1 | 4 | -5 - 2 | 3 | -5 - 3 | 2 | -5 - 4 | 1 | -5 - 5 | 0 | -5 - 6 | 6 | -5 - 7 | 7 | -5 - 8 | 8 | -5 - 0 | | -5 - | | -5 - | 0 | -5 1 | 4 | -5 - 2 | 3 | -5 - 3 | 2 | -5 - 4 | 1 | -5 - 5 | 0 | -5 - 6 | 6 | -5 - 7 | 7 | -5 - 8 | 8 | -5 + 0 | | 2 + 0 | | -3 + 0 | | 4 + 0 | | + 0 | | 0 + 0 | | -1 + 0 | | 0 | | -5 - | | -5 - | 0 | -5 - 1 | 4 | + 0 | | -5 + 2 | 3 | 2 + 2 | 3 | -3 + 2 | 3 | 4 2 | 3 | - 3 | 2 | - 4 | 1 | - 5 | 0 | - 6 | 6 | - 7 | 7 | - 8 | 8 | - 0 | | - | | - | 0 | - 1 | 4 | + 2 | 3 | 0 + 2 | 3 | -1 2 | 3 | + 2 | 3 | -5 + 2 | 3 | -5 + 3 | 2 | 2 + 3 | 2 | -3 + 3 | 2 | 4 3 | 2 | - 4 | 1 | - 5 | 0 | - 6 | 6 | - 7 | 7 | - 8 | 8 | - 0 | | - | | - | 0 | - 1 | 4 | 0 - 2 | 3 | 0 3 | 2 | 0 + 3 | 2 | -1 + 3 | 2 | + 3 | 2 | -5 + 3 | 2 | -5 + 4 | 1 | 2 + 4 | 1 | -3 + 4 | 1 | 4 + 4 | 1 | 4 | 1 | 0 - 5 | 0 | 0 - 6 | 6 | 0 + 4 | 1 | -1 + 4 | 1 | + 4 | 1 | -5 + 4 | 1 | -5 + 7 | 7 | 2 + 7 | 7 | -3 + 7 | 7 | 4 + 7 | 7 | 7 | 7 | 0 + 7 | 7 | -1 + 7 | 7 | + 7 | 7 | -5 + 7 | 7 | -5 + 8 | 8 | 2 + 8 | 8 | -3 + 8 | 8 | 4 + 8 | 8 | 8 | 8 | 0 - 0 | | 0 + 8 | 8 | -1 + 8 | 8 | + 8 | 8 | -5 + 8 | 8 | -5 + | | 2 + | | -3 + | | 4 + | | | | 0 + | | -1 + | | + | | -5 + | | -5 + | 0 | 2 + | 0 | -3 + | 0 | 4 + | 0 | | 0 | 0 + | 0 | -1 + | 0 | + | 0 | -5 + | 0 | -5 (99 rows) SELECT * FROM J1_TBL CROSS JOIN J2_TBL a CROSS JOIN J2_TBL b; i | j | t | i | k | i | k ---+---+-------+---+----+---+---- - 1 | 4 | one | 1 | -1 | 1 | -1 - 1 | 4 | one | 1 | -1 | 2 | 2 - 1 | 4 | one | 1 | -1 | 3 | -3 - 1 | 4 | one | 1 | -1 | 2 | 4 - 1 | 4 | one | 1 | -1 | 5 | -5 - 1 | 4 | one | 1 | -1 | 5 | -5 - 1 | 4 | one | 1 | -1 | 0 | - 1 | 4 | one | 1 | -1 | | - 1 | 4 | one | 1 | -1 | | 0 - 2 | 3 | two | 1 | -1 | 1 | -1 - 2 | 3 | two | 1 | -1 | 2 | 2 - 2 | 3 | two | 1 | -1 | 3 | -3 - 2 | 3 | two | 1 | -1 | 2 | 4 - 2 | 3 | two | 1 | -1 | 5 | -5 2 | 3 | two | 1 | -1 | 5 | -5 - 2 | 3 | two | 1 | -1 | 0 | - 2 | 3 | two | 1 | -1 | | - 2 | 3 | two | 1 | -1 | | 0 - 3 | 2 | three | 1 | -1 | 1 | -1 - 3 | 2 | three | 1 | -1 | 2 | 2 - 3 | 2 | three | 1 | -1 | 3 | -3 - 3 | 2 | three | 1 | -1 | 2 | 4 - 3 | 2 | three | 1 | -1 | 5 | -5 3 | 2 | three | 1 | -1 | 5 | -5 - 3 | 2 | three | 1 | -1 | 0 | - 3 | 2 | three | 1 | -1 | | - 3 | 2 | three | 1 | -1 | | 0 - 4 | 1 | four | 1 | -1 | 1 | -1 - 4 | 1 | four | 1 | -1 | 2 | 2 - 4 | 1 | four | 1 | -1 | 3 | -3 - 4 | 1 | four | 1 | -1 | 2 | 4 - 4 | 1 | four | 1 | -1 | 5 | -5 4 | 1 | four | 1 | -1 | 5 | -5 - 4 | 1 | four | 1 | -1 | 0 | - 4 | 1 | four | 1 | -1 | | - 4 | 1 | four | 1 | -1 | | 0 - 5 | 0 | five | 1 | -1 | 1 | -1 - 5 | 0 | five | 1 | -1 | 2 | 2 - 5 | 0 | five | 1 | -1 | 3 | -3 - 5 | 0 | five | 1 | -1 | 2 | 4 - 5 | 0 | five | 1 | -1 | 5 | -5 - 5 | 0 | five | 1 | -1 | 5 | -5 - 5 | 0 | five | 1 | -1 | 0 | - 5 | 0 | five | 1 | -1 | | - 5 | 0 | five | 1 | -1 | | 0 - 6 | 6 | six | 1 | -1 | 1 | -1 - 6 | 6 | six | 1 | -1 | 2 | 2 - 6 | 6 | six | 1 | -1 | 3 | -3 - 6 | 6 | six | 1 | -1 | 2 | 4 - 6 | 6 | six | 1 | -1 | 5 | -5 - 6 | 6 | six | 1 | -1 | 5 | -5 - 6 | 6 | six | 1 | -1 | 0 | - 6 | 6 | six | 1 | -1 | | - 6 | 6 | six | 1 | -1 | | 0 - 7 | 7 | seven | 1 | -1 | 1 | -1 - 7 | 7 | seven | 1 | -1 | 2 | 2 - 7 | 7 | seven | 1 | -1 | 3 | -3 - 7 | 7 | seven | 1 | -1 | 2 | 4 - 7 | 7 | seven | 1 | -1 | 5 | -5 7 | 7 | seven | 1 | -1 | 5 | -5 - 7 | 7 | seven | 1 | -1 | 0 | - 7 | 7 | seven | 1 | -1 | | - 7 | 7 | seven | 1 | -1 | | 0 - 8 | 8 | eight | 1 | -1 | 1 | -1 - 8 | 8 | eight | 1 | -1 | 2 | 2 - 8 | 8 | eight | 1 | -1 | 3 | -3 - 8 | 8 | eight | 1 | -1 | 2 | 4 - 8 | 8 | eight | 1 | -1 | 5 | -5 8 | 8 | eight | 1 | -1 | 5 | -5 - 8 | 8 | eight | 1 | -1 | 0 | - 8 | 8 | eight | 1 | -1 | | - 8 | 8 | eight | 1 | -1 | | 0 - 0 | | zero | 1 | -1 | 1 | -1 - 0 | | zero | 1 | -1 | 2 | 2 - 0 | | zero | 1 | -1 | 3 | -3 - 0 | | zero | 1 | -1 | 2 | 4 - 0 | | zero | 1 | -1 | 5 | -5 - 0 | | zero | 1 | -1 | 5 | -5 - 0 | | zero | 1 | -1 | 0 | - 0 | | zero | 1 | -1 | | - 0 | | zero | 1 | -1 | | 0 - | | null | 1 | -1 | 1 | -1 - | | null | 1 | -1 | 2 | 2 - | | null | 1 | -1 | 3 | -3 - | | null | 1 | -1 | 2 | 4 | | null | 1 | -1 | 5 | -5 - | | null | 1 | -1 | 5 | -5 - | | null | 1 | -1 | 0 | - | | null | 1 | -1 | | - | | null | 1 | -1 | | 0 - | 0 | zero | 1 | -1 | 1 | -1 - | 0 | zero | 1 | -1 | 2 | 2 - | 0 | zero | 1 | -1 | 3 | -3 - | 0 | zero | 1 | -1 | 2 | 4 | 0 | zero | 1 | -1 | 5 | -5 + 2 | 3 | two | 1 | -1 | 5 | -5 + 3 | 2 | three | 1 | -1 | 5 | -5 + 4 | 1 | four | 1 | -1 | 5 | -5 + 7 | 7 | seven | 1 | -1 | 5 | -5 + 8 | 8 | eight | 1 | -1 | 5 | -5 + | | null | 1 | -1 | 5 | -5 | 0 | zero | 1 | -1 | 5 | -5 - | 0 | zero | 1 | -1 | 0 | - | 0 | zero | 1 | -1 | | - | 0 | zero | 1 | -1 | | 0 - 1 | 4 | one | 2 | 2 | 1 | -1 - 1 | 4 | one | 2 | 2 | 2 | 2 - 1 | 4 | one | 2 | 2 | 3 | -3 - 1 | 4 | one | 2 | 2 | 2 | 4 - 1 | 4 | one | 2 | 2 | 5 | -5 - 1 | 4 | one | 2 | 2 | 5 | -5 - 1 | 4 | one | 2 | 2 | 0 | - 1 | 4 | one | 2 | 2 | | - 1 | 4 | one | 2 | 2 | | 0 - 2 | 3 | two | 2 | 2 | 1 | -1 - 2 | 3 | two | 2 | 2 | 2 | 2 - 2 | 3 | two | 2 | 2 | 3 | -3 - 2 | 3 | two | 2 | 2 | 2 | 4 - 2 | 3 | two | 2 | 2 | 5 | -5 + 2 | 3 | two | 0 | | 5 | -5 + 3 | 2 | three | 0 | | 5 | -5 + 4 | 1 | four | 0 | | 5 | -5 + 7 | 7 | seven | 0 | | 5 | -5 + 8 | 8 | eight | 0 | | 5 | -5 + | | null | 0 | | 5 | -5 + | 0 | zero | 0 | | 5 | -5 + 2 | 3 | two | 0 | | 5 | -5 + 3 | 2 | three | 0 | | 5 | -5 + 4 | 1 | four | 0 | | 5 | -5 + 7 | 7 | seven | 0 | | 5 | -5 + 8 | 8 | eight | 0 | | 5 | -5 + | | null | 0 | | 5 | -5 + | 0 | zero | 0 | | 5 | -5 + 2 | 3 | two | 5 | -5 | 5 | -5 + 3 | 2 | three | 5 | -5 | 5 | -5 + 4 | 1 | four | 5 | -5 | 5 | -5 + 7 | 7 | seven | 5 | -5 | 5 | -5 + 8 | 8 | eight | 5 | -5 | 5 | -5 + | | null | 5 | -5 | 5 | -5 + | 0 | zero | 5 | -5 | 5 | -5 + 2 | 3 | two | 5 | -5 | 5 | -5 + 3 | 2 | three | 5 | -5 | 5 | -5 + 4 | 1 | four | 5 | -5 | 5 | -5 + 7 | 7 | seven | 5 | -5 | 5 | -5 + 8 | 8 | eight | 5 | -5 | 5 | -5 + | | null | 5 | -5 | 5 | -5 + | 0 | zero | 5 | -5 | 5 | -5 + 2 | 3 | two | 5 | -5 | 5 | -5 + 3 | 2 | three | 5 | -5 | 5 | -5 + 4 | 1 | four | 5 | -5 | 5 | -5 + 7 | 7 | seven | 5 | -5 | 5 | -5 + 8 | 8 | eight | 5 | -5 | 5 | -5 + | | null | 5 | -5 | 5 | -5 + | 0 | zero | 5 | -5 | 5 | -5 + 2 | 3 | two | 5 | -5 | 5 | -5 + 3 | 2 | three | 5 | -5 | 5 | -5 + 4 | 1 | four | 5 | -5 | 5 | -5 + 7 | 7 | seven | 5 | -5 | 5 | -5 + 8 | 8 | eight | 5 | -5 | 5 | -5 + | | null | 5 | -5 | 5 | -5 + | 0 | zero | 5 | -5 | 5 | -5 2 | 3 | two | 2 | 2 | 5 | -5 - 2 | 3 | two | 2 | 2 | 0 | - 2 | 3 | two | 2 | 2 | | - 2 | 3 | two | 2 | 2 | | 0 - 3 | 2 | three | 2 | 2 | 1 | -1 - 3 | 2 | three | 2 | 2 | 2 | 2 - 3 | 2 | three | 2 | 2 | 3 | -3 - 3 | 2 | three | 2 | 2 | 2 | 4 3 | 2 | three | 2 | 2 | 5 | -5 - 3 | 2 | three | 2 | 2 | 5 | -5 - 3 | 2 | three | 2 | 2 | 0 | - 3 | 2 | three | 2 | 2 | | - 3 | 2 | three | 2 | 2 | | 0 - 4 | 1 | four | 2 | 2 | 1 | -1 - 4 | 1 | four | 2 | 2 | 2 | 2 - 4 | 1 | four | 2 | 2 | 3 | -3 - 4 | 1 | four | 2 | 2 | 2 | 4 4 | 1 | four | 2 | 2 | 5 | -5 - 4 | 1 | four | 2 | 2 | 5 | -5 - 4 | 1 | four | 2 | 2 | 0 | - 4 | 1 | four | 2 | 2 | | - 4 | 1 | four | 2 | 2 | | 0 - 5 | 0 | five | 2 | 2 | 1 | -1 - 5 | 0 | five | 2 | 2 | 2 | 2 - 5 | 0 | five | 2 | 2 | 3 | -3 - 5 | 0 | five | 2 | 2 | 2 | 4 - 5 | 0 | five | 2 | 2 | 5 | -5 - 5 | 0 | five | 2 | 2 | 5 | -5 - 5 | 0 | five | 2 | 2 | 0 | - 5 | 0 | five | 2 | 2 | | - 5 | 0 | five | 2 | 2 | | 0 - 6 | 6 | six | 2 | 2 | 1 | -1 - 6 | 6 | six | 2 | 2 | 2 | 2 - 6 | 6 | six | 2 | 2 | 3 | -3 - 6 | 6 | six | 2 | 2 | 2 | 4 - 6 | 6 | six | 2 | 2 | 5 | -5 - 6 | 6 | six | 2 | 2 | 5 | -5 - 6 | 6 | six | 2 | 2 | 0 | - 6 | 6 | six | 2 | 2 | | - 6 | 6 | six | 2 | 2 | | 0 - 7 | 7 | seven | 2 | 2 | 1 | -1 - 7 | 7 | seven | 2 | 2 | 2 | 2 - 7 | 7 | seven | 2 | 2 | 3 | -3 - 7 | 7 | seven | 2 | 2 | 2 | 4 7 | 7 | seven | 2 | 2 | 5 | -5 - 7 | 7 | seven | 2 | 2 | 5 | -5 - 7 | 7 | seven | 2 | 2 | 0 | - 7 | 7 | seven | 2 | 2 | | - 7 | 7 | seven | 2 | 2 | | 0 - 8 | 8 | eight | 2 | 2 | 1 | -1 - 8 | 8 | eight | 2 | 2 | 2 | 2 - 8 | 8 | eight | 2 | 2 | 3 | -3 - 8 | 8 | eight | 2 | 2 | 2 | 4 8 | 8 | eight | 2 | 2 | 5 | -5 - 8 | 8 | eight | 2 | 2 | 5 | -5 - 8 | 8 | eight | 2 | 2 | 0 | - 8 | 8 | eight | 2 | 2 | | - 8 | 8 | eight | 2 | 2 | | 0 - 0 | | zero | 2 | 2 | 1 | -1 - 0 | | zero | 2 | 2 | 2 | 2 - 0 | | zero | 2 | 2 | 3 | -3 - 0 | | zero | 2 | 2 | 2 | 4 - 0 | | zero | 2 | 2 | 5 | -5 - 0 | | zero | 2 | 2 | 5 | -5 - 0 | | zero | 2 | 2 | 0 | - 0 | | zero | 2 | 2 | | - 0 | | zero | 2 | 2 | | 0 - | | null | 2 | 2 | 1 | -1 - | | null | 2 | 2 | 2 | 2 - | | null | 2 | 2 | 3 | -3 - | | null | 2 | 2 | 2 | 4 - | | null | 2 | 2 | 5 | -5 | | null | 2 | 2 | 5 | -5 - | | null | 2 | 2 | 0 | - | | null | 2 | 2 | | - | | null | 2 | 2 | | 0 - | 0 | zero | 2 | 2 | 1 | -1 - | 0 | zero | 2 | 2 | 2 | 2 - | 0 | zero | 2 | 2 | 3 | -3 - | 0 | zero | 2 | 2 | 2 | 4 | 0 | zero | 2 | 2 | 5 | -5 + 2 | 3 | two | 2 | 2 | 5 | -5 + 3 | 2 | three | 2 | 2 | 5 | -5 + 4 | 1 | four | 2 | 2 | 5 | -5 + 7 | 7 | seven | 2 | 2 | 5 | -5 + 8 | 8 | eight | 2 | 2 | 5 | -5 + | | null | 2 | 2 | 5 | -5 | 0 | zero | 2 | 2 | 5 | -5 - | 0 | zero | 2 | 2 | 0 | - | 0 | zero | 2 | 2 | | - | 0 | zero | 2 | 2 | | 0 - 1 | 4 | one | 3 | -3 | 1 | -1 - 1 | 4 | one | 3 | -3 | 2 | 2 - 1 | 4 | one | 3 | -3 | 3 | -3 - 1 | 4 | one | 3 | -3 | 2 | 4 - 1 | 4 | one | 3 | -3 | 5 | -5 - 1 | 4 | one | 3 | -3 | 5 | -5 - 1 | 4 | one | 3 | -3 | 0 | - 1 | 4 | one | 3 | -3 | | - 1 | 4 | one | 3 | -3 | | 0 - 2 | 3 | two | 3 | -3 | 1 | -1 - 2 | 3 | two | 3 | -3 | 2 | 2 - 2 | 3 | two | 3 | -3 | 3 | -3 - 2 | 3 | two | 3 | -3 | 2 | 4 - 2 | 3 | two | 3 | -3 | 5 | -5 2 | 3 | two | 3 | -3 | 5 | -5 - 2 | 3 | two | 3 | -3 | 0 | - 2 | 3 | two | 3 | -3 | | - 2 | 3 | two | 3 | -3 | | 0 - 3 | 2 | three | 3 | -3 | 1 | -1 - 3 | 2 | three | 3 | -3 | 2 | 2 - 3 | 2 | three | 3 | -3 | 3 | -3 - 3 | 2 | three | 3 | -3 | 2 | 4 - 3 | 2 | three | 3 | -3 | 5 | -5 3 | 2 | three | 3 | -3 | 5 | -5 - 3 | 2 | three | 3 | -3 | 0 | - 3 | 2 | three | 3 | -3 | | - 3 | 2 | three | 3 | -3 | | 0 - 4 | 1 | four | 3 | -3 | 1 | -1 - 4 | 1 | four | 3 | -3 | 2 | 2 - 4 | 1 | four | 3 | -3 | 3 | -3 - 4 | 1 | four | 3 | -3 | 2 | 4 - 4 | 1 | four | 3 | -3 | 5 | -5 4 | 1 | four | 3 | -3 | 5 | -5 - 4 | 1 | four | 3 | -3 | 0 | - 4 | 1 | four | 3 | -3 | | - 4 | 1 | four | 3 | -3 | | 0 - 5 | 0 | five | 3 | -3 | 1 | -1 - 5 | 0 | five | 3 | -3 | 2 | 2 - 5 | 0 | five | 3 | -3 | 3 | -3 - 5 | 0 | five | 3 | -3 | 2 | 4 - 5 | 0 | five | 3 | -3 | 5 | -5 - 5 | 0 | five | 3 | -3 | 5 | -5 - 5 | 0 | five | 3 | -3 | 0 | - 5 | 0 | five | 3 | -3 | | - 5 | 0 | five | 3 | -3 | | 0 - 6 | 6 | six | 3 | -3 | 1 | -1 - 6 | 6 | six | 3 | -3 | 2 | 2 - 6 | 6 | six | 3 | -3 | 3 | -3 - 6 | 6 | six | 3 | -3 | 2 | 4 - 6 | 6 | six | 3 | -3 | 5 | -5 - 6 | 6 | six | 3 | -3 | 5 | -5 - 6 | 6 | six | 3 | -3 | 0 | - 6 | 6 | six | 3 | -3 | | - 6 | 6 | six | 3 | -3 | | 0 - 7 | 7 | seven | 3 | -3 | 1 | -1 - 7 | 7 | seven | 3 | -3 | 2 | 2 - 7 | 7 | seven | 3 | -3 | 3 | -3 - 7 | 7 | seven | 3 | -3 | 2 | 4 - 7 | 7 | seven | 3 | -3 | 5 | -5 7 | 7 | seven | 3 | -3 | 5 | -5 - 7 | 7 | seven | 3 | -3 | 0 | - 7 | 7 | seven | 3 | -3 | | - 7 | 7 | seven | 3 | -3 | | 0 - 8 | 8 | eight | 3 | -3 | 1 | -1 - 8 | 8 | eight | 3 | -3 | 2 | 2 - 8 | 8 | eight | 3 | -3 | 3 | -3 - 8 | 8 | eight | 3 | -3 | 2 | 4 - 8 | 8 | eight | 3 | -3 | 5 | -5 8 | 8 | eight | 3 | -3 | 5 | -5 - 8 | 8 | eight | 3 | -3 | 0 | - 8 | 8 | eight | 3 | -3 | | - 8 | 8 | eight | 3 | -3 | | 0 - 0 | | zero | 3 | -3 | 1 | -1 - 0 | | zero | 3 | -3 | 2 | 2 - 0 | | zero | 3 | -3 | 3 | -3 - 0 | | zero | 3 | -3 | 2 | 4 - 0 | | zero | 3 | -3 | 5 | -5 - 0 | | zero | 3 | -3 | 5 | -5 - 0 | | zero | 3 | -3 | 0 | - 0 | | zero | 3 | -3 | | - 0 | | zero | 3 | -3 | | 0 - | | null | 3 | -3 | 1 | -1 - | | null | 3 | -3 | 2 | 2 - | | null | 3 | -3 | 3 | -3 - | | null | 3 | -3 | 2 | 4 | | null | 3 | -3 | 5 | -5 - | | null | 3 | -3 | 5 | -5 - | | null | 3 | -3 | 0 | - | | null | 3 | -3 | | - | | null | 3 | -3 | | 0 - | 0 | zero | 3 | -3 | 1 | -1 - | 0 | zero | 3 | -3 | 2 | 2 - | 0 | zero | 3 | -3 | 3 | -3 - | 0 | zero | 3 | -3 | 2 | 4 | 0 | zero | 3 | -3 | 5 | -5 + 2 | 3 | two | 3 | -3 | 5 | -5 + 3 | 2 | three | 3 | -3 | 5 | -5 + 4 | 1 | four | 3 | -3 | 5 | -5 + 7 | 7 | seven | 3 | -3 | 5 | -5 + 8 | 8 | eight | 3 | -3 | 5 | -5 + | | null | 3 | -3 | 5 | -5 | 0 | zero | 3 | -3 | 5 | -5 - | 0 | zero | 3 | -3 | 0 | - | 0 | zero | 3 | -3 | | - | 0 | zero | 3 | -3 | | 0 - 1 | 4 | one | 2 | 4 | 1 | -1 - 1 | 4 | one | 2 | 4 | 2 | 2 - 1 | 4 | one | 2 | 4 | 3 | -3 - 1 | 4 | one | 2 | 4 | 2 | 4 - 1 | 4 | one | 2 | 4 | 5 | -5 - 1 | 4 | one | 2 | 4 | 5 | -5 - 1 | 4 | one | 2 | 4 | 0 | - 1 | 4 | one | 2 | 4 | | - 1 | 4 | one | 2 | 4 | | 0 - 2 | 3 | two | 2 | 4 | 1 | -1 - 2 | 3 | two | 2 | 4 | 2 | 2 - 2 | 3 | two | 2 | 4 | 3 | -3 - 2 | 3 | two | 2 | 4 | 2 | 4 2 | 3 | two | 2 | 4 | 5 | -5 - 2 | 3 | two | 2 | 4 | 5 | -5 - 2 | 3 | two | 2 | 4 | 0 | - 2 | 3 | two | 2 | 4 | | - 2 | 3 | two | 2 | 4 | | 0 - 3 | 2 | three | 2 | 4 | 1 | -1 - 3 | 2 | three | 2 | 4 | 2 | 2 - 3 | 2 | three | 2 | 4 | 3 | -3 - 3 | 2 | three | 2 | 4 | 2 | 4 3 | 2 | three | 2 | 4 | 5 | -5 - 3 | 2 | three | 2 | 4 | 5 | -5 - 3 | 2 | three | 2 | 4 | 0 | - 3 | 2 | three | 2 | 4 | | - 3 | 2 | three | 2 | 4 | | 0 - 4 | 1 | four | 2 | 4 | 1 | -1 - 4 | 1 | four | 2 | 4 | 2 | 2 - 4 | 1 | four | 2 | 4 | 3 | -3 - 4 | 1 | four | 2 | 4 | 2 | 4 4 | 1 | four | 2 | 4 | 5 | -5 - 4 | 1 | four | 2 | 4 | 5 | -5 - 4 | 1 | four | 2 | 4 | 0 | - 4 | 1 | four | 2 | 4 | | - 4 | 1 | four | 2 | 4 | | 0 - 5 | 0 | five | 2 | 4 | 1 | -1 - 5 | 0 | five | 2 | 4 | 2 | 2 - 5 | 0 | five | 2 | 4 | 3 | -3 - 5 | 0 | five | 2 | 4 | 2 | 4 - 5 | 0 | five | 2 | 4 | 5 | -5 - 5 | 0 | five | 2 | 4 | 5 | -5 - 5 | 0 | five | 2 | 4 | 0 | - 5 | 0 | five | 2 | 4 | | - 5 | 0 | five | 2 | 4 | | 0 - 6 | 6 | six | 2 | 4 | 1 | -1 - 6 | 6 | six | 2 | 4 | 2 | 2 - 6 | 6 | six | 2 | 4 | 3 | -3 - 6 | 6 | six | 2 | 4 | 2 | 4 - 6 | 6 | six | 2 | 4 | 5 | -5 - 6 | 6 | six | 2 | 4 | 5 | -5 - 6 | 6 | six | 2 | 4 | 0 | - 6 | 6 | six | 2 | 4 | | - 6 | 6 | six | 2 | 4 | | 0 - 7 | 7 | seven | 2 | 4 | 1 | -1 - 7 | 7 | seven | 2 | 4 | 2 | 2 - 7 | 7 | seven | 2 | 4 | 3 | -3 - 7 | 7 | seven | 2 | 4 | 2 | 4 7 | 7 | seven | 2 | 4 | 5 | -5 - 7 | 7 | seven | 2 | 4 | 5 | -5 - 7 | 7 | seven | 2 | 4 | 0 | - 7 | 7 | seven | 2 | 4 | | - 7 | 7 | seven | 2 | 4 | | 0 - 8 | 8 | eight | 2 | 4 | 1 | -1 - 8 | 8 | eight | 2 | 4 | 2 | 2 - 8 | 8 | eight | 2 | 4 | 3 | -3 - 8 | 8 | eight | 2 | 4 | 2 | 4 8 | 8 | eight | 2 | 4 | 5 | -5 + | | null | 2 | 4 | 5 | -5 + | 0 | zero | 2 | 4 | 5 | -5 + 2 | 3 | two | 2 | 4 | 5 | -5 + 3 | 2 | three | 2 | 4 | 5 | -5 + 4 | 1 | four | 2 | 4 | 5 | -5 + 7 | 7 | seven | 2 | 4 | 5 | -5 8 | 8 | eight | 2 | 4 | 5 | -5 - 8 | 8 | eight | 2 | 4 | 0 | - 8 | 8 | eight | 2 | 4 | | - 8 | 8 | eight | 2 | 4 | | 0 - 0 | | zero | 2 | 4 | 1 | -1 - 0 | | zero | 2 | 4 | 2 | 2 - 0 | | zero | 2 | 4 | 3 | -3 - 0 | | zero | 2 | 4 | 2 | 4 - 0 | | zero | 2 | 4 | 5 | -5 - 0 | | zero | 2 | 4 | 5 | -5 - 0 | | zero | 2 | 4 | 0 | - 0 | | zero | 2 | 4 | | - 0 | | zero | 2 | 4 | | 0 - | | null | 2 | 4 | 1 | -1 - | | null | 2 | 4 | 2 | 2 - | | null | 2 | 4 | 3 | -3 - | | null | 2 | 4 | 2 | 4 | | null | 2 | 4 | 5 | -5 - | | null | 2 | 4 | 5 | -5 - | | null | 2 | 4 | 0 | - | | null | 2 | 4 | | - | | null | 2 | 4 | | 0 - | 0 | zero | 2 | 4 | 1 | -1 - | 0 | zero | 2 | 4 | 2 | 2 - | 0 | zero | 2 | 4 | 3 | -3 - | 0 | zero | 2 | 4 | 2 | 4 - | 0 | zero | 2 | 4 | 5 | -5 | 0 | zero | 2 | 4 | 5 | -5 + 2 | 3 | two | | | 5 | -5 + 3 | 2 | three | | | 5 | -5 + 4 | 1 | four | | | 5 | -5 + 7 | 7 | seven | | | 5 | -5 + 8 | 8 | eight | | | 5 | -5 + | | null | | | 5 | -5 + | 0 | zero | | | 5 | -5 + 2 | 3 | two | | | 5 | -5 + 3 | 2 | three | | | 5 | -5 + 4 | 1 | four | | | 5 | -5 + 7 | 7 | seven | | | 5 | -5 + 8 | 8 | eight | | | 5 | -5 + | | null | | | 5 | -5 + | 0 | zero | | | 5 | -5 + 2 | 3 | two | | 0 | 5 | -5 + 3 | 2 | three | | 0 | 5 | -5 + 4 | 1 | four | | 0 | 5 | -5 + 7 | 7 | seven | | 0 | 5 | -5 + 8 | 8 | eight | | 0 | 5 | -5 + | | null | | 0 | 5 | -5 + | 0 | zero | | 0 | 5 | -5 + 2 | 3 | two | | 0 | 5 | -5 + 3 | 2 | three | | 0 | 5 | -5 + 4 | 1 | four | | 0 | 5 | -5 + 7 | 7 | seven | | 0 | 5 | -5 + 8 | 8 | eight | | 0 | 5 | -5 + | | null | | 0 | 5 | -5 + | 0 | zero | | 0 | 5 | -5 + 2 | 3 | two | 2 | 2 | 1 | -1 + 3 | 2 | three | 2 | 2 | 1 | -1 + 4 | 1 | four | 2 | 2 | 1 | -1 + 7 | 7 | seven | 2 | 2 | 1 | -1 + 8 | 8 | eight | 2 | 2 | 1 | -1 + | | null | 2 | 2 | 1 | -1 + | 0 | zero | 2 | 2 | 1 | -1 + 2 | 3 | two | 2 | 2 | 0 | + 3 | 2 | three | 2 | 2 | 0 | + 4 | 1 | four | 2 | 2 | 0 | + 7 | 7 | seven | 2 | 2 | 0 | + 8 | 8 | eight | 2 | 2 | 0 | + | | null | 2 | 2 | 0 | + | 0 | zero | 2 | 2 | 0 | + 2 | 3 | two | 3 | -3 | 1 | -1 + 3 | 2 | three | 3 | -3 | 1 | -1 + 4 | 1 | four | 3 | -3 | 1 | -1 + 7 | 7 | seven | 3 | -3 | 1 | -1 + 8 | 8 | eight | 3 | -3 | 1 | -1 + | | null | 3 | -3 | 1 | -1 + | 0 | zero | 3 | -3 | 1 | -1 + 2 | 3 | two | 3 | -3 | 0 | + 3 | 2 | three | 3 | -3 | 0 | + 4 | 1 | four | 3 | -3 | 0 | + 7 | 7 | seven | 3 | -3 | 0 | + 8 | 8 | eight | 3 | -3 | 0 | + | | null | 3 | -3 | 0 | + | 0 | zero | 3 | -3 | 0 | + 2 | 3 | two | 2 | 4 | 1 | -1 + 3 | 2 | three | 2 | 4 | 1 | -1 + 4 | 1 | four | 2 | 4 | 1 | -1 + 7 | 7 | seven | 2 | 4 | 1 | -1 + 8 | 8 | eight | 2 | 4 | 1 | -1 + | | null | 2 | 4 | 1 | -1 + | 0 | zero | 2 | 4 | 1 | -1 + 2 | 3 | two | 2 | 4 | 0 | + 3 | 2 | three | 2 | 4 | 0 | + 4 | 1 | four | 2 | 4 | 0 | + 7 | 7 | seven | 2 | 4 | 0 | + 8 | 8 | eight | 2 | 4 | 0 | + | | null | 2 | 4 | 0 | | 0 | zero | 2 | 4 | 0 | - | 0 | zero | 2 | 4 | | - | 0 | zero | 2 | 4 | | 0 - 1 | 4 | one | 5 | -5 | 1 | -1 - 1 | 4 | one | 5 | -5 | 2 | 2 - 1 | 4 | one | 5 | -5 | 3 | -3 - 1 | 4 | one | 5 | -5 | 2 | 4 - 1 | 4 | one | 5 | -5 | 5 | -5 - 1 | 4 | one | 5 | -5 | 5 | -5 - 1 | 4 | one | 5 | -5 | 0 | - 1 | 4 | one | 5 | -5 | | - 1 | 4 | one | 5 | -5 | | 0 + 2 | 3 | two | | | 1 | -1 + 3 | 2 | three | | | 1 | -1 + 4 | 1 | four | | | 1 | -1 + 7 | 7 | seven | | | 1 | -1 + 8 | 8 | eight | | | 1 | -1 + | | null | | | 1 | -1 + | 0 | zero | | | 1 | -1 + 2 | 3 | two | | | 0 | + 3 | 2 | three | | | 0 | + 4 | 1 | four | | | 0 | + 7 | 7 | seven | | | 0 | + 8 | 8 | eight | | | 0 | + | | null | | | 0 | + | 0 | zero | | | 0 | + 2 | 3 | two | | 0 | 1 | -1 + 3 | 2 | three | | 0 | 1 | -1 + 4 | 1 | four | | 0 | 1 | -1 + 7 | 7 | seven | | 0 | 1 | -1 + 8 | 8 | eight | | 0 | 1 | -1 + | | null | | 0 | 1 | -1 + | 0 | zero | | 0 | 1 | -1 + 2 | 3 | two | | 0 | 0 | + 3 | 2 | three | | 0 | 0 | + 4 | 1 | four | | 0 | 0 | + 7 | 7 | seven | | 0 | 0 | + 8 | 8 | eight | | 0 | 0 | + | | null | | 0 | 0 | + | 0 | zero | | 0 | 0 | + 2 | 3 | two | 1 | -1 | 1 | -1 + 3 | 2 | three | 1 | -1 | 1 | -1 + 4 | 1 | four | 1 | -1 | 1 | -1 + 7 | 7 | seven | 1 | -1 | 1 | -1 + 8 | 8 | eight | 1 | -1 | 1 | -1 + | | null | 1 | -1 | 1 | -1 + | 0 | zero | 1 | -1 | 1 | -1 + 2 | 3 | two | 1 | -1 | 0 | + 3 | 2 | three | 1 | -1 | 0 | + 4 | 1 | four | 1 | -1 | 0 | + 7 | 7 | seven | 1 | -1 | 0 | + 8 | 8 | eight | 1 | -1 | 0 | + | | null | 1 | -1 | 0 | + | 0 | zero | 1 | -1 | 0 | + 2 | 3 | two | 0 | | 1 | -1 + 3 | 2 | three | 0 | | 1 | -1 + 4 | 1 | four | 0 | | 1 | -1 + 7 | 7 | seven | 0 | | 1 | -1 + 8 | 8 | eight | 0 | | 1 | -1 + | | null | 0 | | 1 | -1 + | 0 | zero | 0 | | 1 | -1 + 2 | 3 | two | 0 | | 0 | + 3 | 2 | three | 0 | | 0 | + 4 | 1 | four | 0 | | 0 | + 7 | 7 | seven | 0 | | 0 | + 8 | 8 | eight | 0 | | 0 | + | | null | 0 | | 0 | + | 0 | zero | 0 | | 0 | 2 | 3 | two | 5 | -5 | 1 | -1 - 2 | 3 | two | 5 | -5 | 2 | 2 - 2 | 3 | two | 5 | -5 | 3 | -3 - 2 | 3 | two | 5 | -5 | 2 | 4 - 2 | 3 | two | 5 | -5 | 5 | -5 - 2 | 3 | two | 5 | -5 | 5 | -5 - 2 | 3 | two | 5 | -5 | 0 | - 2 | 3 | two | 5 | -5 | | - 2 | 3 | two | 5 | -5 | | 0 3 | 2 | three | 5 | -5 | 1 | -1 - 3 | 2 | three | 5 | -5 | 2 | 2 - 3 | 2 | three | 5 | -5 | 3 | -3 - 3 | 2 | three | 5 | -5 | 2 | 4 - 3 | 2 | three | 5 | -5 | 5 | -5 - 3 | 2 | three | 5 | -5 | 5 | -5 - 3 | 2 | three | 5 | -5 | 0 | - 3 | 2 | three | 5 | -5 | | - 3 | 2 | three | 5 | -5 | | 0 4 | 1 | four | 5 | -5 | 1 | -1 - 4 | 1 | four | 5 | -5 | 2 | 2 - 4 | 1 | four | 5 | -5 | 3 | -3 - 4 | 1 | four | 5 | -5 | 2 | 4 - 4 | 1 | four | 5 | -5 | 5 | -5 - 4 | 1 | four | 5 | -5 | 5 | -5 - 4 | 1 | four | 5 | -5 | 0 | - 4 | 1 | four | 5 | -5 | | - 4 | 1 | four | 5 | -5 | | 0 - 5 | 0 | five | 5 | -5 | 1 | -1 - 5 | 0 | five | 5 | -5 | 2 | 2 - 5 | 0 | five | 5 | -5 | 3 | -3 - 5 | 0 | five | 5 | -5 | 2 | 4 - 5 | 0 | five | 5 | -5 | 5 | -5 - 5 | 0 | five | 5 | -5 | 5 | -5 - 5 | 0 | five | 5 | -5 | 0 | - 5 | 0 | five | 5 | -5 | | - 5 | 0 | five | 5 | -5 | | 0 - 6 | 6 | six | 5 | -5 | 1 | -1 - 6 | 6 | six | 5 | -5 | 2 | 2 - 6 | 6 | six | 5 | -5 | 3 | -3 - 6 | 6 | six | 5 | -5 | 2 | 4 - 6 | 6 | six | 5 | -5 | 5 | -5 - 6 | 6 | six | 5 | -5 | 5 | -5 - 6 | 6 | six | 5 | -5 | 0 | - 6 | 6 | six | 5 | -5 | | - 6 | 6 | six | 5 | -5 | | 0 7 | 7 | seven | 5 | -5 | 1 | -1 - 7 | 7 | seven | 5 | -5 | 2 | 2 - 7 | 7 | seven | 5 | -5 | 3 | -3 - 7 | 7 | seven | 5 | -5 | 2 | 4 - 7 | 7 | seven | 5 | -5 | 5 | -5 - 7 | 7 | seven | 5 | -5 | 5 | -5 - 7 | 7 | seven | 5 | -5 | 0 | - 7 | 7 | seven | 5 | -5 | | - 7 | 7 | seven | 5 | -5 | | 0 8 | 8 | eight | 5 | -5 | 1 | -1 - 8 | 8 | eight | 5 | -5 | 2 | 2 - 8 | 8 | eight | 5 | -5 | 3 | -3 - 8 | 8 | eight | 5 | -5 | 2 | 4 - 8 | 8 | eight | 5 | -5 | 5 | -5 - 8 | 8 | eight | 5 | -5 | 5 | -5 - 8 | 8 | eight | 5 | -5 | 0 | - 8 | 8 | eight | 5 | -5 | | - 8 | 8 | eight | 5 | -5 | | 0 - 0 | | zero | 5 | -5 | 1 | -1 - 0 | | zero | 5 | -5 | 2 | 2 - 0 | | zero | 5 | -5 | 3 | -3 - 0 | | zero | 5 | -5 | 2 | 4 - 0 | | zero | 5 | -5 | 5 | -5 - 0 | | zero | 5 | -5 | 5 | -5 - 0 | | zero | 5 | -5 | 0 | - 0 | | zero | 5 | -5 | | - 0 | | zero | 5 | -5 | | 0 | | null | 5 | -5 | 1 | -1 - | | null | 5 | -5 | 2 | 2 - | | null | 5 | -5 | 3 | -3 - | | null | 5 | -5 | 2 | 4 - | | null | 5 | -5 | 5 | -5 - | | null | 5 | -5 | 5 | -5 - | | null | 5 | -5 | 0 | - | | null | 5 | -5 | | - | | null | 5 | -5 | | 0 | 0 | zero | 5 | -5 | 1 | -1 - | 0 | zero | 5 | -5 | 2 | 2 - | 0 | zero | 5 | -5 | 3 | -3 - | 0 | zero | 5 | -5 | 2 | 4 - | 0 | zero | 5 | -5 | 5 | -5 - | 0 | zero | 5 | -5 | 5 | -5 + 2 | 3 | two | 5 | -5 | 0 | + 3 | 2 | three | 5 | -5 | 0 | + 4 | 1 | four | 5 | -5 | 0 | + 7 | 7 | seven | 5 | -5 | 0 | + 8 | 8 | eight | 5 | -5 | 0 | + | | null | 5 | -5 | 0 | | 0 | zero | 5 | -5 | 0 | - | 0 | zero | 5 | -5 | | - | 0 | zero | 5 | -5 | | 0 - 1 | 4 | one | 5 | -5 | 1 | -1 - 1 | 4 | one | 5 | -5 | 2 | 2 - 1 | 4 | one | 5 | -5 | 3 | -3 - 1 | 4 | one | 5 | -5 | 2 | 4 - 1 | 4 | one | 5 | -5 | 5 | -5 - 1 | 4 | one | 5 | -5 | 5 | -5 - 1 | 4 | one | 5 | -5 | 0 | - 1 | 4 | one | 5 | -5 | | - 1 | 4 | one | 5 | -5 | | 0 2 | 3 | two | 5 | -5 | 1 | -1 - 2 | 3 | two | 5 | -5 | 2 | 2 - 2 | 3 | two | 5 | -5 | 3 | -3 - 2 | 3 | two | 5 | -5 | 2 | 4 - 2 | 3 | two | 5 | -5 | 5 | -5 - 2 | 3 | two | 5 | -5 | 5 | -5 - 2 | 3 | two | 5 | -5 | 0 | - 2 | 3 | two | 5 | -5 | | - 2 | 3 | two | 5 | -5 | | 0 3 | 2 | three | 5 | -5 | 1 | -1 - 3 | 2 | three | 5 | -5 | 2 | 2 - 3 | 2 | three | 5 | -5 | 3 | -3 - 3 | 2 | three | 5 | -5 | 2 | 4 - 3 | 2 | three | 5 | -5 | 5 | -5 - 3 | 2 | three | 5 | -5 | 5 | -5 - 3 | 2 | three | 5 | -5 | 0 | - 3 | 2 | three | 5 | -5 | | - 3 | 2 | three | 5 | -5 | | 0 4 | 1 | four | 5 | -5 | 1 | -1 - 4 | 1 | four | 5 | -5 | 2 | 2 - 4 | 1 | four | 5 | -5 | 3 | -3 - 4 | 1 | four | 5 | -5 | 2 | 4 - 4 | 1 | four | 5 | -5 | 5 | -5 - 4 | 1 | four | 5 | -5 | 5 | -5 - 4 | 1 | four | 5 | -5 | 0 | - 4 | 1 | four | 5 | -5 | | - 4 | 1 | four | 5 | -5 | | 0 - 5 | 0 | five | 5 | -5 | 1 | -1 - 5 | 0 | five | 5 | -5 | 2 | 2 - 5 | 0 | five | 5 | -5 | 3 | -3 - 5 | 0 | five | 5 | -5 | 2 | 4 - 5 | 0 | five | 5 | -5 | 5 | -5 - 5 | 0 | five | 5 | -5 | 5 | -5 - 5 | 0 | five | 5 | -5 | 0 | - 5 | 0 | five | 5 | -5 | | - 5 | 0 | five | 5 | -5 | | 0 - 6 | 6 | six | 5 | -5 | 1 | -1 - 6 | 6 | six | 5 | -5 | 2 | 2 - 6 | 6 | six | 5 | -5 | 3 | -3 - 6 | 6 | six | 5 | -5 | 2 | 4 - 6 | 6 | six | 5 | -5 | 5 | -5 - 6 | 6 | six | 5 | -5 | 5 | -5 - 6 | 6 | six | 5 | -5 | 0 | - 6 | 6 | six | 5 | -5 | | - 6 | 6 | six | 5 | -5 | | 0 7 | 7 | seven | 5 | -5 | 1 | -1 - 7 | 7 | seven | 5 | -5 | 2 | 2 - 7 | 7 | seven | 5 | -5 | 3 | -3 - 7 | 7 | seven | 5 | -5 | 2 | 4 - 7 | 7 | seven | 5 | -5 | 5 | -5 - 7 | 7 | seven | 5 | -5 | 5 | -5 - 7 | 7 | seven | 5 | -5 | 0 | - 7 | 7 | seven | 5 | -5 | | - 7 | 7 | seven | 5 | -5 | | 0 8 | 8 | eight | 5 | -5 | 1 | -1 - 8 | 8 | eight | 5 | -5 | 2 | 2 - 8 | 8 | eight | 5 | -5 | 3 | -3 - 8 | 8 | eight | 5 | -5 | 2 | 4 - 8 | 8 | eight | 5 | -5 | 5 | -5 - 8 | 8 | eight | 5 | -5 | 5 | -5 - 8 | 8 | eight | 5 | -5 | 0 | - 8 | 8 | eight | 5 | -5 | | - 8 | 8 | eight | 5 | -5 | | 0 - 0 | | zero | 5 | -5 | 1 | -1 - 0 | | zero | 5 | -5 | 2 | 2 - 0 | | zero | 5 | -5 | 3 | -3 - 0 | | zero | 5 | -5 | 2 | 4 - 0 | | zero | 5 | -5 | 5 | -5 - 0 | | zero | 5 | -5 | 5 | -5 - 0 | | zero | 5 | -5 | 0 | - 0 | | zero | 5 | -5 | | - 0 | | zero | 5 | -5 | | 0 | | null | 5 | -5 | 1 | -1 - | | null | 5 | -5 | 2 | 2 - | | null | 5 | -5 | 3 | -3 - | | null | 5 | -5 | 2 | 4 - | | null | 5 | -5 | 5 | -5 - | | null | 5 | -5 | 5 | -5 - | | null | 5 | -5 | 0 | - | | null | 5 | -5 | | - | | null | 5 | -5 | | 0 | 0 | zero | 5 | -5 | 1 | -1 - | 0 | zero | 5 | -5 | 2 | 2 - | 0 | zero | 5 | -5 | 3 | -3 - | 0 | zero | 5 | -5 | 2 | 4 - | 0 | zero | 5 | -5 | 5 | -5 - | 0 | zero | 5 | -5 | 5 | -5 + 2 | 3 | two | 5 | -5 | 0 | + 3 | 2 | three | 5 | -5 | 0 | + 4 | 1 | four | 5 | -5 | 0 | + 7 | 7 | seven | 5 | -5 | 0 | + 8 | 8 | eight | 5 | -5 | 0 | + | | null | 5 | -5 | 0 | | 0 | zero | 5 | -5 | 0 | - | 0 | zero | 5 | -5 | | - | 0 | zero | 5 | -5 | | 0 - 1 | 4 | one | 0 | | 1 | -1 - 1 | 4 | one | 0 | | 2 | 2 - 1 | 4 | one | 0 | | 3 | -3 - 1 | 4 | one | 0 | | 2 | 4 - 1 | 4 | one | 0 | | 5 | -5 - 1 | 4 | one | 0 | | 5 | -5 - 1 | 4 | one | 0 | | 0 | - 1 | 4 | one | 0 | | | - 1 | 4 | one | 0 | | | 0 - 2 | 3 | two | 0 | | 1 | -1 + 2 | 3 | two | 1 | -1 | 2 | 2 + 3 | 2 | three | 1 | -1 | 2 | 2 + 4 | 1 | four | 1 | -1 | 2 | 2 + 7 | 7 | seven | 1 | -1 | 2 | 2 + 8 | 8 | eight | 1 | -1 | 2 | 2 + | | null | 1 | -1 | 2 | 2 + | 0 | zero | 1 | -1 | 2 | 2 + 2 | 3 | two | 1 | -1 | 3 | -3 + 3 | 2 | three | 1 | -1 | 3 | -3 + 4 | 1 | four | 1 | -1 | 3 | -3 + 7 | 7 | seven | 1 | -1 | 3 | -3 + 8 | 8 | eight | 1 | -1 | 3 | -3 + | | null | 1 | -1 | 3 | -3 + | 0 | zero | 1 | -1 | 3 | -3 + 2 | 3 | two | 1 | -1 | 2 | 4 + 3 | 2 | three | 1 | -1 | 2 | 4 + 4 | 1 | four | 1 | -1 | 2 | 4 + 7 | 7 | seven | 1 | -1 | 2 | 4 + 8 | 8 | eight | 1 | -1 | 2 | 4 + | | null | 1 | -1 | 2 | 4 + | 0 | zero | 1 | -1 | 2 | 4 + 2 | 3 | two | 1 | -1 | | + 3 | 2 | three | 1 | -1 | | + 4 | 1 | four | 1 | -1 | | + 7 | 7 | seven | 1 | -1 | | + 8 | 8 | eight | 1 | -1 | | + | | null | 1 | -1 | | + | 0 | zero | 1 | -1 | | + 2 | 3 | two | 1 | -1 | | 0 + 3 | 2 | three | 1 | -1 | | 0 + 4 | 1 | four | 1 | -1 | | 0 + 7 | 7 | seven | 1 | -1 | | 0 + 8 | 8 | eight | 1 | -1 | | 0 + | | null | 1 | -1 | | 0 + | 0 | zero | 1 | -1 | | 0 2 | 3 | two | 0 | | 2 | 2 - 2 | 3 | two | 0 | | 3 | -3 - 2 | 3 | two | 0 | | 2 | 4 - 2 | 3 | two | 0 | | 5 | -5 - 2 | 3 | two | 0 | | 5 | -5 - 2 | 3 | two | 0 | | 0 | - 2 | 3 | two | 0 | | | - 2 | 3 | two | 0 | | | 0 - 3 | 2 | three | 0 | | 1 | -1 3 | 2 | three | 0 | | 2 | 2 - 3 | 2 | three | 0 | | 3 | -3 - 3 | 2 | three | 0 | | 2 | 4 - 3 | 2 | three | 0 | | 5 | -5 - 3 | 2 | three | 0 | | 5 | -5 - 3 | 2 | three | 0 | | 0 | - 3 | 2 | three | 0 | | | - 3 | 2 | three | 0 | | | 0 - 4 | 1 | four | 0 | | 1 | -1 4 | 1 | four | 0 | | 2 | 2 - 4 | 1 | four | 0 | | 3 | -3 - 4 | 1 | four | 0 | | 2 | 4 - 4 | 1 | four | 0 | | 5 | -5 - 4 | 1 | four | 0 | | 5 | -5 - 4 | 1 | four | 0 | | 0 | - 4 | 1 | four | 0 | | | - 4 | 1 | four | 0 | | | 0 - 5 | 0 | five | 0 | | 1 | -1 - 5 | 0 | five | 0 | | 2 | 2 - 5 | 0 | five | 0 | | 3 | -3 - 5 | 0 | five | 0 | | 2 | 4 - 5 | 0 | five | 0 | | 5 | -5 - 5 | 0 | five | 0 | | 5 | -5 - 5 | 0 | five | 0 | | 0 | - 5 | 0 | five | 0 | | | - 5 | 0 | five | 0 | | | 0 - 6 | 6 | six | 0 | | 1 | -1 - 6 | 6 | six | 0 | | 2 | 2 - 6 | 6 | six | 0 | | 3 | -3 - 6 | 6 | six | 0 | | 2 | 4 - 6 | 6 | six | 0 | | 5 | -5 - 6 | 6 | six | 0 | | 5 | -5 - 6 | 6 | six | 0 | | 0 | - 6 | 6 | six | 0 | | | - 6 | 6 | six | 0 | | | 0 - 7 | 7 | seven | 0 | | 1 | -1 7 | 7 | seven | 0 | | 2 | 2 - 7 | 7 | seven | 0 | | 3 | -3 - 7 | 7 | seven | 0 | | 2 | 4 - 7 | 7 | seven | 0 | | 5 | -5 - 7 | 7 | seven | 0 | | 5 | -5 - 7 | 7 | seven | 0 | | 0 | - 7 | 7 | seven | 0 | | | - 7 | 7 | seven | 0 | | | 0 - 8 | 8 | eight | 0 | | 1 | -1 8 | 8 | eight | 0 | | 2 | 2 - 8 | 8 | eight | 0 | | 3 | -3 - 8 | 8 | eight | 0 | | 2 | 4 - 8 | 8 | eight | 0 | | 5 | -5 - 8 | 8 | eight | 0 | | 5 | -5 - 8 | 8 | eight | 0 | | 0 | - 8 | 8 | eight | 0 | | | - 8 | 8 | eight | 0 | | | 0 - 0 | | zero | 0 | | 1 | -1 - 0 | | zero | 0 | | 2 | 2 - 0 | | zero | 0 | | 3 | -3 - 0 | | zero | 0 | | 2 | 4 - 0 | | zero | 0 | | 5 | -5 - 0 | | zero | 0 | | 5 | -5 - 0 | | zero | 0 | | 0 | - 0 | | zero | 0 | | | - 0 | | zero | 0 | | | 0 - | | null | 0 | | 1 | -1 | | null | 0 | | 2 | 2 - | | null | 0 | | 3 | -3 - | | null | 0 | | 2 | 4 - | | null | 0 | | 5 | -5 - | | null | 0 | | 5 | -5 - | | null | 0 | | 0 | - | | null | 0 | | | - | | null | 0 | | | 0 - | 0 | zero | 0 | | 1 | -1 | 0 | zero | 0 | | 2 | 2 + 2 | 3 | two | 0 | | 3 | -3 + 3 | 2 | three | 0 | | 3 | -3 + 4 | 1 | four | 0 | | 3 | -3 + 7 | 7 | seven | 0 | | 3 | -3 + 8 | 8 | eight | 0 | | 3 | -3 + | | null | 0 | | 3 | -3 | 0 | zero | 0 | | 3 | -3 + 2 | 3 | two | 0 | | 2 | 4 + 3 | 2 | three | 0 | | 2 | 4 + 4 | 1 | four | 0 | | 2 | 4 + 7 | 7 | seven | 0 | | 2 | 4 + 8 | 8 | eight | 0 | | 2 | 4 + | | null | 0 | | 2 | 4 | 0 | zero | 0 | | 2 | 4 - | 0 | zero | 0 | | 5 | -5 - | 0 | zero | 0 | | 5 | -5 - | 0 | zero | 0 | | 0 | + 2 | 3 | two | 0 | | | + 3 | 2 | three | 0 | | | + 4 | 1 | four | 0 | | | + 7 | 7 | seven | 0 | | | + 8 | 8 | eight | 0 | | | + | | null | 0 | | | | 0 | zero | 0 | | | + 2 | 3 | two | 0 | | | 0 + 3 | 2 | three | 0 | | | 0 + 4 | 1 | four | 0 | | | 0 + 7 | 7 | seven | 0 | | | 0 + 8 | 8 | eight | 0 | | | 0 + | | null | 0 | | | 0 | 0 | zero | 0 | | | 0 - 1 | 4 | one | | | 1 | -1 - 1 | 4 | one | | | 2 | 2 - 1 | 4 | one | | | 3 | -3 - 1 | 4 | one | | | 2 | 4 - 1 | 4 | one | | | 5 | -5 - 1 | 4 | one | | | 5 | -5 - 1 | 4 | one | | | 0 | - 1 | 4 | one | | | | - 1 | 4 | one | | | | 0 - 2 | 3 | two | | | 1 | -1 - 2 | 3 | two | | | 2 | 2 - 2 | 3 | two | | | 3 | -3 - 2 | 3 | two | | | 2 | 4 - 2 | 3 | two | | | 5 | -5 - 2 | 3 | two | | | 5 | -5 - 2 | 3 | two | | | 0 | - 2 | 3 | two | | | | - 2 | 3 | two | | | | 0 - 3 | 2 | three | | | 1 | -1 - 3 | 2 | three | | | 2 | 2 - 3 | 2 | three | | | 3 | -3 - 3 | 2 | three | | | 2 | 4 - 3 | 2 | three | | | 5 | -5 - 3 | 2 | three | | | 5 | -5 - 3 | 2 | three | | | 0 | - 3 | 2 | three | | | | - 3 | 2 | three | | | | 0 - 4 | 1 | four | | | 1 | -1 - 4 | 1 | four | | | 2 | 2 - 4 | 1 | four | | | 3 | -3 - 4 | 1 | four | | | 2 | 4 - 4 | 1 | four | | | 5 | -5 - 4 | 1 | four | | | 5 | -5 - 4 | 1 | four | | | 0 | - 4 | 1 | four | | | | - 4 | 1 | four | | | | 0 - 5 | 0 | five | | | 1 | -1 - 5 | 0 | five | | | 2 | 2 - 5 | 0 | five | | | 3 | -3 - 5 | 0 | five | | | 2 | 4 - 5 | 0 | five | | | 5 | -5 - 5 | 0 | five | | | 5 | -5 - 5 | 0 | five | | | 0 | - 5 | 0 | five | | | | - 5 | 0 | five | | | | 0 - 6 | 6 | six | | | 1 | -1 - 6 | 6 | six | | | 2 | 2 - 6 | 6 | six | | | 3 | -3 - 6 | 6 | six | | | 2 | 4 - 6 | 6 | six | | | 5 | -5 - 6 | 6 | six | | | 5 | -5 - 6 | 6 | six | | | 0 | - 6 | 6 | six | | | | - 6 | 6 | six | | | | 0 - 7 | 7 | seven | | | 1 | -1 + 2 | 3 | two | 5 | -5 | 2 | 2 + 3 | 2 | three | 5 | -5 | 2 | 2 + 4 | 1 | four | 5 | -5 | 2 | 2 + 7 | 7 | seven | 5 | -5 | 2 | 2 + 8 | 8 | eight | 5 | -5 | 2 | 2 + | | null | 5 | -5 | 2 | 2 + | 0 | zero | 5 | -5 | 2 | 2 + 2 | 3 | two | 5 | -5 | 3 | -3 + 3 | 2 | three | 5 | -5 | 3 | -3 + 4 | 1 | four | 5 | -5 | 3 | -3 + 7 | 7 | seven | 5 | -5 | 3 | -3 + 8 | 8 | eight | 5 | -5 | 3 | -3 + | | null | 5 | -5 | 3 | -3 + | 0 | zero | 5 | -5 | 3 | -3 + 2 | 3 | two | 5 | -5 | 2 | 4 + 3 | 2 | three | 5 | -5 | 2 | 4 + 4 | 1 | four | 5 | -5 | 2 | 4 + 7 | 7 | seven | 5 | -5 | 2 | 4 + 8 | 8 | eight | 5 | -5 | 2 | 4 + | | null | 5 | -5 | 2 | 4 + | 0 | zero | 5 | -5 | 2 | 4 + 2 | 3 | two | 5 | -5 | | + 3 | 2 | three | 5 | -5 | | + 4 | 1 | four | 5 | -5 | | + 7 | 7 | seven | 5 | -5 | | + 8 | 8 | eight | 5 | -5 | | + | | null | 5 | -5 | | + | 0 | zero | 5 | -5 | | + 2 | 3 | two | 5 | -5 | | 0 + 3 | 2 | three | 5 | -5 | | 0 + 4 | 1 | four | 5 | -5 | | 0 + 7 | 7 | seven | 5 | -5 | | 0 + 8 | 8 | eight | 5 | -5 | | 0 + | | null | 5 | -5 | | 0 + | 0 | zero | 5 | -5 | | 0 + 2 | 3 | two | 5 | -5 | 2 | 2 + 3 | 2 | three | 5 | -5 | 2 | 2 + 4 | 1 | four | 5 | -5 | 2 | 2 + 7 | 7 | seven | 5 | -5 | 2 | 2 + 8 | 8 | eight | 5 | -5 | 2 | 2 + | | null | 5 | -5 | 2 | 2 + | 0 | zero | 5 | -5 | 2 | 2 + 2 | 3 | two | 5 | -5 | 3 | -3 + 3 | 2 | three | 5 | -5 | 3 | -3 + 4 | 1 | four | 5 | -5 | 3 | -3 + 7 | 7 | seven | 5 | -5 | 3 | -3 + 8 | 8 | eight | 5 | -5 | 3 | -3 + | | null | 5 | -5 | 3 | -3 + | 0 | zero | 5 | -5 | 3 | -3 + 2 | 3 | two | 5 | -5 | 2 | 4 + 3 | 2 | three | 5 | -5 | 2 | 4 + 4 | 1 | four | 5 | -5 | 2 | 4 + 7 | 7 | seven | 5 | -5 | 2 | 4 + 8 | 8 | eight | 5 | -5 | 2 | 4 + | | null | 5 | -5 | 2 | 4 + | 0 | zero | 5 | -5 | 2 | 4 + 2 | 3 | two | 5 | -5 | | + 3 | 2 | three | 5 | -5 | | + 4 | 1 | four | 5 | -5 | | + 7 | 7 | seven | 5 | -5 | | + 8 | 8 | eight | 5 | -5 | | + | | null | 5 | -5 | | + | 0 | zero | 5 | -5 | | + 2 | 3 | two | 5 | -5 | | 0 + 3 | 2 | three | 5 | -5 | | 0 + 4 | 1 | four | 5 | -5 | | 0 + 7 | 7 | seven | 5 | -5 | | 0 + 8 | 8 | eight | 5 | -5 | | 0 + | | null | 5 | -5 | | 0 + | 0 | zero | 5 | -5 | | 0 + 2 | 3 | two | 2 | 2 | 2 | 2 + 3 | 2 | three | 2 | 2 | 2 | 2 + 4 | 1 | four | 2 | 2 | 2 | 2 + 7 | 7 | seven | 2 | 2 | 2 | 2 + 8 | 8 | eight | 2 | 2 | 2 | 2 + | | null | 2 | 2 | 2 | 2 + | 0 | zero | 2 | 2 | 2 | 2 + 2 | 3 | two | 2 | 2 | 3 | -3 + 3 | 2 | three | 2 | 2 | 3 | -3 + 4 | 1 | four | 2 | 2 | 3 | -3 + 7 | 7 | seven | 2 | 2 | 3 | -3 + 8 | 8 | eight | 2 | 2 | 3 | -3 + | | null | 2 | 2 | 3 | -3 + | 0 | zero | 2 | 2 | 3 | -3 + 2 | 3 | two | 2 | 2 | 2 | 4 + 3 | 2 | three | 2 | 2 | 2 | 4 + 4 | 1 | four | 2 | 2 | 2 | 4 + 7 | 7 | seven | 2 | 2 | 2 | 4 + 8 | 8 | eight | 2 | 2 | 2 | 4 + | | null | 2 | 2 | 2 | 4 + | 0 | zero | 2 | 2 | 2 | 4 + 2 | 3 | two | 2 | 2 | | + 3 | 2 | three | 2 | 2 | | + 4 | 1 | four | 2 | 2 | | + 7 | 7 | seven | 2 | 2 | | + 8 | 8 | eight | 2 | 2 | | + | | null | 2 | 2 | | + | 0 | zero | 2 | 2 | | + 2 | 3 | two | 2 | 2 | | 0 + 3 | 2 | three | 2 | 2 | | 0 + 4 | 1 | four | 2 | 2 | | 0 + 7 | 7 | seven | 2 | 2 | | 0 + 8 | 8 | eight | 2 | 2 | | 0 + | | null | 2 | 2 | | 0 + | 0 | zero | 2 | 2 | | 0 + 2 | 3 | two | 3 | -3 | 2 | 2 + 3 | 2 | three | 3 | -3 | 2 | 2 + 4 | 1 | four | 3 | -3 | 2 | 2 + 7 | 7 | seven | 3 | -3 | 2 | 2 + 8 | 8 | eight | 3 | -3 | 2 | 2 + | | null | 3 | -3 | 2 | 2 + | 0 | zero | 3 | -3 | 2 | 2 + 2 | 3 | two | 3 | -3 | 3 | -3 + 3 | 2 | three | 3 | -3 | 3 | -3 + 4 | 1 | four | 3 | -3 | 3 | -3 + 7 | 7 | seven | 3 | -3 | 3 | -3 + 8 | 8 | eight | 3 | -3 | 3 | -3 + | | null | 3 | -3 | 3 | -3 + | 0 | zero | 3 | -3 | 3 | -3 + 2 | 3 | two | 3 | -3 | 2 | 4 + 3 | 2 | three | 3 | -3 | 2 | 4 + 4 | 1 | four | 3 | -3 | 2 | 4 + 7 | 7 | seven | 3 | -3 | 2 | 4 + 8 | 8 | eight | 3 | -3 | 2 | 4 + | | null | 3 | -3 | 2 | 4 + | 0 | zero | 3 | -3 | 2 | 4 + 2 | 3 | two | 3 | -3 | | + 3 | 2 | three | 3 | -3 | | + 4 | 1 | four | 3 | -3 | | + 7 | 7 | seven | 3 | -3 | | + 8 | 8 | eight | 3 | -3 | | + | | null | 3 | -3 | | + | 0 | zero | 3 | -3 | | + 2 | 3 | two | 3 | -3 | | 0 + 3 | 2 | three | 3 | -3 | | 0 + 4 | 1 | four | 3 | -3 | | 0 + 7 | 7 | seven | 3 | -3 | | 0 + 8 | 8 | eight | 3 | -3 | | 0 + | | null | 3 | -3 | | 0 + | 0 | zero | 3 | -3 | | 0 + 2 | 3 | two | 2 | 4 | 2 | 2 + 3 | 2 | three | 2 | 4 | 2 | 2 + 4 | 1 | four | 2 | 4 | 2 | 2 + 7 | 7 | seven | 2 | 4 | 2 | 2 + 8 | 8 | eight | 2 | 4 | 2 | 2 + | | null | 2 | 4 | 2 | 2 + | 0 | zero | 2 | 4 | 2 | 2 + 2 | 3 | two | 2 | 4 | 3 | -3 + 3 | 2 | three | 2 | 4 | 3 | -3 + 4 | 1 | four | 2 | 4 | 3 | -3 + 7 | 7 | seven | 2 | 4 | 3 | -3 + 8 | 8 | eight | 2 | 4 | 3 | -3 + | | null | 2 | 4 | 3 | -3 + | 0 | zero | 2 | 4 | 3 | -3 + 2 | 3 | two | 2 | 4 | 2 | 4 + 3 | 2 | three | 2 | 4 | 2 | 4 + 4 | 1 | four | 2 | 4 | 2 | 4 + 7 | 7 | seven | 2 | 4 | 2 | 4 + 8 | 8 | eight | 2 | 4 | 2 | 4 + | | null | 2 | 4 | 2 | 4 + | 0 | zero | 2 | 4 | 2 | 4 + 2 | 3 | two | 2 | 4 | | + 3 | 2 | three | 2 | 4 | | + 4 | 1 | four | 2 | 4 | | + 7 | 7 | seven | 2 | 4 | | + 8 | 8 | eight | 2 | 4 | | + | | null | 2 | 4 | | + | 0 | zero | 2 | 4 | | + 2 | 3 | two | 2 | 4 | | 0 + 3 | 2 | three | 2 | 4 | | 0 + 4 | 1 | four | 2 | 4 | | 0 + 7 | 7 | seven | 2 | 4 | | 0 + 8 | 8 | eight | 2 | 4 | | 0 + | | null | 2 | 4 | | 0 + | 0 | zero | 2 | 4 | | 0 + 2 | 3 | two | | | 2 | 2 + 3 | 2 | three | | | 2 | 2 + 4 | 1 | four | | | 2 | 2 7 | 7 | seven | | | 2 | 2 - 7 | 7 | seven | | | 3 | -3 - 7 | 7 | seven | | | 2 | 4 - 7 | 7 | seven | | | 5 | -5 - 7 | 7 | seven | | | 5 | -5 - 7 | 7 | seven | | | 0 | - 7 | 7 | seven | | | | - 7 | 7 | seven | | | | 0 - 8 | 8 | eight | | | 1 | -1 8 | 8 | eight | | | 2 | 2 - 8 | 8 | eight | | | 3 | -3 - 8 | 8 | eight | | | 2 | 4 - 8 | 8 | eight | | | 5 | -5 - 8 | 8 | eight | | | 5 | -5 - 8 | 8 | eight | | | 0 | - 8 | 8 | eight | | | | - 8 | 8 | eight | | | | 0 - 0 | | zero | | | 1 | -1 - 0 | | zero | | | 2 | 2 - 0 | | zero | | | 3 | -3 - 0 | | zero | | | 2 | 4 - 0 | | zero | | | 5 | -5 - 0 | | zero | | | 5 | -5 - 0 | | zero | | | 0 | - 0 | | zero | | | | - 0 | | zero | | | | 0 - | | null | | | 1 | -1 | | null | | | 2 | 2 - | | null | | | 3 | -3 - | | null | | | 2 | 4 - | | null | | | 5 | -5 - | | null | | | 5 | -5 - | | null | | | 0 | - | | null | | | | - | | null | | | | 0 - | 0 | zero | | | 1 | -1 | 0 | zero | | | 2 | 2 + 2 | 3 | two | | | 3 | -3 + 3 | 2 | three | | | 3 | -3 + 4 | 1 | four | | | 3 | -3 + 7 | 7 | seven | | | 3 | -3 + 8 | 8 | eight | | | 3 | -3 + | | null | | | 3 | -3 | 0 | zero | | | 3 | -3 + 2 | 3 | two | | | 2 | 4 + 3 | 2 | three | | | 2 | 4 + 4 | 1 | four | | | 2 | 4 + 7 | 7 | seven | | | 2 | 4 + 8 | 8 | eight | | | 2 | 4 + | | null | | | 2 | 4 | 0 | zero | | | 2 | 4 - | 0 | zero | | | 5 | -5 - | 0 | zero | | | 5 | -5 - | 0 | zero | | | 0 | + 2 | 3 | two | | | | + 3 | 2 | three | | | | + 4 | 1 | four | | | | + 7 | 7 | seven | | | | + 8 | 8 | eight | | | | + | | null | | | | | 0 | zero | | | | + 2 | 3 | two | | | | 0 + 3 | 2 | three | | | | 0 + 4 | 1 | four | | | | 0 + 7 | 7 | seven | | | | 0 + 8 | 8 | eight | | | | 0 + | | null | | | | 0 | 0 | zero | | | | 0 - 1 | 4 | one | | 0 | 1 | -1 - 1 | 4 | one | | 0 | 2 | 2 - 1 | 4 | one | | 0 | 3 | -3 - 1 | 4 | one | | 0 | 2 | 4 - 1 | 4 | one | | 0 | 5 | -5 - 1 | 4 | one | | 0 | 5 | -5 - 1 | 4 | one | | 0 | 0 | - 1 | 4 | one | | 0 | | - 1 | 4 | one | | 0 | | 0 - 2 | 3 | two | | 0 | 1 | -1 2 | 3 | two | | 0 | 2 | 2 - 2 | 3 | two | | 0 | 3 | -3 - 2 | 3 | two | | 0 | 2 | 4 - 2 | 3 | two | | 0 | 5 | -5 - 2 | 3 | two | | 0 | 5 | -5 - 2 | 3 | two | | 0 | 0 | - 2 | 3 | two | | 0 | | - 2 | 3 | two | | 0 | | 0 - 3 | 2 | three | | 0 | 1 | -1 3 | 2 | three | | 0 | 2 | 2 - 3 | 2 | three | | 0 | 3 | -3 - 3 | 2 | three | | 0 | 2 | 4 - 3 | 2 | three | | 0 | 5 | -5 - 3 | 2 | three | | 0 | 5 | -5 - 3 | 2 | three | | 0 | 0 | - 3 | 2 | three | | 0 | | - 3 | 2 | three | | 0 | | 0 - 4 | 1 | four | | 0 | 1 | -1 4 | 1 | four | | 0 | 2 | 2 + 7 | 7 | seven | | 0 | 2 | 2 + 8 | 8 | eight | | 0 | 2 | 2 + | | null | | 0 | 2 | 2 + | 0 | zero | | 0 | 2 | 2 + 2 | 3 | two | | 0 | 3 | -3 + 3 | 2 | three | | 0 | 3 | -3 4 | 1 | four | | 0 | 3 | -3 + 7 | 7 | seven | | 0 | 3 | -3 + 8 | 8 | eight | | 0 | 3 | -3 + | | null | | 0 | 3 | -3 + | 0 | zero | | 0 | 3 | -3 + 2 | 3 | two | | 0 | 2 | 4 + 3 | 2 | three | | 0 | 2 | 4 4 | 1 | four | | 0 | 2 | 4 - 4 | 1 | four | | 0 | 5 | -5 - 4 | 1 | four | | 0 | 5 | -5 - 4 | 1 | four | | 0 | 0 | + 7 | 7 | seven | | 0 | 2 | 4 + 8 | 8 | eight | | 0 | 2 | 4 + | | null | | 0 | 2 | 4 + | 0 | zero | | 0 | 2 | 4 + 2 | 3 | two | | 0 | | + 3 | 2 | three | | 0 | | 4 | 1 | four | | 0 | | + 7 | 7 | seven | | 0 | | + 8 | 8 | eight | | 0 | | + | | null | | 0 | | + | 0 | zero | | 0 | | + 2 | 3 | two | | 0 | | 0 + 3 | 2 | three | | 0 | | 0 4 | 1 | four | | 0 | | 0 + 7 | 7 | seven | | 0 | | 0 + 8 | 8 | eight | | 0 | | 0 + | | null | | 0 | | 0 + | 0 | zero | | 0 | | 0 + 5 | 0 | five | 1 | -1 | 5 | -5 + 6 | 6 | six | 1 | -1 | 5 | -5 + 5 | 0 | five | 1 | -1 | 5 | -5 + 6 | 6 | six | 1 | -1 | 5 | -5 + 5 | 0 | five | 0 | | 5 | -5 + 6 | 6 | six | 0 | | 5 | -5 + 5 | 0 | five | 0 | | 5 | -5 + 6 | 6 | six | 0 | | 5 | -5 + 5 | 0 | five | 5 | -5 | 5 | -5 + 6 | 6 | six | 5 | -5 | 5 | -5 + 5 | 0 | five | 5 | -5 | 5 | -5 + 6 | 6 | six | 5 | -5 | 5 | -5 + 5 | 0 | five | 5 | -5 | 5 | -5 + 6 | 6 | six | 5 | -5 | 5 | -5 + 5 | 0 | five | 5 | -5 | 5 | -5 + 6 | 6 | six | 5 | -5 | 5 | -5 + 5 | 0 | five | 2 | 2 | 5 | -5 + 6 | 6 | six | 2 | 2 | 5 | -5 + 5 | 0 | five | 2 | 2 | 5 | -5 + 6 | 6 | six | 2 | 2 | 5 | -5 + 5 | 0 | five | 3 | -3 | 5 | -5 + 6 | 6 | six | 3 | -3 | 5 | -5 + 5 | 0 | five | 3 | -3 | 5 | -5 + 6 | 6 | six | 3 | -3 | 5 | -5 + 5 | 0 | five | 2 | 4 | 5 | -5 + 6 | 6 | six | 2 | 4 | 5 | -5 + 5 | 0 | five | 2 | 4 | 5 | -5 + 6 | 6 | six | 2 | 4 | 5 | -5 + 5 | 0 | five | | | 5 | -5 + 6 | 6 | six | | | 5 | -5 + 5 | 0 | five | | | 5 | -5 + 6 | 6 | six | | | 5 | -5 + 5 | 0 | five | | 0 | 5 | -5 + 6 | 6 | six | | 0 | 5 | -5 + 5 | 0 | five | | 0 | 5 | -5 + 6 | 6 | six | | 0 | 5 | -5 + 5 | 0 | five | 2 | 2 | 1 | -1 + 6 | 6 | six | 2 | 2 | 1 | -1 + 5 | 0 | five | 2 | 2 | 0 | + 6 | 6 | six | 2 | 2 | 0 | + 5 | 0 | five | 3 | -3 | 1 | -1 + 6 | 6 | six | 3 | -3 | 1 | -1 + 5 | 0 | five | 3 | -3 | 0 | + 6 | 6 | six | 3 | -3 | 0 | + 5 | 0 | five | 2 | 4 | 1 | -1 + 6 | 6 | six | 2 | 4 | 1 | -1 + 5 | 0 | five | 2 | 4 | 0 | + 6 | 6 | six | 2 | 4 | 0 | + 5 | 0 | five | | | 1 | -1 + 6 | 6 | six | | | 1 | -1 + 5 | 0 | five | | | 0 | + 6 | 6 | six | | | 0 | 5 | 0 | five | | 0 | 1 | -1 + 6 | 6 | six | | 0 | 1 | -1 + 5 | 0 | five | | 0 | 0 | + 6 | 6 | six | | 0 | 0 | + 5 | 0 | five | 1 | -1 | 1 | -1 + 6 | 6 | six | 1 | -1 | 1 | -1 + 5 | 0 | five | 1 | -1 | 0 | + 6 | 6 | six | 1 | -1 | 0 | + 5 | 0 | five | 0 | | 1 | -1 + 6 | 6 | six | 0 | | 1 | -1 + 5 | 0 | five | 0 | | 0 | + 6 | 6 | six | 0 | | 0 | + 5 | 0 | five | 5 | -5 | 1 | -1 + 6 | 6 | six | 5 | -5 | 1 | -1 + 5 | 0 | five | 5 | -5 | 0 | + 6 | 6 | six | 5 | -5 | 0 | + 5 | 0 | five | 5 | -5 | 1 | -1 + 6 | 6 | six | 5 | -5 | 1 | -1 + 5 | 0 | five | 5 | -5 | 0 | + 6 | 6 | six | 5 | -5 | 0 | + 5 | 0 | five | 1 | -1 | 2 | 2 + 6 | 6 | six | 1 | -1 | 2 | 2 + 5 | 0 | five | 1 | -1 | 3 | -3 + 6 | 6 | six | 1 | -1 | 3 | -3 + 5 | 0 | five | 1 | -1 | 2 | 4 + 6 | 6 | six | 1 | -1 | 2 | 4 + 5 | 0 | five | 1 | -1 | | + 6 | 6 | six | 1 | -1 | | + 5 | 0 | five | 1 | -1 | | 0 + 6 | 6 | six | 1 | -1 | | 0 + 5 | 0 | five | 0 | | 2 | 2 + 6 | 6 | six | 0 | | 2 | 2 + 5 | 0 | five | 0 | | 3 | -3 + 6 | 6 | six | 0 | | 3 | -3 + 5 | 0 | five | 0 | | 2 | 4 + 6 | 6 | six | 0 | | 2 | 4 + 5 | 0 | five | 0 | | | + 6 | 6 | six | 0 | | | + 5 | 0 | five | 0 | | | 0 + 6 | 6 | six | 0 | | | 0 + 5 | 0 | five | 5 | -5 | 2 | 2 + 6 | 6 | six | 5 | -5 | 2 | 2 + 5 | 0 | five | 5 | -5 | 3 | -3 + 6 | 6 | six | 5 | -5 | 3 | -3 + 5 | 0 | five | 5 | -5 | 2 | 4 + 6 | 6 | six | 5 | -5 | 2 | 4 + 5 | 0 | five | 5 | -5 | | + 6 | 6 | six | 5 | -5 | | + 5 | 0 | five | 5 | -5 | | 0 + 6 | 6 | six | 5 | -5 | | 0 + 5 | 0 | five | 5 | -5 | 2 | 2 + 6 | 6 | six | 5 | -5 | 2 | 2 + 5 | 0 | five | 5 | -5 | 3 | -3 + 6 | 6 | six | 5 | -5 | 3 | -3 + 5 | 0 | five | 5 | -5 | 2 | 4 + 6 | 6 | six | 5 | -5 | 2 | 4 + 5 | 0 | five | 5 | -5 | | + 6 | 6 | six | 5 | -5 | | + 5 | 0 | five | 5 | -5 | | 0 + 6 | 6 | six | 5 | -5 | | 0 + 5 | 0 | five | 2 | 2 | 2 | 2 + 6 | 6 | six | 2 | 2 | 2 | 2 + 5 | 0 | five | 2 | 2 | 3 | -3 + 6 | 6 | six | 2 | 2 | 3 | -3 + 5 | 0 | five | 2 | 2 | 2 | 4 + 6 | 6 | six | 2 | 2 | 2 | 4 + 5 | 0 | five | 2 | 2 | | + 6 | 6 | six | 2 | 2 | | + 5 | 0 | five | 2 | 2 | | 0 + 6 | 6 | six | 2 | 2 | | 0 + 5 | 0 | five | 3 | -3 | 2 | 2 + 6 | 6 | six | 3 | -3 | 2 | 2 + 5 | 0 | five | 3 | -3 | 3 | -3 + 6 | 6 | six | 3 | -3 | 3 | -3 + 5 | 0 | five | 3 | -3 | 2 | 4 + 6 | 6 | six | 3 | -3 | 2 | 4 + 5 | 0 | five | 3 | -3 | | + 6 | 6 | six | 3 | -3 | | + 5 | 0 | five | 3 | -3 | | 0 + 6 | 6 | six | 3 | -3 | | 0 + 5 | 0 | five | 2 | 4 | 2 | 2 + 6 | 6 | six | 2 | 4 | 2 | 2 + 5 | 0 | five | 2 | 4 | 3 | -3 + 6 | 6 | six | 2 | 4 | 3 | -3 + 5 | 0 | five | 2 | 4 | 2 | 4 + 6 | 6 | six | 2 | 4 | 2 | 4 + 5 | 0 | five | 2 | 4 | | + 6 | 6 | six | 2 | 4 | | + 5 | 0 | five | 2 | 4 | | 0 + 6 | 6 | six | 2 | 4 | | 0 + 5 | 0 | five | | | 2 | 2 + 6 | 6 | six | | | 2 | 2 + 5 | 0 | five | | | 3 | -3 + 6 | 6 | six | | | 3 | -3 + 5 | 0 | five | | | 2 | 4 + 6 | 6 | six | | | 2 | 4 + 5 | 0 | five | | | | + 6 | 6 | six | | | | + 5 | 0 | five | | | | 0 + 6 | 6 | six | | | | 0 5 | 0 | five | | 0 | 2 | 2 - 5 | 0 | five | | 0 | 3 | -3 - 5 | 0 | five | | 0 | 2 | 4 - 5 | 0 | five | | 0 | 5 | -5 - 5 | 0 | five | | 0 | 5 | -5 - 5 | 0 | five | | 0 | 0 | - 5 | 0 | five | | 0 | | - 5 | 0 | five | | 0 | | 0 - 6 | 6 | six | | 0 | 1 | -1 6 | 6 | six | | 0 | 2 | 2 + 5 | 0 | five | | 0 | 3 | -3 6 | 6 | six | | 0 | 3 | -3 + 5 | 0 | five | | 0 | 2 | 4 6 | 6 | six | | 0 | 2 | 4 - 6 | 6 | six | | 0 | 5 | -5 - 6 | 6 | six | | 0 | 5 | -5 - 6 | 6 | six | | 0 | 0 | + 5 | 0 | five | | 0 | | 6 | 6 | six | | 0 | | + 5 | 0 | five | | 0 | | 0 6 | 6 | six | | 0 | | 0 - 7 | 7 | seven | | 0 | 1 | -1 - 7 | 7 | seven | | 0 | 2 | 2 - 7 | 7 | seven | | 0 | 3 | -3 - 7 | 7 | seven | | 0 | 2 | 4 - 7 | 7 | seven | | 0 | 5 | -5 - 7 | 7 | seven | | 0 | 5 | -5 - 7 | 7 | seven | | 0 | 0 | - 7 | 7 | seven | | 0 | | - 7 | 7 | seven | | 0 | | 0 - 8 | 8 | eight | | 0 | 1 | -1 - 8 | 8 | eight | | 0 | 2 | 2 - 8 | 8 | eight | | 0 | 3 | -3 - 8 | 8 | eight | | 0 | 2 | 4 - 8 | 8 | eight | | 0 | 5 | -5 - 8 | 8 | eight | | 0 | 5 | -5 - 8 | 8 | eight | | 0 | 0 | - 8 | 8 | eight | | 0 | | - 8 | 8 | eight | | 0 | | 0 - 0 | | zero | | 0 | 1 | -1 - 0 | | zero | | 0 | 2 | 2 - 0 | | zero | | 0 | 3 | -3 - 0 | | zero | | 0 | 2 | 4 + 1 | 4 | one | 1 | -1 | 5 | -5 + 0 | | zero | 1 | -1 | 5 | -5 + 1 | 4 | one | 1 | -1 | 5 | -5 + 0 | | zero | 1 | -1 | 5 | -5 + 1 | 4 | one | 0 | | 5 | -5 + 0 | | zero | 0 | | 5 | -5 + 1 | 4 | one | 0 | | 5 | -5 + 0 | | zero | 0 | | 5 | -5 + 1 | 4 | one | 5 | -5 | 5 | -5 + 0 | | zero | 5 | -5 | 5 | -5 + 1 | 4 | one | 5 | -5 | 5 | -5 + 0 | | zero | 5 | -5 | 5 | -5 + 1 | 4 | one | 5 | -5 | 5 | -5 + 0 | | zero | 5 | -5 | 5 | -5 + 1 | 4 | one | 5 | -5 | 5 | -5 + 0 | | zero | 5 | -5 | 5 | -5 + 1 | 4 | one | 2 | 2 | 5 | -5 + 0 | | zero | 2 | 2 | 5 | -5 + 1 | 4 | one | 2 | 2 | 5 | -5 + 0 | | zero | 2 | 2 | 5 | -5 + 1 | 4 | one | 3 | -3 | 5 | -5 + 0 | | zero | 3 | -3 | 5 | -5 + 1 | 4 | one | 3 | -3 | 5 | -5 + 0 | | zero | 3 | -3 | 5 | -5 + 1 | 4 | one | 2 | 4 | 5 | -5 + 0 | | zero | 2 | 4 | 5 | -5 + 1 | 4 | one | 2 | 4 | 5 | -5 + 0 | | zero | 2 | 4 | 5 | -5 + 1 | 4 | one | | | 5 | -5 + 0 | | zero | | | 5 | -5 + 1 | 4 | one | | | 5 | -5 + 0 | | zero | | | 5 | -5 + 1 | 4 | one | | 0 | 5 | -5 0 | | zero | | 0 | 5 | -5 + 1 | 4 | one | | 0 | 5 | -5 0 | | zero | | 0 | 5 | -5 + 1 | 4 | one | 2 | 2 | 1 | -1 + 0 | | zero | 2 | 2 | 1 | -1 + 1 | 4 | one | 2 | 2 | 0 | + 0 | | zero | 2 | 2 | 0 | + 1 | 4 | one | 3 | -3 | 1 | -1 + 0 | | zero | 3 | -3 | 1 | -1 + 1 | 4 | one | 3 | -3 | 0 | + 0 | | zero | 3 | -3 | 0 | + 1 | 4 | one | 2 | 4 | 1 | -1 + 0 | | zero | 2 | 4 | 1 | -1 + 1 | 4 | one | 2 | 4 | 0 | + 0 | | zero | 2 | 4 | 0 | + 1 | 4 | one | | | 1 | -1 + 0 | | zero | | | 1 | -1 + 1 | 4 | one | | | 0 | + 0 | | zero | | | 0 | + 1 | 4 | one | | 0 | 1 | -1 + 0 | | zero | | 0 | 1 | -1 + 1 | 4 | one | | 0 | 0 | 0 | | zero | | 0 | 0 | - 0 | | zero | | 0 | | - 0 | | zero | | 0 | | 0 - | | null | | 0 | 1 | -1 - | | null | | 0 | 2 | 2 - | | null | | 0 | 3 | -3 - | | null | | 0 | 2 | 4 - | | null | | 0 | 5 | -5 - | | null | | 0 | 5 | -5 - | | null | | 0 | 0 | - | | null | | 0 | | - | | null | | 0 | | 0 - | 0 | zero | | 0 | 1 | -1 - | 0 | zero | | 0 | 2 | 2 - | 0 | zero | | 0 | 3 | -3 - | 0 | zero | | 0 | 2 | 4 - | 0 | zero | | 0 | 5 | -5 - | 0 | zero | | 0 | 5 | -5 - | 0 | zero | | 0 | 0 | - | 0 | zero | | 0 | | - | 0 | zero | | 0 | | 0 + 1 | 4 | one | 1 | -1 | 1 | -1 + 0 | | zero | 1 | -1 | 1 | -1 + 1 | 4 | one | 1 | -1 | 0 | + 0 | | zero | 1 | -1 | 0 | + 1 | 4 | one | 0 | | 1 | -1 + 0 | | zero | 0 | | 1 | -1 + 1 | 4 | one | 0 | | 0 | + 0 | | zero | 0 | | 0 | + 1 | 4 | one | 5 | -5 | 1 | -1 + 0 | | zero | 5 | -5 | 1 | -1 + 1 | 4 | one | 5 | -5 | 0 | + 0 | | zero | 5 | -5 | 0 | + 1 | 4 | one | 5 | -5 | 1 | -1 + 0 | | zero | 5 | -5 | 1 | -1 + 1 | 4 | one | 5 | -5 | 0 | + 0 | | zero | 5 | -5 | 0 | + 1 | 4 | one | 1 | -1 | 2 | 2 + 0 | | zero | 1 | -1 | 2 | 2 + 1 | 4 | one | 1 | -1 | 3 | -3 + 0 | | zero | 1 | -1 | 3 | -3 + 1 | 4 | one | 1 | -1 | 2 | 4 + 0 | | zero | 1 | -1 | 2 | 4 + 1 | 4 | one | 1 | -1 | | + 0 | | zero | 1 | -1 | | + 1 | 4 | one | 1 | -1 | | 0 + 0 | | zero | 1 | -1 | | 0 + 1 | 4 | one | 0 | | 2 | 2 + 0 | | zero | 0 | | 2 | 2 + 1 | 4 | one | 0 | | 3 | -3 + 0 | | zero | 0 | | 3 | -3 + 1 | 4 | one | 0 | | 2 | 4 + 0 | | zero | 0 | | 2 | 4 + 1 | 4 | one | 0 | | | + 0 | | zero | 0 | | | + 1 | 4 | one | 0 | | | 0 + 0 | | zero | 0 | | | 0 + 1 | 4 | one | 5 | -5 | 2 | 2 + 0 | | zero | 5 | -5 | 2 | 2 + 1 | 4 | one | 5 | -5 | 3 | -3 + 0 | | zero | 5 | -5 | 3 | -3 + 1 | 4 | one | 5 | -5 | 2 | 4 + 0 | | zero | 5 | -5 | 2 | 4 + 1 | 4 | one | 5 | -5 | | + 0 | | zero | 5 | -5 | | + 1 | 4 | one | 5 | -5 | | 0 + 0 | | zero | 5 | -5 | | 0 + 1 | 4 | one | 5 | -5 | 2 | 2 + 0 | | zero | 5 | -5 | 2 | 2 + 1 | 4 | one | 5 | -5 | 3 | -3 + 0 | | zero | 5 | -5 | 3 | -3 + 1 | 4 | one | 5 | -5 | 2 | 4 + 0 | | zero | 5 | -5 | 2 | 4 + 1 | 4 | one | 5 | -5 | | + 0 | | zero | 5 | -5 | | + 1 | 4 | one | 5 | -5 | | 0 + 0 | | zero | 5 | -5 | | 0 + 1 | 4 | one | 2 | 2 | 2 | 2 + 0 | | zero | 2 | 2 | 2 | 2 + 1 | 4 | one | 2 | 2 | 3 | -3 + 0 | | zero | 2 | 2 | 3 | -3 + 1 | 4 | one | 2 | 2 | 2 | 4 + 0 | | zero | 2 | 2 | 2 | 4 + 1 | 4 | one | 2 | 2 | | + 0 | | zero | 2 | 2 | | + 1 | 4 | one | 2 | 2 | | 0 + 0 | | zero | 2 | 2 | | 0 + 1 | 4 | one | 3 | -3 | 2 | 2 + 0 | | zero | 3 | -3 | 2 | 2 + 1 | 4 | one | 3 | -3 | 3 | -3 + 0 | | zero | 3 | -3 | 3 | -3 + 1 | 4 | one | 3 | -3 | 2 | 4 + 0 | | zero | 3 | -3 | 2 | 4 + 1 | 4 | one | 3 | -3 | | + 0 | | zero | 3 | -3 | | + 1 | 4 | one | 3 | -3 | | 0 + 0 | | zero | 3 | -3 | | 0 + 1 | 4 | one | 2 | 4 | 2 | 2 + 0 | | zero | 2 | 4 | 2 | 2 + 1 | 4 | one | 2 | 4 | 3 | -3 + 0 | | zero | 2 | 4 | 3 | -3 + 1 | 4 | one | 2 | 4 | 2 | 4 + 0 | | zero | 2 | 4 | 2 | 4 + 1 | 4 | one | 2 | 4 | | + 0 | | zero | 2 | 4 | | + 1 | 4 | one | 2 | 4 | | 0 + 0 | | zero | 2 | 4 | | 0 + 1 | 4 | one | | | 2 | 2 + 0 | | zero | | | 2 | 2 + 1 | 4 | one | | | 3 | -3 + 0 | | zero | | | 3 | -3 + 1 | 4 | one | | | 2 | 4 + 0 | | zero | | | 2 | 4 + 1 | 4 | one | | | | + 0 | | zero | | | | + 1 | 4 | one | | | | 0 + 0 | | zero | | | | 0 + 1 | 4 | one | | 0 | 2 | 2 + 0 | | zero | | 0 | 2 | 2 + 1 | 4 | one | | 0 | 3 | -3 + 0 | | zero | | 0 | 3 | -3 + 1 | 4 | one | | 0 | 2 | 4 + 0 | | zero | | 0 | 2 | 4 + 1 | 4 | one | | 0 | | + 0 | | zero | | 0 | | + 1 | 4 | one | | 0 | | 0 + 0 | | zero | | 0 | | 0 (891 rows) -- @@ -1578,13 +1578,13 @@ SELECT * FROM J1_TBL INNER JOIN J2_TBL USING (i); i | j | t | k ---+---+-------+---- - 0 | | zero | - 1 | 4 | one | -1 - 2 | 3 | two | 2 - 2 | 3 | two | 4 - 3 | 2 | three | -3 5 | 0 | five | -5 5 | 0 | five | -5 + 2 | 3 | two | 4 + 2 | 3 | two | 2 + 3 | 2 | three | -3 + 1 | 4 | one | -1 + 0 | | zero | (7 rows) -- Same as above, slightly different syntax @@ -1592,11 +1592,11 @@ SELECT * FROM J1_TBL JOIN J2_TBL USING (i); i | j | t | k ---+---+-------+---- - 0 | | zero | - 1 | 4 | one | -1 - 2 | 3 | two | 2 2 | 3 | two | 4 + 2 | 3 | two | 2 3 | 2 | three | -3 + 1 | 4 | one | -1 + 0 | | zero | 5 | 0 | five | -5 5 | 0 | five | -5 (7 rows) @@ -1686,10 +1686,10 @@ SELECT * FROM J1_TBL NATURAL JOIN J2_TBL; i | j | t | k ---+---+-------+---- - 0 | | zero | 1 | 4 | one | -1 - 2 | 3 | two | 2 + 0 | | zero | 2 | 3 | two | 4 + 2 | 3 | two | 2 3 | 2 | three | -3 5 | 0 | five | -5 5 | 0 | five | -5 @@ -1699,11 +1699,11 @@ SELECT * FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (a, d); a | b | c | d ---+---+-------+---- - 0 | | zero | - 1 | 4 | one | -1 - 2 | 3 | two | 2 2 | 3 | two | 4 + 2 | 3 | two | 2 3 | 2 | three | -3 + 1 | 4 | one | -1 + 0 | | zero | 5 | 0 | five | -5 5 | 0 | five | -5 (7 rows) @@ -1712,9 +1712,9 @@ SELECT * FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a); a | b | c | d ---+---+------+--- - 0 | | zero | 2 | 3 | two | 2 4 | 1 | four | 2 + 0 | | zero | (3 rows) -- mismatch number of columns @@ -1723,11 +1723,11 @@ SELECT * FROM J1_TBL t1 (a, b) NATURAL JOIN J2_TBL t2 (a); a | b | t | k ---+---+-------+---- - 0 | | zero | - 1 | 4 | one | -1 - 2 | 3 | two | 2 2 | 3 | two | 4 + 2 | 3 | two | 2 3 | 2 | three | -3 + 1 | 4 | one | -1 + 0 | | zero | 5 | 0 | five | -5 5 | 0 | five | -5 (7 rows) @@ -1739,13 +1739,13 @@ SELECT * FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.i); i | j | t | i | k ---+---+-------+---+---- - 0 | | zero | 0 | 1 | 4 | one | 1 | -1 - 2 | 3 | two | 2 | 2 - 2 | 3 | two | 2 | 4 - 3 | 2 | three | 3 | -3 + 0 | | zero | 0 | 5 | 0 | five | 5 | -5 5 | 0 | five | 5 | -5 + 2 | 3 | two | 2 | 4 + 2 | 3 | two | 2 | 2 + 3 | 2 | three | 3 | -3 (7 rows) SELECT * @@ -1764,13 +1764,13 @@ SELECT * FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i <= J2_TBL.k); i | j | t | i | k ---+---+-------+---+--- - 1 | 4 | one | 2 | 2 2 | 3 | two | 2 | 2 - 0 | | zero | 2 | 2 - 1 | 4 | one | 2 | 4 2 | 3 | two | 2 | 4 3 | 2 | three | 2 | 4 4 | 1 | four | 2 | 4 + 1 | 4 | one | 2 | 2 + 0 | | zero | 2 | 2 + 1 | 4 | one | 2 | 4 0 | | zero | 2 | 4 0 | | zero | | 0 (9 rows) @@ -1823,30 +1823,30 @@ SELECT * FROM J1_TBL RIGHT OUTER JOIN J2_TBL USING (i); i | j | t | k ---+---+-------+---- - 0 | | zero | 1 | 4 | one | -1 + 0 | | zero | 2 | 3 | two | 2 - 2 | 3 | two | 4 3 | 2 | three | -3 - 5 | 0 | five | -5 - 5 | 0 | five | -5 + 2 | 3 | two | 4 | | | | | | 0 + 5 | 0 | five | -5 + 5 | 0 | five | -5 (9 rows) SELECT * FROM J1_TBL RIGHT JOIN J2_TBL USING (i); i | j | t | k ---+---+-------+---- - 0 | | zero | - 1 | 4 | one | -1 2 | 3 | two | 2 - 2 | 3 | two | 4 3 | 2 | three | -3 - 5 | 0 | five | -5 - 5 | 0 | five | -5 + 2 | 3 | two | 4 | | | | | | 0 + 5 | 0 | five | -5 + 5 | 0 | five | -5 + 1 | 4 | one | -1 + 0 | | zero | (9 rows) SELECT * @@ -1909,33 +1909,43 @@ SELECT * -- -- semijoin selectivity for <> -- +-- start_ignore +-- GPDB: the exact plan shape depends on the optimizer (Postgres planner vs +-- GPORCA) and on MPP motion placement, so the plan is ignored here; this +-- query is retained from upstream only to exercise neqjoinsel's path. explain (costs off) -select * from int4_tbl i4, tenk1 a -where exists(select * from tenk1 b - where a.twothousand = b.twothousand and a.fivethous <> b.fivethous) - and i4.f1 = a.tenthous; - QUERY PLAN -------------------------------------------------------------------------- +select * from tenk1 a, tenk1 b +where exists(select * from tenk1 c + where b.twothousand = c.twothousand and b.fivethous <> c.fivethous) + and a.tenthous = b.tenthous and a.tenthous < 5000; + QUERY PLAN +-------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join - Hash Cond: (a.twothousand = b.twothousand) - Join Filter: (a.fivethous <> b.fivethous) + -> Hash Join + Hash Cond: (b.tenthous = a.tenthous) -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: a.twothousand - -> Nested Loop - Join Filter: true - -> Broadcast Motion 3:3 (slice3; segments: 3) - -> Seq Scan on int4_tbl i4 - -> Index Scan using tenk1_thous_tenthous on tenk1 a - Index Cond: (tenthous = i4.f1) - Filter: (NOT (twothousand IS NULL)) + Hash Key: b.tenthous + -> Hash Semi Join + Hash Cond: (b.twothousand = c.twothousand) + Join Filter: (b.fivethous <> c.fivethous) + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: b.twothousand + -> Index Scan using tenk1_thous_tenthous on tenk1 b + Index Cond: (tenthous < 5000) + Filter: (NOT (twothousand IS NULL)) + -> Hash + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: c.twothousand + -> Seq Scan on tenk1 c -> Hash - -> Redistribute Motion 3:3 (slice4; segments: 3) - Hash Key: b.twothousand - -> Seq Scan on tenk1 b + -> Redistribute Motion 3:3 (slice5; segments: 3) + Hash Key: a.tenthous + -> Index Scan using tenk1_thous_tenthous on tenk1 a + Index Cond: (tenthous < 5000) Optimizer: GPORCA -(18 rows) +(23 rows) +-- end_ignore -- -- More complicated constructs -- @@ -1963,8 +1973,8 @@ SELECT * FROM t1 FULL JOIN t2 USING (name) FULL JOIN t3 USING (name); ------+----+----+---- bb | 11 | 12 | 13 cc | | 22 | 23 - dd | | | 33 ee | | 42 | + dd | | | 33 (4 rows) -- @@ -1978,8 +1988,8 @@ INNER JOIN USING (name); name | n | n ------+----+---- - bb | 12 | 13 cc | 22 | 23 + bb | 12 | 13 (2 rows) SELECT * FROM @@ -1989,9 +1999,9 @@ LEFT JOIN USING (name); name | n | n ------+----+---- - bb | 12 | 13 - ee | 42 | cc | 22 | 23 + ee | 42 | + bb | 12 | 13 (3 rows) SELECT * FROM @@ -2001,10 +2011,10 @@ FULL JOIN USING (name); name | n | n ------+----+---- + cc | 22 | 23 + ee | 42 | bb | 12 | 13 dd | | 33 - ee | 42 | - cc | 22 | 23 (4 rows) -- Cases with non-nullable expressions in subquery results; @@ -2026,8 +2036,8 @@ NATURAL LEFT JOIN name | s2_n | s2_2 | s3_n | s3_2 ------+------+------+------+------ ee | 42 | 2 | | - bb | 12 | 2 | 13 | 3 cc | 22 | 2 | 23 | 3 + bb | 12 | 2 | 13 | 3 (3 rows) SELECT * FROM @@ -2036,10 +2046,10 @@ NATURAL FULL JOIN (SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; name | s2_n | s2_2 | s3_n | s3_2 ------+------+------+------+------ + cc | 22 | 2 | 23 | 3 bb | 12 | 2 | 13 | 3 dd | | | 33 | 3 ee | 42 | 2 | | - cc | 22 | 2 | 23 | 3 (4 rows) SELECT * FROM @@ -2063,8 +2073,8 @@ NATURAL FULL JOIN ------+------+------+------+------+------+------ bb | 11 | 1 | 12 | 2 | 13 | 3 cc | | | 22 | 2 | 23 | 3 - dd | | | | | 33 | 3 ee | | | 42 | 2 | | + dd | | | | | 33 | 3 (4 rows) SELECT * FROM @@ -2077,9 +2087,9 @@ NATURAL FULL JOIN ) ss2; name | s1_n | s2_n | s3_n ------+------+------+------ + ee | | 42 | bb | 11 | 12 | 13 dd | | | 33 - ee | | 42 | cc | | 22 | 23 (4 rows) @@ -2107,10 +2117,10 @@ FULL JOIN ON (s1_n = s2_n); name | s1_n | name | s2_n ------+------+------+------ - | | ee | 2 + bb | 11 | | | | bb | 2 | | cc | 2 - bb | 11 | | + | | ee | 2 (4 rows) -- Test for propagation of nullability constraints into sub-joins @@ -2135,8 +2145,8 @@ select * from x; 2 | 22 3 | 4 | 44 - 1 | 11 5 | + 1 | 11 (5 rows) select * from y; @@ -2151,29 +2161,29 @@ select * from y; select * from x left join y on (x1 = y1 and x2 is not null); x1 | x2 | y1 | y2 ----+----+----+----- - 1 | 11 | 1 | 111 - 5 | | | 2 | 22 | 2 | 222 3 | | | 4 | 44 | 4 | + 1 | 11 | 1 | 111 + 5 | | | (5 rows) select * from x left join y on (x1 = y1 and y2 is not null); x1 | x2 | y1 | y2 ----+----+----+----- + 1 | 11 | 1 | 111 + 5 | | | 2 | 22 | 2 | 222 3 | | 3 | 333 4 | 44 | | - 1 | 11 | 1 | 111 - 5 | | | (5 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 5 | | | | 5 | + 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | 3 | 4 | 44 | 4 | | 4 | 44 @@ -2183,21 +2193,21 @@ select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1 and x2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | | 4 | 44 | 4 | | 4 | 44 5 | | | | | + 1 | 11 | 1 | 111 | 1 | 11 (5 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1 and y2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 5 | | | | | 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | 3 | 4 | 44 | 4 | | | + 5 | | | | | 1 | 11 | 1 | 111 | 1 | 11 (5 rows) @@ -2206,10 +2216,10 @@ on (x1 = xx1 and xx2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- 1 | 11 | 1 | 111 | 1 | 11 - 5 | | | | | 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | | 4 | 44 | 4 | | 4 | 44 + 5 | | | | | (5 rows) -- these should NOT give the same answers as above @@ -2217,9 +2227,9 @@ select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1) where (x2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 4 | 44 | 4 | | 4 | 44 + 1 | 11 | 1 | 111 | 1 | 11 (3 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) @@ -2260,6 +2270,8 @@ select count(*) from tenk1 x where x.unique1 in (select a.f1 from int4_tbl a,float8_tbl b where a.f1=b.f1) and x.unique1 = 0 and x.unique1 in (select aa.f1 from int4_tbl aa,float8_tbl bb where aa.f1=bb.f1); +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl, float8_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. count ------- 1 @@ -2275,6 +2287,8 @@ select count(*) from tenk1 x where x.unique1 in (select a.f1 from int4_tbl a,float8_tbl b where a.f1=b.f1) and x.unique1 = 0 and x.unique1 in (select aa.f1 from int4_tbl aa,float8_tbl bb where aa.f1=bb.f1); +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl, float8_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. count ------- 1 @@ -2292,6 +2306,7 @@ select aa, bb, unique1, unique1 ------------------------------------- Result One-Time Filter: false + Optimizer: Postgres query optimizer (3 rows) select aa, bb, unique1, unique1 @@ -2308,8 +2323,8 @@ explain (costs off) select * from int8_tbl i1 left join (int8_tbl i2 join (select 123 as x) ss on i2.q1 = x) on i1.q2 = i2.q2 order by 1, 2; - QUERY PLAN ------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Merge Key: i1.q1, i1.q2 -> Sort @@ -2330,7 +2345,7 @@ order by 1, 2; -> Result Filter: ((123) = 123) -> Result - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (21 rows) select * from int8_tbl i1 left join (int8_tbl i2 join @@ -2375,8 +2390,10 @@ select a.f1, b.f1, t.thousand, t.tenthous from (select sum(f1)+1 as f1 from int4_tbl i4a) a, (select sum(f1) as f1 from int4_tbl i4b) b where b.f1 = t.thousand and a.f1 = b.f1 and (a.f1+b.f1+999) = t.tenthous; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +----------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Join Hash Cond: ((sum(i4b.f1)) = (((sum(i4a.f1)) + 1))) @@ -2397,7 +2414,7 @@ where b.f1 = t.thousand and a.f1 = b.f1 and (a.f1+b.f1+999) = t.tenthous; -> Gather Motion 3:1 (slice5; segments: 3) -> Partial Aggregate -> Seq Scan on int4_tbl i4a - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (21 rows) select a.f1, b.f1, t.thousand, t.tenthous from @@ -2405,6 +2422,8 @@ select a.f1, b.f1, t.thousand, t.tenthous from (select sum(f1)+1 as f1 from int4_tbl i4a) a, (select sum(f1) as f1 from int4_tbl i4b) b where b.f1 = t.thousand and a.f1 = b.f1 and (a.f1+b.f1+999) = t.tenthous; +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. f1 | f1 | thousand | tenthous ----+----+----------+---------- (0 rows) @@ -2420,8 +2439,10 @@ from int4_tbl t1, int4_tbl t2 left join int4_tbl t3 on t3.f1 > 0 left join int4_tbl t4 on t3.f1 > 1 where t4.f1 is null; - QUERY PLAN --------------------------------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +--------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -2450,6 +2471,8 @@ from int4_tbl t1, int4_tbl t2 left join int4_tbl t3 on t3.f1 > 0 left join int4_tbl t4 on t3.f1 > 1 where t4.f1 is null; +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. f1 ---- (0 rows) @@ -2459,8 +2482,10 @@ select * from int4_tbl t1 left join int4_tbl t2 on true left join int4_tbl t3 on t2.f1 > 0 left join int4_tbl t4 on t3.f1 > 0; - QUERY PLAN --------------------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +--------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: (t3.f1 > 0) @@ -2486,8 +2511,8 @@ select * from onek t1 left join onek t2 on t1.unique1 = t2.unique1 left join onek t3 on t2.unique1 != t3.unique1 left join onek t4 on t3.unique1 = t4.unique1; - QUERY PLAN --------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Left Join Hash Cond: (t3.unique1 = t4.unique1) @@ -2513,8 +2538,10 @@ select * from int4_tbl t1 left join int4_tbl t3 on t2.f1 = t3.f1 left join int4_tbl t4 on t3.f1 = t4.f1) s on true inner join int4_tbl t5 on true; - QUERY PLAN ------------------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: true @@ -2543,8 +2570,10 @@ select * from int4_tbl t1 left join int4_tbl t2 on true left join int4_tbl t3 on true left join int4_tbl t4 on t2.f1 = t3.f1; - QUERY PLAN --------------------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +--------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: (t2.f1 = t3.f1) @@ -2570,8 +2599,10 @@ select * from int4_tbl t1 left join int4_tbl t2 on true left join int4_tbl t3 on t2.f1 = t3.f1 left join int4_tbl t4 on t3.f1 != t4.f1; - QUERY PLAN --------------------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +--------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: (t3.f1 <> t4.f1) @@ -2597,8 +2628,10 @@ select * from int4_tbl t1 left join (int4_tbl t2 left join int4_tbl t3 on t2.f1 > 0) on t2.f1 > 1 left join int4_tbl t4 on t2.f1 > 2 and t3.f1 > 3 where t1.f1 = coalesce(t2.f1, 1); - QUERY PLAN --------------------------------------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +--------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: ((t2.f1 > 2) AND (t3.f1 > 3)) @@ -2629,8 +2662,10 @@ select * from int4_tbl t1 where t3.f1 is null) s left join tenk1 t4 on s.f1 > 1) on s.f1 = t1.f1; - QUERY PLAN --------------------------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +--------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Right Join Hash Cond: (t2.f1 = t1.f1) @@ -2659,8 +2694,10 @@ select * from int4_tbl t1 where t2.f1 <> coalesce(t3.f1, -1)) s left join tenk1 t4 on s.f1 > 1) on s.f1 = t1.f1; - QUERY PLAN --------------------------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +--------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Right Join Hash Cond: (t2.f1 = t1.f1) @@ -2687,8 +2724,8 @@ select * from onek t1 left join onek t2 on t1.unique1 = t2.unique1 left join onek t3 on t2.unique1 = t3.unique1 left join onek t4 on t3.unique1 = t4.unique1 and t2.unique2 = t4.unique2; - QUERY PLAN ------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Hash Left Join Hash Cond: ((t3.unique1 = t4.unique1) AND (t2.unique2 = t4.unique2)) @@ -2711,8 +2748,8 @@ select * from int8_tbl t1 left join (int8_tbl t2 left join int8_tbl t3 full join int8_tbl t4 on false on false) left join int8_tbl t5 on t2.q1 = t5.q1 on t2.q2 = 123; - QUERY PLAN --------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: true @@ -2738,8 +2775,8 @@ select * from int8_tbl t1 left join lateral (select * from int8_tbl t3 where t3.q1 = t2.q1 offset 0) s on t2.q1 = 1; - QUERY PLAN ------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------ Nested Loop Left Join -> Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on int8_tbl t1 @@ -2754,7 +2791,7 @@ select * from int8_tbl t1 -> Materialize -> Gather Motion 3:1 (slice3; segments: 3) -> Seq Scan on int8_tbl t3 - Optimizer: GPORCA + Optimizer: Postgres query optimizer (15 rows) explain (costs off) @@ -2763,8 +2800,8 @@ select * from int8_tbl t1 left join lateral (select * from generate_series(t2.q1, 100)) s on t2.q1 = 1; - QUERY PLAN ---------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join -> Seq Scan on int8_tbl t1 @@ -2774,7 +2811,7 @@ select * from int8_tbl t1 Join Filter: (t2.q1 = 1) -> Seq Scan on int8_tbl t2 -> Function Scan on generate_series - Optimizer: GPORCA + Optimizer: Postgres query optimizer (10 rows) explain (costs off) @@ -2783,15 +2820,15 @@ select * from int8_tbl t1 left join lateral (select t2.q1 from int8_tbl t3) s on t2.q1 = 1; -ERROR: could not devise a query plan for the given query +ERROR: could not devise a query plan for the given query (pathnode.c:285) explain (costs off) select * from onek t1 left join onek t2 on true left join lateral (select * from onek t3 where t3.two = t2.two offset 0) s on t2.unique1 = 1; - QUERY PLAN ------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------ Nested Loop Left Join -> Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on onek t1 @@ -2809,7 +2846,7 @@ select * from onek t1 -> Materialize -> Gather Motion 3:1 (slice3; segments: 3) -> Seq Scan on onek t3 - Optimizer: GPORCA + Optimizer: Postgres query optimizer (18 rows) -- @@ -2840,25 +2877,25 @@ select * from on j1_tbl.i = j2_tbl.i and j1_tbl.i = j2_tbl.k; --order none i | j | t | i | k ---+---+-------+---+---- - | | | 0 | - 0 | | zero | | - | | | 1 | -1 - 1 | 4 | one | | - | | | 5 | -5 - | | | 5 | -5 5 | 0 | five | | 6 | 6 | six | | + | | | 5 | -5 + | | | 5 | -5 + 1 | 4 | one | | + 0 | | zero | | + | | | 1 | -1 + | | | 0 | 2 | 3 | two | 2 | 2 - | | | 2 | 4 - | | | 3 | -3 - | | | | 0 - | | | | 3 | 2 | three | | 4 | 1 | four | | 7 | 7 | seven | | 8 | 8 | eight | | | | null | | | 0 | zero | | + | | | | + | | | 2 | 4 + | | | 3 | -3 + | | | | 0 (19 rows) reset enable_mergejoin; @@ -2874,8 +2911,8 @@ select count(*) from left join (select * from tenk1 y order by y.unique2) y on x.thousand = y.unique2 and x.twothousand = y.hundred and x.fivethous = y.unique2; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- Finalize Aggregate -> Gather Motion 3:1 (slice1; segments: 3) -> Partial Aggregate @@ -2888,7 +2925,7 @@ select count(*) from -> Redistribute Motion 3:3 (slice3; segments: 3) Hash Key: y.unique2, y.hundred, y.unique2 -> Seq Scan on tenk1 y - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) select count(*) from @@ -2916,8 +2953,8 @@ select x.thousand, x.twothousand, count(*) from tenk1 x inner join tenk1 y on x.thousand = y.thousand group by x.thousand, x.twothousand order by x.thousand desc, x.twothousand; - QUERY PLAN ------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Merge Key: x.thousand, x.twothousand -> Sort @@ -2975,9 +3012,9 @@ DELETE FROM t3 USING t1 table1 WHERE t3.x = table1.a; SELECT * FROM t3; x | y -----+----- + 6 | 7 7 | 8 500 | 100 - 6 | 7 (3 rows) DELETE FROM t4 USING t1 JOIN t2 USING (a) WHERE t4.x > t1.a; @@ -3002,11 +3039,11 @@ insert into t2a values (200, 2001); select * from t1 left join t2 on (t1.a = t2.a); a | b | a | b -----+------+-----+------ - 15 | 20 | | 200 | 1000 | 200 | 2000 200 | 1000 | 200 | 2001 100 | 100 | | 5 | 10 | | + 15 | 20 | | (5 rows) -- Test matching of column name with wrong alias @@ -3095,8 +3132,8 @@ set enable_nestloop to off; explain (costs off) select * from tbl_ra t1 where not exists (select 1 from tbl_ra t2 where t2.b = t1.a) and t1.b < 2; - QUERY PLAN ------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Result Filter: (COALESCE((count(*)), '0'::bigint) = '0'::bigint) @@ -3118,29 +3155,127 @@ select * from tbl_ra t1 where not exists (select 1 from tbl_ra t2 where t2.b = t1.a) and t1.b < 2; a | b ------+--- - 100 | 0 + 500 | 0 + 700 | 0 + 800 | 0 + 1000 | 0 101 | 1 - 200 | 0 - 201 | 1 - 300 | 0 301 | 1 - 400 | 0 - 401 | 1 - 500 | 0 501 | 1 + 801 | 1 + 100 | 0 + 200 | 0 600 | 0 601 | 1 - 700 | 0 701 | 1 - 800 | 0 - 801 | 1 - 900 | 0 901 | 1 - 1000 | 0 + 300 | 0 + 400 | 0 + 900 | 0 + 201 | 1 + 401 | 1 (19 rows) -reset enable_hashjoin; +reset enable_hashjoin; +reset enable_nestloop; +-- +-- regression test for bug with hash-right-semi join +-- +create temp table tbl_rs(a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into tbl_rs select i, i from generate_series(1,10)i; +analyze tbl_rs; +set enable_nestloop to off; +set enable_hashagg to off; +-- ensure we get a hash right semi join with SubPlan in hash clauses +-- start_ignore +-- GPDB: the plan shape (and whether a right-semi join is chosen) depends on +-- the optimizer and MPP motions, so the plan is ignored; correctness of the +-- rescan match-flag reset is verified by the result of the query below. +explain (costs off) +select * from tbl_rs t1 +where (select a from tbl_rs t2 + where exists (select 1 from + (select (b in (select b from tbl_rs t3)) as c from tbl_rs t4 where t4.a = 1) s + where c in (select t1.a = 1 from tbl_rs t5 union all select true)) + order by a limit 1) >= 0; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------- + Result + Filter: (SubPlan 2) + -> Gather Motion 3:1 (slice1; segments: 3) + -> Seq Scan on tbl_rs t1 + SubPlan 2 + -> Result + Filter: (t2.a >= 0) + -> Limit + -> Sort + Sort Key: t2.a + -> Nested Loop Semi Join + Join Filter: true + -> Materialize + -> Gather Motion 3:1 (slice7; segments: 3) + -> Seq Scan on tbl_rs t2 + -> Materialize + -> Result + Filter: (SubPlan 1) + -> Materialize + -> Gather Motion 3:1 (slice2; segments: 3) + -> Finalize GroupAggregate + Group Key: t4.a, t4.b, t4.ctid, t4.gp_segment_id + -> Sort + Sort Key: t4.a, t4.b, t4.ctid, t4.gp_segment_id + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t4.a, t4.b, t4.ctid, t4.gp_segment_id + -> Partial GroupAggregate + Group Key: t4.a, t4.b, t4.ctid, t4.gp_segment_id + -> Result + -> Sort + Sort Key: t4.a, t4.b, t4.ctid, t4.gp_segment_id + -> Redistribute Motion 3:3 (slice4; segments: 3) + -> Nested Loop Left Join + Join Filter: ((t4.b = t3.b) IS NOT FALSE) + -> Seq Scan on tbl_rs t4 + Filter: (a = 1) + -> Materialize + -> Result + -> Broadcast Motion 3:3 (slice5; segments: 3) + -> Seq Scan on tbl_rs t3 + SubPlan 1 + -> Append + -> Result + -> Materialize + -> Gather Motion 3:1 (slice6; segments: 3) + -> Seq Scan on tbl_rs t5 + -> Result + Optimizer: GPORCA +(48 rows) + +-- end_ignore +-- and check we get the expected results +select * from tbl_rs t1 +where (select a from tbl_rs t2 + where exists (select 1 from + (select (b in (select b from tbl_rs t3)) as c from tbl_rs t4 where t4.a = 1) s + where c in (select t1.a = 1 from tbl_rs t5 union all select true)) + order by a limit 1) >= 0; + a | b +----+---- + 2 | 2 + 3 | 3 + 4 | 4 + 7 | 7 + 8 | 8 + 1 | 1 + 5 | 5 + 6 | 6 + 9 | 9 + 10 | 10 +(10 rows) + reset enable_nestloop; +reset enable_hashagg; -- -- regression test for bug #13908 (hash join with skew tuples & nbatch increase) -- @@ -3165,7 +3300,7 @@ select count(*) from tenk1 a, tenk1 b Hash Key: b.thousand -> Seq Scan on tenk1 b Filter: ((fivethous % 10) < 10) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (14 rows) select count(*) from tenk1 a, tenk1 b @@ -3202,8 +3337,8 @@ LEFT JOIN ( ) AS d ON (a.f1 = d.f1) WHERE COALESCE(d.f1, 0) = 0 ORDER BY 1; - QUERY PLAN --------------------------------------------------- + QUERY PLAN +------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Merge Key: a.f1 -> Sort @@ -3247,8 +3382,8 @@ reset enable_nestloop; explain (costs off) select a.* from tenk1 a where unique1 in (select unique2 from tenk1 b); - QUERY PLAN ----------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Hash Semi Join Hash Cond: (a.unique1 = b.unique2) @@ -3264,8 +3399,8 @@ where unique1 in (select unique2 from tenk1 b); explain (costs off) select a.* from tenk1 a where unique1 not in (select unique2 from tenk1 b); - QUERY PLAN --------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Left Anti Semi (Not-In) Join Hash Cond: (a.unique1 = b.unique2) @@ -3279,8 +3414,8 @@ where unique1 not in (select unique2 from tenk1 b); explain (costs off) select a.* from tenk1 a where exists (select 1 from tenk1 b where a.unique1 = b.unique2); - QUERY PLAN --------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Hash Semi Join Hash Cond: (a.unique1 = b.unique2) @@ -3297,8 +3432,8 @@ where exists (select 1 from tenk1 b where a.unique1 = b.unique2); explain (costs off) select a.* from tenk1 a where not exists (select 1 from tenk1 b where a.unique1 = b.unique2); - QUERY PLAN ------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Hash Anti Join Hash Cond: (a.unique1 = b.unique2) @@ -3314,8 +3449,8 @@ where not exists (select 1 from tenk1 b where a.unique1 = b.unique2); explain (costs off) select a.* from tenk1 a left join tenk1 b on a.unique1 = b.unique2 where b.unique2 is null; - QUERY PLAN ------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Result Filter: (b.unique2 IS NULL) @@ -3370,7 +3505,7 @@ where not exists ( -> Hash -> Gather Motion 3:1 (slice5; segments: 3) -> Seq Scan on tt4x t5 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (24 rows) -- @@ -3505,7 +3640,8 @@ rollback; begin; create type mycomptype as (id int, v bigint); create temp table tidv (idv mycomptype); -NOTICE: Table doesn't have 'DISTRIBUTED BY' clause, and no column type is suitable for a distribution key. Creating a NULL policy entry. +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'idv' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create index on tidv (idv); analyze tidv; explain (costs off) @@ -3685,8 +3821,8 @@ SELECT qq, unique1 ( SELECT COALESCE(q2, -1) AS qq FROM int8_tbl b ) AS ss2 USING (qq) INNER JOIN tenk1 c ON qq = unique2; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -3789,7 +3925,7 @@ where nt3.id = 1 and ss2.b3; Filter: ((NOT (nt1.id IS NULL))) -> Index Scan using nt1_pkey on nt1 Index Cond: (id = nt2.nt1_id) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (18 rows) select nt3.id @@ -3844,7 +3980,7 @@ order by 1,2; -> Materialize -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on int8_tbl t3 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (24 rows) -- @@ -3883,26 +4019,7 @@ select * from right join int4_tbl as i43 on (i43.f1 > 1) where ss1.loc = ss1.lat) as ss2 where i41.f1 > 0; -ERROR: could not devise a query plan for the given query (pathnode.c:277) ---start_ignore ---GPDB_14_MERGE_FIXME: We need to make plan work. One idea is generate a gather ---motion for relations. Even it is not efficient, but better than error out here. - QUERY PLAN --------------------------------------------------- - Nested Loop - -> Nested Loop - -> Seq Scan on int4_tbl i41 - Filter: (f1 > 0) - -> Nested Loop - Join Filter: (i41.f1 = i42.f1) - -> Seq Scan on int8_tbl i81 - -> Materialize - -> Seq Scan on int4_tbl i42 - -> Materialize - -> Seq Scan on int4_tbl i43 - Filter: (f1 > 1) -(12 rows) ---end_ignore +ERROR: could not devise a query plan for the given query (pathnode.c:285) select * from int4_tbl as i41, lateral @@ -3913,34 +4030,7 @@ select * from right join int4_tbl as i43 on (i43.f1 > 1) where ss1.loc = ss1.lat) as ss2 where i41.f1 > 0; -ERROR: could not devise a query plan for the given query (pathnode.c:277) ---start_ignore ---GPDB_14_MERGE_FIXME: We need to make plan work. One idea is generate a gather ---motion for relations. Even it is not efficient, but better than error out here. - f1 | x -------------+--- - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 -(20 rows) ---end_ignore +ERROR: could not devise a query plan for the given query (pathnode.c:285) -- -- test the corner cases FULL JOIN ON TRUE and FULL JOIN ON FALSE -- @@ -4003,6 +4093,8 @@ select * from tenk1 join int4_tbl on f1 = twothousand, q1, q2 where q1 = thousand or q2 = thousand; +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN ------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) @@ -4026,7 +4118,7 @@ where q1 = thousand or q2 = thousand; -> Hash -> Broadcast Motion 3:3 (slice4; segments: 3) -> Seq Scan on int4_tbl - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (22 rows) explain (costs off) @@ -4034,8 +4126,10 @@ select * from tenk1 join int4_tbl on f1 = twothousand, q1, q2 where thousand = (q1 + q2); - QUERY PLAN --------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +--------------------------------------------------------------------------- Hash Join Hash Cond: (tenk1.twothousand = int4_tbl.f1) -> Gather Motion 3:1 (slice1; segments: 3) @@ -4079,7 +4173,7 @@ where thousand = a.q1 and tenthous = b.q1 and a.q2 = 1 and b.q2 = 2; -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on int8_tbl a Filter: (q2 = 1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (15 rows) reset enable_nestloop; @@ -4102,41 +4196,43 @@ select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from left join tenk1 t2 on (subq1.y1 = t2.unique1) where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; - QUERY PLAN ------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) - -> Hash Join - Hash Cond: (tenk1.unique1 = (3)) - Join Filter: (tenk1_1.stringu1 > tenk1.stringu2) - -> Seq Scan on tenk1 - -> Hash +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +--------------------------------------------------------------------------------------------------------- + Hash Join + Hash Cond: ((11) = t1.unique2) + Join Filter: (t1.stringu1 > t2.stringu2) + -> Gather Motion 3:1 (slice1; segments: 3) + -> Hash Join + Hash Cond: ((0) = i1.f1) -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: (3) + Hash Key: (0) -> Hash Join - Hash Cond: ((0) = int4_tbl.f1) - -> Hash Join - Hash Cond: (tenk1_1.unique2 = (11)) - -> Index Scan using tenk1_unique2 on tenk1 tenk1_1 - Index Cond: ((unique2 < 42) AND (unique2 = 11)) - -> Hash - -> Broadcast Motion 3:3 (slice3; segments: 3) - -> Result - Filter: (((11) < 42) AND ((11) = 11)) - -> Hash Left Join - Hash Cond: ((1) = (1)) - -> Result - Filter: ((0) = 0) - -> Seq Scan on onerow - -> Hash - -> Broadcast Motion 3:3 (slice4; segments: 3) - -> Result - Filter: ((1) = 1) - -> Seq Scan on onerow onerow_1 + Hash Cond: (t2.unique1 = (3)) + -> Seq Scan on tenk1 t2 -> Hash - -> Broadcast Motion 3:3 (slice5; segments: 3) - -> Seq Scan on int4_tbl - Filter: (f1 = 0) - Optimizer: Pivotal Optimizer (GPORCA) + -> Result + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Hash Left Join + Hash Cond: ((1) = (1)) + -> Result + Filter: ((0) = 0) + -> Seq Scan on onerow + Filter: ((11 < 42) AND (11 = 11)) + -> Hash + -> Broadcast Motion 3:3 (slice4; segments: 3) + -> Result + Filter: ((1) = 1) + -> Seq Scan on onerow onerow_1 + -> Hash + -> Seq Scan on int4_tbl i1 + Filter: (f1 = 0) + -> Hash + -> Gather Motion 3:1 (slice5; segments: 3) + -> Index Scan using tenk1_unique2 on tenk1 t1 + Index Cond: ((unique2 < 42) AND (unique2 = 11)) + Optimizer: GPORCA (33 rows) --end_ignore @@ -4152,6 +4248,8 @@ select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from left join tenk1 t2 on (subq1.y1 = t2.unique1) where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. unique2 | stringu1 | unique1 | stringu2 ---------+----------+---------+---------- 11 | WFAAAA | 3 | LKIAAA @@ -4191,6 +4289,8 @@ select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from left join tenk1 t2 on (subq1.y1 = t2.unique1) where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN -------------------------------------------------------------------------- Hash Join @@ -4234,6 +4334,8 @@ select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from left join tenk1 t2 on (subq1.y1 = t2.unique1) where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. unique2 | stringu1 | unique1 | stringu2 ---------+----------+---------+---------- 11 | WFAAAA | 3 | LKIAAA @@ -4288,7 +4390,8 @@ where b; -> Result -> Result One-Time Filter: (true) -(6 rows) + Optimizer: Postgres query optimizer +(7 rows) select * from (select 0 as z) as t1 @@ -4310,8 +4413,8 @@ explain (verbose, costs off) with ctetable as not materialized ( select 1 as f1 ) select * from ctetable c1 where f1 in ( select c3.f1 from ctetable c2 full join ctetable c3 on true ); - QUERY PLAN ------------------------------------- + QUERY PLAN +------------------------------------- Hash Semi Join Output: (1) Hash Cond: ((1) = (1)) @@ -4327,7 +4430,8 @@ where f1 in ( select c3.f1 from ctetable c2 full join ctetable c3 on true ); Output: (1) -> Result Output: 1 - Optimizer: GPORCA + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer (17 rows) with ctetable as not materialized ( select 1 as f1 ) @@ -4345,12 +4449,13 @@ from int4_tbl t1 inner join (int8_tbl t2 left join information_schema.column_udt_usage on null) on null; - QUERY PLAN ----------------------------------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------------------------------- Result Output: 'regression'::information_schema.sql_identifier, (c.relname)::information_schema.sql_identifier One-Time Filter: false - Optimizer: GPORCA + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer (5 rows) -- Test handling of qual pushdown to appendrel members with non-Var outputs @@ -4359,8 +4464,10 @@ select * from int4_tbl left join ( select text 'foo' union all select text 'bar' ) ss(x) on true where ss.x is null; - QUERY PLAN ----------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +----------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: f1, ('foo'::text) -> Result @@ -4380,6 +4487,7 @@ where ss.x is null; Output: ('bar'::text) -> Result Output: 'bar'::text + Settings: optimizer = 'on' Optimizer: GPORCA (21 rows) @@ -4412,8 +4520,8 @@ explain (verbose, costs off) select unique1, x.* from tenk1, (select *, random() from f_immutable_int4(1) x) x where x = unique1; - QUERY PLAN ------------------------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: unique1, (1), (random()) -> Nested Loop @@ -4430,7 +4538,7 @@ where x = unique1; -> Index Only Scan using tenk1_unique1 on public.tenk1 Output: unique1 Index Cond: ((tenk1.unique1 = (1)) AND (tenk1.unique1 = 1)) - Settings: enable_nestloop = 'on', enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on', enable_nestloop = 'on' Optimizer: GPORCA (18 rows) @@ -4462,10 +4570,11 @@ select unique1 from tenk1, lateral f_immutable_int4(1) x where x = unique1; explain (costs off) select unique1 from tenk1, lateral f_immutable_int4(1) x where x in (select 17); - QUERY PLAN --------------------------- + QUERY PLAN +------------------------------------- Result One-Time Filter: false + Optimizer: Postgres query optimizer (3 rows) explain (costs off) @@ -4494,7 +4603,7 @@ select unique1, x from tenk1 left join f_immutable_int4(1) x on unique1 = x; -> Seq Scan on tenk1 -> Hash -> Result - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) explain (costs off) @@ -4531,11 +4640,11 @@ select unique1, x from tenk1 full join f_immutable_int4(1) x on unique1 = x; -- check that pullup of a const function allows further const-folding explain (costs off) select unique1 from tenk1, f_immutable_int4(1) x where x = 42; - QUERY PLAN ---------------------------------------- + QUERY PLAN +-------------------------- Result One-Time Filter: false - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) reset enable_nestloop; @@ -4568,7 +4677,7 @@ where nt3.id = 1 and ss2.b3; -> Seq Scan on nt2 -> Hash -> Result - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (15 rows) drop function f_immutable_int4(int); @@ -4579,13 +4688,13 @@ create function mki4(int) returns int4_tbl as $$select row($1)::int4_tbl$$ language sql; explain (verbose, costs off) select * from mki8(1,2); - QUERY PLAN ---------------------------------------- + QUERY PLAN +------------------------------------ Function Scan on mki8 Output: q1, q2 Function Call: '(1,2)'::int8_tbl Settings: optimizer = 'on' - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) select * from mki8(1,2); @@ -4596,13 +4705,13 @@ select * from mki8(1,2); explain (verbose, costs off) select * from mki4(42); - QUERY PLAN ---------------------------------------- + QUERY PLAN +----------------------------------- Function Scan on mki4 Output: f1 Function Call: '(42)'::int4_tbl Settings: optimizer = 'on' - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) select * from mki4(42); @@ -4621,8 +4730,8 @@ explain (verbose, costs off) select (t2.*).unique1, f_field_select(t2) from tenk1 t1 left join onek t2 on t1.unique1 = t2.unique1 left join int8_tbl t3 on true; - QUERY PLAN --------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: t2.unique1, t2.unique2 -> Hash Left Join @@ -4640,6 +4749,7 @@ select (t2.*).unique1, f_field_select(t2) from tenk1 t1 Output: t2.unique1, t2.unique2 -> Seq Scan on public.onek t2 Output: t2.unique1, t2.unique2 + Settings: optimizer = 'on' Optimizer: GPORCA (19 rows) @@ -4651,8 +4761,8 @@ drop function f_field_select(t onek); explain (costs off) select * from tenk1 a join tenk1 b on (a.unique1 = 1 and b.unique1 = 2) or (a.unique2 = 3 and b.hundred = 4); - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -4678,14 +4788,14 @@ select * from tenk1 a join tenk1 b on Index Cond: (unique1 = 2) -> Bitmap Index Scan on tenk1_hundred Index Cond: (hundred = 4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (26 rows) explain (costs off) select * from tenk1 a join tenk1 b on (a.unique1 = 1 and b.unique1 = 2) or (a.unique2 = 3 and b.ten = 4); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -4706,15 +4816,15 @@ select * from tenk1 a join tenk1 b on Index Cond: (unique1 = 1) -> Bitmap Index Scan on tenk1_unique2 Index Cond: (unique2 = 3) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (21 rows) explain (costs off) select * from tenk1 a join tenk1 b on (a.unique1 = 1 and b.unique1 = 2) or ((a.unique2 = 3 or a.unique2 = 7) and b.hundred = 4); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -4741,7 +4851,7 @@ select * from tenk1 a join tenk1 b on Index Cond: (unique2 = 3) -> Bitmap Index Scan on tenk1_unique2 Index Cond: (unique2 = 7) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (27 rows) -- @@ -4752,8 +4862,8 @@ select * from tenk1 t1 left join (tenk1 t2 join tenk1 t3 on t2.thousand = t3.unique2) on t1.hundred = t2.hundred and t1.ten = t3.ten where t1.unique1 = 1; - QUERY PLAN ----------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Hash Right Join Hash Cond: ((t2.hundred = t1.hundred) AND (t3.ten = t1.ten)) @@ -4773,7 +4883,7 @@ where t1.unique1 = 1; Hash Key: t1.hundred -> Index Scan using tenk1_unique1 on tenk1 t1 Index Cond: (unique1 = 1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (20 rows) explain (costs off) @@ -4803,7 +4913,7 @@ where t1.unique1 = 1; Hash Key: t1.hundred -> Index Scan using tenk1_unique1 on tenk1 t1 Index Cond: (unique1 = 1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (21 rows) explain (costs off) @@ -4811,6 +4921,8 @@ select count(*) from tenk1 a join tenk1 b on a.unique1 = b.unique2 left join tenk1 c on a.unique2 = b.unique1 and c.thousand = a.thousand join int4_tbl on b.thousand = f1; +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN ------------------------------------------------------------------------------------------------ Finalize Aggregate @@ -4837,13 +4949,15 @@ select count(*) from -> Redistribute Motion 3:3 (slice5; segments: 3) Hash Key: c.thousand -> Seq Scan on tenk1 c - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (25 rows) select count(*) from tenk1 a join tenk1 b on a.unique1 = b.unique2 left join tenk1 c on a.unique2 = b.unique1 and c.thousand = a.thousand join int4_tbl on b.thousand = f1; +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. count ------- 10 @@ -4856,8 +4970,10 @@ select b.unique1 from join int4_tbl i1 on b.thousand = f1 right join int4_tbl i2 on i2.f1 = b.tenthous order by 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +------------------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Merge Key: b.unique1 -> Sort @@ -4889,7 +5005,7 @@ select b.unique1 from -> Seq Scan on tenk1 c -> Hash -> Seq Scan on int4_tbl i2 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (32 rows) select b.unique1 from @@ -4898,6 +5014,8 @@ select b.unique1 from join int4_tbl i1 on b.thousand = f1 right join int4_tbl i2 on i2.f1 = b.tenthous order by 1; +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. unique1 --------- 0 @@ -4915,8 +5033,8 @@ select * from ) ss where fault = 122 order by fault; - QUERY PLAN ----------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Merge Key: ((COALESCE(tenk1.unique1, '-1'::integer) + int8_tbl.q1)) -> Sort @@ -4932,7 +5050,7 @@ order by fault; -> Redistribute Motion 3:3 (slice3; segments: 3) Hash Key: int8_tbl.q2 -> Seq Scan on int8_tbl - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (16 rows) select * from @@ -4982,8 +5100,8 @@ explain (costs off) select q1, unique2, thousand, hundred from int8_tbl a left join tenk1 b on q1 = unique2 where coalesce(thousand,123) = q1 and q1 = coalesce(hundred,123); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Result Filter: ((COALESCE(b.thousand, 123) = a.q1) AND (a.q1 = COALESCE(b.hundred, 123))) @@ -4994,7 +5112,7 @@ select q1, unique2, thousand, hundred -> Seq Scan on tenk1 b -> Hash -> Seq Scan on int8_tbl a - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) select q1, unique2, thousand, hundred @@ -5008,6 +5126,8 @@ explain (costs off) select f1, unique2, case when unique2 is null then f1 else 0 end from int4_tbl a left join tenk1 b on f1 = unique2 where (case when unique2 is null then f1 else 0 end) = 0; +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN -------------------------------------------------------------------------------- Result @@ -5027,6 +5147,8 @@ select f1, unique2, case when unique2 is null then f1 else 0 end select f1, unique2, case when unique2 is null then f1 else 0 end from int4_tbl a left join tenk1 b on f1 = unique2 where (case when unique2 is null then f1 else 0 end) = 0; +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. f1 | unique2 | case ----+---------+------ 0 | 0 | 0 @@ -5039,8 +5161,8 @@ explain (costs off) select a.unique1, b.unique1, c.unique1, coalesce(b.twothousand, a.twothousand) from tenk1 a left join tenk1 b on b.thousand = a.unique1 left join tenk1 c on c.unique2 = coalesce(b.twothousand, a.twothousand) where a.unique2 < 10 and coalesce(b.twothousand, a.twothousand) = 44; - QUERY PLAN ---------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Right Join Hash Cond: (c.unique2 = COALESCE(b.twothousand, a.twothousand)) @@ -5060,7 +5182,7 @@ select a.unique1, b.unique1, c.unique1, coalesce(b.twothousand, a.twothousand) -> Hash -> Index Scan using tenk1_unique2 on tenk1 a Index Cond: (unique2 < 10) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (20 rows) select a.unique1, b.unique1, c.unique1, coalesce(b.twothousand, a.twothousand) @@ -5074,8 +5196,8 @@ select a.unique1, b.unique1, c.unique1, coalesce(b.twothousand, a.twothousand) explain (costs off) select * from int8_tbl t1 left join int8_tbl t2 on t1.q2 = t2.q1, lateral (select * from int8_tbl t3 where t2.q1 = t2.q2) ss; - QUERY PLAN ------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop -> Hash Left Join @@ -5089,23 +5211,23 @@ select * from int8_tbl t1 left join int8_tbl t2 on t1.q2 = t2.q1, -> Materialize -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on int8_tbl t3 - Optimizer: GPORCA + Optimizer: Postgres query optimizer (14 rows) select * from int8_tbl t1 left join int8_tbl t2 on t1.q2 = t2.q1, lateral (select * from int8_tbl t3 where t2.q1 = t2.q2) ss; q1 | q2 | q1 | q2 | q1 | q2 ------------------+------------------+------------------+------------------+------------------+------------------- - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 456 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 456 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 456 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 456 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 (10 rows) -- @@ -5124,6 +5246,8 @@ left join using (join_key) ) foo3 using (join_key); +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN ------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) @@ -5149,8 +5273,9 @@ using (join_key); Output: (666), i1.f1 -> Seq Scan on public.int4_tbl i1 Output: 666, i1.f1 - Optimizer: Pivotal Optimizer (GPORCA) -(24 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(25 rows) select foo1.join_key as foo1_id, foo3.join_key AS foo3_id, bug_field from (values (0),(1)) foo1(join_key) @@ -5164,6 +5289,8 @@ left join using (join_key) ) foo3 using (join_key); +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. foo1_id | foo3_id | bug_field ---------+---------+----------- 0 | 0 | 666 @@ -5183,8 +5310,10 @@ int4_tbl i0 left join ) ss0 on (i0.f1 = ss0.f1) order by i0.f1, x; - QUERY PLAN --------------------------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +--------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: i0.f1, (((123))::bigint), i1.f1, i2.q1, i2.q2 Merge Key: i0.f1, (((123))::bigint) @@ -5210,6 +5339,7 @@ order by i0.f1, x; -> Seq Scan on public.int8_tbl i2 Output: i2.q1, i2.q2 Filter: (i2.q2 = 123) + Settings: optimizer = 'on' Optimizer: GPORCA (27 rows) @@ -5222,13 +5352,15 @@ int4_tbl i0 left join ) ss0 on (i0.f1 = ss0.f1) order by i0.f1, x; +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. f1 | x | f1 | q1 | q2 -------------+-----+-------------+------------------+----- + -2147483647 | 123 | -2147483647 | 4567890123456789 | 123 + -123456 | 123 | -123456 | 4567890123456789 | 123 0 | 123 | 0 | 4567890123456789 | 123 123456 | 123 | 123456 | 4567890123456789 | 123 - -123456 | 123 | -123456 | 4567890123456789 | 123 2147483647 | 123 | 2147483647 | 4567890123456789 | 123 - -2147483647 | 123 | -2147483647 | 4567890123456789 | 123 (5 rows) -- @@ -5245,8 +5377,10 @@ select t1.* from on (t1.f1 = b1.d1) left join int4_tbl i4 on (i8.q2 = i4.f1); - QUERY PLAN ----------------------------------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: text_tbl, int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Output: t1.f1 -> Hash Left Join @@ -5291,8 +5425,9 @@ select t1.* from Output: i4.f1 -> Seq Scan on public.int4_tbl i4 Output: i4.f1 - Optimizer: Pivotal Optimizer (GPORCA) -(48 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(46 rows) select t1.* from text_tbl t1 @@ -5304,6 +5439,8 @@ select t1.* from on (t1.f1 = b1.d1) left join int4_tbl i4 on (i8.q2 = i4.f1); +NOTICE: One or more columns in the following table(s) do not have statistics: text_tbl, int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. f1 ------------------- hi de ho neighbor @@ -5321,6 +5458,8 @@ select t1.* from on (t1.f1 = b1.d1) left join int4_tbl i4 on (i8.q2 = i4.f1); +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl, text_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN --------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) @@ -5373,8 +5512,9 @@ select t1.* from Output: i4.f1 -> Seq Scan on public.int4_tbl i4 Output: i4.f1 - Optimizer: Pivotal Optimizer (GPORCA) -(54 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(52 rows) select t1.* from text_tbl t1 @@ -5386,6 +5526,8 @@ select t1.* from on (t1.f1 = b1.d1) left join int4_tbl i4 on (i8.q2 = i4.f1); +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl, text_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. f1 ------------------- doh! @@ -5404,8 +5546,10 @@ select t1.* from on (t1.f1 = b1.d1) left join int4_tbl i4 on (i8.q2 = i4.f1); - QUERY PLAN ---------------------------------------------------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl, text_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +------------------------------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Output: t1.f1 -> Hash Left Join @@ -5460,8 +5604,9 @@ select t1.* from Output: i4.f1 -> Seq Scan on public.int4_tbl i4 Output: i4.f1 - Optimizer: Pivotal Optimizer (GPORCA) -(58 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(56 rows) select t1.* from text_tbl t1 @@ -5474,6 +5619,8 @@ select t1.* from on (t1.f1 = b1.d1) left join int4_tbl i4 on (i8.q2 = i4.f1); +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl, text_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. f1 ------------------- hi de ho neighbor @@ -5489,8 +5636,10 @@ select * from on t1.f1 = 'doh!' left join int4_tbl i4 on i8.q1 = i4.f1; - QUERY PLAN ----------------------------------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: text_tbl, int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +--------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: t1.f1, i8.q1, i8.q2, t2.f1, i4.f1 -> Hash Left Join @@ -5524,7 +5673,8 @@ select * from Output: i4.f1 -> Seq Scan on public.int4_tbl i4 Output: i4.f1 - Optimizer: Pivotal Optimizer (GPORCA) + Settings: optimizer = 'on' + Optimizer: GPORCA (35 rows) select * from @@ -5535,6 +5685,8 @@ select * from on t1.f1 = 'doh!' left join int4_tbl i4 on i8.q1 = i4.f1; +NOTICE: One or more columns in the following table(s) do not have statistics: text_tbl, int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. f1 | q1 | q2 | f1 | f1 ------+-----+-----+-------------------+---- doh! | 123 | 456 | doh! | @@ -5550,14 +5702,14 @@ left join from pg_class c left join pg_namespace n on n.oid = c.relnamespace where c.relkind = 'r' ) ss2 on false; - QUERY PLAN -------------------------------- + QUERY PLAN +------------------------------------- Nested Loop Left Join Join Filter: false -> Result -> Result One-Time Filter: false - Optimizer: GPORCA + Optimizer: Postgres query optimizer (6 rows) -- check handling of apparently-commutable outer joins with non-commutable @@ -5570,8 +5722,10 @@ select 1 from join int4_tbl i42 on ss1.a is null or i8.q1 <> i8.q2 right join (select 2 as b) ss2 on ss2.b < i4.f1; - QUERY PLAN --------------------------------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +--------------------------------------------------------------------------------------- Nested Loop Left Join Join Filter: ((2) < i4.f1) -> Result @@ -5663,12 +5817,13 @@ select 1 from right join (select 1 as z) as ss2 on true) on false, lateral (select i4.f1, ss1.n from int8_tbl as i8 limit 1) as ss3; - QUERY PLAN -------------------------- + QUERY PLAN +------------------------------------- Result Output: 1 One-Time Filter: false - Optimizer: GPORCA + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer (5 rows) select 1 from @@ -5698,11 +5853,11 @@ select 1 from t t1 on false where t3.a = coalesce(t5.a,1)) as s2 on true; - QUERY PLAN -------------------------- + QUERY PLAN +------------------------------------- Result One-Time Filter: false - Optimizer: GPORCA + Optimizer: Postgres query optimizer (3 rows) rollback; @@ -5787,8 +5942,8 @@ select * from left join (tenk1 as a1 full join (select 1 as id) as yy on (a1.unique1 = yy.id)) on (xx.id = coalesce(yy.id)); - QUERY PLAN ------------------------------------------------- + QUERY PLAN +------------------------------------------------------ Hash Right Join Hash Cond: (COALESCE((1)) = (1)) -> Hash Full Join @@ -5817,8 +5972,10 @@ select * from -- explain (costs off) select * from int4_tbl a left join tenk1 b on f1 = unique2 where f1 = 0; - QUERY PLAN ------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +------------------------------------------------------- Hash Right Join Hash Cond: (b.unique2 = a.f1) -> Gather Motion 3:1 (slice1; segments: 3) @@ -5828,7 +5985,7 @@ explain (costs off) -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on int4_tbl a Filter: (f1 = 0) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) explain (costs off) @@ -5862,8 +6019,8 @@ explain (verbose, costs off) select a.q2, b.q1 from int8_tbl a left join int8_tbl b on a.q2 = coalesce(b.q1, 1) where coalesce(b.q1, 1) > 0; - QUERY PLAN -------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: a.q2, b.q1 -> Result @@ -5884,8 +6041,8 @@ explain (verbose, costs off) Hash Key: COALESCE(b.q1, '1'::bigint) -> Seq Scan on public.int8_tbl b Output: b.q1 + Settings: optimizer = 'on', enable_hashjoin = 'off', enable_nestloop = 'off', enable_mergejoin = 'on' Optimizer: GPORCA - Settings: enable_hashjoin = 'off', enable_mergejoin = 'on' (22 rows) select a.q2, b.q1 @@ -5915,8 +6072,8 @@ explain (costs off) select a.unique1, b.unique2 from onek a left join onek b on a.unique1 = b.unique2 where b.unique2 = any (select q1 from int8_tbl c where c.q1 < b.unique1); - QUERY PLAN ------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Hash Semi Join Hash Cond: ((b.unique2)::bigint = c.q1) @@ -5949,8 +6106,8 @@ explain (costs off) select a.unique1, b.unique2 from onek a full join onek b on a.unique1 = b.unique2 where a.unique1 = 42; - QUERY PLAN ---------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------- Hash Left Join Hash Cond: (a.unique1 = b.unique2) -> Gather Motion 3:1 (slice1; segments: 3) @@ -5975,8 +6132,8 @@ explain (costs off) select a.unique1, b.unique2 from onek a full join onek b on a.unique1 = b.unique2 where b.unique2 = 43; - QUERY PLAN ------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Result Filter: (b.unique2 = 43) @@ -6002,8 +6159,8 @@ explain (costs off) select a.unique1, b.unique2 from onek a full join onek b on a.unique1 = b.unique2 where a.unique1 = 42 and b.unique2 = 42; - QUERY PLAN ---------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -6033,8 +6190,8 @@ select * from full join (select * from (values(456,2)) w(v1,v2) join int8_tbl i82 on q2=v1) ss2 on true; - QUERY PLAN ------------------------------------------------------ + QUERY PLAN +------------------------------------------------------ Merge Full Join -> Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on int8_tbl i81 @@ -6043,7 +6200,7 @@ on true; -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on int8_tbl i82 Filter: (q2 = 456) - Optimizer: GPORCA + Optimizer: Postgres query optimizer (9 rows) select * from @@ -6080,7 +6237,7 @@ explain (costs off) SELECT a.* FROM a LEFT JOIN b ON a.b_id = b.id; ------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on a - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) explain (costs off) SELECT b.* FROM b LEFT JOIN c ON b.c_id = c.id; @@ -6088,7 +6245,7 @@ explain (costs off) SELECT b.* FROM b LEFT JOIN c ON b.c_id = c.id; ------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on b - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) explain (costs off) @@ -6098,7 +6255,7 @@ explain (costs off) ------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on a - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) -- check optimization of outer join within another special join @@ -6124,8 +6281,8 @@ select a1.id from left join (a a3 left join a a4 on a3.id = a4.id) on a2.id = a3.id; - QUERY PLAN --------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: true @@ -6142,8 +6299,8 @@ select a1.id from left join (a a3 left join a a4 on a3.id = a4.id) on a2.id = a3.id; - QUERY PLAN --------------------------------------------- + QUERY PLAN +--------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: true @@ -6158,8 +6315,8 @@ select 1 from a t1 left join a t2 on true inner join a t3 on true left join a t4 on t2.id = t4.id and t2.id = t3.id; - QUERY PLAN --------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------- Result -> Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join @@ -6196,8 +6353,10 @@ from int4_tbl as t1 inner join int8_tbl as t7 on null) on t5.q1 = t7.q2) on false; - QUERY PLAN ------------------------------------------ +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: true @@ -6220,8 +6379,10 @@ from int4_tbl as t1 inner join int8_tbl as t7 on null) on t5.q1 = t7.q2) on false; - QUERY PLAN ------------------------------------------ +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: true @@ -6237,8 +6398,10 @@ select ss1.x from (select f1/2 as x from int4_tbl i4 left join a on a.id = i4.f1) ss1 right join int8_tbl i8 on true where current_user is not null; -- this is to add a Result node - QUERY PLAN --------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +--------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: true @@ -6257,8 +6420,8 @@ from int8_tbl t1 on t1.q2 = t2.q2 left join onek t4 on t2.q2 < t3.unique2; - QUERY PLAN --------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: (t2.q2 < t3.unique2) @@ -6289,8 +6452,8 @@ select * from int8_tbl t1 left join (int8_tbl t2 inner join int8_tbl t3 on false left join int8_tbl t4 on t2.q2 = t4.q2) on t1.q1 = t2.q1; - QUERY PLAN -------------------------------------------- + QUERY PLAN +-------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Left Join Hash Cond: (q1 = (NULL::bigint)) @@ -6307,8 +6470,8 @@ select * from int8_tbl t1 left join (int8_tbl t2 inner join int8_tbl t3 on (t2.q1-t3.q2) = 0 and (t2.q1-t3.q2) = 1 left join int8_tbl t4 on t2.q2 = t4.q2) on t1.q1 = t2.q1; - QUERY PLAN ------------------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Hash Right Join Hash Cond: (t2.q1 = t1.q1) @@ -6341,8 +6504,10 @@ select exists( left join int8_tbl t4 on t2.q2 = t4.q2) on t1.q1 = t2.q1 ) from int4_tbl x0; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- Result -> Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on int4_tbl x0 @@ -6384,7 +6549,7 @@ select d.* from d left join (select * from b group by b.id, b.c_id) s ------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on d - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) -- similarly, but keying off a DISTINCT clause @@ -6395,7 +6560,7 @@ select d.* from d left join (select distinct * from b) s ------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on d - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) -- join removal is not possible when the GROUP BY contains a column that is @@ -6413,7 +6578,7 @@ select d.* from d left join (select * from b group by b.id, b.c_id) s -> Seq Scan on d -> Index Scan using b_pkey on b Index Cond: (id = d.a) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) -- similarly, but keying off a DISTINCT clause @@ -6435,8 +6600,8 @@ select d.* from d left join (select distinct * from b) s explain (costs off) select 1 from a t1 left join (a t2 left join a t3 on t2.id = 1) on t2.id = 1; - QUERY PLAN --------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------- Result -> Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join @@ -6463,7 +6628,7 @@ select d.* from d left join (select id from a union select id from b) s ------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on d - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) -- check join removal with a cross-type comparison operator @@ -6474,7 +6639,7 @@ select i8.* from int8_tbl i8 left join (select f1 from int4_tbl group by f1) i4 ------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on int8_tbl i8 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) -- check join removal with lateral references @@ -6488,7 +6653,7 @@ select 1 from (select a.id FROM a left join b on a.b_id = b.id) q, -> Seq Scan on a -> Function Scan on generate_series gs Filter: (a.id = i) - Optimizer: GPORCA + Optimizer: Postgres query optimizer (6 rows) -- check join removal within RHS of an outer join @@ -6496,8 +6661,8 @@ explain (costs off) select c.id, ss.a from c left join (select d.a from onerow, d left join b on d.a = b.id) ss on c.id = ss.a; - QUERY PLAN --------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Left Join Hash Cond: (c.id = d.a) @@ -6514,11 +6679,12 @@ select c.id, ss.a from c CREATE TEMP TABLE parted_b (id int PRIMARY KEY) partition by range(id); CREATE TEMP TABLE parted_b1 partition of parted_b for values from (0) to (10); +NOTICE: table has parent, setting distribution columns to match parent table -- test join removals on a partitioned table explain (costs off) select a.* from a left join parted_b pb on a.b_id = pb.id; - QUERY PLAN ------------------------------------------ + QUERY PLAN +------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on a Optimizer: GPORCA @@ -6544,7 +6710,7 @@ explain (costs off) ------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on parent p - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) -- this case is not @@ -6562,15 +6728,15 @@ explain (costs off) select p.*, linked from parent p left join (select c.*, true as linked from child c) as ss on (p.k = ss.k); - QUERY PLAN ---------------------------------------------------- + QUERY PLAN +----------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: true -> Seq Scan on parent p -> Index Scan using child_k_key on child c Index Cond: (k = p.k) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) -- check for a 9.0rc1 bug: join removal breaks pseudoconstant qual handling @@ -6585,11 +6751,11 @@ explain (costs off) select p.* from parent p left join child c on (p.k = c.k) where p.k = 1 and p.k = 2; - QUERY PLAN ---------------------------------------- + QUERY PLAN +-------------------------- Result One-Time Filter: false - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) select p.* from @@ -6603,11 +6769,11 @@ explain (costs off) select p.* from (parent p left join child c on (p.k = c.k)) join parent x on p.k = x.k where p.k = 1 and p.k = 2; - QUERY PLAN ---------------------------------------- + QUERY PLAN +-------------------------- Result One-Time Filter: false - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) -- bug 5255: this is not optimizable by join removal @@ -6641,11 +6807,11 @@ SELECT * FROM ON true; x | q1 | q2 | y ---+------------------+-------------------+------------------ - 1 | 4567890123456789 | 123 | 42 1 | 123 | 456 | 123 1 | 123 | 4567890123456789 | 123 1 | 4567890123456789 | 4567890123456789 | 4567890123456789 1 | 4567890123456789 | -4567890123456789 | 4567890123456789 + 1 | 4567890123456789 | 123 | 42 (5 rows) -- join removal bug #17769: can't remove if there's a pushed-down reference @@ -6654,8 +6820,8 @@ SELECT q2 FROM (SELECT * FROM int8_tbl LEFT JOIN innertab ON q2 = id) ss WHERE COALESCE(dat1, 0) = q1; - QUERY PLAN ---------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Result Filter: (COALESCE(innertab.dat1, '0'::bigint) = int8_tbl.q1) @@ -6676,11 +6842,12 @@ SELECT q2 FROM FROM int8_tbl LEFT JOIN innertab ON q2 = id) ss RIGHT JOIN int4_tbl ON NULL WHERE x >= x; - QUERY PLAN -------------------------- + QUERY PLAN +---------------------------- Result Output: NULL::bigint One-Time Filter: false + Settings: optimizer = 'on' Optimizer: GPORCA (5 rows) @@ -6691,8 +6858,8 @@ FROM int4_tbl JOIN ((SELECT 42 AS x FROM int8_tbl LEFT JOIN innertab ON q1 = id) AS ss1 RIGHT JOIN tenk1 ON NULL) ON tenk1.unique1 = ss1.x OR tenk1.unique2 = ss1.x; - QUERY PLAN -------------------------- + QUERY PLAN +-------------------------- Result One-Time Filter: false Optimizer: GPORCA @@ -6709,15 +6876,15 @@ select t1.* from on t1.f1 = t2.f1 left join uniquetbl t3 on t2.d1 = t3.f1; - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: true -> Seq Scan on uniquetbl t1 -> Index Scan using uniquetbl_f1_key on uniquetbl Index Cond: (f1 = t1.f1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) explain (costs off) @@ -6732,8 +6899,10 @@ from left join uniquetbl u1 ON u1.f1 = t1.string4) ss on t0.f1 = ss.case1 where ss.stringu2 !~* ss.case1; - QUERY PLAN --------------------------------------------------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl, text_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +-------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Join Hash Cond: ((CASE t1.ten WHEN 0 THEN 'doh!'::text ELSE NULL::text END) = t0.f1) @@ -6761,6 +6930,8 @@ from left join uniquetbl u1 ON u1.f1 = t1.string4) ss on t0.f1 = ss.case1 where ss.stringu2 !~* ss.case1; +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl, text_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. f1 ------ doh! @@ -6778,8 +6949,8 @@ from t t1 from t t2 left join t t3 on t2.a = t3.a) s on true where t1.a = s.c; - QUERY PLAN --------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------- Result -> Gather Motion 3:1 (slice1; segments: 3) -> Hash Join @@ -6820,8 +6991,8 @@ from t t1 on true left join t t4 on true where s.a < s.c; - QUERY PLAN --------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------- Result -> Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop @@ -6847,8 +7018,8 @@ from t t1 on true left join t t4 on true where s.a < s.c; - QUERY PLAN --------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join -> Nested Loop @@ -6859,7 +7030,7 @@ where s.a < s.c; -> Materialize -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on t t4 - Optimizer: GPORCA + Optimizer: Postgres query optimizer (11 rows) select t1.a, s.* @@ -6913,8 +7084,9 @@ where q2 = 456; -> Seq Scan on public.int4_tbl i4 Output: i4.f1 Filter: (i4.f1 = 1) + Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(28 rows) +(29 rows) select i8.*, ss.v, t.unique2 from int8_tbl i8 @@ -6931,6 +7103,7 @@ where q2 = 456; -- a PHV that's been translated to a child rel create temp table parttbl (a integer primary key) partition by range (a); create temp table parttbl1 partition of parttbl for values from (1) to (100); +NOTICE: table has parent, setting distribution columns to match parent table insert into parttbl values (11), (12); set optimizer_enable_dynamicindexonlyscan=off; explain (costs off) @@ -6938,8 +7111,10 @@ select * from (select *, 12 as phv from parttbl) as ss right join int4_tbl on true where ss.a = ss.phv and f1 = 0; - QUERY PLAN ------------------------------------------------------------------ +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl, parttbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +----------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -6960,6 +7135,8 @@ select * from (select *, 12 as phv from parttbl) as ss right join int4_tbl on true where ss.a = ss.phv and f1 = 0; +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl, parttbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | phv | f1 ----+-----+---- 12 | 12 | 0 @@ -6979,6 +7156,8 @@ LINE 2: ...bl x join (int4_tbl x cross join int4_tbl y) j on q1 = y.f1; DETAIL: There is an entry for table "y", but it cannot be referenced from this part of the query. select * from int8_tbl x join (int4_tbl x cross join int4_tbl y(ff)) j on q1 = f1; -- ok +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. q1 | q2 | f1 | ff ----+----+----+---- (0 rows) @@ -7027,11 +7206,12 @@ explain (verbose, costs off) select 1 from (select * from int8_tbl where q1 <> (select 42) offset 0) ss where false; - QUERY PLAN -------------------------- + QUERY PLAN +---------------------------- Result Output: NULL::integer One-Time Filter: false + Settings: optimizer = 'on' Optimizer: GPORCA (5 rows) @@ -7150,8 +7330,8 @@ select count(*) from tenk1 a, lateral generate_series(1,two) g; explain (costs off) select count(*) from tenk1 a, lateral generate_series(1,two) g; - QUERY PLAN ------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Finalize Aggregate -> Gather Motion 3:1 (slice1; segments: 3) -> Partial Aggregate @@ -7166,8 +7346,8 @@ explain (costs off) explain (costs off) select count(*) from tenk1 a cross join lateral generate_series(1,two) g; - QUERY PLAN ------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Finalize Aggregate -> Gather Motion 3:1 (slice1; segments: 3) -> Partial Aggregate @@ -7177,13 +7357,14 @@ explain (costs off) Cache Key: a.two Cache Mode: binary -> Function Scan on generate_series g + Optimizer: Postgres query optimizer (10 rows) -- don't need the explicit LATERAL keyword for functions explain (costs off) select count(*) from tenk1 a, generate_series(1,two) g; - QUERY PLAN ------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Finalize Aggregate -> Gather Motion 3:1 (slice1; segments: 3) -> Partial Aggregate @@ -7299,12 +7480,12 @@ explain (costs off) int8_tbl x left join lateral (select a.q1 from int4_tbl y) ss(z) on x.q2 = ss.z order by a.q1, a.q2, x.q1, x.q2, ss.z; -ERROR: could not devise a query plan for the given query (pathnode.c:277) +ERROR: could not devise a query plan for the given query (pathnode.c:285) select * from int8_tbl a, int8_tbl x left join lateral (select a.q1 from int4_tbl y) ss(z) on x.q2 = ss.z order by a.q1, a.q2, x.q1, x.q2, ss.z; -ERROR: could not devise a query plan for the given query (pathnode.c:277) +ERROR: could not devise a query plan for the given query (pathnode.c:285) --end_ignore -- lateral reference to a join alias variable select * from (select f1/2 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1, @@ -7416,14 +7597,14 @@ select * from ------------------+-------------------+------------------+-------------------+------------------+------------------+------------------- 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 123 | 123 | 456 | 4567890123456789 | 123 | 456 - 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 123 - 4567890123456789 | -4567890123456789 | | | 4567890123456789 | | 123 | 456 | | | 123 | | 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | -4567890123456789 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 123 | 4567890123456789 | 4567890123456789 | 123 | 123 | 4567890123456789 | 123 + 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 123 + 4567890123456789 | -4567890123456789 | | | 4567890123456789 | | (10 rows) select x.* from @@ -7431,16 +7612,16 @@ select x.* from lateral (select x.q1,y.q1,y.q2) v(xq1,yq1,yq2); q1 | q2 ------------------+------------------- - 4567890123456789 | 123 - 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 123 | 456 123 | 4567890123456789 123 | 4567890123456789 123 | 4567890123456789 + 4567890123456789 | 4567890123456789 + 4567890123456789 | 4567890123456789 + 4567890123456789 | 4567890123456789 + 4567890123456789 | -4567890123456789 + 4567890123456789 | 123 + 4567890123456789 | 123 (10 rows) select v.* from @@ -7449,10 +7630,14 @@ select v.* from lateral (select x.q1,y.q1 union all select x.q2,y.q2) v(vx,vy); vx | vy -------------------+------------------- - 4567890123456789 | 123 + 123 | + 456 | + 123 | 4567890123456789 + 4567890123456789 | -4567890123456789 + 123 | 4567890123456789 + 4567890123456789 | 4567890123456789 123 | 4567890123456789 4567890123456789 | 123 - 123 | 456 4567890123456789 | 4567890123456789 4567890123456789 | -4567890123456789 4567890123456789 | 4567890123456789 @@ -7461,14 +7646,10 @@ select v.* from 4567890123456789 | 123 4567890123456789 | -4567890123456789 | - 123 | - 456 | - 123 | 4567890123456789 - 4567890123456789 | -4567890123456789 - 123 | 4567890123456789 - 4567890123456789 | 4567890123456789 + 4567890123456789 | 123 123 | 4567890123456789 4567890123456789 | 123 + 123 | 456 (20 rows) select v.* from @@ -7477,14 +7658,10 @@ select v.* from lateral (select x.q1,y.q1 union all select x.q2,y.q2) v(vx,vy); vx | vy -------------------+------------------- - 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 4567890123456789 | 123 - 4567890123456789 | - -4567890123456789 | + 123 | 4567890123456789 + 4567890123456789 | 123 + 123 | 456 123 | 456 | 123 | 4567890123456789 @@ -7493,10 +7670,14 @@ select v.* from 4567890123456789 | 4567890123456789 123 | 4567890123456789 4567890123456789 | 123 + 4567890123456789 | 4567890123456789 + 4567890123456789 | -4567890123456789 + 4567890123456789 | 4567890123456789 + 4567890123456789 | 4567890123456789 + 4567890123456789 | 4567890123456789 4567890123456789 | 123 - 123 | 4567890123456789 - 4567890123456789 | 123 - 123 | 456 + 4567890123456789 | + -4567890123456789 | (20 rows) select v.* from @@ -7505,10 +7686,6 @@ select v.* from lateral (select x.q1,y.q1 from onerow union all select x.q2,y.q2 from onerow) v(vx,vy); vx | vy -------------------+------------------- - 4567890123456789 | 123 - 123 | 4567890123456789 - 4567890123456789 | 123 - 123 | 456 4567890123456789 | 4567890123456789 4567890123456789 | -4567890123456789 4567890123456789 | 4567890123456789 @@ -7525,6 +7702,10 @@ select v.* from 4567890123456789 | 4567890123456789 123 | 4567890123456789 4567890123456789 | 123 + 4567890123456789 | 123 + 123 | 4567890123456789 + 4567890123456789 | 123 + 123 | 456 (20 rows) explain (verbose, costs off) @@ -7554,6 +7735,8 @@ select * from lateral (select *, a.q2 as x from int8_tbl b) ss on a.q2 = ss.q1; q1 | q2 | q1 | q2 | x ------------------+-------------------+------------------+-------------------+------------------ + 4567890123456789 | 123 | 123 | 456 | 123 + 4567890123456789 | 123 | 123 | 4567890123456789 | 123 123 | 456 | | | 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 @@ -7562,8 +7745,6 @@ select * from 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 4567890123456789 | -4567890123456789 | | | - 4567890123456789 | 123 | 123 | 456 | 123 - 4567890123456789 | 123 | 123 | 4567890123456789 | 123 (10 rows) explain (verbose, costs off) @@ -7593,16 +7774,16 @@ select * from lateral (select *, coalesce(a.q2, 42) as x from int8_tbl b) ss on a.q2 = ss.q1; q1 | q2 | q1 | q2 | x ------------------+-------------------+------------------+-------------------+------------------ - 4567890123456789 | 123 | 123 | 456 | 123 - 4567890123456789 | 123 | 123 | 4567890123456789 | 123 - 123 | 456 | | | - 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 4567890123456789 | -4567890123456789 | | | + 123 | 456 | | | + 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 + 4567890123456789 | 123 | 123 | 456 | 123 + 4567890123456789 | 123 | 123 | 4567890123456789 | 123 (10 rows) -- lateral can result in join conditions appearing below their @@ -7652,18 +7833,19 @@ select * from int4_tbl i left join -> Seq Scan on public.int2_tbl j Output: j.f1, COALESCE(i.*) Filter: (i.f1 = j.f1) + Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(10 rows) +(11 rows) select * from int4_tbl i left join lateral (select coalesce(i) from int2_tbl j where i.f1 = j.f1) k on true; f1 | coalesce -------------+---------- - 123456 | - -123456 | 0 | (0) 2147483647 | -2147483647 | + 123456 | + -123456 | (5 rows) explain (verbose, costs off) @@ -7701,8 +7883,9 @@ select * from int4_tbl a, Output: b.f1 -> Seq Scan on public.int4_tbl b Output: b.f1 + Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(29 rows) +(30 rows) select * from int4_tbl a, lateral ( @@ -7747,13 +7930,13 @@ select * from (select b.q1 as bq1, c.q1 as cq1, least(a.q1,b.q1,c.q1) from int8_tbl b cross join int8_tbl c) ss on a.q2 = ss.bq1; -ERROR: could not devise a query plan for the given query (pathnode.c:275) +ERROR: could not devise a query plan for the given query (pathnode.c:285) select * from int8_tbl a left join lateral (select b.q1 as bq1, c.q1 as cq1, least(a.q1,b.q1,c.q1) from int8_tbl b cross join int8_tbl c) ss on a.q2 = ss.bq1; -ERROR: could not devise a query plan for the given query (pathnode.c:275) +ERROR: could not devise a query plan for the given query (pathnode.c:285) -- case requiring nested PlaceHolderVars explain (verbose, costs off) select * from @@ -7802,7 +7985,8 @@ select * from Output: ((COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2))) -> Result Output: (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)) - Optimizer: GPORCA + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer (38 rows) -- another case requiring nested PlaceHolderVars @@ -7811,8 +7995,8 @@ select * from (select 0 as val0) as ss0 left join (select 1 as val) as ss1 on true left join lateral (select ss1.val as val_filtered where false) as ss2 on true; - QUERY PLAN -------------------------------- + QUERY PLAN +------------------------------------- Nested Loop Left Join Output: 0, (1), ((1)) Join Filter: false @@ -7821,7 +8005,8 @@ select * from -> Result Output: (1) One-Time Filter: false - Optimizer: GPORCA + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer (10 rows) select * from @@ -7845,8 +8030,8 @@ select c.*,a.*,ss1.q1,ss2.q1,ss3.* from lateral (select q1, coalesce(ss1.x,q2) as y from int8_tbl d) ss2 ) on c.q2 = ss2.q1, lateral (select * from int4_tbl i where ss2.y > f1) ss3; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: c.q1, c.q2, a.q1, a.q2, b.q1, d.q1, i.f1 -> Nested Loop @@ -7895,8 +8080,9 @@ select c.*,a.*,ss1.q1,ss2.q1,ss3.* from Hash Key: c.q2 -> Seq Scan on public.int8_tbl c Output: c.q1, c.q2 + Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(49 rows) +(50 rows) -- check processing of postponed quals (bug #9041) explain (verbose, costs off) @@ -7922,7 +8108,8 @@ select * from Output: (3) -> Result Output: 3 - Optimizer: GPORCA + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer (17 rows) -- a new postponed-quals issue (bug #17768) @@ -7930,8 +8117,8 @@ explain (costs off) select * from int4_tbl t1, lateral (select * from int4_tbl t2 inner join int4_tbl t3 on t1.f1 = 1 inner join (int4_tbl t4 left join int4_tbl t5 on true) on true) ss; - QUERY PLAN ------------------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop -> Redistribute Motion 3:3 (slice2; segments: 3) @@ -7955,7 +8142,7 @@ select * from int4_tbl t1, -> Redistribute Motion 3:3 (slice5; segments: 3) Hash Key: 1 -> Seq Scan on int4_tbl t5 - Optimizer: GPORCA + Optimizer: Postgres query optimizer (24 rows) -- check dummy rels with lateral references (bug #15694) @@ -7974,8 +8161,9 @@ select * from int8_tbl i8 left join lateral -> Result Output: f1, i8.q2 One-Time Filter: false + Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(10 rows) +(12 rows) explain (verbose, costs off) select * from int8_tbl i8 left join lateral @@ -7991,8 +8179,9 @@ select * from int8_tbl i8 left join lateral -> Result Output: f1, f1, i8.q2 One-Time Filter: false + Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(10 rows) +(11 rows) -- check handling of nested appendrels inside LATERAL select * from @@ -8044,8 +8233,9 @@ select * from Output: tenk1.unique1, tenk1.unique2 -> Seq Scan on public.tenk1 Output: tenk1.unique1, tenk1.unique2 + Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(20 rows) +(21 rows) select * from (values (0,9998), (1,1000)) v(id,x), @@ -8128,6 +8318,8 @@ LINE 1: select 1 from tenk1 a, lateral (select max(a.unique1) from i... -- check behavior of LATERAL in UPDATE/DELETE create temp table xx1 as select f1 as x1, -f1 as x2 from int4_tbl; NOTICE: Table doesn't have 'DISTRIBUTED BY' clause. Creating a NULL policy entry. +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. -- error, can't do this: update xx1 set x2 = f1 from (select * from int4_tbl where f1 = x1) ss; ERROR: column "x1" does not exist @@ -8193,12 +8385,12 @@ select t1.b, ss.phv from join_ut1 t1 left join lateral (select t2.a as t2a, t3.a t3a, least(t1.a, t2.a, t3.a) phv from join_pt1 t2 join join_ut1 t3 on t2.a = t3.b) ss on t1.a = ss.t2a order by t1.a; -ERROR: could not devise a query plan for the given query (pathnode.c:275) +ERROR: could not devise a query plan for the given query (pathnode.c:285) select t1.b, ss.phv from join_ut1 t1 left join lateral (select t2.a as t2a, t3.a t3a, least(t1.a, t2.a, t3.a) phv from join_pt1 t2 join join_ut1 t3 on t2.a = t3.b) ss on t1.a = ss.t2a order by t1.a; -ERROR: could not devise a query plan for the given query (pathnode.c:275) +ERROR: could not devise a query plan for the given query (pathnode.c:285) -- end_ignore drop table join_pt1; drop table join_ut1; @@ -8207,6 +8399,8 @@ drop table join_ut1; -- begin; create table fkest (x integer, x10 integer, x10b integer, x100 integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'x' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into fkest select x, x/10, x/10, x/100 from generate_series(1,1000) x; create unique index on fkest(x, x10, x100); analyze fkest; @@ -8287,8 +8481,8 @@ from fkest f left join fkest1 f2 on f.a = f2.a and f.b = f2.b left join fkest1 f3 on f.a = f3.a and f.b = f3.b where f.c = 1; - QUERY PLAN -------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Left Join Join Filter: true @@ -8304,7 +8498,7 @@ where f.c = 1; Index Cond: ((a = f.a) AND (b = f.b)) -> Index Scan using fkest1_pkey on fkest1 f3 Index Cond: ((a = f.a) AND (b = f.b)) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (16 rows) rollback; @@ -8348,8 +8542,9 @@ select * from j1 inner join j2 on j1.id = j2.id; Output: j2.id -> Seq Scan on public.j2 Output: j2.id - Optimizer: Pivotal Optimizer (GPORCA) -(12 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(13 rows) -- ensure join is not unique when not an equi-join explain (verbose, costs off) @@ -8368,8 +8563,9 @@ select * from j1 inner join j2 on j1.id > j2.id; -> Index Scan using j2_pkey on public.j2 Output: j2.id Index Cond: (j2.id < j1.id) - Optimizer: Pivotal Optimizer (GPORCA) -(13 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(14 rows) -- ensure non-unique rel is not chosen as inner explain (verbose, costs off) @@ -8387,8 +8583,9 @@ select * from j1 inner join j3 on j1.id = j3.id; Output: j1.id -> Seq Scan on public.j1 Output: j1.id - Optimizer: Pivotal Optimizer (GPORCA) -(12 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(13 rows) -- ensure left join is marked as unique explain (verbose, costs off) @@ -8406,8 +8603,9 @@ select * from j1 left join j2 on j1.id = j2.id; Output: j2.id -> Seq Scan on public.j2 Output: j2.id - Optimizer: Pivotal Optimizer (GPORCA) -(12 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(13 rows) -- ensure right join is marked as unique explain (verbose, costs off) @@ -8425,8 +8623,9 @@ select * from j1 right join j2 on j1.id = j2.id; Output: j1.id -> Seq Scan on public.j1 Output: j1.id - Optimizer: Pivotal Optimizer (GPORCA) -(12 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(13 rows) -- ensure full join is marked as unique explain (verbose, costs off) @@ -8444,8 +8643,9 @@ select * from j1 full join j2 on j1.id = j2.id; Output: j2.id -> Seq Scan on public.j2 Output: j2.id + Settings: optimizer = 'on' Optimizer: GPORCA -(12 rows) +(13 rows) -- a clauseless (cross) join can't be unique explain (verbose, costs off) @@ -8463,8 +8663,9 @@ select * from j1 cross join j2; Output: j1.id -> Seq Scan on public.j2 Output: j2.id - Optimizer: Pivotal Optimizer (GPORCA) -(12 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(13 rows) -- ensure a natural join is marked as unique explain (verbose, costs off) @@ -8482,8 +8683,9 @@ select * from j1 natural join j2; Output: j2.id -> Seq Scan on public.j2 Output: j2.id - Optimizer: Pivotal Optimizer (GPORCA) -(12 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(13 rows) -- ensure a distinct clause allows the inner to become unique explain (verbose, costs off) @@ -8518,8 +8720,9 @@ inner join (select distinct id from j3) j3 on j1.id = j3.id; -> Index Scan using j1_pkey on public.j1 Output: j1.id Index Cond: (j1.id = j3.id) - Optimizer: Pivotal Optimizer (GPORCA) -(28 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(29 rows) -- ensure group by clause allows the inner to become unique explain (verbose, costs off) @@ -8554,8 +8757,9 @@ inner join (select id from j3 group by id) j3 on j1.id = j3.id; -> Index Scan using j1_pkey on public.j1 Output: j1.id Index Cond: (j1.id = j3.id) - Optimizer: Pivotal Optimizer (GPORCA) -(28 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(29 rows) drop table j1; drop table j2; @@ -8589,8 +8793,9 @@ inner join j2 on j1.id1 = j2.id1; -> Index Scan using j1_pkey on public.j1 Output: j1.id1, j1.id2 Index Cond: (j1.id1 = j2.id1) - Optimizer: Pivotal Optimizer (GPORCA) -(13 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(14 rows) -- ensure proper unique detection with multiple join quals explain (verbose, costs off) @@ -8608,8 +8813,9 @@ inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2; -> Index Scan using j1_pkey on public.j1 Output: j1.id1, j1.id2 Index Cond: ((j1.id1 = j2.id1) AND (j1.id2 = j2.id2)) - Optimizer: Pivotal Optimizer (GPORCA) -(11 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(12 rows) -- ensure we don't detect the join to be unique when quals are not part of the -- join condition @@ -8632,8 +8838,8 @@ inner join j2 on j1.id1 = j2.id1 where j1.id2 = 1; -> Index Scan using j2_pkey on public.j2 Output: j2.id1, j2.id2 Index Cond: (j2.id1 = j1.id1) - Optimizer: Pivotal Optimizer (GPORCA) - Settings: enable_nestloop=on + Settings: optimizer = 'on', enable_nestloop = 'on' + Optimizer: GPORCA (15 rows) -- as above, but for left joins. @@ -8656,19 +8862,19 @@ left join j2 on j1.id1 = j2.id1 where j1.id2 = 1; Output: j2.id1, j2.id2 -> Seq Scan on public.j2 Output: j2.id1, j2.id2 - Optimizer: Pivotal Optimizer (GPORCA) - Settings: enable_nestloop=on + Settings: optimizer = 'on', enable_nestloop = 'on' + Optimizer: GPORCA (16 rows) create unique index j1_id2_idx on j1(id2) where id2 is not null; -DETAIL: Distribution key column "id1" is not included in the constraint. ERROR: UNIQUE index must contain all columns in the table's distribution key +DETAIL: Distribution key column "id1" is not included in the constraint. -- ensure we don't use a partial unique index as unique proofs explain (verbose, costs off) select * from j1 inner join j2 on j1.id2 = j2.id2; - QUERY PLAN --------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: j1.id1, j1.id2, j2.id1, j2.id2 -> Nested Loop @@ -8681,6 +8887,7 @@ inner join j2 on j1.id2 = j2.id2; -> Index Scan using j1_pkey on public.j1 Output: j1.id1, j1.id2 Index Cond: (j1.id2 = j2.id2) + Settings: optimizer = 'on', enable_nestloop = 'on' Optimizer: GPORCA (14 rows) @@ -8713,7 +8920,7 @@ where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1; -> Index Scan using j2_pkey on j2 Index Cond: ((id1 = j1.id1) AND (id2 = j1.id2)) Filter: ((id1 % 1000) = 1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) select * from j1 @@ -8740,7 +8947,7 @@ where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1 and j2.id1 = any (array[1]); -> Index Scan using j2_pkey on j2 Index Cond: ((id1 = j1.id1) AND (id1 = ANY ('{1}'::integer[])) AND (id1 = 1) AND (id2 = j1.id2)) Filter: ((id1 % 1000) = 1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) select * from j1 @@ -8767,7 +8974,7 @@ where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1 and j2.id1 >= any (array[1,5]); -> Index Scan using j1_pkey on j1 Index Cond: ((id1 = j2.id1) AND (id2 = j2.id2)) Filter: ((id1 % 1000) = 1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) select * from j1 @@ -8797,8 +9004,8 @@ from onek t1, tenk1 t2 where exists (select 1 from tenk1 t3 where t3.thousand = t1.unique1 and t3.tenthous = t2.hundred) and t1.unique1 < 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: t1.unique1, t2.hundred -> Hash Semi Join @@ -8821,7 +9028,7 @@ where exists (select 1 from tenk1 t3 -> Index Only Scan using tenk1_thous_tenthous on public.tenk1 t3 Output: t3.thousand, t3.tenthous Index Cond: (t3.thousand < 1) - Settings: enable_bitmapscan = 'off', enable_hashjoin = 'off', enable_mergejoin = 'on', enable_nestloop = 'on', enable_parallel = 'off', enable_seqscan = 'off', optimizer = 'on' + Settings: optimizer = 'on', enable_mergejoin = 'on', enable_hashjoin = 'off', enable_nestloop = 'on', enable_seqscan = 'off', enable_bitmapscan = 'off' Optimizer: GPORCA (24 rows) @@ -8837,8 +9044,8 @@ from onek t1, tenk1 t2 where exists (select 1 from j3 where j3.unique1 = t1.unique1 and j3.tenthous = t2.hundred) and t1.unique1 < 1; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: t1.unique1, t2.hundred -> Hash Semi Join @@ -8861,13 +9068,15 @@ where exists (select 1 from j3 -> Seq Scan on public.j3 Output: j3.unique1, j3.tenthous Filter: (j3.unique1 < 1) - Optimizer: Pivotal Optimizer (GPORCA) - Settings: enable_bitmapscan=off, enable_hashjoin=off, enable_mergejoin=on, enable_nestloop=on, enable_seqscan=off + Settings: optimizer = 'on', enable_mergejoin = 'on', enable_hashjoin = 'off', enable_nestloop = 'on', enable_seqscan = 'off', enable_bitmapscan = 'off' + Optimizer: GPORCA (24 rows) drop table j3; -- Test that we do not account for nullingrels when looking up statistics CREATE TABLE group_tbl (a INT, b INT); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO group_tbl SELECT 1, 1; CREATE STATISTICS group_tbl_stat (ndistinct) ON a, b FROM group_tbl; ANALYZE group_tbl; @@ -8875,8 +9084,8 @@ EXPLAIN (COSTS OFF) SELECT 1 FROM group_tbl t1 LEFT JOIN (SELECT a c1, COALESCE(a) c2 FROM group_tbl t2) s ON TRUE GROUP BY s.c1, s.c2; - QUERY PLAN --------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------- Result -> Gather Motion 3:1 (slice1; segments: 3) -> GroupAggregate diff --git a/src/test/regress/expected/memoize_optimizer.out b/src/test/regress/expected/memoize_optimizer.out index 08ac4f997ef..4f0f365f492 100644 --- a/src/test/regress/expected/memoize_optimizer.out +++ b/src/test/regress/expected/memoize_optimizer.out @@ -81,6 +81,7 @@ WHERE t1.unique1 < 1000;', false); -> Seq Scan on tenk1 t1 (actual rows=340 loops=N) Filter: (unique1 < 1000) Rows Removed by Filter: 2906 + -> Materialize (actual rows=1 loops=N) -> Memoize (actual rows=1 loops=N) Cache Key: t1.twenty Cache Mode: binary @@ -90,7 +91,6 @@ WHERE t1.unique1 < 1000;', false); -> Materialize (actual rows=10000 loops=N) -> Gather Motion 3:1 (slice2; segments: 3) (actual rows=10000 loops=N) -> Seq Scan on tenk1 t2 (actual rows=3386 loops=N) - -> Materialize (actual rows=1 loops=N) Optimizer: Postgres query optimizer (17 rows) @@ -107,6 +107,8 @@ WHERE t1.unique1 < 1000; SET enable_mergejoin TO off; -- Test for varlena datatype with expr evaluation CREATE TABLE expr_key (x numeric, t text); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'x' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO expr_key (x, t) SELECT d1::numeric, d1::text FROM ( SELECT round((d / pi())::numeric, 7) AS d1 FROM generate_series(1, 20) AS d @@ -243,8 +245,12 @@ DROP TABLE strtest; -- Ensure memoize works with partitionwise join SET enable_partitionwise_join TO on; CREATE TABLE prt (a int) PARTITION BY RANGE(a); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TABLE prt_p1 PARTITION OF prt FOR VALUES FROM (0) TO (10); +NOTICE: table has parent, setting distribution columns to match parent table CREATE TABLE prt_p2 PARTITION OF prt FOR VALUES FROM (10) TO (20); +NOTICE: table has parent, setting distribution columns to match parent table INSERT INTO prt VALUES (0), (0), (0), (0); INSERT INTO prt VALUES (10), (10), (10), (10); CREATE INDEX iprt_p1_a ON prt_p1 (a); @@ -264,6 +270,7 @@ SELECT * FROM prt t1 INNER JOIN prt t2 ON t1.a = t2.a;', false); -> Dynamic Seq Scan on prt t2 (actual rows=3 loops=N) Number of partitions to scan: 2 (out of 2) Partitions scanned: Avg 1.4 x 3 workers of 5 scans. Max 2 parts (seg2). + Optimizer: GPORCA (10 rows) RESET enable_parallel; @@ -278,11 +285,12 @@ ON t1.a = t2.a;', false); Gather Motion 3:1 (slice1; segments: 3) (actual rows=16 loops=N) -> Nested Loop (actual rows=16 loops=N) Join Filter: true - -> Index Scan using iprt_p1_a on prt_p1 t1 (actual rows=4 loops=N) -> Append (actual rows=4 loops=N) -> Seq Scan on prt_p1 (actual rows=4 loops=N) -> Seq Scan on prt_p2 (actual rows=4 loops=N) + -> Index Scan using iprt_p1_a on prt_p1 t1 (actual rows=4 loops=N) Index Cond: (a = prt_p1.a) + Optimizer: GPORCA (9 rows) DROP TABLE prt; @@ -297,32 +305,29 @@ WHERE unique1 < 3 SELECT 1 FROM tenk1 t1 INNER JOIN tenk1 t2 ON t1.unique1 = t2.hundred WHERE t0.ten = t1.twenty AND t0.two <> t2.four OFFSET 0); - QUERY PLAN ------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> GroupAggregate - Group Key: t0.unique1, t0.ctid, t0.gp_segment_id - -> Sort - Sort Key: t0.ctid, t0.gp_segment_id + -> Hash Right Semi Join + Hash Cond: (t0.ten = t1.twenty) + Join Filter: (t0.two <> t2.four) + -> Result -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: t0.ctid, t0.gp_segment_id - -> Streaming HashAggregate - Group Key: t0.unique1, t0.ctid, t0.gp_segment_id - -> Nested Loop - Join Filter: ((t0.ten = t1.twenty) AND (t0.two <> t2.four)) - -> Broadcast Motion 3:3 (slice4; segments: 3) - -> Index Scan using tenk1_unique1 on tenk1 t0 - Index Cond: (unique1 < 3) - -> Materialize - -> Nested Loop - Join Filter: true - -> Redistribute Motion 3:3 (slice3; segments: 3) - Hash Key: t2.hundred - -> Seq Scan on tenk1 t2 - -> Index Scan using tenk1_unique1 on tenk1 t1 - Index Cond: (unique1 = t2.hundred) + Hash Key: t1.twenty + -> Nested Loop + Join Filter: true + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t2.hundred + -> Seq Scan on tenk1 t2 + -> Index Scan using tenk1_unique1 on tenk1 t1 + Index Cond: (unique1 = t2.hundred) + -> Hash + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: t0.ten + -> Index Scan using tenk1_unique1 on tenk1 t0 + Index Cond: (unique1 < 3) Optimizer: GPORCA -(23 rows) +(20 rows) -- Ensure the above query returns the correct result SELECT unique1 FROM tenk1 t0 @@ -370,7 +375,7 @@ WHERE t1.unique1 < 1000; -> Bitmap Index Scan on tenk1_unique1 Index Cond: (unique1 < 1000) Optimizer: Postgres query optimizer -(12 rows) +(14 rows) -- And ensure the parallel plan gives us the correct results. SELECT COUNT(*),AVG(t2.unique1) FROM tenk1 t1, diff --git a/src/test/regress/expected/partition_append.out b/src/test/regress/expected/partition_append.out index 9154c7d5a6b..1ad541e01f5 100755 --- a/src/test/regress/expected/partition_append.out +++ b/src/test/regress/expected/partition_append.out @@ -2,9 +2,13 @@ set optimizer to on; set optimizer_disable_dynamic_table_scan to on; drop table if exists d; +NOTICE: table "d" does not exist, skipping drop table if exists c; +NOTICE: table "c" does not exist, skipping drop table if exists b; +NOTICE: table "b" does not exist, skipping drop table if exists a; +NOTICE: table "a" does not exist, skipping -- Check multi level partition COPY create table region ( @@ -108,7 +112,7 @@ select * from region where r_regionkey = '7'; -- tables since we cannot enforce them. But since this insert maps to a -- single definitive partition, we can detect it. insert into region values(7, 'AUSTRALIA', 'def'); -ERROR: duplicate key value violates unique constraint "region_1_prt_region3_2_prt_australia_r_regionkey_r_name_idx" +ERROR: duplicate key value violates unique constraint "region_1_prt_region3_2_prt_australia_r_regionkey_r_name_idx" (seg0 172.18.0.2:7002 pid=20852) DETAIL: Key (r_regionkey, r_name)=(7, AUSTRALIA ) already exists. drop table region; -- exchange @@ -395,12 +399,12 @@ insert into bar_p values(6); insert into bar_p values(100); -- should fail alter table foo_p exchange partition for(6) with table bar_p; -ERROR: partition constraint of relation "bar_p" is violated by some row +ERROR: partition constraint of relation "bar_p" is violated by some row (seg2 172.18.0.2:7004 pid=20912) alter table foo_p exchange partition for(6) with table bar_p without validation; NOTICE: specifying "WITHOUT VALIDATION" acts as no operation DETAIL: If the new partition is a regular table, validation is performed to make sure all the rows obey partition constraint. If the new partition is external or foreign table, no validation is performed. -ERROR: partition constraint of relation "bar_p" is violated by some row +ERROR: partition constraint of relation "bar_p" is violated by some row (seg2 172.18.0.2:7004 pid=20912) analyze foo_p; select * from foo_p; i @@ -472,9 +476,9 @@ select * from foo_p; i | j ---+--- 2 | 1 - 6 | 6 - 1 | 1 3 | 1 + 1 | 1 + 6 | 6 (4 rows) drop table bar_p; @@ -492,8 +496,8 @@ select * from foo_p; i | j ---+--- 1 | 1 - 3 | 2 2 | 1 + 3 | 2 6 | 6 (4 rows) @@ -511,10 +515,10 @@ analyze foo_p; select * from foo_p; i | j ---+--- - 2 | 3 6 | 6 - 1 | 2 + 2 | 3 3 | 4 + 1 | 2 (4 rows) drop table bar_p; @@ -869,7 +873,7 @@ Distributed by: (i) insert into foo_p values(5994400); insert into foo_p values(1); insert into foo_p values(6000002); -ERROR: no partition of relation "foo_p" found for row +ERROR: no partition of relation "foo_p" found for row (seg2 172.18.0.2:7004 pid=20912) DETAIL: Partition key of the failing row contains (i) = (6000002). insert into foo_p values(5994376); drop table foo_p; @@ -925,18 +929,18 @@ copy foo_p from stdin; select * from foo_p; i --- - 1 - 3 2 + 3 4 + 1 (4 rows) select * from foo_p_1_prt_p1; i --- - 1 - 3 2 + 3 + 1 (3 rows) select * from foo_p_1_prt_p2; @@ -958,17 +962,17 @@ copy foo_p from stdin; select * from foo_p; i --- - 1 - 3 2 + 3 4 + 1 (4 rows) select * from foo_p_1_prt_p1; i --- - 2 1 + 2 3 (3 rows) @@ -995,14 +999,14 @@ select * from mixed_ao_part; ---------+--------- 1 | 95 1 | 100 + 5 | 99 + 5 | 104 2 | 96 - 2 | 101 3 | 97 - 3 | 102 4 | 98 + 2 | 101 + 3 | 102 4 | 103 - 5 | 99 - 5 | 104 (10 rows) -- Don't drop the table, so that we leave behind a mixed table in the @@ -1102,10 +1106,14 @@ alter table i drop partition foo2; -- we shoud check whether the matched table belong to the partitioned table. -- raise error instead of executing on the irrelevant table. create table i_1_prt_3 (like i); +NOTICE: table doesn't have 'DISTRIBUTED BY' clause, defaulting to distribution columns from LIKE table -- create another partitioned table which contains a partition table that -- could be matched by partition name when targeted on an irrelevant table. create table i2 (i int) partition by range(i) (start (1) end(3) every(1)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create table i_1_prt_4 partition of i2 for values from (4) to (5); +NOTICE: table has parent, setting distribution columns to match parent table -- the matechd table name is i_1_prt_3, but it's a normal table, raise error. alter table i drop partition "3"; ERROR: partition "3" of "i" does not exist @@ -1120,6 +1128,8 @@ drop table i; drop table i2; drop table i_1_prt_3; create table i (i int) partition by range(i) (start(1) end(3) every(1), default partition extra); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. -- should raise error since we always make sure the partitioned table at least have one partition; alter table i drop partition "2", drop partition "3", drop default partition; ERROR: cannot drop partition "i_1_prt_extra" of "i" -- only one remains @@ -1128,6 +1138,8 @@ drop table i; create table i (i int, c text) partition by range(i) subpartition by list(c) subpartition template (subpartition a values ('a'), subpartition b values ('b')) (start (1) end(3) every(1)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. -- should raise error since we always make sure the partitioned table at least have one partition; alter table i alter partition "1" drop partition a, alter partition "1" drop partition b; ERROR: cannot drop partition "i_1_prt_1_2_prt_b" of "i_1_prt_1" -- only one remains @@ -1319,7 +1331,6 @@ alter table ataprank alter partition girls drop partition for ('2001-01-01') ; -- ok , skipping alter table ataprank alter partition girls drop partition if exists jan01; -NOTICE: partition "jan01" of partition "girls" of relation "ataprank" does not exist, skipping -- ok alter table ataprank alter partition girls drop partition for ('2002-01-01'); alter table ataprank alter partition girls drop partition for ('2003-01-01'); @@ -1475,13 +1486,13 @@ select relname, has_table_privilege('part_role_append', oid,'select') as tabpriv from pg_class where relname like 'granttest%'; relname | tabpriv | i_priv | j_priv ---------------------------+---------+--------+-------- + granttest | f | f | f + granttest_1_prt_1 | f | f | f + granttest_1_prt_1_2_prt_1 | f | f | f granttest_1_prt_2 | f | f | f granttest_1_prt_2_2_prt_1 | f | f | f granttest_1_prt_3 | f | f | f granttest_1_prt_3_2_prt_1 | f | f | f - granttest | f | f | f - granttest_1_prt_1 | f | f | f - granttest_1_prt_1_2_prt_1 | f | f | f (7 rows) grant select (i) on granttest to part_role_append; @@ -1491,13 +1502,13 @@ select relname, has_table_privilege('part_role_append', oid,'select') as tabpriv from pg_class where relname like 'granttest%'; relname | tabpriv | i_priv | j_priv ---------------------------+---------+--------+-------- + granttest | f | t | f + granttest_1_prt_1 | f | t | f + granttest_1_prt_1_2_prt_1 | f | t | f granttest_1_prt_2 | f | t | f granttest_1_prt_2_2_prt_1 | f | t | f granttest_1_prt_3 | f | t | f granttest_1_prt_3_2_prt_1 | f | t | f - granttest | f | t | f - granttest_1_prt_1 | f | t | f - granttest_1_prt_1_2_prt_1 | f | t | f (7 rows) grant select on granttest to part_role_append; @@ -1507,13 +1518,13 @@ select relname, has_table_privilege('part_role_append', oid,'select') as tabpriv from pg_class where relname like 'granttest%'; relname | tabpriv | i_priv | j_priv ---------------------------+---------+--------+-------- + granttest | t | t | t granttest_1_prt_1 | t | t | t granttest_1_prt_1_2_prt_1 | t | t | t granttest_1_prt_2 | t | t | t granttest_1_prt_2_2_prt_1 | t | t | t granttest_1_prt_3 | t | t | t granttest_1_prt_3_2_prt_1 | t | t | t - granttest | t | t | t (7 rows) grant insert on granttest to part_role_append; @@ -1523,13 +1534,13 @@ select relname, has_table_privilege('part_role_append', oid, 'insert') as tabpri from pg_class where relname like 'granttest%'; relname | tabpriv | i_priv | j_priv ---------------------------+---------+--------+-------- + granttest | t | t | t granttest_1_prt_1 | t | t | t granttest_1_prt_1_2_prt_1 | t | t | t granttest_1_prt_2 | t | t | t granttest_1_prt_2_2_prt_1 | t | t | t granttest_1_prt_3 | t | t | t granttest_1_prt_3_2_prt_1 | t | t | t - granttest | t | t | t (7 rows) revoke insert on granttest from part_role_append; @@ -1540,13 +1551,13 @@ select relname, has_table_privilege('part_role_append', oid, 'insert') as tabpri from pg_class where relname like 'granttest%'; relname | tabpriv | i_priv | j_priv ---------------------------+---------+--------+-------- + granttest | f | f | t granttest_1_prt_1 | f | f | t granttest_1_prt_1_2_prt_1 | f | f | t granttest_1_prt_2 | f | f | t granttest_1_prt_2_2_prt_1 | f | f | t granttest_1_prt_3 | f | f | t granttest_1_prt_3_2_prt_1 | f | f | t - granttest | f | f | t (7 rows) -- Check that when a new partition is created, it inherits the permissions @@ -1554,6 +1565,7 @@ from pg_class where relname like 'granttest%'; alter table granttest add partition newpart start(100) end (101); -- same with the new upstream syntax. create table granttest_newpartsyntax partition of granttest for values from (110) to (120); +NOTICE: table has parent, setting distribution columns to match parent table select relname, has_table_privilege('part_role_append', oid, 'select') as tabpriv, has_column_privilege('part_role_append', oid, 'i', 'select') as i_priv, has_column_privilege('part_role_append', oid, 'j', 'select') as j_priv @@ -1821,6 +1833,8 @@ drop table partsupp; ERROR: table "partsupp" does not exist -- Deletion tests CREATE TABLE tmp_nation_region (n_regionkey integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'n_regionkey' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. drop table if exists tmp_nation; NOTICE: table "tmp_nation" does not exist, skipping CREATE TABLE tmp_nation (N_NATIONKEY INTEGER, N_NAME CHAR(25), N_REGIONKEY INTEGER, N_COMMENT VARCHAR(152)) @@ -1863,21 +1877,21 @@ select * from j_1_prt_fa; select * from j_1_prt_fb; i --- - 3 2 + 3 (2 rows) alter table j split partition for(5) at (6); select * from j; i --- - 1 - 3 - 5 - 7 4 2 + 3 + 7 8 + 1 + 5 6 (8 rows) @@ -1906,11 +1920,11 @@ alter table k split default partition start(15) end(20) into select * from k_1_prt_foo; i ---- + 17 16 18 - 15 - 17 19 + 15 (5 rows) alter table k split default partition start(22) exclusive end(25) inclusive @@ -1918,9 +1932,9 @@ into (partition bar, partition mydef); select * from k_1_prt_bar; i ---- + 24 23 25 - 24 (3 rows) -- This fails, because it would create a partition with an empty range. Before @@ -2245,8 +2259,8 @@ insert into rank_exc values(2, 2, 2008, 'M', 3); select * from rank_exc; id | rank | year | gender | count ----+------+------+--------+------- - 1 | 1 | 2007 | M | 1 2 | 2 | 2008 | M | 3 + 1 | 1 | 2007 | M | 1 (2 rows) alter table rank_exc alter partition boys split default partition start ('2007') @@ -2266,8 +2280,8 @@ select * from rank_exc_1_prt_boys_2_prt_year7; select * from rank_exc; id | rank | year | gender | count ----+------+------+--------+------- - 2 | 2 | 2008 | M | 3 1 | 1 | 2007 | M | 1 + 2 | 2 | 2008 | M | 3 (2 rows) --exchange test @@ -2318,7 +2332,7 @@ alter table bar_p alter partition for ('5') alter partition for ('5') drop partition for ('5'); insert into bar_p values(1, 1); insert into bar_p values(5, 5); -ERROR: no partition of relation "bar_p_1_prt_1_2_prt_5" found for row +ERROR: no partition of relation "bar_p_1_prt_1_2_prt_5" found for row (seg2 172.18.0.2:7004 pid=21365) DETAIL: Partition key of the failing row contains (i) = (5). drop table bar_p; -- Drop should not leave anything lingering for bar_p or its @@ -2598,8 +2612,8 @@ into (partition p10_20, default partition); select c.oid::regclass, relkind, amname, reloptions from pg_class c left join pg_am am on am.oid = relam where c.oid in ('foo_p_1_prt_p10_20'::regclass, 'foo_p_1_prt_def'::regclass); oid | relkind | amname | reloptions --------------------+---------+--------+------------ - foo_p_1_prt_p10_20 | r | ao_row | foo_p_1_prt_def | r | ao_row | + foo_p_1_prt_p10_20 | r | ao_row | (2 rows) select count(distinct k) from foo_p; @@ -2645,9 +2659,9 @@ truncate table mpp5941; select relid::regclass, level from gp_partition_template where relid = 'mpp5941'::regclass; relid | level ---------+------- + mpp5941 | 3 mpp5941 | 1 mpp5941 | 2 - mpp5941 | 3 (3 rows) -- clear level 1 @@ -2655,8 +2669,8 @@ alter table mpp5941 set subpartition template (); select relid::regclass, level from gp_partition_template where relid = 'mpp5941'::regclass; relid | level ---------+------- - mpp5941 | 2 mpp5941 | 3 + mpp5941 | 2 (2 rows) -- clear level 2 @@ -2753,6 +2767,8 @@ PARTITION BY RANGE(ps_partkey) ( partition nnull start (NULL) end (300) ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'ps_partkey' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. ERROR: cannot use NULL with range partition specification LINE 6: partition nnull start (NULL) end (300) ^ @@ -2927,14 +2943,14 @@ alter table ti add partition p3 start(3) end(10); select * from pg_indexes where schemaname = 'public' and tablename like 'ti%'; schemaname | tablename | indexname | tablespace | indexdef ------------+-------------+---------------------+------------+---------------------------------------------------------------------------------- + public | ti_1_prt_p3 | ti_1_prt_p3_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_p3_i_j_idx ON public.ti_1_prt_p3 USING btree (i, j) + public | ti_1_prt_p3 | ti_1_prt_p3_j_idx | | CREATE INDEX ti_1_prt_p3_j_idx ON public.ti_1_prt_p3 USING bitmap (j) public | ti_1_prt_1 | ti_1_prt_1_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_1_i_j_idx ON public.ti_1_prt_1 USING btree (i, j) public | ti | ti_pkey | | CREATE UNIQUE INDEX ti_pkey ON ONLY public.ti USING btree (i, j) public | ti_1_prt_2 | ti_1_prt_2_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_2_i_j_idx ON public.ti_1_prt_2 USING btree (i, j) public | ti_1_prt_1 | ti_1_prt_1_j_idx | | CREATE INDEX ti_1_prt_1_j_idx ON public.ti_1_prt_1 USING bitmap (j) public | ti | ti_j_idx | | CREATE INDEX ti_j_idx ON ONLY public.ti USING bitmap (j) public | ti_1_prt_2 | ti_1_prt_2_j_idx | | CREATE INDEX ti_1_prt_2_j_idx ON public.ti_1_prt_2 USING bitmap (j) - public | ti_1_prt_p3 | ti_1_prt_p3_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_p3_i_j_idx ON public.ti_1_prt_p3 USING btree (i, j) - public | ti_1_prt_p3 | ti_1_prt_p3_j_idx | | CREATE INDEX ti_1_prt_p3_j_idx ON public.ti_1_prt_p3 USING bitmap (j) (8 rows) -- Should not be able to drop child indexes added implicitly via ADD PARTITION @@ -2948,16 +2964,16 @@ alter table ti split partition p3 at (7) into (partition pnew1, partition pnew2) select * from pg_indexes where schemaname = 'public' and tablename like 'ti%'; schemaname | tablename | indexname | tablespace | indexdef ------------+----------------+------------------------+------------+---------------------------------------------------------------------------------------- + public | ti_1_prt_pnew1 | ti_1_prt_pnew1_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_pnew1_i_j_idx ON public.ti_1_prt_pnew1 USING btree (i, j) + public | ti_1_prt_pnew1 | ti_1_prt_pnew1_j_idx | | CREATE INDEX ti_1_prt_pnew1_j_idx ON public.ti_1_prt_pnew1 USING bitmap (j) + public | ti_1_prt_pnew2 | ti_1_prt_pnew2_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_pnew2_i_j_idx ON public.ti_1_prt_pnew2 USING btree (i, j) + public | ti_1_prt_pnew2 | ti_1_prt_pnew2_j_idx | | CREATE INDEX ti_1_prt_pnew2_j_idx ON public.ti_1_prt_pnew2 USING bitmap (j) public | ti_1_prt_1 | ti_1_prt_1_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_1_i_j_idx ON public.ti_1_prt_1 USING btree (i, j) public | ti | ti_pkey | | CREATE UNIQUE INDEX ti_pkey ON ONLY public.ti USING btree (i, j) public | ti_1_prt_2 | ti_1_prt_2_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_2_i_j_idx ON public.ti_1_prt_2 USING btree (i, j) public | ti_1_prt_1 | ti_1_prt_1_j_idx | | CREATE INDEX ti_1_prt_1_j_idx ON public.ti_1_prt_1 USING bitmap (j) public | ti | ti_j_idx | | CREATE INDEX ti_j_idx ON ONLY public.ti USING bitmap (j) public | ti_1_prt_2 | ti_1_prt_2_j_idx | | CREATE INDEX ti_1_prt_2_j_idx ON public.ti_1_prt_2 USING bitmap (j) - public | ti_1_prt_pnew1 | ti_1_prt_pnew1_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_pnew1_i_j_idx ON public.ti_1_prt_pnew1 USING btree (i, j) - public | ti_1_prt_pnew1 | ti_1_prt_pnew1_j_idx | | CREATE INDEX ti_1_prt_pnew1_j_idx ON public.ti_1_prt_pnew1 USING bitmap (j) - public | ti_1_prt_pnew2 | ti_1_prt_pnew2_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_pnew2_i_j_idx ON public.ti_1_prt_pnew2 USING btree (i, j) - public | ti_1_prt_pnew2 | ti_1_prt_pnew2_j_idx | | CREATE INDEX ti_1_prt_pnew2_j_idx ON public.ti_1_prt_pnew2 USING bitmap (j) (10 rows) -- Should not be able to drop child indexes added implicitly via SPLIT PARTITION @@ -2995,9 +3011,6 @@ partition by list (b) partition p2 values (2), default partition junk_data ); -NOTICE: CREATE TABLE will create partition "dis_tupdesc_1_prt_p1" for table "dis_tupdesc" -NOTICE: CREATE TABLE will create partition "dis_tupdesc_1_prt_p2" for table "dis_tupdesc" -NOTICE: CREATE TABLE will create partition "dis_tupdesc_1_prt_junk_data" for table "dis_tupdesc" create index dis_tupdesc_idx on dis_tupdesc using btree (c); insert into dis_tupdesc select i, i % 3, i % 4 from generate_series (1, 240) as i; analyze dis_tupdesc; @@ -3006,9 +3019,9 @@ set optimizer_segments = 2; select distinct b from dis_tupdesc where c >= 2; b --- + 2 0 1 - 2 (3 rows) reset gp_segments_for_planner; @@ -3043,9 +3056,9 @@ select schemaname, tablename from pg_tables where schemaname = 'public' and tabl public | newit_1_prt_2 public | newit_1_prt_2_2_prt_1 public | newit_1_prt_2_2_prt_2 + public | newit_1_prt_def public | newit_1_prt_def_2_prt_1 public | newit_1_prt_def_2_prt_2 - public | newit_1_prt_def (10 rows) alter table newit rename to anotherit; @@ -3080,8 +3093,8 @@ alter table it add constraint it_unique_i unique (i); select schemaname, tablename, indexname from pg_indexes where schemaname = 'public' and tablename like 'it%'; schemaname | tablename | indexname ------------+------------+------------------ - public | it | it_unique_i public | it_1_prt_1 | it_1_prt_1_i_key + public | it | it_unique_i public | it_1_prt_2 | it_1_prt_2_i_key (3 rows) @@ -3103,8 +3116,8 @@ alter table it add primary key(i); select schemaname, tablename, indexname from pg_indexes where schemaname = 'public' and tablename like 'it%'; schemaname | tablename | indexname ------------+------------+----------------- - public | it | it_pkey public | it_1_prt_1 | it_1_prt_1_pkey + public | it | it_pkey public | it_1_prt_2 | it_1_prt_2_pkey (3 rows) @@ -3125,8 +3138,8 @@ alter table it add primary key(i); select schemaname, tablename, indexname from pg_indexes where schemaname = 'public' and tablename like 'it%'; schemaname | tablename | indexname ------------+------------+----------------- - public | it | it_pkey public | it_1_prt_1 | it_1_prt_1_pkey + public | it | it_pkey public | it_1_prt_2 | it_1_prt_2_pkey (3 rows) @@ -4481,20 +4494,20 @@ where relname ~ '^s_' group by relname; relname | missing | oid_count ---------------------------+---------+----------- + s_1_prt_1 | 0 | 1 s_1_prt_1_amt_idx | 0 | 1 - s_1_prt_1_units_idx | 0 | 1 - s_1_prt_s_test2_log_idx | 0 | 1 - s_1_prt_s_test_log_idx1 | 0 | 1 - s_i_expr | 0 | 1 - s_j | 0 | 1 + s_1_prt_1_log_idx | 0 | 1 + s_1_prt_s_test2 | 0 | 1 s_1_prt_s_test2_amt_idx | 0 | 1 s_1_prt_s_test2_units_idx | 0 | 1 - s_1_prt_s_test_amt_idx1 | 0 | 1 + s_1_prt_1_units_idx | 0 | 1 s_1_prt_s_test_units_idx1 | 0 | 1 - s_1_prt_1 | 0 | 1 - s_1_prt_1_log_idx | 0 | 1 + s_i_expr | 0 | 1 + s_j | 0 | 1 s_1_prt_s_test | 0 | 1 - s_1_prt_s_test2 | 0 | 1 + s_1_prt_s_test2_log_idx | 0 | 1 + s_1_prt_s_test_amt_idx1 | 0 | 1 + s_1_prt_s_test_log_idx1 | 0 | 1 s_i | 0 | 1 (15 rows) @@ -4516,8 +4529,8 @@ create table tc default partition d, start (0) inclusive end(100) inclusive every (50) ); -DETAIL: PRIMARY KEY constraint on table "tc" lacks column "b" which is part of the partition key. ERROR: unique constraint on partitioned table must include all partitioning columns +DETAIL: PRIMARY KEY constraint on table "tc" lacks column "b" which is part of the partition key. create table cc (a int primary key, b int, c int) distributed by (a) @@ -4526,8 +4539,8 @@ create table cc default partition d, start (0) inclusive end(100) inclusive every (50) ); -DETAIL: PRIMARY KEY constraint on table "cc" lacks column "b" which is part of the partition key. ERROR: unique constraint on partitioned table must include all partitioning columns +DETAIL: PRIMARY KEY constraint on table "cc" lacks column "b" which is part of the partition key. create table at (a int, b int, c int) distributed by (a) @@ -4538,8 +4551,8 @@ create table at ); alter table at add primary key (a); -DETAIL: PRIMARY KEY constraint on table "at" lacks column "b" which is part of the partition key. ERROR: unique constraint on partitioned table must include all partitioning columns +DETAIL: PRIMARY KEY constraint on table "at" lacks column "b" which is part of the partition key. -- MPP-14471 end -- MPP-17606 (using table "at" from above) alter table at @@ -4932,9 +4945,9 @@ from pnx; tableoid | x | y -------------+---+---- pnx_1_prt_a | 1 | x1 - pnx_1_prt_c | 3 | x3 pnx_1_prt_a | 2 | x2 pnx_1_prt_c | 4 | x4 + pnx_1_prt_c | 3 | x3 (4 rows) alter table pnx @@ -4945,8 +4958,8 @@ select tableoid::regclass, * from pnx; tableoid | x | y -------------+---+---- - pnx_1_prt_a | 1 | x1 pnx_1_prt_c | 3 | x3 + pnx_1_prt_a | 1 | x1 pnx_1_prt_a | 2 | x2 pnx_1_prt_c | 4 | x4 (4 rows) @@ -4954,6 +4967,8 @@ from pnx; select tableoid::regclass, * from pnx where y = 'x1'; +NOTICE: One or more columns in the following table(s) do not have statistics: pnx +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. tableoid | x | y -------------+---+---- pnx_1_prt_a | 1 | x1 @@ -4962,6 +4977,8 @@ where y = 'x1'; select tableoid::regclass, * from pnx where x = 1; +NOTICE: One or more columns in the following table(s) do not have statistics: pnx +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. tableoid | x | y -------------+---+---- pnx_1_prt_a | 1 | x1 @@ -4987,8 +5004,8 @@ from pxn; tableoid | x | y -------------+---+---- pxn_1_prt_a | 1 | x1 - pxn_1_prt_c | 3 | x3 pxn_1_prt_a | 2 | x2 + pxn_1_prt_c | 3 | x3 pxn_1_prt_c | 4 | x4 (4 rows) @@ -5000,15 +5017,17 @@ select tableoid::regclass, * from pxn; tableoid | x | y -------------+---+---- - pxn_1_prt_a | 2 | x2 + pxn_1_prt_c | 3 | x3 pxn_1_prt_c | 4 | x4 + pxn_1_prt_a | 2 | x2 pxn_1_prt_a | 1 | x1 - pxn_1_prt_c | 3 | x3 (4 rows) select tableoid::regclass, * from pxn where y = 'x2'; +NOTICE: One or more columns in the following table(s) do not have statistics: pxn +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. tableoid | x | y -------------+---+---- pxn_1_prt_a | 2 | x2 @@ -5017,6 +5036,8 @@ where y = 'x2'; select tableoid::regclass, * from pxn where x = 2; +NOTICE: One or more columns in the following table(s) do not have statistics: pxn +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. tableoid | x | y -------------+---+---- pxn_1_prt_a | 2 | x2 @@ -5041,9 +5062,9 @@ from pxn; tableoid | x | y -------------+----+---- pxn_1_prt_a | 4 | 4 - pxn_1_prt_c | 14 | 14 pxn_1_prt_a | 9 | 9 pxn_1_prt_c | 19 | 19 + pxn_1_prt_c | 14 | 14 (4 rows) alter table pxn @@ -5054,15 +5075,17 @@ select tableoid::regclass, * from pxn; tableoid | x | y -------------+----+---- + pxn_1_prt_c | 14 | 14 + pxn_1_prt_a | 4 | 4 pxn_1_prt_a | 9 | 9 pxn_1_prt_c | 19 | 19 - pxn_1_prt_a | 4 | 4 - pxn_1_prt_c | 14 | 14 (4 rows) select tableoid::regclass, * from pxn where y = 4; +NOTICE: One or more columns in the following table(s) do not have statistics: pxn +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. tableoid | x | y -------------+---+--- pxn_1_prt_a | 4 | 4 @@ -5071,6 +5094,8 @@ where y = 4; select tableoid::regclass, * from pxn where x = 4; +NOTICE: One or more columns in the following table(s) do not have statistics: pxn +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. tableoid | x | y -------------+---+--- pxn_1_prt_a | 4 | 4 @@ -5095,9 +5120,9 @@ from pxn; tableoid | x | y -------------+----+---- pxn_1_prt_a | 4 | 4 - pxn_1_prt_c | 14 | 14 pxn_1_prt_a | 9 | 9 pxn_1_prt_c | 19 | 19 + pxn_1_prt_c | 14 | 14 (4 rows) alter table pxn @@ -5108,15 +5133,17 @@ select tableoid::regclass, * from pxn; tableoid | x | y -------------+----+---- + pxn_1_prt_c | 14 | 14 + pxn_1_prt_a | 4 | 4 pxn_1_prt_a | 9 | 9 pxn_1_prt_c | 19 | 19 - pxn_1_prt_a | 4 | 4 - pxn_1_prt_c | 14 | 14 (4 rows) select tableoid::regclass, * from pxn where y = 9; +NOTICE: One or more columns in the following table(s) do not have statistics: pxn +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. tableoid | x | y -------------+---+--- pxn_1_prt_a | 9 | 9 @@ -5125,6 +5152,8 @@ where y = 9; select tableoid::regclass, * from pxn where x = 9; +NOTICE: One or more columns in the following table(s) do not have statistics: pxn +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. tableoid | x | y -------------+---+--- pxn_1_prt_a | 9 | 9 @@ -5150,6 +5179,8 @@ alter table parttest_t drop column d; alter table parttest_t split partition for(1) at (2) into (partition p11, partition p22); insert into parttest_t values(1,2,'a'); select * from parttest_t; +NOTICE: One or more columns in the following table(s) do not have statistics: parttest_t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b | c ---+---+--- 1 | 2 | a @@ -5161,9 +5192,11 @@ reset optimizer_nestloop_factor; create table part_tab ( i int, j int) distributed by (i) partition by range(j) (start(0) end(10) every(2)); -- Wrong part insert into part_tab_1_prt_1 values(5,5); -ERROR: new row for relation "part_tab_1_prt_1" violates partition constraint +ERROR: new row for relation "part_tab_1_prt_1" violates partition constraint (seg2 172.18.0.2:7004 pid=21365) DETAIL: Failing row contains (5, 5). select * from part_tab; +NOTICE: One or more columns in the following table(s) do not have statistics: part_tab +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. i | j ---+--- (0 rows) @@ -5174,9 +5207,11 @@ select * from part_tab_1_prt_1; (0 rows) insert into part_tab_1_prt_2 values(5,5); -ERROR: new row for relation "part_tab_1_prt_2" violates partition constraint +ERROR: new row for relation "part_tab_1_prt_2" violates partition constraint (seg2 172.18.0.2:7004 pid=21365) DETAIL: Failing row contains (5, 5). select * from part_tab; +NOTICE: One or more columns in the following table(s) do not have statistics: part_tab +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. i | j ---+--- (0 rows) @@ -5224,7 +5259,7 @@ HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sur insert into input2 select i, i from (select generate_series(1,10) as i) as t; -- Multiple range table entries in the plan insert into part_tab_1_prt_1 select i1.x, i2.y from input1 as i1 join input2 as i2 on i1.x = i2.x where i2.y = 5; -ERROR: new row for relation "part_tab_1_prt_1" violates partition constraint +ERROR: new row for relation "part_tab_1_prt_1" violates partition constraint (seg2 172.18.0.2:7004 pid=21365) DETAIL: Failing row contains (5, 5). analyze part_tab; select * from part_tab; @@ -5240,7 +5275,7 @@ select * from part_tab_1_prt_1; (0 rows) insert into part_tab_1_prt_2 select i1.x, i2.y from input1 as i1 join input2 as i2 on i1.x = i2.x where i2.y = 5; -ERROR: new row for relation "part_tab_1_prt_2" violates partition constraint +ERROR: new row for relation "part_tab_1_prt_2" violates partition constraint (seg2 172.18.0.2:7004 pid=21365) DETAIL: Failing row contains (5, 5). select * from part_tab; i | j @@ -5276,15 +5311,15 @@ select * from part_tab_1_prt_3; -- Root part but no matching part for i2.y == 10 insert into part_tab select i1.x, i2.y from input1 as i1 join input2 as i2 on i1.x = i2.x; -ERROR: no partition of relation "part_tab" found for row +ERROR: no partition of relation "part_tab" found for row (seg2 172.18.0.2:7004 pid=21365) DETAIL: Partition key of the failing row contains (j) = (10). select * from part_tab; i | j ---+--- + 4 | 4 5 | 5 5 | 5 5 | 5 - 4 | 4 (4 rows) -- Root part @@ -5292,19 +5327,19 @@ insert into part_tab select i1.x, i2.y from input1 as i1 join input2 as i2 on i1 select * from part_tab; i | j ---+--- - 1 | 1 2 | 2 3 | 3 + 4 | 4 + 4 | 4 + 7 | 7 + 8 | 8 5 | 5 5 | 5 - 4 | 4 5 | 5 - 4 | 4 5 | 5 6 | 6 - 7 | 7 - 8 | 8 9 | 9 + 1 | 1 (13 rows) -- Multi-level partitioning @@ -5319,11 +5354,11 @@ subpartition by range (k) subpartition template (start(1) end(10) every(2)) insert into deep_part_1_prt_male_2_prt_2 values(1,3,1,'M'); -- but only if it's the right partition. insert into deep_part_1_prt_male_2_prt_2 values(1,1,1,'M'); -ERROR: new row for relation "deep_part_1_prt_male_2_prt_2" violates partition constraint +ERROR: new row for relation "deep_part_1_prt_male_2_prt_2" violates partition constraint (seg1 172.18.0.2:7003 pid=21364) DETAIL: Failing row contains (1, 1, 1, M ). -- Wrong sub-partition (inserting a female value in male partition) insert into deep_part_1_prt_male_2_prt_2_3_prt_2 values (1, 1, 1, 'F'); -ERROR: new row for relation "deep_part_1_prt_male_2_prt_2_3_prt_2" violates partition constraint +ERROR: new row for relation "deep_part_1_prt_male_2_prt_2_3_prt_2" violates partition constraint (seg1 172.18.0.2:7003 pid=21364) DETAIL: Failing row contains (1, 1, 1, F ). select * from deep_part; i | j | k | s @@ -5402,10 +5437,10 @@ select * from deep_part; i | j | k | s ---+---+---+------- 1 | 1 | 1 | F - 9 | 9 | 9 | F 1 | 1 | 1 | M 1 | 1 | 1 | M 1 | 3 | 1 | M + 9 | 9 | 9 | F 5 | 5 | 5 | M (6 rows) @@ -5417,17 +5452,17 @@ select * from deep_part_1_prt_female_2_prt_5_3_prt_5; -- Out of range partition insert into deep_part values (9, 9, 10, 'F'); -ERROR: no partition of relation "deep_part_1_prt_female_2_prt_5" found for row +ERROR: no partition of relation "deep_part_1_prt_female_2_prt_5" found for row (seg2 172.18.0.2:7004 pid=21365) DETAIL: Partition key of the failing row contains (k) = (10). select * from deep_part; i | j | k | s ---+---+---+------- - 1 | 1 | 1 | F 9 | 9 | 9 | F + 5 | 5 | 5 | M + 1 | 1 | 1 | F 1 | 1 | 1 | M 1 | 1 | 1 | M 1 | 3 | 1 | M - 5 | 5 | 5 | M (6 rows) drop table input2; @@ -5451,6 +5486,8 @@ partition by range(col2) ); insert into pt_td_leak select i,i,i from generate_series(1,9) i; copy pt_td_leak to '/tmp/pt_td_leak.out' csv; +NOTICE: One or more columns in the following table(s) do not have statistics: pt_td_leak +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. alter table pt_td_leak drop column col3; alter table pt_td_leak add column col3 int default 7; drop table if exists pt_td_leak_exchange; @@ -5460,6 +5497,8 @@ alter table pt_td_leak exchange partition part2 with table pt_td_leak_exchange; insert into pt_td_leak values(1,8,1); copy pt_td_leak from '/tmp/pt_td_leak.out' with delimiter ','; select * from pt_td_leak where col1 = 5; +NOTICE: One or more columns in the following table(s) do not have statistics: pt_td_leak +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. col1 | col2 | col3 ------+------+------ 5 | 5 | 5 @@ -5467,6 +5506,8 @@ select * from pt_td_leak where col1 = 5; -- Check that data inserted into dropped/added column is correct select * from pt_td_leak where col3 = 1; +NOTICE: One or more columns in the following table(s) do not have statistics: pt_td_leak +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. col1 | col2 | col3 ------+------+------ 1 | 1 | 1 @@ -5489,6 +5530,8 @@ ALTER TABLE pt_dropped_col_distkey DROP COLUMN to_be_dropped; ALTER TABLE pt_dropped_col_distkey ADD PARTITION pt_dropped_col_distkey_new_part START (10) END (100); INSERT INTO pt_dropped_col_distkey SELECT g, 'after drop ' || g FROM generate_series(8, 15) g; SELECT * FROM pt_dropped_col_distkey ORDER BY i; +NOTICE: One or more columns in the following table(s) do not have statistics: pt_dropped_col_distkey +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. i | t ----+--------------- 1 | before drop 1 @@ -5509,9 +5552,13 @@ SELECT * FROM pt_dropped_col_distkey ORDER BY i; (15 rows) COPY pt_dropped_col_distkey TO '/tmp/pt_dropped_col_distkey.out'; +NOTICE: One or more columns in the following table(s) do not have statistics: pt_dropped_col_distkey +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. DELETE FROM pt_dropped_col_distkey; COPY pt_dropped_col_distkey FROM '/tmp/pt_dropped_col_distkey.out'; SELECT * FROM pt_dropped_col_distkey ORDER BY i; +NOTICE: One or more columns in the following table(s) do not have statistics: pt_dropped_col_distkey +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. i | t ----+--------------- 1 | before drop 1 @@ -5688,13 +5735,6 @@ select relname, relkind from pg_class where relkind in ('r', 'p') and relname li select gp_segment_id, relname, relkind from gp_dist_random('pg_class') where relkind in ('r', 'p') and relname like 'sales%' and relfrozenxid=0; gp_segment_id | relname | relkind ---------------+----------------------------+--------- - 0 | sales | p - 0 | sales | p - 0 | sales_1_prt_2 | p - 0 | sales_1_prt_3 | p - 0 | sales_1_prt_4 | p - 0 | sales_1_prt_5 | p - 0 | sales_1_prt_outlying_dates | p 1 | sales | p 1 | sales | p 1 | sales_1_prt_2 | p @@ -5702,6 +5742,13 @@ select gp_segment_id, relname, relkind from gp_dist_random('pg_class') where rel 1 | sales_1_prt_4 | p 1 | sales_1_prt_5 | p 1 | sales_1_prt_outlying_dates | p + 0 | sales | p + 0 | sales | p + 0 | sales_1_prt_2 | p + 0 | sales_1_prt_3 | p + 0 | sales_1_prt_4 | p + 0 | sales_1_prt_5 | p + 0 | sales_1_prt_outlying_dates | p 2 | sales | p 2 | sales | p 2 | sales_1_prt_2 | p @@ -5728,13 +5775,6 @@ select relname, relkind from pg_class where relkind in ('r', 'p') and relname li select gp_segment_id, relname, relkind from gp_dist_random('pg_class') where relkind in ('r', 'p') and relname like 'sales%' and relfrozenxid=0; gp_segment_id | relname | relkind ---------------+----------------------------+--------- - 2 | sales | p - 2 | sales | p - 2 | sales_1_prt_2 | p - 2 | sales_1_prt_3 | p - 2 | sales_1_prt_4 | p - 2 | sales_1_prt_5 | p - 2 | sales_1_prt_outlying_dates | p 0 | sales | p 0 | sales | p 0 | sales_1_prt_2 | p @@ -5742,6 +5782,13 @@ select gp_segment_id, relname, relkind from gp_dist_random('pg_class') where rel 0 | sales_1_prt_4 | p 0 | sales_1_prt_5 | p 0 | sales_1_prt_outlying_dates | p + 2 | sales | p + 2 | sales | p + 2 | sales_1_prt_2 | p + 2 | sales_1_prt_3 | p + 2 | sales_1_prt_4 | p + 2 | sales_1_prt_5 | p + 2 | sales_1_prt_outlying_dates | p 1 | sales | p 1 | sales | p 1 | sales_1_prt_2 | p @@ -5753,6 +5800,7 @@ select gp_segment_id, relname, relkind from gp_dist_random('pg_class') where rel alter table sales drop column tax; create table newpart(like sales); +NOTICE: table doesn't have 'DISTRIBUTED BY' clause, defaulting to distribution columns from LIKE table alter table newpart add constraint newpart_pkey primary key(pkid, option3); alter table sales split partition for(1) at (50) into (partition aa1, partition aa2); select table_schema, table_name, constraint_name, constraint_type @@ -5768,17 +5816,22 @@ select table_schema, table_name, constraint_name, constraint_type alter table sales exchange partition for (101) with table newpart; select * from sales order by pkid; +NOTICE: One or more columns in the following table(s) do not have statistics: sales +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. pkid | option1 | option2 | option3 ------+---------+---------+--------- (0 rows) -- Create exchange table before drop column, make sure the consistency check still exist create table newpart2(like sales); +NOTICE: table doesn't have 'DISTRIBUTED BY' clause, defaulting to distribution columns from LIKE table alter table sales drop column option2; alter table sales exchange partition for (101) with table newpart2; ERROR: table "newpart2" contains column "option2" not found in parent "sales" DETAIL: The new partition may contain only the columns present in parent. select * from sales order by pkid; +NOTICE: One or more columns in the following table(s) do not have statistics: sales +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. pkid | option1 | option3 ------+---------+--------- (0 rows) @@ -5787,35 +5840,41 @@ drop table sales cascade; NOTICE: drop cascades to default value for column pkid of table newpart -- Exchage partition table with a table having dropped column create table exchange_part(a int, b int) partition by range(b) (start (0) end (10) every (5)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create table exchange1(a int, c int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. alter table exchange1 drop column c; alter table exchange_part exchange partition for (1) with table exchange1; copy exchange_part from STDIN DELIMITER as '|'; select * from exchange_part; +NOTICE: One or more columns in the following table(s) do not have statistics: exchange_part +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b ------+--- + 9794 | 1 9797 | 3 9799 | 4 + 9808 | 1 9801 | 5 - 9836 | 5 9802 | 6 - 9840 | 6 9803 | 7 - 9822 | 7 9806 | 8 - 9824 | 8 9807 | 9 - 9794 | 1 - 9808 | 1 + 9822 | 7 + 9824 | 8 + 9836 | 5 + 9840 | 6 9810 | 2 + 9827 | 1 9828 | 2 9831 | 3 9817 | 5 9818 | 6 + 9825 | 9 9843 | 7 9844 | 8 - 9825 | 9 - 9827 | 1 9795 | 2 9814 | 3 9815 | 4 @@ -5886,7 +5945,11 @@ select c.oid::regclass, relkind, amname, reloptions from pg_class c left join pg -- Ensure that only the correct type of partitions can be added create table at_range (a int) partition by range (a) (start(1) end(5)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create table at_list (i int) partition by list(i) (partition p1 values(1)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. alter table at_list add partition foo2 start(6) end (10); ERROR: invalid boundary specification for LIST partition LINE 1: alter table at_list add partition foo2 start(6) end (10); @@ -6010,8 +6073,14 @@ ERROR: operator class "employee_incomplete_op_class" of access method btree is -- able to SELECT from any partition table we create later. -- (https://github.com/greenplum-db/gpdb/issues/9524) DROP TABLE IF EXISTS user_prt_acl_append.t_part_acl; +NOTICE: schema "user_prt_acl_append" does not exist, skipping +NOTICE: schema "user_prt_acl_append" does not exist, skipping (seg0 172.18.0.2:7002 pid=21363) +NOTICE: schema "user_prt_acl_append" does not exist, skipping (seg1 172.18.0.2:7003 pid=21364) +NOTICE: schema "user_prt_acl_append" does not exist, skipping (seg2 172.18.0.2:7004 pid=21365) DROP SCHEMA IF EXISTS user_prt_acl_append; +NOTICE: schema "user_prt_acl_append" does not exist, skipping DROP ROLE IF EXISTS user_prt_acl_append; +NOTICE: role "user_prt_acl_append" does not exist, skipping CREATE ROLE user_prt_acl_append; NOTICE: resource queue required -- using default resource queue "pg_default" CREATE SCHEMA schema_part_acl_append; @@ -6041,6 +6110,8 @@ WHERE relname LIKE 't_part_acl%' -- check if new user can SELECT all data SET ROLE user_prt_acl_append; SELECT * FROM schema_part_acl_append.t_part_acl; +NOTICE: One or more columns in the following table(s) do not have statistics: t_part_acl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. dt ------------ 12-01-2019 @@ -6081,6 +6152,8 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into temp_parent select i from generate_series(1, 5) i; select count(*) from temp_parent; +NOTICE: One or more columns in the following table(s) do not have statistics: temp_parent +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. count ------- 5 @@ -6089,6 +6162,8 @@ select count(*) from temp_parent; commit; -- DELETE ROWS will not cascaded to its partitions when we use DELETE ROWS behavior select count(*) from temp_parent; +NOTICE: One or more columns in the following table(s) do not have statistics: temp_parent +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. count ------- 5 @@ -6420,9 +6495,6 @@ WHERE c.relname LIKE 'part_inherit%' AND c.relkind NOT IN ('i', 'I'); relname | reloptions | relkind | am | hasindex | owner | acl | numchecks | hasrules | hastriggers | rowsecurity --------------------------------------------------+-------------------+---------+--------+----------+-------------------------+-------------------------------------------------------------------------------------------------------------------------+-----------+----------+-------------+------------- - part_inherit_1_prt_l1_to_exchange_2_prt_l2_child | {fillfactor=30} | r | heap | t | part_inherit_other_role | {part_inherit_other_role=arwdDxt/part_inherit_other_role,part_inherit_exchange_out_priv_role=w/part_inherit_other_role} | 2 | f | t | f - part_inherit_attach | {fillfactor=30} | r | heap | t | part_inherit_other_role | {part_inherit_other_role=arwdDxt/part_inherit_other_role,part_inherit_attach_priv_role=w/part_inherit_other_role} | 2 | f | t | f - part_inherit_partof | {compresslevel=7} | r | ao_row | t | part_inherit_other_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f part_inherit | {compresslevel=7} | p | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | t | t | t part_inherit_1_prt_added | {compresslevel=7} | p | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f part_inherit_1_prt_added_2_prt_l2_child | {compresslevel=7} | r | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f @@ -6435,6 +6507,9 @@ WHERE c.relname LIKE 'part_inherit%' AND part_inherit_1_prt_l1_to_split_2_prt_split1 | {compresslevel=7} | r | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f part_inherit_1_prt_l1_to_split_2_prt_split2 | {compresslevel=7} | r | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f part_inherit_exchange_out | {compresslevel=7} | r | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_partof | {compresslevel=7} | r | ao_row | t | part_inherit_other_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_1_prt_l1_to_exchange_2_prt_l2_child | {fillfactor=30} | r | heap | t | part_inherit_other_role | {part_inherit_other_role=arwdDxt/part_inherit_other_role,part_inherit_exchange_out_priv_role=w/part_inherit_other_role} | 2 | f | t | f + part_inherit_attach | {fillfactor=30} | r | heap | t | part_inherit_other_role | {part_inherit_other_role=arwdDxt/part_inherit_other_role,part_inherit_attach_priv_role=w/part_inherit_other_role} | 2 | f | t | f (15 rows) RESET ROLE; @@ -6562,8 +6637,8 @@ NOTICE: One or more columns in the following table(s) do not have statistics: t HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. datedday ------------ - 10-22-2022 10-23-2022 + 10-22-2022 (2 rows) drop table test_rangePartition; @@ -6811,8 +6886,8 @@ explain select * from foo_part_rls; select * from foo_part_rls; a | b | c ---+----+----- - 5 | 50 | 500 4 | 40 | 400 + 5 | 50 | 500 (2 rows) reset session authorization; @@ -6870,62 +6945,53 @@ explain (costs off, timing off, summary off, analyze) select * from pt where pti select * from pt where ptid in (select tid from pt2 where t1 = 'hello' || tid); dist | pt1 | pt2 | pt3 | ptid ------+---------+-------+-----------+------ - 0 | hello0 | world | drop this | 0 - 6 | hello6 | world | drop this | 0 - 12 | hello12 | world | drop this | 0 18 | hello18 | world | drop this | 0 24 | hello24 | world | drop this | 0 + 42 | hello42 | world | drop this | 0 + 7 | hello7 | world | drop this | 1 + 19 | hello19 | world | drop this | 1 + 37 | hello37 | world | drop this | 1 + 0 | hello0 | world | drop this | 0 + 12 | hello12 | world | drop this | 0 30 | hello30 | world | drop this | 0 36 | hello36 | world | drop this | 0 - 42 | hello42 | world | drop this | 0 48 | hello48 | world | drop this | 0 1 | hello1 | world | drop this | 1 - 7 | hello7 | world | drop this | 1 + 31 | hello31 | world | drop this | 1 + 49 | hello49 | world | drop this | 1 + 6 | hello6 | world | drop this | 0 13 | hello13 | world | drop this | 1 - 19 | hello19 | world | drop this | 1 25 | hello25 | world | drop this | 1 - 31 | hello31 | world | drop this | 1 - 37 | hello37 | world | drop this | 1 43 | hello43 | world | drop this | 1 - 49 | hello49 | world | drop this | 1 (18 rows) explain (costs off, timing off, summary off, analyze) select ptid from pt where ptid in (select tid from pt2 where t1 = 'hello' || tid) and pt1 = 'hello1'; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=1 loops=1) - -> Hash Join (actual rows=1 loops=1) - Hash Cond: (pt2.tid = pt_1_prt_2.ptid) - Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 1 of 262144 buckets. - -> GroupAggregate (actual rows=2 loops=1) - Group Key: pt2.tid - -> Sort (actual rows=2 loops=1) - Sort Key: pt2.tid - Sort Method: quicksort Memory: 25kB - -> Redistribute Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) - Hash Key: pt2.tid - -> Seq Scan on pt2 (actual rows=2 loops=1) - Filter: (t1 = ('hello'::text || (tid)::text)) + -> Hash Right Semi Join (actual rows=1 loops=1) + Hash Cond: (pt_1_prt_2.ptid = pt2.tid) + Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 1 of 524288 buckets. + -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) + -> Seq Scan on pt2 (actual rows=2 loops=1) + Filter: (t1 = ('hello'::text || (tid)::text)) -> Hash (actual rows=1 loops=1) - Buckets: 262144 Batches: 1 Memory Usage: 2049kB - -> Redistribute Motion 3:3 (slice3; segments: 3) (actual rows=1 loops=1) - Hash Key: pt_1_prt_2.ptid - -> Result (actual rows=1 loops=1) - -> Append (actual rows=1 loops=1) - -> Index Scan using pt_1_prt_2_pt1_idx on pt_1_prt_2 (actual rows=0 loops=1) - Index Cond: (pt1 = 'hello1'::text) - -> Index Scan using pt_1_prt_3_pt1_idx on pt_1_prt_3 (actual rows=1 loops=1) - Index Cond: (pt1 = 'hello1'::text) - -> Index Scan using pt_1_prt_4_pt1_idx on pt_1_prt_4 (actual rows=0 loops=1) - Index Cond: (pt1 = 'hello1'::text) - -> Index Scan using pt_1_prt_5_pt1_idx on pt_1_prt_5 (actual rows=0 loops=1) - Index Cond: (pt1 = 'hello1'::text) - -> Index Scan using pt_1_prt_6_pt1_idx on pt_1_prt_6 (actual rows=0 loops=1) - Index Cond: (pt1 = 'hello1'::text) - -> Index Scan using pt_1_prt_junk_data_pt1_idx on pt_1_prt_junk_data (actual rows=0 loops=1) - Index Cond: (pt1 = 'hello1'::text) + Buckets: 524288 Batches: 1 Memory Usage: 4097kB + -> Append (actual rows=1 loops=1) + -> Index Scan using pt_1_prt_2_pt1_idx on pt_1_prt_2 (actual rows=0 loops=1) + Index Cond: (pt1 = 'hello1'::text) + -> Index Scan using pt_1_prt_3_pt1_idx on pt_1_prt_3 (actual rows=1 loops=1) + Index Cond: (pt1 = 'hello1'::text) + -> Index Scan using pt_1_prt_4_pt1_idx on pt_1_prt_4 (actual rows=0 loops=1) + Index Cond: (pt1 = 'hello1'::text) + -> Index Scan using pt_1_prt_5_pt1_idx on pt_1_prt_5 (actual rows=0 loops=1) + Index Cond: (pt1 = 'hello1'::text) + -> Index Scan using pt_1_prt_6_pt1_idx on pt_1_prt_6 (actual rows=0 loops=1) + Index Cond: (pt1 = 'hello1'::text) + -> Index Scan using pt_1_prt_junk_data_pt1_idx on pt_1_prt_junk_data (actual rows=0 loops=1) + Index Cond: (pt1 = 'hello1'::text) Optimizer: GPORCA -(32 rows) +(23 rows) select ptid from pt where ptid in (select tid from pt2 where t1 = 'hello' || tid) and pt1 = 'hello1'; ptid @@ -6970,7 +7036,7 @@ EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM rp_multi_inds WHERE b = 11 AND (c = 1 Index Cond: (rp_multi_inds_part2.c = 4201) -> Bitmap Index Scan on rp_multi_inds_part2_b_idx Index Cond: (rp_multi_inds_part2.b = 11) - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (16 rows) diff --git a/src/test/regress/expected/partition_append_optimizer.out b/src/test/regress/expected/partition_append_optimizer.out new file mode 100644 index 00000000000..263042f8fda --- /dev/null +++ b/src/test/regress/expected/partition_append_optimizer.out @@ -0,0 +1,7074 @@ +\c partition_append +set optimizer to on; +set optimizer_disable_dynamic_table_scan to on; +drop table if exists d; +NOTICE: table "d" does not exist, skipping +drop table if exists c; +NOTICE: table "c" does not exist, skipping +drop table if exists b; +NOTICE: table "b" does not exist, skipping +drop table if exists a; +NOTICE: table "a" does not exist, skipping +-- Check multi level partition COPY +create table region +( + r_regionkey integer not null, + r_name char(25), + r_comment varchar(152) +) +distributed by (r_regionkey) +partition by range (r_regionkey) +subpartition by list (r_name) subpartition template +( + subpartition africa values ('AFRICA'), + subpartition america values ('AMERICA'), + subpartition asia values ('ASIA'), + subpartition europe values ('EUROPE'), + subpartition mideast values ('MIDDLE EAST'), + subpartition australia values ('AUSTRALIA'), + subpartition antarctica values ('ANTARCTICA') +) +( + partition region1 start (0), + partition region2 start (3), + partition region3 start (5) end (8) +); +-- root and internal parent partitions should have relfrozenxid as 0 +select relname, relkind from pg_class where relkind in ('r', 'p') and relname like 'region%' and relfrozenxid=0; + relname | relkind +----------------------+--------- + region | p + region_1_prt_region1 | p + region_1_prt_region2 | p + region_1_prt_region3 | p +(4 rows) + +select gp_segment_id, relname, relkind from gp_dist_random('pg_class') where relkind in ('r', 'p') and relname like 'region%' and relfrozenxid=0; + gp_segment_id | relname | relkind +---------------+----------------------+--------- + 1 | region | p + 1 | region_1_prt_region1 | p + 1 | region_1_prt_region2 | p + 1 | region_1_prt_region3 | p + 0 | region | p + 0 | region_1_prt_region1 | p + 0 | region_1_prt_region2 | p + 0 | region_1_prt_region3 | p + 2 | region | p + 2 | region_1_prt_region1 | p + 2 | region_1_prt_region2 | p + 2 | region_1_prt_region3 | p +(12 rows) + +create unique index region_pkey on region(r_regionkey, r_name); +copy region from stdin with delimiter '|'; +-- Test indexes +set enable_seqscan to off; +select * from region where r_regionkey = 1; + r_regionkey | r_name | r_comment +-------------+---------------------------+--------------------------------- + 1 | AMERICA | hs use ironic, even requests. s +(1 row) + +select * from region where r_regionkey = 2; + r_regionkey | r_name | r_comment +-------------+---------------------------+--------------------------------- + 2 | ASIA | ges. thinly even pinto beans ca +(1 row) + +select * from region where r_regionkey = 3; + r_regionkey | r_name | r_comment +-------------+---------------------------+----------------------------------------------- + 3 | EUROPE | ly final courts cajole furiously final excuse +(1 row) + +select * from region where r_regionkey = 4; + r_regionkey | r_name | r_comment +-------------+---------------------------+---------------------------------------------------------- + 4 | MIDDLE EAST | uickly special accounts cajole carefully blithely close +(1 row) + +select * from region where r_regionkey = 5; + r_regionkey | r_name | r_comment +-------------+---------------------------+----------- + 5 | AUSTRALIA | sdf +(1 row) + +select * from region where r_regionkey = 6; + r_regionkey | r_name | r_comment +-------------+---------------------------+----------- + 6 | ANTARCTICA | dsfdfg +(1 row) + +-- Test indexes with insert +insert into region values(7, 'AUSTRALIA', 'def'); +select * from region where r_regionkey = '7'; + r_regionkey | r_name | r_comment +-------------+---------------------------+----------- + 7 | AUSTRALIA | def +(1 row) + +-- test duplicate key. We shouldn't really allow primary keys on partitioned +-- tables since we cannot enforce them. But since this insert maps to a +-- single definitive partition, we can detect it. +insert into region values(7, 'AUSTRALIA', 'def'); +ERROR: duplicate key value violates unique constraint "region_1_prt_region3_2_prt_australia_r_regionkey_r_name_idx" (seg0 172.18.0.2:7002 pid=21628) +DETAIL: Key (r_regionkey, r_name)=(7, AUSTRALIA ) already exists. +drop table region; +-- exchange +-- 1) test all sanity checking +create table foo_p (i int, j int) distributed by (i) +partition by range(j) +(start(1) end(10) every(1)); +-- policies are different +create table bar_p_diff_pol (i int, j int) distributed by (j); +-- should fail +alter table foo_p exchange partition for(6) with table bar_p_diff_pol; +ERROR: distribution policy for "bar_p_diff_pol" must be the same as that for "foo_p" +-- random policy vs. hash policy +create table bar_p_rand_pol (i int, j int) distributed randomly; +-- should fail +alter table foo_p exchange partition for(6) with table bar_p_rand_pol; +ERROR: distribution policy for "bar_p_rand_pol" must be the same as that for "foo_p" +-- different number of columns +create table bar_p_diff_col (i int, j int, k int) distributed by (i); +-- should fail +alter table foo_p exchange partition for(6) with table bar_p_diff_col; +ERROR: table "bar_p_diff_col" contains column "k" not found in parent "foo_p" +DETAIL: The new partition may contain only the columns present in parent. +-- different types +create table bar_p_diff_typ (i int, j int8) distributed by (i); +-- should fail +alter table foo_p exchange partition for(6) with table bar_p_diff_typ; +ERROR: child table "bar_p_diff_typ" has different type for column "j" +-- different column names +create table bar_p_diff_colnam (i int, m int) distributed by (i); +-- should fail +alter table foo_p exchange partition for(6) with table bar_p_diff_colnam; +ERROR: table "bar_p_diff_colnam" contains column "m" not found in parent "foo_p" +DETAIL: The new partition may contain only the columns present in parent. +-- still different schema, but more than one level partitioning +CREATE TABLE two_level_pt(a int, b int, c int) +DISTRIBUTED BY (a) +PARTITION BY RANGE (b) + SUBPARTITION BY RANGE (c) + SUBPARTITION TEMPLATE ( + START (11) END (12) EVERY (1)) + ( START (1) END (2) EVERY (1)); +CREATE TABLE candidate_for_leaf(a int, c int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +-- should fail +ALTER TABLE two_level_pt ALTER PARTITION FOR (1) + EXCHANGE PARTITION FOR (11) WITH TABLE candidate_for_leaf; +ERROR: child table is missing column "b" +-- different owner +create role part_role_append; +NOTICE: resource queue required -- using default resource queue "pg_default" +GRANT CREATE ON SCHEMA public TO part_role_append; +create table bar_p (i int, j int) distributed by (i); +set session authorization part_role_append; +-- should fail +alter table foo_p exchange partition for(6) with table bar_p; +ERROR: must be owner of table foo_p +-- back to superuser +\c - +alter table bar_p owner to part_role_append; +set session authorization part_role_append; +-- should fail +alter table foo_p exchange partition for(6) with table bar_p; +ERROR: must be owner of table foo_p +\c - +-- owners should be the same, error out +alter table foo_p exchange partition for(6) with table bar_p; +drop table foo_p; +drop table bar_p; +-- should work, and new partition should inherit ownership (mpp-6538) +set role part_role_append; +create table foo_p (i int, j int) distributed by (i) +partition by range(j) +(start(1) end(6) every(3)); +reset role; +alter table foo_p split partition for (1) at (2) into (partition prt_11, partition prt_12); +\dt foo_* + List of relations + Schema | Name | Type | Owner | Storage +--------+--------------------+-------------------+------------------+--------- + public | foo_p | partitioned table | part_role_append | + public | foo_p_1_prt_2 | table | part_role_append | heap + public | foo_p_1_prt_prt_11 | table | part_role_append | heap + public | foo_p_1_prt_prt_12 | table | part_role_append | heap +(4 rows) + +drop table foo_p; +REVOKE CREATE ON SCHEMA public FROM part_role_append; +drop role part_role_append; +-- WITH OIDS is no longer supported. Check that it't rejected with the GPDB +-- partitioning syntax, too. +create table foo_p (i int, j int) with (oids = true) distributed by (i) +partition by range(j) +(start(1) end(10) every(1)); +ERROR: tables declared WITH OIDS are not supported +-- non-partition table involved in inheritance +create table foo_p (i int, j int) distributed by (i) +partition by range(j) +(start(1) end(10) every(1)); +create table barparent(i int, j int) distributed by (i); +create table bar_p () inherits(barparent); +NOTICE: table has parent, setting distribution columns to match parent table +-- should fail +alter table foo_p exchange partition for(6) with table bar_p; +ERROR: cannot attach inheritance child as partition +drop table bar_p; +drop table barparent; +-- non-partition table involved in inheritance +create table bar_p(i int, j int) distributed by (i); +create table barchild () inherits(bar_p); +NOTICE: table has parent, setting distribution columns to match parent table +-- should fail +alter table foo_p exchange partition for(6) with table bar_p; +ERROR: cannot attach inheritance parent as partition +drop table barchild; +drop table bar_p; +-- rules on non-partition table +create table bar_p(i int, j int) distributed by (i); +create table baz_p(i int, j int) distributed by (i); +create rule bar_baz as on insert to bar_p do instead insert into baz_p + values(NEW.i, NEW.j); +alter table foo_p exchange partition for(2) with table bar_p; +drop table foo_p, bar_p, baz_p; +create table foo_p (i int, j int) distributed by (i) +partition by range(j) +(start(1) end(5) every(1)); +-- Shouldn't fail: check constraint matches partition rule. +-- Note this test is slightly different from prior versions to get +-- in line with constraint consistency requirement. +create table bar_d(i int, j int check (j >= 2 and j < 3 )) +distributed by (i); +insert into bar_d values(100000, 2); +alter table foo_p exchange partition for(2) with table bar_d; +insert into bar_d values(200000, 2); +select * from bar_d; + i | j +--------+--- + 200000 | 2 +(1 row) + +drop table foo_p, bar_d; +-- permissions +create role part_role_append; +NOTICE: resource queue required -- using default resource queue "pg_default" +create table foo_p (i int) partition by range(i) (start(1) end(10) every(1)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +create table bar_p (i int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +grant select on foo_p to part_role_append; +revoke all on bar_p from part_role_append; +NOTICE: no privileges could be revoked +select has_table_privilege('part_role_append', 'foo_p_1_prt_6'::regclass, 'select'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('part_role_append', 'bar_p'::regclass, 'select'); + has_table_privilege +--------------------- + f +(1 row) + +alter table foo_p exchange partition for(6) with table bar_p; +select has_table_privilege('part_role_append', 'foo_p_1_prt_6'::regclass, 'select'); + has_table_privilege +--------------------- + f +(1 row) + +select has_table_privilege('part_role_append', 'bar_p'::regclass, 'select'); + has_table_privilege +--------------------- + t +(1 row) + +-- the ONLY keyword will affect just the partition root for both grant/revoke +create role part_role_append2; +NOTICE: resource queue required -- using default resource queue "pg_default" +grant select on only foo_p to part_role_append2; +select has_table_privilege('part_role_append2', 'foo_p'::regclass, 'select'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('part_role_append2', 'foo_p_1_prt_6'::regclass, 'select'); + has_table_privilege +--------------------- + f +(1 row) + +grant select on foo_p to part_role_append2; +revoke select on only foo_p from part_role_append2; +select has_table_privilege('part_role_append2', 'foo_p'::regclass, 'select'); + has_table_privilege +--------------------- + f +(1 row) + +select has_table_privilege('part_role_append2', 'foo_p_1_prt_6'::regclass, 'select'); + has_table_privilege +--------------------- + t +(1 row) + +revoke select on foo_p from part_role_append2; +select has_table_privilege('part_role_append2', 'foo_p_1_prt_6'::regclass, 'select'); + has_table_privilege +--------------------- + f +(1 row) + +create table foo_p2 (a int, b int) partition by range(a) (start(1) end(10) every(1)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +grant select on foo_p, only foo_p2 to part_role_append2; -- multiple tables in same statement +select has_table_privilege('part_role_append2', 'foo_p'::regclass, 'select'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('part_role_append2', 'foo_p_1_prt_6'::regclass, 'select'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('part_role_append2', 'foo_p2'::regclass, 'select'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('part_role_append2', 'foo_p2_1_prt_6'::regclass, 'select'); + has_table_privilege +--------------------- + f +(1 row) + +-- more cases +revoke all on foo_p from part_role_append2; +revoke all on foo_p2 from part_role_append2; +grant select on only public.foo_p to part_role_append2; -- with schema +select has_table_privilege('part_role_append2', 'foo_p'::regclass, 'select'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('part_role_append2', 'foo_p_1_prt_6'::regclass, 'select'); + has_table_privilege +--------------------- + f +(1 row) + +grant update(b) on only foo_p2 to part_role_append2; -- column level priviledge +select relname, has_column_privilege('part_role_append2', oid, 'b', 'update') from pg_class +where relname = 'foo_p2' or relname = 'foo_p2_1_prt_6'; + relname | has_column_privilege +----------------+---------------------- + foo_p2 | t + foo_p2_1_prt_6 | f +(2 rows) + +drop table foo_p; +drop table foo_p2; +drop table bar_p; +drop role part_role_append; +drop role part_role_append2; +-- validation +create table foo_p (i int) partition by range(i) +(start(1) end(10) every(1)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +create table bar_p (i int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into bar_p values(6); +insert into bar_p values(100); +-- should fail +alter table foo_p exchange partition for(6) with table bar_p; +ERROR: partition constraint of relation "bar_p" is violated by some row (seg2 172.18.0.2:7004 pid=21692) +alter table foo_p exchange partition for(6) with table bar_p without +validation; +NOTICE: specifying "WITHOUT VALIDATION" acts as no operation +DETAIL: If the new partition is a regular table, validation is performed to make sure all the rows obey partition constraint. If the new partition is external or foreign table, no validation is performed. +ERROR: partition constraint of relation "bar_p" is violated by some row (seg2 172.18.0.2:7004 pid=21692) +analyze foo_p; +select * from foo_p; + i +--- +(0 rows) + +drop table foo_p, bar_p; +-- basic test +create table foo_p (i int, j int) distributed by (i) +partition by range(j) +(start(1) end(10) every(1)); +create table bar_p(i int, j int) distributed by (i); +insert into bar_p values(0,6); +alter table foo_p exchange partition for(6) with table bar_p; +analyze foo_p; +select * from foo_p; + i | j +---+--- + 0 | 6 +(1 row) + +select * from bar_p; + i | j +---+--- +(0 rows) + +-- test that we got the dependencies right +drop table bar_p; +select * from foo_p; + i | j +---+--- + 0 | 6 +(1 row) + +drop table foo_p; +create table foo_p (i int, j int) distributed by (i) +partition by range(j) +(start(1) end(10) every(1)); +create table bar_p(i int, j int) distributed by (i); +insert into bar_p values(6, 6); +alter table foo_p exchange partition for(6) with table bar_p; +insert into bar_p values(10, 10); +drop table foo_p; +select * from bar_p; + i | j +----+---- + 10 | 10 +(1 row) + +insert into bar_p values(6, 6); +select * from bar_p; + i | j +----+---- + 10 | 10 + 6 | 6 +(2 rows) + +drop table bar_p; +-- AO exchange with heap +create table foo_p (i int, j int) with(appendonly = true) distributed by (i) +partition by range(j) +(start(1) end(10) every(1)); +create table bar_p(i int, j int) distributed by (i); +insert into foo_p values(1, 1), (2, 1), (3, 1); +insert into bar_p values(6, 6); +alter table foo_p exchange partition for(6) with table bar_p; +analyze foo_p; +select * from foo_p; + i | j +---+--- + 1 | 1 + 6 | 6 + 2 | 1 + 3 | 1 +(4 rows) + +drop table bar_p; +drop table foo_p; +-- other way around +create table foo_p (i int, j int) with(appendonly = false) distributed by (i) +partition by range(j) +(start(1) end(10) every(1)); +create table bar_p(i int, j int) with(appendonly = true) distributed by (i); +insert into foo_p values(1, 1), (2, 1), (3, 2); +insert into bar_p values(6, 6); +alter table foo_p exchange partition for(6) with table bar_p; +analyze foo_p; +select * from foo_p; + i | j +---+--- + 2 | 1 + 3 | 2 + 6 | 6 + 1 | 1 +(4 rows) + +drop table bar_p; +drop table foo_p; +-- exchange AO with AO +create table foo_p (i int, j int) with(appendonly = true) distributed by (i) +partition by range(j) +(start(1) end(10) every(1)); +create table bar_p(i int, j int) with(appendonly = true) distributed by (i); +insert into foo_p values(1, 2), (2, 3), (3, 4); +insert into bar_p values(6, 6); +alter table foo_p exchange partition for(6) with table bar_p; +analyze foo_p; +select * from foo_p; + i | j +---+--- + 1 | 2 + 2 | 3 + 3 | 4 + 6 | 6 +(4 rows) + +drop table bar_p; +drop table foo_p; +-- exchange same table more than once +create table foo_p (i int, j int) distributed by (i) +partition by range(j) +(start(1) end(10) every(1)); +create table bar_p(i int, j int) distributed by (i); +insert into bar_p values(6, 6); +alter table foo_p exchange partition for(6) with table bar_p; +analyze foo_p; +select * from foo_p; + i | j +---+--- + 6 | 6 +(1 row) + +select * from bar_p; + i | j +---+--- +(0 rows) + +alter table foo_p exchange partition for(6) with table bar_p; +select * from foo_p; + i | j +---+--- +(0 rows) + +select * from bar_p; + i | j +---+--- + 6 | 6 +(1 row) + +alter table foo_p exchange partition for(6) with table bar_p; +select * from foo_p; + i | j +---+--- + 6 | 6 +(1 row) + +select * from bar_p; + i | j +---+--- +(0 rows) + +drop table foo_p; +drop table bar_p; +-- exchange default partition is not allowed (single level) +drop table if exists dex; +NOTICE: table "dex" does not exist, skipping +drop table if exists exh_abc; +NOTICE: table "exh_abc" does not exist, skipping +create table dex (i int, j int) partition by range(j) +(partition a start (1) end(10), partition b start(11) end(20), +default partition abc); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +create table exh_abc (like dex); +NOTICE: table doesn't have 'DISTRIBUTED BY' clause, defaulting to distribution columns from LIKE table +alter table dex exchange default partition with table exh_abc; +drop table dex; +drop table exh_abc; +-- exchange default partition is not allowed (multi level) +Drop table if exists sto_ao_ao; +NOTICE: table "sto_ao_ao" does not exist, skipping +drop table if exists exh_ao_ao; +NOTICE: table "exh_ao_ao" does not exist, skipping +Create table sto_ao_ao + ( + col1 bigint, col2 date, col3 text, col4 int) with(appendonly=true) + distributed randomly partition by range(col2) + subpartition by list (col3) + subpartition template ( default subpartition subothers, subpartition sub1 values ('one'), subpartition sub2 values ('two')) + (default partition others, start(date '2008-01-01') end(date '2008-04-30') every(interval '1 month')); +create table exh_ao_ao (like sto_ao_ao) with (appendonly=true); +NOTICE: table doesn't have 'DISTRIBUTED BY' clause, defaulting to distribution columns from LIKE table +alter table sto_ao_ao alter partition for ('2008-03-01') exchange default partition with table exh_ao_ao; +-- Exchange a non-default sub-partition of a default partition, should fail +alter table sto_ao_ao alter default partition exchange partition for ('one') with table exh_ao_ao; +ERROR: cannot specify a name, rank, or value for a DEFAULT partition in this context +-- Exchange a partition that has sub partitions, should fail. +alter table sto_ao_ao exchange partition for ('2008-01-01') with table exh_ao_ao; +ERROR: cannot EXCHANGE PARTITION for relation "sto_ao_ao" -- partition has children +-- XXX: not yet: VALIDATE parameter +-- Exchange a partition with an external table; +create table foo_p (i int, j int) distributed by (i) partition by range(j) (start(1) end(10) every(2)); +create readable external table bar_p(i int, j int) location ('gpfdist://host.invalid:8000/file') format 'text'; +alter table foo_p exchange partition for(3) with table bar_p; +NOTICE: partition constraints are not validated when attaching a readable external table +truncate foo_p; +ERROR: cannot truncate foreign table "foo_p_1_prt_2" +drop table foo_p; +drop table bar_p; +-- Check for overflow of circular data types like time +-- Should fail +CREATE TABLE TIME_TBL_HOUR_2 (f1 time(2)) distributed by (f1) +partition by range (f1) +( + start (time '00:00') end (time '24:00') EVERY (INTERVAL '1 hour') +); +ERROR: END parameter not reached before type overflows +LINE 4: start (time '00:00') end (time '24:00') EVERY (INTERVAL '1... + ^ +-- Should fail +CREATE TABLE TIME_TBL_HOUR_2 (f1 time(2)) distributed by (f1) +partition by range (f1) +( + start (time '00:00') end (time '23:59') EVERY (INTERVAL '1 hour') +); +ERROR: END parameter not reached before type overflows +LINE 4: start (time '00:00') end (time '23:59') EVERY (INTERVAL '1... + ^ +-- Should work +CREATE TABLE TIME_TBL_HOUR_2 (f1 time(2)) distributed by (f1) +partition by range (f1) +( + start (time '00:00') end (time '23:00') EVERY (INTERVAL '1 hour') +); +drop table TIME_TBL_HOUR_2; +-- Check for every parameters that just don't make sense +create table hhh_r2 (a char(1), b date, d char(3)) +distributed by (a) partition by range (b) +( +partition aa start (date '2007-01-01') end (date '2008-01-01') + every (interval '0 days') +); +ERROR: EVERY parameter too small +LINE 5: every (interval '0 days') + ^ +create table foo_p (i int) distributed by(i) +partition by range(i) +(start (1) end (20) every(0)); +ERROR: EVERY parameter too small +LINE 3: (start (1) end (20) every(0)); + ^ +-- Check for ambiguous EVERY parameters +create table foo_p (i int) distributed by (i) +partition by range(i) +(start (1) end (3) every (0.6)); +\d+ foo_p + Partitioned table "public.foo_p" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + i | integer | | | | plain | | +Partition key: RANGE (i) +Partitions: foo_p_1_prt_1 FOR VALUES FROM (1) TO (2), + foo_p_1_prt_2 FOR VALUES FROM (2) TO (3) +Distributed by: (i) + +drop table foo_p; +-- should fail +create table foo_p (i int) distributed by (i) +partition by range(i) +(start (1) end (3) every (0.3)); +ERROR: EVERY parameter too small +LINE 3: (start (1) end (3) every (0.3)); + ^ +create table foo_p (i int) distributed by (i) +partition by range(i) +(start (1) end (3) every (1.3)); +\d+ foo_p + Partitioned table "public.foo_p" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + i | integer | | | | plain | | +Partition key: RANGE (i) +Partitions: foo_p_1_prt_1 FOR VALUES FROM (1) TO (2), + foo_p_1_prt_2 FOR VALUES FROM (2) TO (3) +Distributed by: (i) + +drop table foo_p; +create table foo_p (i int) distributed by (i) +partition by range(i) +(start (1) end (20) every (10.9)); +\d+ foo_p + Partitioned table "public.foo_p" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + i | integer | | | | plain | | +Partition key: RANGE (i) +Partitions: foo_p_1_prt_1 FOR VALUES FROM (1) TO (12), + foo_p_1_prt_2 FOR VALUES FROM (12) TO (20) +Distributed by: (i) + +drop table foo_p; +-- should fail +create table foo_p (i int, j date) distributed by (i) +partition by range(j) +(start ('2007-01-01') end ('2008-01-01') every (interval '0.5 days')); +ERROR: EVERY parameter too small +LINE 3: (start ('2007-01-01') end ('2008-01-01') every (interval '0.... + ^ +-- should fail +create table foo_p (i int, j date) distributed by (i) +partition by range(j) +(start ('2007-01-01') end ('2008-01-01') every (interval '12 hours')); +ERROR: EVERY parameter too small +LINE 3: (start ('2007-01-01') end ('2008-01-01') every (interval '12... + ^ +create table foo_p (i int, j date) distributed by (i) +partition by range(j) +(start ('2007-01-01') end ('2007-01-05') every (interval '1.2 days')); +\d+ foo_p + Partitioned table "public.foo_p" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + i | integer | | | | plain | | + j | date | | | | plain | | +Partition key: RANGE (j) +Partitions: foo_p_1_prt_1 FOR VALUES FROM ('01-01-2007') TO ('01-02-2007'), + foo_p_1_prt_2 FOR VALUES FROM ('01-02-2007') TO ('01-03-2007'), + foo_p_1_prt_3 FOR VALUES FROM ('01-03-2007') TO ('01-04-2007'), + foo_p_1_prt_4 FOR VALUES FROM ('01-04-2007') TO ('01-05-2007') +Distributed by: (i) + +drop table foo_p; +-- should work +create table foo_p (i int, j timestamp) distributed by (i) +partition by range(j) +(start ('2007-01-01') end ('2007-01-05') every (interval '1.2 days')); +\d+ foo_p + Partitioned table "public.foo_p" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+-----------------------------+-----------+----------+---------+---------+--------------+------------- + i | integer | | | | plain | | + j | timestamp without time zone | | | | plain | | +Partition key: RANGE (j) +Partitions: foo_p_1_prt_1 FOR VALUES FROM ('Mon Jan 01 00:00:00 2007') TO ('Tue Jan 02 04:48:00 2007'), + foo_p_1_prt_2 FOR VALUES FROM ('Tue Jan 02 04:48:00 2007') TO ('Wed Jan 03 09:36:00 2007'), + foo_p_1_prt_3 FOR VALUES FROM ('Wed Jan 03 09:36:00 2007') TO ('Thu Jan 04 14:24:00 2007'), + foo_p_1_prt_4 FOR VALUES FROM ('Thu Jan 04 14:24:00 2007') TO ('Fri Jan 05 00:00:00 2007') +Distributed by: (i) + +drop table foo_p; +-- test inclusive/exclusive +CREATE TABLE supplier2( + S_SUPPKEY INTEGER, + S_NAME CHAR(25), + S_ADDRESS VARCHAR(40), + S_NATIONKEY INTEGER, + S_PHONECHAR char(15), + S_ACCTBAL decimal, + S_COMMENT VARCHAR(100) +) +partition by range (s_nationkey) +( +partition p1 start(0) , +partition p2 start(12) end(13), +partition p3 end(20) inclusive, +partition p4 start(20) exclusive , +partition p5 start(22) end(25) +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 's_suppkey' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +\d+ supplier2 + Partitioned table "public.supplier2" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +-------------+------------------------+-----------+----------+---------+----------+--------------+------------- + s_suppkey | integer | | | | plain | | + s_name | character(25) | | | | extended | | + s_address | character varying(40) | | | | extended | | + s_nationkey | integer | | | | plain | | + s_phonechar | character(15) | | | | extended | | + s_acctbal | numeric | | | | main | | + s_comment | character varying(100) | | | | extended | | +Partition key: RANGE (s_nationkey) +Partitions: supplier2_1_prt_p1 FOR VALUES FROM (0) TO (12), + supplier2_1_prt_p2 FOR VALUES FROM (12) TO (13), + supplier2_1_prt_p3 FOR VALUES FROM (13) TO (21), + supplier2_1_prt_p4 FOR VALUES FROM (21) TO (22), + supplier2_1_prt_p5 FOR VALUES FROM (22) TO (25) +Distributed by: (s_suppkey) + +insert into supplier2 (s_suppkey, s_nationkey) select i, i +from generate_series(1, 24) i; +select * from supplier2_1_prt_p1 order by S_NATIONKEY; + s_suppkey | s_name | s_address | s_nationkey | s_phonechar | s_acctbal | s_comment +-----------+--------+-----------+-------------+-------------+-----------+----------- + 1 | | | 1 | | | + 2 | | | 2 | | | + 3 | | | 3 | | | + 4 | | | 4 | | | + 5 | | | 5 | | | + 6 | | | 6 | | | + 7 | | | 7 | | | + 8 | | | 8 | | | + 9 | | | 9 | | | + 10 | | | 10 | | | + 11 | | | 11 | | | +(11 rows) + +select * from supplier2_1_prt_p2 order by S_NATIONKEY; + s_suppkey | s_name | s_address | s_nationkey | s_phonechar | s_acctbal | s_comment +-----------+--------+-----------+-------------+-------------+-----------+----------- + 12 | | | 12 | | | +(1 row) + +select * from supplier2_1_prt_p3 order by S_NATIONKEY; + s_suppkey | s_name | s_address | s_nationkey | s_phonechar | s_acctbal | s_comment +-----------+--------+-----------+-------------+-------------+-----------+----------- + 13 | | | 13 | | | + 14 | | | 14 | | | + 15 | | | 15 | | | + 16 | | | 16 | | | + 17 | | | 17 | | | + 18 | | | 18 | | | + 19 | | | 19 | | | + 20 | | | 20 | | | +(8 rows) + +select * from supplier2_1_prt_p4 order by S_NATIONKEY; + s_suppkey | s_name | s_address | s_nationkey | s_phonechar | s_acctbal | s_comment +-----------+--------+-----------+-------------+-------------+-----------+----------- + 21 | | | 21 | | | +(1 row) + +select * from supplier2_1_prt_p5 order by S_NATIONKEY; + s_suppkey | s_name | s_address | s_nationkey | s_phonechar | s_acctbal | s_comment +-----------+--------+-----------+-------------+-------------+-----------+----------- + 22 | | | 22 | | | + 23 | | | 23 | | | + 24 | | | 24 | | | +(3 rows) + +drop table supplier2; +-- mpp3238 +create table foo_p (i int) partition by range (i) +( + partition p1 start('1') , + partition p2 start('2639161') , + partition p3 start('5957166') , + partition p4 start('5981976') end('5994376') inclusive, + partition p5 end('6000001') +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +\d+ foo_p + Partitioned table "public.foo_p" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + i | integer | | | | plain | | +Partition key: RANGE (i) +Partitions: foo_p_1_prt_p1 FOR VALUES FROM (1) TO (2639161), + foo_p_1_prt_p2 FOR VALUES FROM (2639161) TO (5957166), + foo_p_1_prt_p3 FOR VALUES FROM (5957166) TO (5981976), + foo_p_1_prt_p4 FOR VALUES FROM (5981976) TO (5994377), + foo_p_1_prt_p5 FOR VALUES FROM (5994377) TO (6000001) +Distributed by: (i) + +insert into foo_p values(5994400); +insert into foo_p values(1); +insert into foo_p values(6000002); +ERROR: no partition of relation "foo_p" found for row (seg2 172.18.0.2:7004 pid=21692) +DETAIL: Partition key of the failing row contains (i) = (6000002). +insert into foo_p values(5994376); +drop table foo_p; +create table foo_p (i int) +partition by range(i) +(partition p1 start(1) end(5), + partition p2 start(10), + partition p3 end(10) exclusive); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +\d+ foo_p + Partitioned table "public.foo_p" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + i | integer | | | | plain | | +Partition key: RANGE (i) +Partitions: foo_p_1_prt_p1 FOR VALUES FROM (1) TO (5), + foo_p_1_prt_p2 FOR VALUES FROM (10) TO (MAXVALUE), + foo_p_1_prt_p3 FOR VALUES FROM (5) TO (10) +Distributed by: (i) + +drop table foo_p; +create table foo_p (i int) +partition by range(i) +(partition p1 start(1) end(5), + partition p2 start(10) exclusive, + partition p3 end(10) inclusive); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +\d+ foo_p + Partitioned table "public.foo_p" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + i | integer | | | | plain | | +Partition key: RANGE (i) +Partitions: foo_p_1_prt_p1 FOR VALUES FROM (1) TO (5), + foo_p_1_prt_p2 FOR VALUES FROM (11) TO (MAXVALUE), + foo_p_1_prt_p3 FOR VALUES FROM (5) TO (11) +Distributed by: (i) + +insert into foo_p values(1), (5), (10); +drop table foo_p; +-- MPP-3264 +-- mix AO with master HEAP and see if copy works +create table foo_p (i int) +partition by list(i) +(partition p1 values(1, 2, 3) with (appendonly = true), + partition p2 values(4) +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +copy foo_p from stdin; +select * from foo_p; +NOTICE: One or more columns in the following table(s) do not have statistics: foo_p +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + i +--- + 2 + 3 + 4 + 1 +(4 rows) + +select * from foo_p_1_prt_p1; + i +--- + 2 + 3 + 1 +(3 rows) + +select * from foo_p_1_prt_p2; + i +--- + 4 +(1 row) + +drop table foo_p; +-- other way around +create table foo_p (i int) with(appendonly = true) +partition by list(i) +(partition p1 values(1, 2, 3) with (appendonly = false), + partition p2 values(4) +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +copy foo_p from stdin; +select * from foo_p; +NOTICE: One or more columns in the following table(s) do not have statistics: foo_p +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + i +--- + 2 + 3 + 4 + 1 +(4 rows) + +select * from foo_p_1_prt_p1; + i +--- + 2 + 3 + 1 +(3 rows) + +select * from foo_p_1_prt_p2; + i +--- + 4 +(1 row) + +drop table foo_p; +-- Same as above, but the input is ordered so that the inserts to the heap +-- partition happen first. Had a bug related flushing the multi-insert +-- buffers in that scenario at one point. +-- (https://github.com/greenplum-db/gpdb/issues/6678 +create table mixed_ao_part(distkey int, partkey int) +with (appendonly=true) distributed by(distkey) +partition by range(partkey) ( + partition p1 start(0) end(100) with (appendonly = false), + partition p2 start(100) end(199) +); +copy mixed_ao_part from stdin; +select * from mixed_ao_part; +NOTICE: One or more columns in the following table(s) do not have statistics: mixed_ao_part +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + distkey | partkey +---------+--------- + 2 | 96 + 3 | 97 + 4 | 98 + 2 | 101 + 3 | 102 + 4 | 103 + 1 | 95 + 1 | 100 + 5 | 99 + 5 | 104 +(10 rows) + +-- Don't drop the table, so that we leave behind a mixed table in the +-- regression database for pg_dump/restore testing. +-- MPP-3283 +CREATE TABLE PARTSUPP ( +PS_PARTKEY INTEGER, +PS_SUPPKEY INTEGER, +PS_AVAILQTY integer, +PS_SUPPLYCOST decimal, +PS_COMMENT VARCHAR(199) +) +partition by range (ps_suppkey) +subpartition by range (ps_partkey) +subpartition by range (ps_supplycost) subpartition template (start('1') +end('1001') every(500)) +( +partition p1 start('1') end('10001') every(5000) +(subpartition sp1 start('1') end('200001') every(66666) +) +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'ps_partkey' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into partsupp values(1,2,3325,771.64,', even theodolites. regular, final +theodolites eat after the carefully pending foxes. furiously regular deposits +sleep slyly. carefully bold realms above the ironic dependencies haggle +careful'); +copy partsupp from stdin with delimiter '|'; +drop table partsupp; +--MPP-3285 +CREATE TABLE PARTLINEITEM ( + L_ORDERKEY INT8, + L_PARTKEY INTEGER, + L_SUPPKEY INTEGER, + L_LINENUMBER integer, + L_QUANTITY decimal, + L_EXTENDEDPRICE decimal, + L_DISCOUNT decimal, + L_TAX decimal, + L_RETURNFLAG CHAR(1), + L_LINESTATUS CHAR(1), + L_SHIPDATE date, + L_COMMITDATE date, + L_RECEIPTDATE date, + L_SHIPINSTRUCT CHAR(25), + L_SHIPMODE CHAR(10), + L_COMMENT VARCHAR(44) + ) +partition by range (l_commitdate) +( +partition p1 start('1992-01-31') end('1998-11-01') every(interval '20 months') +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'l_orderkey' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +copy partlineitem from stdin with delimiter '|'; +\d+ partlineitem + Partitioned table "public.partlineitem" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +-----------------+-----------------------+-----------+----------+---------+----------+--------------+------------- + l_orderkey | bigint | | | | plain | | + l_partkey | integer | | | | plain | | + l_suppkey | integer | | | | plain | | + l_linenumber | integer | | | | plain | | + l_quantity | numeric | | | | main | | + l_extendedprice | numeric | | | | main | | + l_discount | numeric | | | | main | | + l_tax | numeric | | | | main | | + l_returnflag | character(1) | | | | extended | | + l_linestatus | character(1) | | | | extended | | + l_shipdate | date | | | | plain | | + l_commitdate | date | | | | plain | | + l_receiptdate | date | | | | plain | | + l_shipinstruct | character(25) | | | | extended | | + l_shipmode | character(10) | | | | extended | | + l_comment | character varying(44) | | | | extended | | +Partition key: RANGE (l_commitdate) +Partitions: partlineitem_1_prt_p1_1 FOR VALUES FROM ('01-31-1992') TO ('09-30-1993'), + partlineitem_1_prt_p1_2 FOR VALUES FROM ('09-30-1993') TO ('05-30-1995'), + partlineitem_1_prt_p1_3 FOR VALUES FROM ('05-30-1995') TO ('01-30-1997'), + partlineitem_1_prt_p1_4 FOR VALUES FROM ('01-30-1997') TO ('09-30-1998'), + partlineitem_1_prt_p1_5 FOR VALUES FROM ('09-30-1998') TO ('11-01-1998') +Distributed by: (l_orderkey) + +drop table partlineitem; +-- Make sure ADD creates dependencies +create table i (i int) partition by range(i) (start (1) end(3) every(1)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +alter table i add partition foo2 start(40) end (50); +drop table i; +create table i (i int) partition by range(i) (start (1) end(3) every(1)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +alter table i add partition foo2 start(40) end (50); +alter table i drop partition foo2; +-- when using the partition name to find target partition table, +-- we shoud check whether the matched table belong to the partitioned table. +-- raise error instead of executing on the irrelevant table. +create table i_1_prt_3 (like i); +NOTICE: table doesn't have 'DISTRIBUTED BY' clause, defaulting to distribution columns from LIKE table +-- create another partitioned table which contains a partition table that +-- could be matched by partition name when targeted on an irrelevant table. +create table i2 (i int) partition by range(i) (start (1) end(3) every(1)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +create table i_1_prt_4 partition of i2 for values from (4) to (5); +NOTICE: table has parent, setting distribution columns to match parent table +-- the matechd table name is i_1_prt_3, but it's a normal table, raise error. +alter table i drop partition "3"; +ERROR: partition "3" of "i" does not exist +-- the matched table name is i_1_prt_4, but it belongs to i2, raise error +alter table i drop partition "4"; +ERROR: partition "4" of "i" does not exist +-- should raise error since we always make sure the partitioned table at least have one partition; +alter table i drop partition "1", drop partition "2"; +ERROR: cannot drop partition "i_1_prt_2" of "i" -- only one remains +HINT: Use DROP TABLE "i" to remove the table and the final partition +drop table i; +drop table i2; +drop table i_1_prt_3; +create table i (i int) partition by range(i) (start(1) end(3) every(1), default partition extra); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +-- should raise error since we always make sure the partitioned table at least have one partition; +alter table i drop partition "2", drop partition "3", drop default partition; +ERROR: cannot drop partition "i_1_prt_extra" of "i" -- only one remains +HINT: Use DROP TABLE "i" to remove the table and the final partition +drop table i; +create table i (i int, c text) partition by range(i) subpartition by list(c) +subpartition template (subpartition a values ('a'), subpartition b values ('b')) +(start (1) end(3) every(1)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +-- should raise error since we always make sure the partitioned table at least have one partition; +alter table i alter partition "1" drop partition a, alter partition "1" drop partition b; +ERROR: cannot drop partition "i_1_prt_1_2_prt_b" of "i_1_prt_1" -- only one remains +HINT: Use DROP TABLE "i_1_prt_1" to remove the table and the final partition +drop table i; +CREATE TABLE PARTSUPP ( +PS_PARTKEY INTEGER, +PS_SUPPKEY INTEGER, +PS_AVAILQTY integer, +PS_SUPPLYCOST decimal, +PS_COMMENT VARCHAR(199) +) +partition by range (ps_suppkey) +subpartition by range (ps_partkey) +subpartition by range (ps_supplycost) subpartition template (start('1') +end('1001') every(500)) +( +partition p1 start('1') end('10001') every(5000) +(subpartition sp1 start('1') end('200001') every(66666) +) +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'ps_partkey' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +select relname, pg_get_expr(relpartbound, oid, false) from pg_class where relname like 'partsupp%'; + relname | pg_get_expr +-----------------------------------------+-------------------------------------- + partsupp | + partsupp_1_prt_p1_1 | FOR VALUES FROM (1) TO (5001) + partsupp_1_prt_p1_1_2_prt_sp1_1 | FOR VALUES FROM (1) TO (66667) + partsupp_1_prt_p1_1_2_prt_sp1_1_3_prt_1 | FOR VALUES FROM ('1') TO ('501') + partsupp_1_prt_p1_1_2_prt_sp1_1_3_prt_2 | FOR VALUES FROM ('501') TO ('1001') + partsupp_1_prt_p1_1_2_prt_sp1_2 | FOR VALUES FROM (66667) TO (133333) + partsupp_1_prt_p1_1_2_prt_sp1_2_3_prt_1 | FOR VALUES FROM ('1') TO ('501') + partsupp_1_prt_p1_1_2_prt_sp1_2_3_prt_2 | FOR VALUES FROM ('501') TO ('1001') + partsupp_1_prt_p1_1_2_prt_sp1_3 | FOR VALUES FROM (133333) TO (199999) + partsupp_1_prt_p1_1_2_prt_sp1_3_3_prt_1 | FOR VALUES FROM ('1') TO ('501') + partsupp_1_prt_p1_1_2_prt_sp1_3_3_prt_2 | FOR VALUES FROM ('501') TO ('1001') + partsupp_1_prt_p1_1_2_prt_sp1_4 | FOR VALUES FROM (199999) TO (200001) + partsupp_1_prt_p1_1_2_prt_sp1_4_3_prt_1 | FOR VALUES FROM ('1') TO ('501') + partsupp_1_prt_p1_1_2_prt_sp1_4_3_prt_2 | FOR VALUES FROM ('501') TO ('1001') + partsupp_1_prt_p1_2 | FOR VALUES FROM (5001) TO (10001) + partsupp_1_prt_p1_2_2_prt_sp1_1 | FOR VALUES FROM (1) TO (66667) + partsupp_1_prt_p1_2_2_prt_sp1_1_3_prt_1 | FOR VALUES FROM ('1') TO ('501') + partsupp_1_prt_p1_2_2_prt_sp1_1_3_prt_2 | FOR VALUES FROM ('501') TO ('1001') + partsupp_1_prt_p1_2_2_prt_sp1_2 | FOR VALUES FROM (66667) TO (133333) + partsupp_1_prt_p1_2_2_prt_sp1_2_3_prt_1 | FOR VALUES FROM ('1') TO ('501') + partsupp_1_prt_p1_2_2_prt_sp1_2_3_prt_2 | FOR VALUES FROM ('501') TO ('1001') + partsupp_1_prt_p1_2_2_prt_sp1_3 | FOR VALUES FROM (133333) TO (199999) + partsupp_1_prt_p1_2_2_prt_sp1_3_3_prt_1 | FOR VALUES FROM ('1') TO ('501') + partsupp_1_prt_p1_2_2_prt_sp1_3_3_prt_2 | FOR VALUES FROM ('501') TO ('1001') + partsupp_1_prt_p1_2_2_prt_sp1_4 | FOR VALUES FROM (199999) TO (200001) + partsupp_1_prt_p1_2_2_prt_sp1_4_3_prt_1 | FOR VALUES FROM ('1') TO ('501') + partsupp_1_prt_p1_2_2_prt_sp1_4_3_prt_2 | FOR VALUES FROM ('501') TO ('1001') +(27 rows) + +drop table partsupp; +-- ALTER TABLE ALTER PARTITION tests +CREATE TABLE ataprank (id int, rank int, +year date, gender char(1), +usstate char(2)) +DISTRIBUTED BY (id, gender, year, usstate) +partition by list (gender) +subpartition by range (year) +subpartition template ( +subpartition jan01 start (date '2001-01-01'), +subpartition jan02 start (date '2002-01-01'), +subpartition jan03 start (date '2003-01-01'), +subpartition jan04 start (date '2004-01-01'), +subpartition jan05 start (date '2005-01-01') +) +subpartition by list (usstate) +subpartition template ( +subpartition mass values ('MA'), +subpartition cali values ('CA'), +subpartition ohio values ('OH') +) +( + partition boys values ('M'), + partition girls values ('F') +); +-- and without subpartition templates... +CREATE TABLE ataprank2 (id int, rank int, +year date, gender char(1), +usstate char(2)) +DISTRIBUTED BY (id, gender, year, usstate) +partition by list (gender) +subpartition by range (year) +subpartition by list (usstate) +( + partition boys values ('M') +( +subpartition jan01 start (date '2001-01-01') +( +subpartition mass values ('MA'), +subpartition cali values ('CA'), +subpartition ohio values ('OH') +), +subpartition jan02 start (date '2002-01-01') +( +subpartition mass values ('MA'), +subpartition cali values ('CA'), +subpartition ohio values ('OH') +), +subpartition jan03 start (date '2003-01-01') +( +subpartition mass values ('MA'), +subpartition cali values ('CA'), +subpartition ohio values ('OH') +), +subpartition jan04 start (date '2004-01-01') +( +subpartition mass values ('MA'), +subpartition cali values ('CA'), +subpartition ohio values ('OH') +), +subpartition jan05 start (date '2005-01-01') +( +subpartition mass values ('MA'), +subpartition cali values ('CA'), +subpartition ohio values ('OH') +) +), + partition girls values ('F') +( +subpartition jan01 start (date '2001-01-01') +( +subpartition mass values ('MA'), +subpartition cali values ('CA'), +subpartition ohio values ('OH') +), +subpartition jan02 start (date '2002-01-01') +( +subpartition mass values ('MA'), +subpartition cali values ('CA'), +subpartition ohio values ('OH') +), +subpartition jan03 start (date '2003-01-01') +( +subpartition mass values ('MA'), +subpartition cali values ('CA'), +subpartition ohio values ('OH') +), +subpartition jan04 start (date '2004-01-01') +( +subpartition mass values ('MA'), +subpartition cali values ('CA'), +subpartition ohio values ('OH') +), +subpartition jan05 start (date '2005-01-01') +( +subpartition mass values ('MA'), +subpartition cali values ('CA'), +subpartition ohio values ('OH') +) +) +); +-- ok +alter table ataprank truncate partition girls; +alter table ataprank alter partition girls truncate partition for ('2001-01-01'); +alter table ataprank alter partition girls alter partition +for ('2001-01-01') truncate partition mass; +-- addressing partitions by RANK is no longer supported +alter table ataprank truncate partition for (rank (1)); +ERROR: addressing partition by RANK is no longer supported +LINE 1: alter table ataprank truncate partition for (rank (1)); + ^ +HINT: Use partition name or FOR () instead. +-- don't NOTIFY of children if cascade +alter table ataprank truncate partition girls cascade; +-- fail - no partition for '1999-01-01' +alter table ataprank alter partition girls truncate partition for ('1999-01-01'); +ERROR: partition for specified value of ataprank_1_prt_girls does not exist +-- fail - no funky +alter table ataprank alter partition girls alter partition +for ('2001-01-01') truncate partition "funky"; +ERROR: relation "public.ataprank_1_prt_girls_2_prt_jan01_3_prt_funky" does not exist +-- fail - no funky (drop) +alter table ataprank alter partition girls alter partition +for ('2001-01-01') drop partition "funky"; +ERROR: relation "public.ataprank_1_prt_girls_2_prt_jan01_3_prt_funky" does not exist +-- fail - missing name +alter table ataprank alter partition girls alter partition +for ('2001-01-01') drop partition ; +ERROR: syntax error at or near ";" +LINE 2: for ('2001-01-01') drop partition ; + ^ +-- ok +alter table ataprank alter partition girls drop partition +for ('2001-01-01') ; +-- ok , skipping +alter table ataprank alter partition girls drop partition if exists jan01; +-- ok +alter table ataprank alter partition girls drop partition for ('2002-01-01'); +alter table ataprank alter partition girls drop partition for ('2003-01-01'); +alter table ataprank alter partition girls drop partition for ('2004-01-01'); +-- ok, skipping +alter table ataprank alter partition girls drop partition if exists for ('2004-01-01'); +-- ok +alter table ataprank alter partition girls rename partition jan05 +to "funky fresh"; +alter table ataprank alter partition girls rename partition "funky fresh" +to jan05; +-- fail , not exist +alter table ataprank alter partition girls alter partition jan05 rename +partition jan01 to foo; +ERROR: relation "public.ataprank_1_prt_girls_2_prt_jan05_3_prt_jan01" does not exist +-- fail not exist +alter table ataprank alter partition girls alter partition jan05 alter +partition cali rename partition foo to bar; +ERROR: table "ataprank_1_prt_girls_2_prt_jan05_3_prt_cali" is not partitioned +-- fail not partitioned +alter table ataprank alter partition girls alter partition jan05 alter +partition cali alter partition foo drop partition bar; +ERROR: table "ataprank_1_prt_girls_2_prt_jan05_3_prt_cali" is not partitioned +-- ADD PARTITION, with and without templates +-- fails for ataprank (due to template), works for ataprank2 +alter table ataprank +add partition neuter values ('N') + (subpartition foo + start ('2001-01-01') end ('2002-01-01') + every (interval '1 month') + (subpartition bar values ('AZ'))); +ERROR: subpartition configuration conflicts with subpartition template +LINE 3: (subpartition foo + ^ +alter table ataprank2 +add partition neuter values ('N') + (subpartition foo + start ('2001-01-01') end ('2002-01-01') + every (interval '1 month') + (subpartition bar values ('AZ'))); +-- fail , no subpartition spec for ataprank2, works for ataprank +alter table ataprank alter partition boys +add partition jan00 start ('2000-01-01') end ('2001-01-01'); +alter table ataprank2 alter partition boys +add partition jan00 start ('2000-01-01') end ('2001-01-01'); +ERROR: no partitions specified at depth 3 +-- work - create subpartition for ataprank2, fail for ataprank +alter table ataprank alter partition boys +add partition jan99 start ('1999-01-01') end ('2000-01-01') + (subpartition ariz values ('AZ')); +ERROR: subpartition configuration conflicts with subpartition template +alter table ataprank2 alter partition boys +add partition jan00 start ('2000-01-01') end ('2001-01-01') + (subpartition ariz values ('AZ')); +-- works for both -- adding leaf partition doesn't conflict with template +alter table ataprank alter partition boys +alter partition jan00 +add partition haw values ('HI'); +alter table ataprank2 alter partition boys +alter partition jan00 +add partition haw values ('HI'); +alter table ataprank drop partition neuter; +ERROR: relation "public.ataprank_1_prt_neuter" does not exist +alter table ataprank2 drop partition neuter; +-- fail , no subpartition spec for ataprank2, work for ataprank +alter table ataprank +add default partition neuter ; +alter table ataprank2 +add default partition neuter ; +ERROR: no partitions specified at depth 2 +alter table ataprank +add default partition neuter + (subpartition foo + start ('2001-01-01') end ('2002-01-01') + every (interval '1 month') + (subpartition ariz values ('AZ'))); +ERROR: subpartition configuration conflicts with subpartition template +LINE 3: (subpartition foo + ^ +alter table ataprank2 +add default partition neuter + (subpartition foo + start ('2001-01-01') end ('2002-01-01') + every (interval '1 month') + (subpartition ariz values ('AZ'))); +-- fail +alter table ataprank +alter default partition add default partition def1 +(subpartition haw values ('HI')); +ERROR: subpartition configuration conflicts with subpartition template +-- fail +alter table ataprank +alter default partition alter default partition +add default partition def2; +ERROR: DEFAULT partition of relation "ataprank_1_prt_neuter" does not exist +-- work +alter table ataprank +alter default partition add default partition def1; +alter table ataprank +alter default partition alter default partition +add default partition def2; +alter table ataprank2 +alter default partition add default partition def1 +(subpartition haw values ('HI')); +alter table ataprank2 +alter default partition alter default partition +add default partition def2; +drop table ataprank ; +drop table ataprank2 ; +-- **END** ALTER TABLE ALTER PARTITION tests +-- Test casting +create table f (i int) partition by range (i) (start(1::int) end(10::int)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +drop table f; +create table f (i bigint) partition by range (i) (start(1::int8) +end(1152921504606846976::int8) every(576460752303423488)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +drop table f; +create table f (n numeric(20, 2)) partition by range(n) (start(1::bigint) +end(10000::bigint)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'n' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +drop table f; +--should fail, there's no assignment cast from text to numeric +create table f (n numeric(20, 2)) partition by range(n) (start(1::bigint) +end(10000::text)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'n' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +ERROR: specified value cannot be cast to type numeric for column "n" +LINE 2: end(10000::text)); + ^ +--should fail. there's no assignment cast from bool to numeric +create table f (n numeric(20, 2)) partition by range(n) (start(1::bigint) +end('f'::bool)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'n' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +ERROR: specified value cannot be cast to type numeric for column "n" +LINE 2: end('f'::bool)); + ^ +-- see that grant and revoke cascade to children +create role part_role_append; +NOTICE: resource queue required -- using default resource queue "pg_default" +create table granttest (i int, j int) partition by range(i) +subpartition by list(j) subpartition template (values(1, 2, 3)) +(start(1) end(4) every(1)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +select relname, has_table_privilege('part_role_append', oid,'select') as tabpriv, + has_column_privilege('part_role_append', oid, 'i', 'select') as i_priv, + has_column_privilege('part_role_append', oid, 'j', 'select') as j_priv +from pg_class where relname like 'granttest%'; + relname | tabpriv | i_priv | j_priv +---------------------------+---------+--------+-------- + granttest | f | f | f + granttest_1_prt_1 | f | f | f + granttest_1_prt_1_2_prt_1 | f | f | f + granttest_1_prt_2 | f | f | f + granttest_1_prt_2_2_prt_1 | f | f | f + granttest_1_prt_3 | f | f | f + granttest_1_prt_3_2_prt_1 | f | f | f +(7 rows) + +grant select (i) on granttest to part_role_append; +select relname, has_table_privilege('part_role_append', oid,'select') as tabpriv, + has_column_privilege('part_role_append', oid, 'i', 'select') as i_priv, + has_column_privilege('part_role_append', oid, 'j', 'select') as j_priv +from pg_class where relname like 'granttest%'; + relname | tabpriv | i_priv | j_priv +---------------------------+---------+--------+-------- + granttest | f | t | f + granttest_1_prt_1 | f | t | f + granttest_1_prt_1_2_prt_1 | f | t | f + granttest_1_prt_2 | f | t | f + granttest_1_prt_2_2_prt_1 | f | t | f + granttest_1_prt_3 | f | t | f + granttest_1_prt_3_2_prt_1 | f | t | f +(7 rows) + +grant select on granttest to part_role_append; +select relname, has_table_privilege('part_role_append', oid,'select') as tabpriv, + has_column_privilege('part_role_append', oid, 'i', 'select') as i_priv, + has_column_privilege('part_role_append', oid, 'j', 'select') as j_priv +from pg_class where relname like 'granttest%'; + relname | tabpriv | i_priv | j_priv +---------------------------+---------+--------+-------- + granttest | t | t | t + granttest_1_prt_1 | t | t | t + granttest_1_prt_1_2_prt_1 | t | t | t + granttest_1_prt_2 | t | t | t + granttest_1_prt_2_2_prt_1 | t | t | t + granttest_1_prt_3 | t | t | t + granttest_1_prt_3_2_prt_1 | t | t | t +(7 rows) + +grant insert on granttest to part_role_append; +select relname, has_table_privilege('part_role_append', oid, 'insert') as tabpriv, + has_column_privilege('part_role_append', oid, 'i', 'insert') as i_priv, + has_column_privilege('part_role_append', oid, 'j', 'insert') as j_priv +from pg_class where relname like 'granttest%'; + relname | tabpriv | i_priv | j_priv +---------------------------+---------+--------+-------- + granttest | t | t | t + granttest_1_prt_1 | t | t | t + granttest_1_prt_1_2_prt_1 | t | t | t + granttest_1_prt_2 | t | t | t + granttest_1_prt_2_2_prt_1 | t | t | t + granttest_1_prt_3 | t | t | t + granttest_1_prt_3_2_prt_1 | t | t | t +(7 rows) + +revoke insert on granttest from part_role_append; +grant insert (j) on granttest to part_role_append; +select relname, has_table_privilege('part_role_append', oid, 'insert') as tabpriv, + has_column_privilege('part_role_append', oid, 'i', 'insert') as i_priv, + has_column_privilege('part_role_append', oid, 'j', 'insert') as j_priv +from pg_class where relname like 'granttest%'; + relname | tabpriv | i_priv | j_priv +---------------------------+---------+--------+-------- + granttest | f | f | t + granttest_1_prt_1 | f | f | t + granttest_1_prt_1_2_prt_1 | f | f | t + granttest_1_prt_2 | f | f | t + granttest_1_prt_2_2_prt_1 | f | f | t + granttest_1_prt_3 | f | f | t + granttest_1_prt_3_2_prt_1 | f | f | t +(7 rows) + +-- Check that when a new partition is created, it inherits the permissions +-- from the parent. +alter table granttest add partition newpart start(100) end (101); +-- same with the new upstream syntax. +create table granttest_newpartsyntax partition of granttest for values from (110) to (120); +NOTICE: table has parent, setting distribution columns to match parent table +select relname, has_table_privilege('part_role_append', oid, 'select') as tabpriv, + has_column_privilege('part_role_append', oid, 'i', 'select') as i_priv, + has_column_privilege('part_role_append', oid, 'j', 'select') as j_priv +from pg_class where relname like 'granttest%'; + relname | tabpriv | i_priv | j_priv +---------------------------------+---------+--------+-------- + granttest | t | t | t + granttest_1_prt_1 | t | t | t + granttest_1_prt_1_2_prt_1 | t | t | t + granttest_1_prt_2 | t | t | t + granttest_1_prt_2_2_prt_1 | t | t | t + granttest_1_prt_3 | t | t | t + granttest_1_prt_3_2_prt_1 | t | t | t + granttest_1_prt_newpart | t | t | t + granttest_1_prt_newpart_2_prt_1 | t | t | t + granttest_newpartsyntax | t | t | t +(10 rows) + +select relname, has_table_privilege('part_role_append', oid, 'insert') as tabpriv, + has_column_privilege('part_role_append', oid, 'i', 'insert') as i_priv, + has_column_privilege('part_role_append', oid, 'j', 'insert') as j_priv +from pg_class where relname like 'granttest%'; + relname | tabpriv | i_priv | j_priv +---------------------------------+---------+--------+-------- + granttest | f | f | t + granttest_1_prt_1 | f | f | t + granttest_1_prt_1_2_prt_1 | f | f | t + granttest_1_prt_2 | f | f | t + granttest_1_prt_2_2_prt_1 | f | f | t + granttest_1_prt_3 | f | f | t + granttest_1_prt_3_2_prt_1 | f | f | t + granttest_1_prt_newpart | f | f | t + granttest_1_prt_newpart_2_prt_1 | f | f | t + granttest_newpartsyntax | f | f | t +(10 rows) + +revoke all on granttest from part_role_append; +select relname, has_table_privilege('part_role_append', oid, 'insert') as tabpriv, + has_column_privilege('part_role_append', oid, 'i', 'insert') as i_priv, + has_column_privilege('part_role_append', oid, 'j', 'insert') as j_priv +from pg_class where relname like 'granttest%'; + relname | tabpriv | i_priv | j_priv +---------------------------------+---------+--------+-------- + granttest | f | f | f + granttest_1_prt_1 | f | f | f + granttest_1_prt_1_2_prt_1 | f | f | f + granttest_1_prt_2 | f | f | f + granttest_1_prt_2_2_prt_1 | f | f | f + granttest_1_prt_3 | f | f | f + granttest_1_prt_3_2_prt_1 | f | f | f + granttest_1_prt_newpart | f | f | f + granttest_1_prt_newpart_2_prt_1 | f | f | f + granttest_newpartsyntax | f | f | f +(10 rows) + +drop table granttest; +drop role part_role_append; +-- deep inline + optional subpartition comma: +CREATE TABLE partsupp_1 ( + ps_partkey integer, + ps_suppkey integer, + ps_availqty integer, + ps_supplycost numeric, + ps_comment character varying(199) +) distributed by (ps_partkey) PARTITION BY RANGE(ps_suppkey) + SUBPARTITION BY RANGE(ps_partkey) + SUBPARTITION BY RANGE(ps_supplycost) + ( + PARTITION p1_1 START (1) END (1666667) EVERY (1666666) + ( + START (1) END (19304783) + ( + START (1::numeric) END (501::numeric) EVERY (500), + START (501::numeric) END (1001::numeric) EVERY (500) + ), + START (19304783) END (100000001) + ( + START (1::numeric) END (501::numeric) EVERY (500), + START (501::numeric) END (1001::numeric) EVERY (500) + ) + ), + PARTITION p1_2 START (1666667) END (3333333) EVERY (1666666) + ( + START (1) END (19304783) + ( + START (1::numeric) END (501::numeric) EVERY (500), + START (501::numeric) END (1001::numeric) EVERY (500) + ), + START (19304783) END (100000001) + ( + START (1::numeric) END (501::numeric) EVERY (500), + START (501::numeric) END (1001::numeric) EVERY (500) + ) + ), + PARTITION p1_3 START (3333333) END (4999999) EVERY (1666666) + ( + START (1) END (19304783) + ( + START (1::numeric) END (501::numeric) EVERY (500), + START (501::numeric) END (1001::numeric) EVERY (500) + ), + START (19304783) END (100000001) + ( + START (1::numeric) END (501::numeric) EVERY (500), + START (501::numeric) END (1001::numeric) EVERY (500) + ) + ), + PARTITION p1_4 START (4999999) END (5000001) EVERY (1666666) + ( + START (1) END (19304783) + ( + START (1::numeric) END (501::numeric) EVERY (500), + START (501::numeric) END (1001::numeric) EVERY (500) + ), + START (19304783) END (100000001) + ( + START (1::numeric) END (501::numeric) EVERY (500), + START (501::numeric) END (1001::numeric) EVERY (500) + ) + ) + ); +-- Accept negative values trivially: +create table partition_g (i int) partition by range(i) (start((-1)) end(10)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +drop table partition_g; +create table partition_g (i int) partition by range(i) (start(-1) end(10)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +drop table partition_g; +CREATE TABLE orders ( + o_orderkey bigint, + o_custkey integer, + o_orderstatus character(1), + o_totalprice numeric, + o_orderdate date, + o_orderpriority character(15), + o_clerk character(15), + o_shippriority integer, + o_comment character varying(79) +) +WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) PARTITION BY RANGE(o_orderdate) + SUBPARTITION BY RANGE(o_custkey) + SUBPARTITION BY RANGE(o_orderkey) + ( + PARTITION p1_1 START ('1992-01-01'::date) END ('1993-06-01'::date) EVERY ('1 year 5 mons'::interval) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ( + SUBPARTITION sp1 START (1) END (46570) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ( + START (1::bigint) END (1500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (1500001::bigint) END (3000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (3000001::bigint) END (4500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (4500001::bigint) END (6000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ), + SUBPARTITION sp2 START (46570) END (150001) INCLUSIVE WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ( + START (1::bigint) END (1500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (1500001::bigint) END (3000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (3000001::bigint) END (4500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (4500001::bigint) END (6000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ) + ), + PARTITION p1_2 START ('1993-06-01'::date) END ('1994-11-01'::date) EVERY ('1 year 5 mons'::interval) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ( + SUBPARTITION sp1 START (1) END (46570) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ( + START (1::bigint) END (1500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (1500001::bigint) END (3000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (3000001::bigint) END (4500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (4500001::bigint) END (6000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ), + SUBPARTITION sp2 START (46570) END (150001) INCLUSIVE WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ( + START (1::bigint) END (1500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (1500001::bigint) END (3000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (3000001::bigint) END (4500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (4500001::bigint) END (6000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ) + ), + PARTITION p1_3 START ('1994-11-01'::date) END ('1996-04-01'::date) EVERY ('1 year 5 mons'::interval) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ( + SUBPARTITION sp1 START (1) END (46570) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ( + START (1::bigint) END (1500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (1500001::bigint) END (3000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (3000001::bigint) END (4500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (4500001::bigint) END (6000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ), + SUBPARTITION sp2 START (46570) END (150001) INCLUSIVE WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ( + START (1::bigint) END (1500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (1500001::bigint) END (3000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (3000001::bigint) END (4500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (4500001::bigint) END (6000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ) + ), + PARTITION p1_4 START ('1996-04-01'::date) END ('1997-09-01'::date) EVERY ('1 year 5 mons'::interval) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ( + SUBPARTITION sp1 START (1) END (46570) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ( + START (1::bigint) END (1500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (1500001::bigint) END (3000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (3000001::bigint) END (4500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (4500001::bigint) END (6000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ), + SUBPARTITION sp2 START (46570) END (150001) INCLUSIVE WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ( + START (1::bigint) END (1500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (1500001::bigint) END (3000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (3000001::bigint) END (4500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (4500001::bigint) END (6000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ) + ), + PARTITION p1_5 START ('1997-09-01'::date) END ('1998-08-03'::date) EVERY ('1 year 5 mons'::interval) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ( + SUBPARTITION sp1 START (1) END (46570) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ( + START (1::bigint) END (1500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (1500001::bigint) END (3000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (3000001::bigint) END (4500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (4500001::bigint) END (6000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ), + SUBPARTITION sp2 START (46570) END (150001) INCLUSIVE WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ( + START (1::bigint) END (1500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (1500001::bigint) END (3000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (3000001::bigint) END (4500001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9), + START (4500001::bigint) END (6000001::bigint) EVERY (1500000) WITH (appendonly=true, checksum=true, blocksize=368640, compresslevel=9) + ) + ) + ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'o_orderkey' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +-- grammar bug: MPP-3361 +create table i2 (i int) partition by range(i) (start(-2::int) end(20)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +drop table i2; +create table i2 (i int) partition by range(i) (start((-2)::int) end(20)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +drop table i2; +create table i2 (i int) partition by range(i) (start(cast ((-2)::bigint as int)) +end(20)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +drop table i2; +CREATE TABLE partsupp ( + ps_partkey integer, + ps_suppkey integer, + ps_availqty integer, + ps_supplycost numeric, + ps_comment character varying(199) +) PARTITION BY RANGE(ps_supplycost) + ( + PARTITION newpart START ((-10000)::numeric) EXCLUSIVE END (1::numeric) +, + PARTITION p1 START (1::numeric) END (1001::numeric) + ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'ps_partkey' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +ERROR: START EXCLUSIVE not supported for partition key data type: numeric +HINT: Specify an inclusive START value and remove the EXCLUSIVE keyword +drop table partsupp; +ERROR: table "partsupp" does not exist +-- Deletion tests +CREATE TABLE tmp_nation_region (n_regionkey integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'n_regionkey' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +drop table if exists tmp_nation; +NOTICE: table "tmp_nation" does not exist, skipping +CREATE TABLE tmp_nation (N_NATIONKEY INTEGER, N_NAME CHAR(25), N_REGIONKEY INTEGER, N_COMMENT VARCHAR(152)) +partition by range (n_nationkey) + ( +partition p1 start('0') WITH (appendonly=true,checksum=true,blocksize=1998848,compresslevel=4), +partition p2 start('11') end('15') inclusive WITH (checksum=false,appendonly=true,blocksize=655360,compresslevel=4), +partition p3 start('15') exclusive end('19'), partition p4 start('19') WITH (compresslevel=8,appendonly=true,checksum=false,blocksize=884736), +partition p5 start('20') +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'n_nationkey' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +delete from tmp_nation where n_regionkey in (select n_regionkey from tmp_nation_region) and n_nationkey between 1 and 5; +drop table tmp_nation; +-- SPLIT tests +-- basic sanity tests. All should pass. +create table k (i int) partition by range(i) (start(1) end(10) every(2), +default partition mydef); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into k select i from generate_series(1, 100) i; +alter table k split partition mydef at (20) into (partition mydef, +partition foo); +ERROR: AT clause cannot be used when splitting a default RANGE partition +drop table k; +create table j (i int) partition by list(i) (partition a values(1, 2, 3, 4), +partition b values(5, 6, 7, 8)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into j select i from generate_series(1, 8) i; +alter table j split partition for(1) at (2, 3) into (partition fa, partition +fb); +select * from j_1_prt_fa; + i +--- + 4 + 1 +(2 rows) + +select * from j_1_prt_fb; + i +--- + 2 + 3 +(2 rows) + +alter table j split partition for(5) at (6); +select * from j; +NOTICE: One or more columns in the following table(s) do not have statistics: j +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + i +--- + 4 + 2 + 3 + 7 + 8 + 5 + 6 + 1 +(8 rows) + +-- should fail +alter table j split partition for (1) at (100); +ERROR: AT clause parameter is not a member of the target partition specification +drop table j; +create table k (i int) partition by range(i) (start(1) end(10) every(2), +default partition mydef); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +-- should fail +alter table k split default partition start(30) end (300) into (partition mydef, partition mydef); +ERROR: both INTO partitions already exist +alter table k split partition for(3) at (20); +ERROR: partition "k_1_prt_1" would overlap partition "k_1_prt_4" +drop table k; +-- should work +create table k (i int) partition by range(i) (start(1) end(10) every(2), +default partition mydef); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into k select i from generate_series(1, 30) i; +alter table k split default partition start(15) end(20) into +(partition mydef, partition foo); +select * from k_1_prt_foo; + i +---- + 15 + 16 + 18 + 19 + 17 +(5 rows) + +alter table k split default partition start(22) exclusive end(25) inclusive +into (partition bar, partition mydef); +select * from k_1_prt_bar; + i +---- + 24 + 23 + 25 +(3 rows) + +-- This fails, because it would create a partition with an empty range. Before +-- GPDB 7, this passed, because a partition like "start (22) exclusive end (23) +-- exclusive" was considered valid. +alter table k split partition bar at (23) into (partition baz, partition foz); +ERROR: empty range bound specified for partition "k_1_prt_baz" +DETAIL: Specified lower bound (23) is greater than or equal to upper bound (23). +\d+ k + Partitioned table "public.k" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + i | integer | | | | plain | | +Partition key: RANGE (i) +Partitions: k_1_prt_2 FOR VALUES FROM (1) TO (3), + k_1_prt_3 FOR VALUES FROM (3) TO (5), + k_1_prt_4 FOR VALUES FROM (5) TO (7), + k_1_prt_5 FOR VALUES FROM (7) TO (9), + k_1_prt_6 FOR VALUES FROM (9) TO (10), + k_1_prt_bar FOR VALUES FROM (23) TO (26), + k_1_prt_foo FOR VALUES FROM (15) TO (20), + k_1_prt_mydef DEFAULT +Distributed by: (i) + +drop table k; +-- Add CO partition and split, reported in MPP-17761 +create table k (i int) with (appendonly = true, orientation = column) distributed by (i) partition by range(i) (start(1) end(10) every(5)); +alter table k add partition co start(11) end (17) with (appendonly = true, orientation = column); +alter table k split partition co at (14) into (partition co1, partition co2); +drop table k; +create table k (a int, b int) with (appendonly = true) distributed by (a) partition by list(b) +( + partition a values (1, 2, 3, 4) with (appendonly = true, orientation = column), + partition b values (5, 6, 7 ,8) with (appendonly = true, orientation = column) +); +alter table k split partition for(2) at(2) into (partition one, partition two); +drop table k; +-- Test errors for default handling +create table k (i int) partition by range(i) (start(1) end(2), +default partition mydef); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +alter table k split partition mydef at (25) into (partition foo, partition +mydef); +ERROR: AT clause cannot be used when splitting a default RANGE partition +drop table k; +create table k (i int) partition by list(i) (values(1), values(2), +default partition mydef); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +alter table k split default partition start(10) end(20); +ERROR: cannot SPLIT LIST PARTITION with START +HINT: Use SPLIT with the AT clause instead. +drop table k; +-- Check that we support int2 +CREATE TABLE myINT2_TBL(q1 int2) + partition by range (q1) + (start (1) end (3) every (1)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'q1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into myint2_tbl values(1), (2); +drop table myint2_tbl; +-- try SREH on a partitioned table. +create table ao_p (i int) with (appendonly = true) + partition by range(i) + (start(1) end(5) every(1)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +copy ao_p from stdin log errors segment reject limit 100; +NOTICE: found 2 data formatting errors (2 or more input rows), rejected related input data +select * from ao_p; +NOTICE: One or more columns in the following table(s) do not have statistics: ao_p +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + i +--- + 2 + 3 +(2 rows) + +drop table ao_p; +-- MPP-3591: make sure we get inclusive/exclusive right with every(). +create table k (i int) partition by range(i) +(start(0) exclusive end(100) inclusive every(25)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +\d+ k + Partitioned table "public.k" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + i | integer | | | | plain | | +Partition key: RANGE (i) +Partitions: k_1_prt_1 FOR VALUES FROM (1) TO (26), + k_1_prt_2 FOR VALUES FROM (26) TO (51), + k_1_prt_3 FOR VALUES FROM (51) TO (76), + k_1_prt_4 FOR VALUES FROM (76) TO (101) +Distributed by: (i) + +insert into k select i from generate_series(1, 100) i; +drop table k; +-- ADD and SPLIT must get inherit permissions of the partition they're +-- modifying +create role part_role_append; +NOTICE: resource queue required -- using default resource queue "pg_default" +create table a (a int, b int, c int) partition by range(a) subpartition by +range(b) subpartition template (subpartition h start(1) end(10)) +subpartition by range(c) +subpartition template(subpartition i start(1) end(10)) +(partition g start(1) end(2)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +revoke all on a from public; +NOTICE: no privileges could be revoked +grant insert on a to part_role_append; +-- revoke it from one existing partition, to make sure we don't screw up +-- existing permissions +revoke all on a_1_prt_g_2_prt_h_3_prt_i from part_role_append; +alter table a add partition b start(40) end(50); +set session authorization part_role_append; +select has_table_privilege('part_role_append', 'a'::regclass,'insert'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('part_role_append', 'a_1_prt_b_2_prt_h'::regclass,'insert'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('part_role_append', 'a_1_prt_b_2_prt_h_3_prt_i'::regclass,'insert'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('part_role_append', 'a_1_prt_g_2_prt_h_3_prt_i'::regclass, +'insert'); + has_table_privilege +--------------------- + f +(1 row) + +insert into a values(45, 5, 5); +-- didn't grant select +select has_table_privilege('part_role_append', 'a'::regclass,'select'); + has_table_privilege +--------------------- + f +(1 row) + +select has_table_privilege('part_role_append', 'a_1_prt_b_2_prt_h'::regclass,'select'); + has_table_privilege +--------------------- + f +(1 row) + +select has_table_privilege('part_role_append', 'a_1_prt_b_2_prt_h_3_prt_i'::regclass,'select'); + has_table_privilege +--------------------- + f +(1 row) + +\c - +drop table a; +create table a (i date) partition by range(i) +(partition f start(date '2005-01-01') end (date '2009-01-01') + every(interval '2 years')); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +revoke all on a from public; +NOTICE: no privileges could be revoked +grant insert on a to part_role_append; +alter table a split partition for ('2005-01-01') at (date '2006-01-01') + into (partition f, partition g); +alter table a add default partition mydef; +alter table a split default partition start(date '2010-01-01') end(date +'2011-01-01') into(partition mydef, partition other); +set session authorization part_role_append; +select has_table_privilege('part_role_append', 'a'::regclass,'insert'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('part_role_append', 'a_1_prt_f'::regclass,'insert'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('part_role_append', 'a_1_prt_mydef'::regclass,'insert'); + has_table_privilege +--------------------- + t +(1 row) + +select has_table_privilege('part_role_append', 'a_1_prt_other'::regclass,'insert'); + has_table_privilege +--------------------- + t +(1 row) + +insert into a values('2005-05-05'); +insert into a values('2006-05-05'); +insert into a values('2010-10-10'); +\c - +drop table a; +drop role part_role_append; +-- Check that when we split a default, the INTO clause must named the default +create table k (i date) partition by range(i) (start('2008-01-01') +end('2009-01-01') every(interval '1 month'), default partition default_part); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +alter table k split default partition start ('2009-01-01') end ('2009-02-01') +into (partition aa, partition nodate); +ERROR: default partition name missing from INTO clause +alter table k split default partition start ('2009-01-01') end ('2009-02-01') +into (partition aa, partition default_part); +-- check that it works without INTO +alter table k split default partition start ('2009-02-01') end ('2009-03-01'); +drop table k; +-- List too +create table k (i int) partition by list(i) (partition a values(1, 2), +partition b values(3, 4), default partition mydef); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +alter table k split partition mydef at (5) into (partition foo, partition bar); +ERROR: default partition name missing from INTO clause +alter table k split partition mydef at (5) into (partition foo, partition mydef); +alter table k split partition mydef at (10); +drop table k; +-- For LIST, make sure that we reject AT() clauses which match all parameters +create table j (i int) partition by list(i) (partition a values(1, 2, 3, 4), + partition b values(5, 6, 7, 8)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +alter table j split partition for(1) at (1,2) into (partition fa, partition fb); +alter table j split partition for(1) at (1,2) +into (partition f1a, partition f1b); -- This has partition rules that overlaps +ERROR: AT clause cannot contain all values in the partition to be split +drop table j; +-- Check that we can split LIST partitions that have a default partition +create table j (i int) partition by list(i) (partition a values(1, 2, 3, 4), +partition b values(5, 6, 7, 8), default partition default_part); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +alter table j split partition for(1) at (1,2) into (partition f1a, partition +f1b); +drop table j; +-- Make sure range can too +create table j (i int) partition by range(i) (partition a start(1) end(10), +default partition default_part); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +alter table j split partition for(1) at (5) into (partition f1a, partition f1b); +drop table j; +-- MPP-3667 ADD PARTITION overlaps +create table mpp3621 (aa date, bb date) partition by range (bb) +(partition foo start('2008-01-01')); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'aa' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +-- these are ok +alter table mpp3621 add partition a1 start ('2007-01-01') end ('2007-02-01'); +alter table mpp3621 add partition a2 start ('2007-02-01') end ('2007-03-01'); +alter table mpp3621 add partition a3 start ('2007-03-01') end ('2007-04-01'); +alter table mpp3621 add partition a4 start ('2007-09-01') end ('2007-10-01'); +alter table mpp3621 add partition a5 start ('2007-08-01') end ('2007-09-01'); +alter table mpp3621 add partition a6 start ('2007-04-01') end ('2007-05-01'); +alter table mpp3621 add partition a7 start ('2007-05-01') end ('2007-06-01'); + -- was error due to startSearchpoint != endSearchpoint +alter table mpp3621 add partition a8 start ('2007-07-01') end ('2007-08-01'); +-- ok +alter table mpp3621 add partition a9 start ('2007-06-01') end ('2007-07-01'); +drop table mpp3621; +-- Check for MPP-3679 and MPP-3692 +create table list_test (a text, b text) partition by list (a) ( + partition foo values ('foo'), + partition bar values ('bar'), + default partition baz); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into list_test values ('foo', 'blah'); +insert into list_test values ('bar', 'blah'); +insert into list_test values ('baz', 'blah'); +alter table list_test split default partition at ('baz') + into (partition bing, default partition); +drop table list_test; +-- MPP-3816: cannot drop column which is the subject of partition config +create table list_test(a int, b int, c int) distributed by (a) + partition by list(b) + subpartition by list(c) subpartition template(subpartition c values(2)) + (partition b values(1)); +-- should fail +alter table list_test drop column b; +ERROR: cannot drop column "b" because it is part of the partition key of relation "list_test" +alter table list_test drop column c; +ERROR: cannot drop column "c" because it is part of the partition key of relation "list_test_1_prt_b" +drop table list_test; +-- MPP-3678: allow exchange and split on tables with subpartitioning +CREATE TABLE rank_exc ( +id int, +rank int, +year int, +gender char(1), +count int ) +DISTRIBUTED BY (id) +PARTITION BY LIST (gender) +SUBPARTITION BY RANGE (year) +SUBPARTITION TEMPLATE ( +SUBPARTITION year1 START (2001), +SUBPARTITION year2 START (2002), +SUBPARTITION year3 START (2003), +SUBPARTITION year4 START (2004), +SUBPARTITION year5 START (2005), +SUBPARTITION year6 START (2006) END (2007) ) +(PARTITION girls VALUES ('F'), +PARTITION boys VALUES ('M') +); +alter table rank_exc alter partition girls add default partition gfuture; +alter table rank_exc alter partition boys add default partition bfuture; +insert into rank_exc values(1, 1, 2007, 'M', 1); +insert into rank_exc values(2, 2, 2008, 'M', 3); +select * from rank_exc; + id | rank | year | gender | count +----+------+------+--------+------- + 1 | 1 | 2007 | M | 1 + 2 | 2 | 2008 | M | 3 +(2 rows) + +alter table rank_exc alter partition boys split default partition start ('2007') +end ('2008') into (partition bfuture, partition year7); +select * from rank_exc_1_prt_boys_2_prt_bfuture; + id | rank | year | gender | count +----+------+------+--------+------- + 2 | 2 | 2008 | M | 3 +(1 row) + +select * from rank_exc_1_prt_boys_2_prt_year7; + id | rank | year | gender | count +----+------+------+--------+------- + 1 | 1 | 2007 | M | 1 +(1 row) + +select * from rank_exc; + id | rank | year | gender | count +----+------+------+--------+------- + 2 | 2 | 2008 | M | 3 + 1 | 1 | 2007 | M | 1 +(2 rows) + +--exchange test +create table r (like rank_exc); +NOTICE: table doesn't have 'DISTRIBUTED BY' clause, defaulting to distribution columns from LIKE table +insert into rank_exc values(3, 3, 2004, 'F', 100); +insert into r values(3, 3, 2004, 'F', 100000); +alter table rank_exc alter partition girls exchange partition year4 with table r; +select * from rank_exc_1_prt_girls_2_prt_year4; + id | rank | year | gender | count +----+------+------+--------+-------- + 3 | 3 | 2004 | F | 100000 +(1 row) + +select * from r; + id | rank | year | gender | count +----+------+------+--------+------- + 3 | 3 | 2004 | F | 100 +(1 row) + +alter table rank_exc alter partition girls exchange partition year4 with table r; +select * from rank_exc_1_prt_girls_2_prt_year4; + id | rank | year | gender | count +----+------+------+--------+------- + 3 | 3 | 2004 | F | 100 +(1 row) + +select * from r; + id | rank | year | gender | count +----+------+------+--------+-------- + 3 | 3 | 2004 | F | 100000 +(1 row) + +-- Split test +alter table rank_exc alter partition girls split default partition start('2008') + end('2020') into (partition years, partition gfuture); +insert into rank_exc values(4, 4, 2009, 'F', 100); +drop table rank_exc; +drop table r; +-- MPP-4245: remove virtual subpartition templates when we drop the partitioned +-- table +create table bar_p (i int, j int) partition by range(i) subpartition by range(j) +subpartition template(start(1) end(10) every(1)) subpartition by range(i) +subpartition template(start(1) end(10) every(5)) (start(1) end(10)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +alter table bar_p alter partition for ('5') alter partition for ('5') + drop partition for ('5'); +insert into bar_p values(1, 1); +insert into bar_p values(5, 5); +ERROR: no partition of relation "bar_p_1_prt_1_2_prt_5" found for row (seg2 172.18.0.2:7004 pid=22128) +DETAIL: Partition key of the failing row contains (i) = (5). +drop table bar_p; +-- Drop should not leave anything lingering for bar_p or its +-- subpartitions in pg_partition* catalog tables. +select relid, level, template from gp_partition_template where not exists (select oid from pg_class where oid = relid); + relid | level | template +-------+-------+---------- +(0 rows) + +-- MPP-4172 +-- should fail +create table ggg (a char(1), b int) +distributed by (b) +partition by range(a) +( +partition aa start ('2006') end ('2009'), partition bb start ('2007') end ('2008') +); +ERROR: value too long for type character(1) +-- MPP-4892 SET SUBPARTITION TEMPLATE +create table mpp4892 (a char, b int, d char) +partition by range (b) +subpartition by list (d) +subpartition template ( + subpartition sp1 values ('a'), + subpartition sp2 values ('b')) +( +start (1) end (10) every (1) +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +-- works +alter table mpp4892 add partition p1 end (11); +-- complain about existing template +alter table mpp4892 add partition p3 end (13) (subpartition sp3 values ('c')); +ERROR: subpartition configuration conflicts with subpartition template +LINE 1: alter table mpp4892 add partition p3 end (13) (subpartition ... + ^ +-- remove template +alter table mpp4892 set subpartition template (); +-- should work (because the template is gone) +alter table mpp4892 add partition p3 end (13) (subpartition sp3 values ('c')); +-- complain because the template is already gone +alter table mpp4892 set subpartition template (); +ERROR: relation "mpp4892" does not have a level 1 subpartition template specification +-- should work +alter table mpp4892 set subpartition template (subpartition sp3 values ('c')); +-- should work +alter table mpp4892 add partition p4 end (15); +drop table mpp4892; +-- make sure we do not allow overlapping range intervals +-- should fail +-- unordered elems +create table ttt (t int) partition by range(t) ( +partition a start (1) end(10) inclusive, +partition c start(11) end(14), +partition b start(5) end(15) +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 't' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +ERROR: partition "ttt_1_prt_b" would overlap partition "ttt_1_prt_a" +-- should fail, this time it's ordered +create table ttt (t int) partition by range(t) ( +partition a start (1) end(10) inclusive, +partition b start(5) end(15), +partition c start(11) end(14) +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 't' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +ERROR: partition "ttt_1_prt_b" would overlap partition "ttt_1_prt_a" +-- should fail +create table ttt (t date) partition by range(t) ( +partition a start ('2005-01-01') end('2006-01-01') inclusive, +partition b start('2005-05-01') end('2005-06-11'), +partition c start('2006-01-01') exclusive end('2006-01-10') +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 't' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +ERROR: partition "ttt_1_prt_b" would overlap partition "ttt_1_prt_a" +-- should fail +create table ttt (t char) partition by range(t) ( +partition a start('a') end('f'), +partition b start('e') end('g') +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 't' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +ERROR: partition "ttt_1_prt_b" would overlap partition "ttt_1_prt_a" +-- MPP-5159 MPP-26829 +-- Should fail -- missing partition spec and subpartition template follows the +-- partition declaration. +CREATE TABLE list_sales (trans_id int, date date, amount +decimal(9,2), region text) +DISTRIBUTED BY (trans_id) +PARTITION BY LIST (region) +SUBPARTITION TEMPLATE +( SUBPARTITION usa VALUES ('usa'), + SUBPARTITION asia VALUES ('asia'), + SUBPARTITION europe VALUES ('europe') +); +ERROR: syntax error at or near "TEMPLATE" +LINE 5: SUBPARTITION TEMPLATE + ^ +-- MPP-5185 MPP-26829 +-- Should work +CREATE TABLE rank_settemp (id int, rank int, year date, gender +char(1)) DISTRIBUTED BY (id, gender, year) +partition by list (gender) +subpartition by range (year) +subpartition template ( +start (date '2001-01-01'), +start (date '2002-01-01'), +start (date '2003-01-01'), +start (date '2004-01-01'), +start (date '2005-01-01') +) +( +partition boys values ('M'), +partition girls values ('F') +); +alter table rank_settemp set subpartition template (); +-- nothing there +select relid::regclass, level from gp_partition_template where relid = 'rank_settemp'::regclass; + relid | level +-------+------- +(0 rows) + +alter table rank_settemp set subpartition template (default subpartition def2); +-- def2 is there +select relid::regclass, level, template from gp_partition_template where relid = 'rank_settemp'::regclass; + relid | level | template +--------------+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + rank_settemp | 1 | {GPPARTITIONDEFINITION :partDefElems ({GPPARTDEFELEM :partName def2 :boundSpec <> :subSpec <> :isDefault true :options <> :accessMethod <> :tablespacename <> :colencs <>}) :encClauses <> :isTemplate true} +(1 row) + +alter table rank_settemp set subpartition template (default subpartition def2); +-- Should still be there +select relid::regclass, level, template from gp_partition_template where relid = 'rank_settemp'::regclass; + relid | level | template +--------------+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + rank_settemp | 1 | {GPPARTITIONDEFINITION :partDefElems ({GPPARTDEFELEM :partName def2 :boundSpec <> :subSpec <> :isDefault true :options <> :accessMethod <> :tablespacename <> :colencs <>}) :encClauses <> :isTemplate true} +(1 row) + +alter table rank_settemp set subpartition template (start (date '2006-01-01') with (appendonly=true)); +alter table rank_settemp add partition f1 values ('N'); +alter table rank_settemp set subpartition template (start (date '2007-01-01') with (appendonly=true, compresslevel=5)); +alter table rank_settemp add partition f2 values ('C'); +select relid::regclass, level, template from gp_partition_template where relid = 'rank_settemp'::regclass; + relid | level | template +--------------+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + rank_settemp | 1 | {GPPARTITIONDEFINITION :partDefElems ({GPPARTDEFELEM :partName <> :boundSpec {GPPARTITIONRANGESPEC :partStart {GPPARTITIONRANGEITEM :val ({TYPECAST :arg {A_CONST :val "\2007-01-01" :location 64} :typeName {TYPENAME :names ("date") :typeOid 0 :setof false :pct_type false :typmods <> :typemod -1 :arrayBounds <> :location 59} :location -1}) :edge 1} :partEnd <> :partEvery <>} :subSpec <> :isDefault false :options ({DEFELEM :defnamespace <> :defname compresslevel :arg 5 :defaction 0 :location 101}) :accessMethod ao_row :tablespacename <> :colencs <>}) :encClauses <> :isTemplate true} +(1 row) + +drop table rank_settemp; +-- MPP-5397 and MPP-7002 +-- should be able to add/split/exchange partition after dropped a col +create table mpp_5397 (a int, b int, c int, d int) + distributed by (a) + partition by range (b) + (partition a1 start (0) end (5), + partition a2 end (10), + partition a3 end(15)); +alter table mpp_5397 drop column c; +-- should work now +alter table mpp_5397 add partition z end (20); +-- ensure splitting default partition also works +alter table mpp_5397 add default partition adefault; +alter table mpp_5397 drop column d; +alter table mpp_5397 split default partition start (21) inclusive end (25) inclusive; +drop table mpp_5397; +-- MPP-4987 -- make sure we can't damage a partitioning configuration +-- this works +create table rank_damage (i int, j int) +partition by range(j) (start(1) end(5) every(1)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +-- should all fail +alter table rank_damage_1_prt_1 no inherit rank_damage; +ERROR: cannot change inheritance of a partition +create table rank2_damage(like rank_damage); +NOTICE: table doesn't have 'DISTRIBUTED BY' clause, defaulting to distribution columns from LIKE table +alter table rank_damage_1_prt_1 inherit rank2_damage; +ERROR: cannot change inheritance of a partition +alter table rank_damage_1_prt_1 alter column i type bigint; +ERROR: cannot alter inherited column "i" +alter table rank_damage_1_prt_1 set without oids; -- no-op +alter table rank_damage add partition ppo end (22) with (oids = true); +ERROR: tables declared WITH OIDS are not supported +drop table rank_damage, rank2_damage; +-- MPP-5831, type cast in SPLIT +CREATE TABLE sg_cal_event_silvertail_hour ( +caldt date NOT NULL, +calhr smallint NOT NULL, +ip character varying(128), +transactionid character varying(32), +transactiontime timestamp(2) without time zone +) +WITH (appendonly=true, compresslevel=5) +distributed by (ip) PARTITION BY RANGE(transactiontime) +( +PARTITION "P2009041607" +START ('2009-04-16 07:00:00'::timestamp without time zone) +END ('2009-04-16 08:00:00'::timestamp without time zone), +PARTITION "P2009041608" +START ('2009-04-16 08:00:00'::timestamp without time zone) +END ('2009-04-16 09:00:00'::timestamp without time zone), +DEFAULT PARTITION st_default +); +ALTER TABLE SG_CAL_EVENT_SILVERTAIL_HOUR SPLIT DEFAULT PARTITION +START ('2009-04-29 07:00:00'::timestamp) INCLUSIVE END ('2009-04-29 +08:00:00'::timestamp) EXCLUSIVE INTO ( PARTITION P2009042907 , +PARTITION st_default ); +\d+ sg_cal_event_silvertail_hour + Partitioned table "public.sg_cal_event_silvertail_hour" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +-----------------+--------------------------------+-----------+----------+---------+----------+--------------+------------- + caldt | date | | not null | | plain | | + calhr | smallint | | not null | | plain | | + ip | character varying(128) | | | | extended | | + transactionid | character varying(32) | | | | extended | | + transactiontime | timestamp(2) without time zone | | | | plain | | +Partition key: RANGE (transactiontime) +Partitions: "sg_cal_event_silvertail_hour_1_prt_P2009041607" FOR VALUES FROM ('Thu Apr 16 07:00:00 2009') TO ('Thu Apr 16 08:00:00 2009'), + "sg_cal_event_silvertail_hour_1_prt_P2009041608" FOR VALUES FROM ('Thu Apr 16 08:00:00 2009') TO ('Thu Apr 16 09:00:00 2009'), + sg_cal_event_silvertail_hour_1_prt_p2009042907 FOR VALUES FROM ('Wed Apr 29 07:00:00 2009') TO ('Wed Apr 29 08:00:00 2009'), + sg_cal_event_silvertail_hour_1_prt_st_default DEFAULT +Distributed by: (ip) +Options: compresslevel=5 + +\d+ sg_cal_event_silvertail_hour_1_prt_P2009042907 + Table "public.sg_cal_event_silvertail_hour_1_prt_p2009042907" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +-----------------+--------------------------------+-----------+----------+---------+----------+--------------+------------- + caldt | date | | not null | | plain | | + calhr | smallint | | not null | | plain | | + ip | character varying(128) | | | | extended | | + transactionid | character varying(32) | | | | extended | | + transactiontime | timestamp(2) without time zone | | | | plain | | +Partition of: sg_cal_event_silvertail_hour FOR VALUES FROM ('Wed Apr 29 07:00:00 2009') TO ('Wed Apr 29 08:00:00 2009') +Partition constraint: ((transactiontime IS NOT NULL) AND (transactiontime >= 'Wed Apr 29 07:00:00 2009'::timestamp(2) without time zone) AND (transactiontime < 'Wed Apr 29 08:00:00 2009'::timestamp(2) without time zone)) +Compression Type: zlib +Compression Level: 5 +Block Size: 32768 +Checksum: t +Distributed by: (ip) +Options: compresslevel=5 + +drop table sg_cal_event_silvertail_hour; +-- Make sure we inherit master's storage settings +create table foo_p (i int, j int, k text) +with (appendonly = true, compresslevel = 5) +partition by range(j) (start(1) end(10) every(1), default partition def); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into foo_p select i, i+1, repeat('fooo', 9000) from generate_series(1, 100) i; +alter table foo_p split default partition start (10) end(20) +into (partition p10_20, default partition); +select c.oid::regclass, relkind, amname, reloptions from pg_class c left join pg_am am on am.oid = relam where c.oid = 'foo_p_1_prt_p10_20'::regclass; + oid | relkind | amname | reloptions +--------------------+---------+--------+------------------- + foo_p_1_prt_p10_20 | r | ao_row | {compresslevel=5} +(1 row) + +select count(distinct k) from foo_p; +NOTICE: One or more columns in the following table(s) do not have statistics: foo_p +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + count +------- + 1 +(1 row) + +drop table foo_p; +create table foo_p (i int, j int, k text) +partition by range(j) (start(1) end(10) every(1), default partition def +with(appendonly = true)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into foo_p select i, i+1, repeat('fooo', 9000) from generate_series(1, 100) i; +alter table foo_p split default partition start (10) end(20) +into (partition p10_20, default partition); +select c.oid::regclass, relkind, amname, reloptions from pg_class c left join pg_am am on am.oid = relam where c.oid in ('foo_p_1_prt_p10_20'::regclass, 'foo_p_1_prt_def'::regclass); + oid | relkind | amname | reloptions +--------------------+---------+--------+------------ + foo_p_1_prt_def | r | ao_row | + foo_p_1_prt_p10_20 | r | ao_row | +(2 rows) + +select count(distinct k) from foo_p; +NOTICE: One or more columns in the following table(s) do not have statistics: foo_p +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + count +------- + 1 +(1 row) + +drop table foo_p; +-- MPP-5941: work with many levels of templates +CREATE TABLE mpp5941 (a int, b date, c char, + d char(4), e varchar(20), f timestamp) +partition by range (b) +subpartition by list (a) +subpartition template ( +subpartition l1 values (1,2,3,4,5), +subpartition l2 values (6,7,8,9,10) ) +subpartition by list (e) +subpartition template ( +subpartition ll1 values ('Engineering'), +subpartition ll2 values ('QA') ) +subpartition by list (c) +subpartition template ( +subpartition lll1 values ('M'), +subpartition lll2 values ('F') ) +( + start (date '2007-01-01') + end (date '2010-01-01') every (interval '1 year') +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +-- just truncate for fun to see that everything is there +alter table mpp5941 alter partition for ('2008-01-01') +alter partition for (1) alter partition for ('QA') +truncate partition for ('M'); +alter table mpp5941 alter partition for ('2008-01-01') +alter partition for (1) truncate partition for ('QA'); +alter table mpp5941 alter partition for ('2008-01-01') +truncate partition for (1); +alter table mpp5941 truncate partition for ('2008-01-01') ; +truncate table mpp5941; +-- now look at the templates that we have +select relid::regclass, level from gp_partition_template where relid = 'mpp5941'::regclass; + relid | level +---------+------- + mpp5941 | 3 + mpp5941 | 1 + mpp5941 | 2 +(3 rows) + +-- clear level 1 +alter table mpp5941 set subpartition template (); +select relid::regclass, level from gp_partition_template where relid = 'mpp5941'::regclass; + relid | level +---------+------- + mpp5941 | 3 + mpp5941 | 2 +(2 rows) + +-- clear level 2 +alter table mpp5941 alter partition for ('2008-01-01') +set subpartition template (); +select relid::regclass, level from gp_partition_template where relid = 'mpp5941'::regclass; + relid | level +---------+------- + mpp5941 | 3 +(1 row) + +-- clear level 3 +alter table mpp5941 alter partition for ('2008-01-01') +alter partition for (1) +set subpartition template (); +select relid::regclass, level from gp_partition_template where relid = 'mpp5941'::regclass; + relid | level +-------+------- +(0 rows) + +-- no level 4 (error) +alter table mpp5941 alter partition for ('2008-01-01') +alter partition for (1) alter partition for ('QA') +set subpartition template (); +ERROR: relation "mpp5941" does not have a level 4 subpartition template specification +select relid::regclass, level from gp_partition_template where relid = 'mpp5941'::regclass; + relid | level +-------+------- +(0 rows) + +-- no level 5 (error) +alter table mpp5941 alter partition for ('2008-01-01') +alter partition for (1) alter partition for ('QA') +alter partition for ('M') +set subpartition template (); +ERROR: table "mpp5941_1_prt_2_2_prt_l1_3_prt_ll2_4_prt_lll1" is not partitioned +select relid::regclass, level from gp_partition_template where relid = 'mpp5941'::regclass; + relid | level +-------+------- +(0 rows) + +-- set level 1 (error, because no templates for level 2, 3) +alter table mpp5941 set subpartition template ( +subpartition l1 values (1,2,3,4,5), +subpartition l2 values (6,7,8,9,10) ); +ERROR: can't add sub-partition template at level 1 since next level template doesn't exist +HINT: Add sub-partition template for next level. +-- MPP-5992 - add deep templates correctly +-- Note: need to re-add the templates from deepest to shallowest, +-- because adding a template has a dependency on the existence of the +-- deeper template. +-- set level 3 +alter table mpp5941 alter partition for ('2008-01-01') +alter partition for (1) +set subpartition template ( +subpartition lll1 values ('M'), +subpartition lll2 values ('F') ); +select relid::regclass, level from gp_partition_template where relid = 'mpp5941'::regclass; + relid | level +---------+------- + mpp5941 | 3 +(1 row) + +-- set level 2 +alter table mpp5941 alter partition for ('2008-01-01') +set subpartition template ( +subpartition ll1 values ('Engineering'), +subpartition ll2 values ('QA') ); +select relid::regclass, level from gp_partition_template where relid = 'mpp5941'::regclass; + relid | level +---------+------- + mpp5941 | 3 + mpp5941 | 2 +(2 rows) + +-- set level 1 +alter table mpp5941 set subpartition template ( +subpartition l1 values (1,2,3,4,5), +subpartition l2 values (6,7,8,9,10) ); +select relid::regclass, level from gp_partition_template where relid = 'mpp5941'::regclass; + relid | level +---------+------- + mpp5941 | 3 + mpp5941 | 2 + mpp5941 | 1 +(3 rows) + +drop table mpp5941; +-- MPP-5984 - NULL is not allowed in RANGE partition +CREATE TABLE partsupp ( ps_partkey integer, +ps_suppkey integer, ps_availqty integer, +ps_supplycost numeric, ps_comment character varying(199) ) +PARTITION BY RANGE(ps_partkey) +( +partition nnull start (NULL) end (300) +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'ps_partkey' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +ERROR: cannot use NULL with range partition specification +LINE 6: partition nnull start (NULL) end (300) + ^ +CREATE TABLE partsupp ( ps_partkey integer, +ps_suppkey integer, ps_availqty integer, +ps_supplycost numeric, ps_comment character varying(199) ) +PARTITION BY RANGE(ps_partkey) +( +partition nnull start (300) end (NULL) +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'ps_partkey' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +ERROR: cannot use NULL with range partition specification +LINE 6: partition nnull start (300) end (NULL) + ^ +CREATE TABLE partsupp ( ps_partkey integer, +ps_suppkey integer, ps_availqty integer, +ps_supplycost numeric, ps_comment character varying(199) ) +PARTITION BY RANGE(ps_partkey) +( +partition nnull start (300) end (NULL::int) +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'ps_partkey' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +ERROR: cannot use NULL with range partition specification +LINE 6: partition nnull start (300) end (NULL::int) + ^ +CREATE TABLE partsupp ( ps_partkey integer, +ps_suppkey integer, ps_availqty integer, +ps_supplycost numeric, ps_comment character varying(199) ) +PARTITION BY RANGE(ps_partkey) +( +partition p1 start(1) end(10), +partition p2 start(10) end(20), +default partition def +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'ps_partkey' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +alter table partsupp split partition p2 at (NULL); +ERROR: cannot use NULL with range partition specification +LINE 1: alter table partsupp split partition p2 at (NULL); + ^ +alter table partsupp split default partition start(null) end(200); +ERROR: cannot use NULL with range partition specification +LINE 1: ...table partsupp split default partition start(null) end(200); + ^ +drop table partsupp; +CREATE TABLE partsupp ( ps_partkey integer, +ps_suppkey integer, ps_availqty integer, +ps_supplycost numeric, ps_comment character varying(199) ) +PARTITION BY RANGE(ps_partkey) +( +partition nnull start (300) end (400) +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'ps_partkey' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +alter table partsupp add partition foo start(500) end(NULL); +ERROR: cannot use NULL with range partition specification +LINE 1: alter table partsupp add partition foo start(500) end(NULL); + ^ +drop table partsupp; +-- Test for an old bug, where we used to crash on NULLs, because the code +-- to order the partitions by their start/end boundaries did not anticipate +-- NULLs. NULLs in boundaries are not accepted, but because we check for +-- them only after ordering the partitions, the sorting code needs to +-- handle them. (This test needs at least two partitions, so that there +-- is something to sort.) +create table partnulltest ( + col1 int, + col2 numeric +) +distributed by (col1) +partition by range(col2) +( + partition part2 start(1) end(10) , + partition part1 start (NULL) +); +ERROR: cannot use NULL with range partition specification +LINE 9: partition part1 start (NULL) + ^ +-- Test pg_dump on a somewhat complicated partitioned table. (MPP-6240) +-- We actually just create the table here, and leave it behind, so that +-- it gets dumped by pg_dump at end of the regression test suite. +CREATE TABLE supplier_hybrid_part( + S_SUPPKEY INTEGER, + S_NAME CHAR(25), + S_ADDRESS VARCHAR(40), + S_NATIONKEY INTEGER, S_PHONE CHAR(15), + S_ACCTBAL decimal, + S_COMMENT VARCHAR(101) + ) +partition by range (s_suppkey) +subpartition by list (s_nationkey) subpartition template ( + values('22','21','17'), + values('6','11','1','7','16','2') WITH (checksum=false,appendonly=true,blocksize=1171456, compresslevel=3), + values('18','20'), + values('9','23','13') WITH (checksum=true,appendonly=true,blocksize=1335296,compresslevel=7), + values('0','3','12','15','14','8','4','24','19','10','5') +) +( +partition p1 start('1') end('10001') every(10000) +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 's_suppkey' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +-- MPP-3544 +-- Domain +create domain domainvarchar varchar(5); +create domain domainnumeric numeric(8,2); +create domain domainint4 int4; +create domain domaintext text; +-- Test tables using domains +-- list +create table basictest1 + ( testint4 domainint4 + , testtext domaintext + , testvarchar domainvarchar + , testnumeric domainnumeric + ) +partition by LIST(testvarchar) +( +partition aa values ('aaaaa'), +partition bb values ('bbbbb'), +partition cc values ('ccccc') +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'testint4' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +alter table basictest1 add partition dd values('ddddd'); +insert into basictest1 values(1, 1, 'ddddd', 1); +insert into basictest1 values(1, 1, 'ccccc', 1); +insert into basictest1 values(1, 1, 'bbbbb', 1); +insert into basictest1 values(1, 1, 'aaaaa', 1); +drop table basictest1; +--range +create table basictest1 (testnumeric domainint4) +partition by range(testnumeric) + (start(1) end(10) every(5)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'testnumeric' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into basictest1 values(1); +insert into basictest1 values(2); +alter table basictest1 add partition ff start(10) end(20); +insert into basictest1 values(10); +drop table basictest1; +drop domain domainvarchar, domainnumeric, domainint4, domaintext; +-- Test index inheritance with partitions +create table ti (i int not null, j int) +distributed by (i) +partition by range (j) +(start(1) end(3) every(1)); +create unique index ti_pkey on ti(i,j); +select * from pg_indexes where schemaname = 'public' and tablename like 'ti%'; + schemaname | tablename | indexname | tablespace | indexdef +------------+------------+--------------------+------------+-------------------------------------------------------------------------------- + public | ti_1_prt_1 | ti_1_prt_1_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_1_i_j_idx ON public.ti_1_prt_1 USING btree (i, j) + public | ti | ti_pkey | | CREATE UNIQUE INDEX ti_pkey ON ONLY public.ti USING btree (i, j) + public | ti_1_prt_2 | ti_1_prt_2_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_2_i_j_idx ON public.ti_1_prt_2 USING btree (i, j) +(3 rows) + +create index ti_j_idx on ti using bitmap(j); +select * from pg_indexes where schemaname = 'public' and tablename like 'ti%'; + schemaname | tablename | indexname | tablespace | indexdef +------------+------------+--------------------+------------+-------------------------------------------------------------------------------- + public | ti_1_prt_1 | ti_1_prt_1_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_1_i_j_idx ON public.ti_1_prt_1 USING btree (i, j) + public | ti | ti_pkey | | CREATE UNIQUE INDEX ti_pkey ON ONLY public.ti USING btree (i, j) + public | ti_1_prt_2 | ti_1_prt_2_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_2_i_j_idx ON public.ti_1_prt_2 USING btree (i, j) + public | ti_1_prt_1 | ti_1_prt_1_j_idx | | CREATE INDEX ti_1_prt_1_j_idx ON public.ti_1_prt_1 USING bitmap (j) + public | ti | ti_j_idx | | CREATE INDEX ti_j_idx ON ONLY public.ti USING bitmap (j) + public | ti_1_prt_2 | ti_1_prt_2_j_idx | | CREATE INDEX ti_1_prt_2_j_idx ON public.ti_1_prt_2 USING bitmap (j) +(6 rows) + +alter table ti add partition p3 start(3) end(10); +select * from pg_indexes where schemaname = 'public' and tablename like 'ti%'; + schemaname | tablename | indexname | tablespace | indexdef +------------+-------------+---------------------+------------+---------------------------------------------------------------------------------- + public | ti_1_prt_1 | ti_1_prt_1_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_1_i_j_idx ON public.ti_1_prt_1 USING btree (i, j) + public | ti | ti_pkey | | CREATE UNIQUE INDEX ti_pkey ON ONLY public.ti USING btree (i, j) + public | ti_1_prt_2 | ti_1_prt_2_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_2_i_j_idx ON public.ti_1_prt_2 USING btree (i, j) + public | ti_1_prt_1 | ti_1_prt_1_j_idx | | CREATE INDEX ti_1_prt_1_j_idx ON public.ti_1_prt_1 USING bitmap (j) + public | ti | ti_j_idx | | CREATE INDEX ti_j_idx ON ONLY public.ti USING bitmap (j) + public | ti_1_prt_2 | ti_1_prt_2_j_idx | | CREATE INDEX ti_1_prt_2_j_idx ON public.ti_1_prt_2 USING bitmap (j) + public | ti_1_prt_p3 | ti_1_prt_p3_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_p3_i_j_idx ON public.ti_1_prt_p3 USING btree (i, j) + public | ti_1_prt_p3 | ti_1_prt_p3_j_idx | | CREATE INDEX ti_1_prt_p3_j_idx ON public.ti_1_prt_p3 USING bitmap (j) +(8 rows) + +-- Should not be able to drop child indexes added implicitly via ADD PARTITION +drop index ti_1_prt_p3_i_j_idx; +ERROR: cannot drop index ti_1_prt_p3_i_j_idx because index ti_pkey requires it +HINT: You can drop index ti_pkey instead. +drop index ti_1_prt_p3_j_idx; +ERROR: cannot drop index ti_1_prt_p3_j_idx because index ti_j_idx requires it +HINT: You can drop index ti_j_idx instead. +alter table ti split partition p3 at (7) into (partition pnew1, partition pnew2); +select * from pg_indexes where schemaname = 'public' and tablename like 'ti%'; + schemaname | tablename | indexname | tablespace | indexdef +------------+----------------+------------------------+------------+---------------------------------------------------------------------------------------- + public | ti_1_prt_pnew2 | ti_1_prt_pnew2_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_pnew2_i_j_idx ON public.ti_1_prt_pnew2 USING btree (i, j) + public | ti_1_prt_pnew2 | ti_1_prt_pnew2_j_idx | | CREATE INDEX ti_1_prt_pnew2_j_idx ON public.ti_1_prt_pnew2 USING bitmap (j) + public | ti_1_prt_1 | ti_1_prt_1_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_1_i_j_idx ON public.ti_1_prt_1 USING btree (i, j) + public | ti | ti_pkey | | CREATE UNIQUE INDEX ti_pkey ON ONLY public.ti USING btree (i, j) + public | ti_1_prt_2 | ti_1_prt_2_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_2_i_j_idx ON public.ti_1_prt_2 USING btree (i, j) + public | ti_1_prt_1 | ti_1_prt_1_j_idx | | CREATE INDEX ti_1_prt_1_j_idx ON public.ti_1_prt_1 USING bitmap (j) + public | ti | ti_j_idx | | CREATE INDEX ti_j_idx ON ONLY public.ti USING bitmap (j) + public | ti_1_prt_2 | ti_1_prt_2_j_idx | | CREATE INDEX ti_1_prt_2_j_idx ON public.ti_1_prt_2 USING bitmap (j) + public | ti_1_prt_pnew1 | ti_1_prt_pnew1_i_j_idx | | CREATE UNIQUE INDEX ti_1_prt_pnew1_i_j_idx ON public.ti_1_prt_pnew1 USING btree (i, j) + public | ti_1_prt_pnew1 | ti_1_prt_pnew1_j_idx | | CREATE INDEX ti_1_prt_pnew1_j_idx ON public.ti_1_prt_pnew1 USING bitmap (j) +(10 rows) + +-- Should not be able to drop child indexes added implicitly via SPLIT PARTITION +drop index ti_1_prt_pnew1_i_j_idx; +ERROR: cannot drop index ti_1_prt_pnew1_i_j_idx because index ti_pkey requires it +HINT: You can drop index ti_pkey instead. +drop index ti_1_prt_pnew1_j_idx; +ERROR: cannot drop index ti_1_prt_pnew1_j_idx because index ti_j_idx requires it +HINT: You can drop index ti_j_idx instead. +drop index ti_1_prt_pnew2_i_j_idx; +ERROR: cannot drop index ti_1_prt_pnew2_i_j_idx because index ti_pkey requires it +HINT: You can drop index ti_pkey instead. +drop index ti_1_prt_pnew2_j_idx; +ERROR: cannot drop index ti_1_prt_pnew2_j_idx because index ti_j_idx requires it +HINT: You can drop index ti_j_idx instead. +-- Index drop should cascade to all partitions- including those later added via +-- ADD PARTITION or SPLIT PARTITION +drop index ti_pkey; +drop index ti_j_idx; +select * from pg_indexes where schemaname = 'public' and tablename like 'ti%'; + schemaname | tablename | indexname | tablespace | indexdef +------------+-----------+-----------+------------+---------- +(0 rows) + +drop table ti; +-- Partitioned table with btree index and hash aggregate should use a correct +-- memory context for its tuples` descriptor +drop table if exists dis_tupdesc; +NOTICE: table "dis_tupdesc" does not exist, skipping +create table dis_tupdesc (a int, b int, c int) +distributed by (a) +partition by list (b) +( + partition p1 values (1), + partition p2 values (2), + default partition junk_data +); +create index dis_tupdesc_idx on dis_tupdesc using btree (c); +insert into dis_tupdesc select i, i % 3, i % 4 from generate_series (1, 240) as i; +analyze dis_tupdesc; +set gp_segments_for_planner = 2; +set optimizer_segments = 2; +select distinct b from dis_tupdesc where c >= 2; + b +--- + 0 + 1 + 2 +(3 rows) + +reset gp_segments_for_planner; +reset optimizer_segments; +-- MPP-6611, make sure rename works with default partitions +create table it (i int, j int) partition by range(i) +subpartition by range(j) subpartition template(start(1) end(10) every(5)) +(start(1) end(3) every(1)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +alter table it rename to newit; +select schemaname, tablename from pg_tables where schemaname = 'public' and tablename like 'newit%'; + schemaname | tablename +------------+----------------------- + public | newit + public | newit_1_prt_1 + public | newit_1_prt_1_2_prt_1 + public | newit_1_prt_1_2_prt_2 + public | newit_1_prt_2 + public | newit_1_prt_2_2_prt_1 + public | newit_1_prt_2_2_prt_2 +(7 rows) + +alter table newit add default partition def; +select schemaname, tablename from pg_tables where schemaname = 'public' and tablename like 'newit%'; + schemaname | tablename +------------+------------------------- + public | newit + public | newit_1_prt_1 + public | newit_1_prt_1_2_prt_1 + public | newit_1_prt_1_2_prt_2 + public | newit_1_prt_2 + public | newit_1_prt_2_2_prt_1 + public | newit_1_prt_2_2_prt_2 + public | newit_1_prt_def + public | newit_1_prt_def_2_prt_1 + public | newit_1_prt_def_2_prt_2 +(10 rows) + +alter table newit rename to anotherit; +select schemaname, tablename from pg_tables where schemaname = 'public' and tablename like +'anotherit%'; + schemaname | tablename +------------+----------------------------- + public | anotherit + public | anotherit_1_prt_1 + public | anotherit_1_prt_1_2_prt_1 + public | anotherit_1_prt_1_2_prt_2 + public | anotherit_1_prt_2 + public | anotherit_1_prt_2_2_prt_1 + public | anotherit_1_prt_2_2_prt_2 + public | anotherit_1_prt_def + public | anotherit_1_prt_def_2_prt_1 + public | anotherit_1_prt_def_2_prt_2 +(10 rows) + +drop table anotherit; +-- +-- Test table constraint inheritance +-- +-- with a named UNIQUE constraint +create table it (i int) distributed by (i) partition by range(i) (start(1) end(3) every(1)); +select schemaname, tablename, indexname from pg_indexes where schemaname = 'public' and tablename like 'it%'; + schemaname | tablename | indexname +------------+-----------+----------- +(0 rows) + +alter table it add constraint it_unique_i unique (i); +select schemaname, tablename, indexname from pg_indexes where schemaname = 'public' and tablename like 'it%'; + schemaname | tablename | indexname +------------+------------+------------------ + public | it_1_prt_1 | it_1_prt_1_i_key + public | it | it_unique_i + public | it_1_prt_2 | it_1_prt_2_i_key +(3 rows) + +alter table it drop constraint it_unique_i; +select schemaname, tablename, indexname from pg_indexes where schemaname = 'public' and tablename like 'it%'; + schemaname | tablename | indexname +------------+-----------+----------- +(0 rows) + +drop table it; +-- with a PRIMARY KEY constraint, without giving it a name explicitly. +create table it (i int) distributed by (i) partition by range(i) (start(1) end(3) every(1)); +select schemaname, tablename, indexname from pg_indexes where schemaname = 'public' and tablename like 'it%'; + schemaname | tablename | indexname +------------+-----------+----------- +(0 rows) + +alter table it add primary key(i); +select schemaname, tablename, indexname from pg_indexes where schemaname = 'public' and tablename like 'it%'; + schemaname | tablename | indexname +------------+------------+----------------- + public | it_1_prt_1 | it_1_prt_1_pkey + public | it | it_pkey + public | it_1_prt_2 | it_1_prt_2_pkey +(3 rows) + +-- FIXME: dropping a primary key doesn't currently work correctly. It doesn't +-- drop the key on the partitions, only the parent. See +-- https://github.com/greenplum-db/gpdb/issues/3750 +-- +-- alter table it add primary key(i); +-- select schemaname, tablename, indexname from pg_indexes where schemaname = 'public' and tablename like 'it%'; +drop table it; +create table it (i int) distributed by (i) partition by range(i) (start(1) end(3) every(1)); +select schemaname, tablename, indexname from pg_indexes where schemaname = 'public' and tablename like 'it%'; + schemaname | tablename | indexname +------------+-----------+----------- +(0 rows) + +alter table it add primary key(i); +select schemaname, tablename, indexname from pg_indexes where schemaname = 'public' and tablename like 'it%'; + schemaname | tablename | indexname +------------+------------+----------------- + public | it_1_prt_1 | it_1_prt_1_pkey + public | it | it_pkey + public | it_1_prt_2 | it_1_prt_2_pkey +(3 rows) + +drop table it; +-- +-- Exclusion constraints are currently not supported on partitioned tables. +-- +create table parttab_with_excl_constraint ( + i int, + j int, + CONSTRAINT part_excl EXCLUDE (i WITH =) ) +distributed by (i) partition by list (i) ( + partition a values (1), + partition b values (2), + partition c values (3) +); +ERROR: exclusion constraints are not supported on partitioned tables +LINE 4: CONSTRAINT part_excl EXCLUDE (i WITH =) ) + ^ +create table parttab_with_excl_constraint ( + i int, + j int) +distributed by (i) partition by list (i) ( + partition a values (1), + partition b values (2), + partition c values (3) +); +alter table parttab_with_excl_constraint ADD CONSTRAINT part_excl EXCLUDE (i WITH =); +ERROR: exclusion constraints are not supported on partitioned tables +LINE 1: alter table parttab_with_excl_constraint ADD CONSTRAINT part... + ^ +drop table parttab_with_excl_constraint; +-- MPP-6297: test special WITH(tablename=...) syntax for dump/restore +-- original table was: +-- PARTITION BY RANGE(l_commitdate) +-- ( +-- PARTITION p1 +-- START ('1992-01-31'::date) END ('1995-04-30'::date) +-- EVERY ('1 year 1 mon'::interval) +-- ) +-- dump used to give a definition like this: +-- without the WITH(tablename=...), the vagaries of EVERY arithmetic +-- create >3 partitions +CREATE TABLE mpp6297 ( l_orderkey bigint, +l_commitdate date +) +distributed BY (l_orderkey) PARTITION BY RANGE(l_commitdate) +( +PARTITION p1_1 START ('1992-01-31'::date) END ('1993-02-28'::date) +EVERY ('1 year 1 mon'::interval) +, +PARTITION p1_2 START ('1993-02-28'::date) END ('1994-03-31'::date) +EVERY ('1 year 1 mon'::interval) +, +PARTITION p1_3 START ('1994-03-31'::date) END ('1995-04-30'::date) +EVERY ('1 year 1 mon'::interval) +); +\d+ mpp6297 + Partitioned table "public.mpp6297" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------------+--------+-----------+----------+---------+---------+--------------+------------- + l_orderkey | bigint | | | | plain | | + l_commitdate | date | | | | plain | | +Partition key: RANGE (l_commitdate) +Partitions: mpp6297_1_prt_p1_1_1 FOR VALUES FROM ('01-31-1992') TO ('02-28-1993'), + mpp6297_1_prt_p1_2_1 FOR VALUES FROM ('02-28-1993') TO ('03-28-1994'), + mpp6297_1_prt_p1_2_2 FOR VALUES FROM ('03-28-1994') TO ('03-31-1994'), + mpp6297_1_prt_p1_3_1 FOR VALUES FROM ('03-31-1994') TO ('04-30-1995') +Distributed by: (l_orderkey) + +drop table mpp6297; +-- when WITH(tablename=...) is specified, the EVERY is stored as an +-- attribute, but not expanded into additional partitions +CREATE TABLE mpp6297 ( l_orderkey bigint, +l_commitdate date +) +distributed BY (l_orderkey) PARTITION BY RANGE(l_commitdate) +( +PARTITION p1_1 START ('1992-01-31'::date) END ('1993-02-28'::date) +EVERY ('1 year 1 mon'::interval) +WITH (tablename='mpp6297_1_prt_p1_1'), +PARTITION p1_2 START ('1993-02-28'::date) END ('1994-03-31'::date) +EVERY ('1 year 1 mon'::interval) +WITH (tablename='mpp6297_1_prt_p1_2'), +PARTITION p1_3 START ('1994-03-31'::date) END ('1995-04-30'::date) +EVERY ('1 year 1 mon'::interval) +WITH (tablename='mpp6297_1_prt_p1_3') +); +\d+ mpp6297 + Partitioned table "public.mpp6297" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------------+--------+-----------+----------+---------+---------+--------------+------------- + l_orderkey | bigint | | | | plain | | + l_commitdate | date | | | | plain | | +Partition key: RANGE (l_commitdate) +Partitions: mpp6297_1_prt_p1_1 FOR VALUES FROM ('01-31-1992') TO ('02-28-1993'), + mpp6297_1_prt_p1_2 FOR VALUES FROM ('02-28-1993') TO ('03-31-1994'), + mpp6297_1_prt_p1_3 FOR VALUES FROM ('03-31-1994') TO ('04-30-1995') +Distributed by: (l_orderkey) + +drop table mpp6297; +-- more with basic cases +create table mpp6297 +(a int, +b int) +partition by range (b) +( +start (1) end (10) every (1), +end (11) +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +\d+ mpp6297 + Partitioned table "public.mpp6297" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + a | integer | | | | plain | | + b | integer | | | | plain | | +Partition key: RANGE (b) +Partitions: mpp6297_1_prt_1 FOR VALUES FROM (1) TO (2), + mpp6297_1_prt_10 FOR VALUES FROM (10) TO (11), + mpp6297_1_prt_2 FOR VALUES FROM (2) TO (3), + mpp6297_1_prt_3 FOR VALUES FROM (3) TO (4), + mpp6297_1_prt_4 FOR VALUES FROM (4) TO (5), + mpp6297_1_prt_5 FOR VALUES FROM (5) TO (6), + mpp6297_1_prt_6 FOR VALUES FROM (6) TO (7), + mpp6297_1_prt_7 FOR VALUES FROM (7) TO (8), + mpp6297_1_prt_8 FOR VALUES FROM (8) TO (9), + mpp6297_1_prt_9 FOR VALUES FROM (9) TO (10) +Distributed by: (a) + +alter table mpp6297 drop partition for (3); +\d+ mpp6297 + Partitioned table "public.mpp6297" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + a | integer | | | | plain | | + b | integer | | | | plain | | +Partition key: RANGE (b) +Partitions: mpp6297_1_prt_1 FOR VALUES FROM (1) TO (2), + mpp6297_1_prt_10 FOR VALUES FROM (10) TO (11), + mpp6297_1_prt_2 FOR VALUES FROM (2) TO (3), + mpp6297_1_prt_4 FOR VALUES FROM (4) TO (5), + mpp6297_1_prt_5 FOR VALUES FROM (5) TO (6), + mpp6297_1_prt_6 FOR VALUES FROM (6) TO (7), + mpp6297_1_prt_7 FOR VALUES FROM (7) TO (8), + mpp6297_1_prt_8 FOR VALUES FROM (8) TO (9), + mpp6297_1_prt_9 FOR VALUES FROM (9) TO (10) +Distributed by: (a) + +-- this isn't legal (but it would be nice) +alter table mpp6297 add partition start (3) end (4) every (1); +ERROR: syntax error at or near "every" +LINE 1: ...ter table mpp6297 add partition start (3) end (4) every (1); + ^ +-- this is legal but it doesn't fix the EVERY clause +alter table mpp6297 add partition start (3) end (4) ; +\d+ mpp6297 + Partitioned table "public.mpp6297" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + a | integer | | | | plain | | + b | integer | | | | plain | | +Partition key: RANGE (b) +Partitions: mpp6297_1_prt_1 FOR VALUES FROM (1) TO (2), + mpp6297_1_prt_10 FOR VALUES FROM (10) TO (11), + mpp6297_1_prt_11 FOR VALUES FROM (3) TO (4), + mpp6297_1_prt_2 FOR VALUES FROM (2) TO (3), + mpp6297_1_prt_4 FOR VALUES FROM (4) TO (5), + mpp6297_1_prt_5 FOR VALUES FROM (5) TO (6), + mpp6297_1_prt_6 FOR VALUES FROM (6) TO (7), + mpp6297_1_prt_7 FOR VALUES FROM (7) TO (8), + mpp6297_1_prt_8 FOR VALUES FROM (8) TO (9), + mpp6297_1_prt_9 FOR VALUES FROM (9) TO (10) +Distributed by: (a) + +drop table mpp6297; +-- similarly, we can merge adjacent EVERY clauses if they match +create table mpp6297 +(a int, +b int) +partition by range (b) +( +start (1) end (5) every (1), +start (5) end (10) every (1) +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +\d+ mpp6297 + Partitioned table "public.mpp6297" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + a | integer | | | | plain | | + b | integer | | | | plain | | +Partition key: RANGE (b) +Partitions: mpp6297_1_prt_1 FOR VALUES FROM (1) TO (2), + mpp6297_1_prt_2 FOR VALUES FROM (2) TO (3), + mpp6297_1_prt_3 FOR VALUES FROM (3) TO (4), + mpp6297_1_prt_4 FOR VALUES FROM (4) TO (5), + mpp6297_1_prt_5 FOR VALUES FROM (5) TO (6), + mpp6297_1_prt_6 FOR VALUES FROM (6) TO (7), + mpp6297_1_prt_7 FOR VALUES FROM (7) TO (8), + mpp6297_1_prt_8 FOR VALUES FROM (8) TO (9), + mpp6297_1_prt_9 FOR VALUES FROM (9) TO (10) +Distributed by: (a) + +drop table mpp6297; +-- we cannot merge adjacent EVERY clauses if inclusivity/exclusivity is wrong +create table mpp6297 +(a int, +b int) +partition by range (b) +( +start (1) end (5) every (1), +start (5) exclusive end (10) every (1) +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +\d+ mpp6297 + Partitioned table "public.mpp6297" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + a | integer | | | | plain | | + b | integer | | | | plain | | +Partition key: RANGE (b) +Partitions: mpp6297_1_prt_1 FOR VALUES FROM (1) TO (2), + mpp6297_1_prt_2 FOR VALUES FROM (2) TO (3), + mpp6297_1_prt_3 FOR VALUES FROM (3) TO (4), + mpp6297_1_prt_4 FOR VALUES FROM (4) TO (5), + mpp6297_1_prt_5 FOR VALUES FROM (6) TO (7), + mpp6297_1_prt_6 FOR VALUES FROM (7) TO (8), + mpp6297_1_prt_7 FOR VALUES FROM (8) TO (9), + mpp6297_1_prt_8 FOR VALUES FROM (9) TO (10) +Distributed by: (a) + +drop table mpp6297; +-- more fun with inclusivity/exclusivity (normal case) +create table mpp6297 +(a int, +b int) +partition by range (b) +( +start (1) inclusive end (10) exclusive every (1) +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +\d+ mpp6297 + Partitioned table "public.mpp6297" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + a | integer | | | | plain | | + b | integer | | | | plain | | +Partition key: RANGE (b) +Partitions: mpp6297_1_prt_1 FOR VALUES FROM (1) TO (2), + mpp6297_1_prt_2 FOR VALUES FROM (2) TO (3), + mpp6297_1_prt_3 FOR VALUES FROM (3) TO (4), + mpp6297_1_prt_4 FOR VALUES FROM (4) TO (5), + mpp6297_1_prt_5 FOR VALUES FROM (5) TO (6), + mpp6297_1_prt_6 FOR VALUES FROM (6) TO (7), + mpp6297_1_prt_7 FOR VALUES FROM (7) TO (8), + mpp6297_1_prt_8 FOR VALUES FROM (8) TO (9), + mpp6297_1_prt_9 FOR VALUES FROM (9) TO (10) +Distributed by: (a) + +drop table mpp6297; +-- more fun with inclusivity/exclusivity (abnormal case) +create table mpp6297 +(a int, +b int) +partition by range (b) +( +start (1) exclusive end (10) inclusive every (1) +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +\d+ mpp6297 + Partitioned table "public.mpp6297" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + a | integer | | | | plain | | + b | integer | | | | plain | | +Partition key: RANGE (b) +Partitions: mpp6297_1_prt_1 FOR VALUES FROM (2) TO (3), + mpp6297_1_prt_2 FOR VALUES FROM (3) TO (4), + mpp6297_1_prt_3 FOR VALUES FROM (4) TO (5), + mpp6297_1_prt_4 FOR VALUES FROM (5) TO (6), + mpp6297_1_prt_5 FOR VALUES FROM (6) TO (7), + mpp6297_1_prt_6 FOR VALUES FROM (7) TO (8), + mpp6297_1_prt_7 FOR VALUES FROM (8) TO (9), + mpp6297_1_prt_8 FOR VALUES FROM (9) TO (10), + mpp6297_1_prt_9 FOR VALUES FROM (10) TO (11) +Distributed by: (a) + +alter table mpp6297 drop partition for (3); +\d+ mpp6297 + Partitioned table "public.mpp6297" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + a | integer | | | | plain | | + b | integer | | | | plain | | +Partition key: RANGE (b) +Partitions: mpp6297_1_prt_1 FOR VALUES FROM (2) TO (3), + mpp6297_1_prt_3 FOR VALUES FROM (4) TO (5), + mpp6297_1_prt_4 FOR VALUES FROM (5) TO (6), + mpp6297_1_prt_5 FOR VALUES FROM (6) TO (7), + mpp6297_1_prt_6 FOR VALUES FROM (7) TO (8), + mpp6297_1_prt_7 FOR VALUES FROM (8) TO (9), + mpp6297_1_prt_8 FOR VALUES FROM (9) TO (10), + mpp6297_1_prt_9 FOR VALUES FROM (10) TO (11) +Distributed by: (a) + +drop table mpp6297; +-- we cannot merge adjacent EVERY clauses, even though the +-- inclusivity/exclusivity matches, because it is different from the +-- normal start inclusive/end exclusive +create table mpp6297 +(a int, +b int) +partition by range (b) +( +start (1) end (5) inclusive every (1), +start (5) exclusive end (10) every (1) +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +\d+ mpp6297 + Partitioned table "public.mpp6297" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + a | integer | | | | plain | | + b | integer | | | | plain | | +Partition key: RANGE (b) +Partitions: mpp6297_1_prt_1 FOR VALUES FROM (1) TO (2), + mpp6297_1_prt_2 FOR VALUES FROM (2) TO (3), + mpp6297_1_prt_3 FOR VALUES FROM (3) TO (4), + mpp6297_1_prt_4 FOR VALUES FROM (4) TO (5), + mpp6297_1_prt_5 FOR VALUES FROM (5) TO (6), + mpp6297_1_prt_6 FOR VALUES FROM (6) TO (7), + mpp6297_1_prt_7 FOR VALUES FROM (7) TO (8), + mpp6297_1_prt_8 FOR VALUES FROM (8) TO (9), + mpp6297_1_prt_9 FOR VALUES FROM (9) TO (10) +Distributed by: (a) + +drop table mpp6297; +-- MPP-6589: SPLITting an "open" ended partition (ie, no start or end) +CREATE TABLE mpp6589a +( + id bigint, + day_dt date +) +DISTRIBUTED BY (id) +PARTITION BY RANGE(day_dt) + ( + PARTITION p20090312 END ('2009-03-12'::date) + ); +select relname, pg_get_expr(relpartbound, oid, false) from pg_class where relname like 'mpp6589a%'; + relname | pg_get_expr +--------------------------+---------------------------------------------- + mpp6589a | + mpp6589a_1_prt_p20090312 | FOR VALUES FROM (MINVALUE) TO ('03-12-2009') +(2 rows) + +-- should work +ALTER TABLE mpp6589a +SPLIT PARTITION p20090312 AT( '20090310' ) +INTO( PARTITION p20090309, PARTITION p20090312_tmp); +select relname, pg_get_expr(relpartbound, oid, false) from pg_class where relname like 'mpp6589a%'; + relname | pg_get_expr +------------------------------+-------------------------------------------------- + mpp6589a | + mpp6589a_1_prt_p20090309 | FOR VALUES FROM (MINVALUE) TO ('03-10-2009') + mpp6589a_1_prt_p20090312_tmp | FOR VALUES FROM ('03-10-2009') TO ('03-12-2009') +(3 rows) + +CREATE TABLE mpp6589i(a int, b int) +partition by range (b) (start (1) end (3)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +select relname, pg_get_expr(relpartbound, oid, false) from pg_class where relname like 'mpp6589i%'; + relname | pg_get_expr +------------------+---------------------------- + mpp6589i | + mpp6589i_1_prt_1 | FOR VALUES FROM (1) TO (3) +(2 rows) + +-- should fail (overlap) +ALTER TABLE mpp6589i ADD PARTITION start (2); +ERROR: partition "mpp6589i_1_prt_11" would overlap partition "mpp6589i_1_prt_1" +-- should work (there's a "point" hole at value 2) +ALTER TABLE mpp6589i ADD PARTITION start (3) exclusive; +select relname, pg_get_expr(relpartbound, oid, false) from pg_class where relname like 'mpp6589i%'; + relname | pg_get_expr +-------------------+----------------------------------- + mpp6589i | + mpp6589i_1_prt_1 | FOR VALUES FROM (1) TO (3) + mpp6589i_1_prt_11 | FOR VALUES FROM (4) TO (MAXVALUE) +(3 rows) + +-- test open-ended SPLIT +CREATE TABLE mpp6589b +( + id bigint, + day_dt date +) +DISTRIBUTED BY (id) +PARTITION BY RANGE(day_dt) + ( + PARTITION p20090312 START ('2008-03-12'::date) + ); +select relname, pg_get_expr(relpartbound, oid, false) from pg_class where relname like 'mpp6589b%'; + relname | pg_get_expr +--------------------------+---------------------------------------------- + mpp6589b | + mpp6589b_1_prt_p20090312 | FOR VALUES FROM ('03-12-2008') TO (MAXVALUE) +(2 rows) + +-- should work +ALTER TABLE mpp6589b +SPLIT PARTITION p20090312 AT( '20090310' ) +INTO( PARTITION p20090309, PARTITION p20090312_tmp); +select relname, pg_get_expr(relpartbound, oid, false) from pg_class where relname like 'mpp6589b%'; + relname | pg_get_expr +------------------------------+-------------------------------------------------- + mpp6589b | + mpp6589b_1_prt_p20090309 | FOR VALUES FROM ('03-12-2008') TO ('03-10-2009') + mpp6589b_1_prt_p20090312_tmp | FOR VALUES FROM ('03-10-2009') TO (MAXVALUE) +(3 rows) + +-- MPP-7191, MPP-7193: partitioned tables - fully-qualify storage type +-- if not specified (and not a template) +CREATE TABLE mpp5992 (a int, b date, c char, + d char(4), e varchar(20), f timestamp) +WITH (orientation=column,appendonly=true) +partition by range (b) +subpartition by list (a) +subpartition template ( +subpartition l1 values (1,2,3,4,5), +subpartition l2 values (6,7,8,9,10) ) +subpartition by list (e) +subpartition template ( +subpartition ll1 values ('Engineering'), +subpartition ll2 values ('QA') ) +subpartition by list (c) +subpartition template ( +subpartition lll1 values ('M'), +subpartition lll2 values ('F') ) +( + start (date '2007-01-01') + end (date '2010-01-01') every (interval '1 year') +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +-- Delete subpartition template +alter table mpp5992 alter partition for ('2008-01-01') +set subpartition template (); +alter table mpp5992 alter partition for ('2008-01-01') +alter partition for (1) +set subpartition template (); +alter table mpp5992 set subpartition template (); +-- Add subpartition template +alter table mpp5992 alter partition for ('2008-01-01') +alter partition for (1) +set subpartition template ( subpartition lll1 values ('M'), +subpartition lll2 values ('F')); +alter table mpp5992 alter partition for ('2008-01-01') +set subpartition template ( +subpartition ll1 values ('Engineering'), +subpartition ll2 values ('QA') +); +alter table mpp5992 +set subpartition template (subpartition l1 values (1,2,3,4,5), +subpartition l2 values (6,7,8,9,10) ); +alter table mpp5992 +set subpartition template (subpartition l1 values (1,2,3), +subpartition l2 values (4,5,6), subpartition l3 values (7,8,9,10)); +select relid::regclass, level, template from gp_partition_template where relid = 'mpp5992'::regclass; + relid | level | template +---------+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + mpp5992 | 3 | {GPPARTITIONDEFINITION :partDefElems ({GPPARTDEFELEM :partName lll1 :boundSpec {GPPARTITIONLISTSPEC :partValues (({A_CONST :val "M" :location 133}))} :subSpec <> :isDefault false :options <> :accessMethod <> :tablespacename <> :colencs <>} {GPPARTDEFELEM :partName lll2 :boundSpec {GPPARTITIONLISTSPEC :partValues (({A_CONST :val "F" :location 165}))} :subSpec <> :isDefault false :options <> :accessMethod <> :tablespacename <> :colencs <>}) :encClauses <> :isTemplate true} + mpp5992 | 2 | {GPPARTITIONDEFINITION :partDefElems ({GPPARTDEFELEM :partName ll1 :boundSpec {GPPARTITIONLISTSPEC :partValues (({A_CONST :val "Engineering" :location 108}))} :subSpec <> :isDefault false :options <> :accessMethod <> :tablespacename <> :colencs <>} {GPPARTDEFELEM :partName ll2 :boundSpec {GPPARTITIONLISTSPEC :partValues (({A_CONST :val "QA" :location 149}))} :subSpec <> :isDefault false :options <> :accessMethod <> :tablespacename <> :colencs <>}) :encClauses <> :isTemplate true} + mpp5992 | 1 | {GPPARTITIONDEFINITION :partDefElems ({GPPARTDEFELEM :partName l1 :boundSpec {GPPARTITIONLISTSPEC :partValues (({A_CONST :val 1 :location 72}) ({A_CONST :val 2 :location 74}) ({A_CONST :val 3 :location 76}))} :subSpec <> :isDefault false :options <> :accessMethod <> :tablespacename <> :colencs <>} {GPPARTDEFELEM :partName l2 :boundSpec {GPPARTITIONLISTSPEC :partValues (({A_CONST :val 4 :location 105}) ({A_CONST :val 5 :location 107}) ({A_CONST :val 6 :location 109}))} :subSpec <> :isDefault false :options <> :accessMethod <> :tablespacename <> :colencs <>} {GPPARTDEFELEM :partName l3 :boundSpec {GPPARTITIONLISTSPEC :partValues (({A_CONST :val 7 :location 137}) ({A_CONST :val 8 :location 139}) ({A_CONST :val 9 :location 141}) ({A_CONST :val 10 :location 143}))} :subSpec <> :isDefault false :options <> :accessMethod <> :tablespacename <> :colencs <>}) :encClauses <> :isTemplate true} +(3 rows) + +-- Now we can add a new partition +alter table mpp5992 +add partition foo1 +start (date '2011-01-01') +end (date '2012-01-01'); -- should inherit from parent storage option +alter table mpp5992 +add partition foo2 +start (date '2012-01-01') +end (date '2013-01-01') WITH (orientation=column,appendonly=true); +alter table mpp5992 +add partition foo3 +start (date '2013-01-01') end (date '2014-01-01') WITH (appendonly=true); +select * from pg_partition_tree('mpp5992'); + relid | parentrelid | isleaf | level +--------------------------------------------------+---------------------------------------+--------+------- + mpp5992 | | f | 0 + mpp5992_1_prt_1 | mpp5992 | f | 1 + mpp5992_1_prt_2 | mpp5992 | f | 1 + mpp5992_1_prt_3 | mpp5992 | f | 1 + mpp5992_1_prt_foo1 | mpp5992 | f | 1 + mpp5992_1_prt_foo2 | mpp5992 | f | 1 + mpp5992_1_prt_foo3 | mpp5992 | f | 1 + mpp5992_1_prt_1_2_prt_l1 | mpp5992_1_prt_1 | f | 2 + mpp5992_1_prt_1_2_prt_l2 | mpp5992_1_prt_1 | f | 2 + mpp5992_1_prt_2_2_prt_l1 | mpp5992_1_prt_2 | f | 2 + mpp5992_1_prt_2_2_prt_l2 | mpp5992_1_prt_2 | f | 2 + mpp5992_1_prt_3_2_prt_l1 | mpp5992_1_prt_3 | f | 2 + mpp5992_1_prt_3_2_prt_l2 | mpp5992_1_prt_3 | f | 2 + mpp5992_1_prt_foo1_2_prt_l1 | mpp5992_1_prt_foo1 | f | 2 + mpp5992_1_prt_foo1_2_prt_l2 | mpp5992_1_prt_foo1 | f | 2 + mpp5992_1_prt_foo1_2_prt_l3 | mpp5992_1_prt_foo1 | f | 2 + mpp5992_1_prt_foo2_2_prt_l1 | mpp5992_1_prt_foo2 | f | 2 + mpp5992_1_prt_foo2_2_prt_l2 | mpp5992_1_prt_foo2 | f | 2 + mpp5992_1_prt_foo2_2_prt_l3 | mpp5992_1_prt_foo2 | f | 2 + mpp5992_1_prt_foo3_2_prt_l1 | mpp5992_1_prt_foo3 | f | 2 + mpp5992_1_prt_foo3_2_prt_l2 | mpp5992_1_prt_foo3 | f | 2 + mpp5992_1_prt_foo3_2_prt_l3 | mpp5992_1_prt_foo3 | f | 2 + mpp5992_1_prt_1_2_prt_l1_3_prt_ll1 | mpp5992_1_prt_1_2_prt_l1 | f | 3 + mpp5992_1_prt_1_2_prt_l1_3_prt_ll2 | mpp5992_1_prt_1_2_prt_l1 | f | 3 + mpp5992_1_prt_1_2_prt_l2_3_prt_ll1 | mpp5992_1_prt_1_2_prt_l2 | f | 3 + mpp5992_1_prt_1_2_prt_l2_3_prt_ll2 | mpp5992_1_prt_1_2_prt_l2 | f | 3 + mpp5992_1_prt_2_2_prt_l1_3_prt_ll1 | mpp5992_1_prt_2_2_prt_l1 | f | 3 + mpp5992_1_prt_2_2_prt_l1_3_prt_ll2 | mpp5992_1_prt_2_2_prt_l1 | f | 3 + mpp5992_1_prt_2_2_prt_l2_3_prt_ll1 | mpp5992_1_prt_2_2_prt_l2 | f | 3 + mpp5992_1_prt_2_2_prt_l2_3_prt_ll2 | mpp5992_1_prt_2_2_prt_l2 | f | 3 + mpp5992_1_prt_3_2_prt_l1_3_prt_ll1 | mpp5992_1_prt_3_2_prt_l1 | f | 3 + mpp5992_1_prt_3_2_prt_l1_3_prt_ll2 | mpp5992_1_prt_3_2_prt_l1 | f | 3 + mpp5992_1_prt_3_2_prt_l2_3_prt_ll1 | mpp5992_1_prt_3_2_prt_l2 | f | 3 + mpp5992_1_prt_3_2_prt_l2_3_prt_ll2 | mpp5992_1_prt_3_2_prt_l2 | f | 3 + mpp5992_1_prt_foo1_2_prt_l1_3_prt_ll1 | mpp5992_1_prt_foo1_2_prt_l1 | f | 3 + mpp5992_1_prt_foo1_2_prt_l1_3_prt_ll2 | mpp5992_1_prt_foo1_2_prt_l1 | f | 3 + mpp5992_1_prt_foo1_2_prt_l2_3_prt_ll1 | mpp5992_1_prt_foo1_2_prt_l2 | f | 3 + mpp5992_1_prt_foo1_2_prt_l2_3_prt_ll2 | mpp5992_1_prt_foo1_2_prt_l2 | f | 3 + mpp5992_1_prt_foo1_2_prt_l3_3_prt_ll1 | mpp5992_1_prt_foo1_2_prt_l3 | f | 3 + mpp5992_1_prt_foo1_2_prt_l3_3_prt_ll2 | mpp5992_1_prt_foo1_2_prt_l3 | f | 3 + mpp5992_1_prt_foo2_2_prt_l1_3_prt_ll1 | mpp5992_1_prt_foo2_2_prt_l1 | f | 3 + mpp5992_1_prt_foo2_2_prt_l1_3_prt_ll2 | mpp5992_1_prt_foo2_2_prt_l1 | f | 3 + mpp5992_1_prt_foo2_2_prt_l2_3_prt_ll1 | mpp5992_1_prt_foo2_2_prt_l2 | f | 3 + mpp5992_1_prt_foo2_2_prt_l2_3_prt_ll2 | mpp5992_1_prt_foo2_2_prt_l2 | f | 3 + mpp5992_1_prt_foo2_2_prt_l3_3_prt_ll1 | mpp5992_1_prt_foo2_2_prt_l3 | f | 3 + mpp5992_1_prt_foo2_2_prt_l3_3_prt_ll2 | mpp5992_1_prt_foo2_2_prt_l3 | f | 3 + mpp5992_1_prt_foo3_2_prt_l1_3_prt_ll1 | mpp5992_1_prt_foo3_2_prt_l1 | f | 3 + mpp5992_1_prt_foo3_2_prt_l1_3_prt_ll2 | mpp5992_1_prt_foo3_2_prt_l1 | f | 3 + mpp5992_1_prt_foo3_2_prt_l2_3_prt_ll1 | mpp5992_1_prt_foo3_2_prt_l2 | f | 3 + mpp5992_1_prt_foo3_2_prt_l2_3_prt_ll2 | mpp5992_1_prt_foo3_2_prt_l2 | f | 3 + mpp5992_1_prt_foo3_2_prt_l3_3_prt_ll1 | mpp5992_1_prt_foo3_2_prt_l3 | f | 3 + mpp5992_1_prt_foo3_2_prt_l3_3_prt_ll2 | mpp5992_1_prt_foo3_2_prt_l3 | f | 3 + mpp5992_1_prt_1_2_prt_l1_3_prt_ll1_4_prt_lll1 | mpp5992_1_prt_1_2_prt_l1_3_prt_ll1 | t | 4 + mpp5992_1_prt_1_2_prt_l1_3_prt_ll1_4_prt_lll2 | mpp5992_1_prt_1_2_prt_l1_3_prt_ll1 | t | 4 + mpp5992_1_prt_1_2_prt_l1_3_prt_ll2_4_prt_lll1 | mpp5992_1_prt_1_2_prt_l1_3_prt_ll2 | t | 4 + mpp5992_1_prt_1_2_prt_l1_3_prt_ll2_4_prt_lll2 | mpp5992_1_prt_1_2_prt_l1_3_prt_ll2 | t | 4 + mpp5992_1_prt_1_2_prt_l2_3_prt_ll1_4_prt_lll1 | mpp5992_1_prt_1_2_prt_l2_3_prt_ll1 | t | 4 + mpp5992_1_prt_1_2_prt_l2_3_prt_ll1_4_prt_lll2 | mpp5992_1_prt_1_2_prt_l2_3_prt_ll1 | t | 4 + mpp5992_1_prt_1_2_prt_l2_3_prt_ll2_4_prt_lll1 | mpp5992_1_prt_1_2_prt_l2_3_prt_ll2 | t | 4 + mpp5992_1_prt_1_2_prt_l2_3_prt_ll2_4_prt_lll2 | mpp5992_1_prt_1_2_prt_l2_3_prt_ll2 | t | 4 + mpp5992_1_prt_2_2_prt_l1_3_prt_ll1_4_prt_lll1 | mpp5992_1_prt_2_2_prt_l1_3_prt_ll1 | t | 4 + mpp5992_1_prt_2_2_prt_l1_3_prt_ll1_4_prt_lll2 | mpp5992_1_prt_2_2_prt_l1_3_prt_ll1 | t | 4 + mpp5992_1_prt_2_2_prt_l1_3_prt_ll2_4_prt_lll1 | mpp5992_1_prt_2_2_prt_l1_3_prt_ll2 | t | 4 + mpp5992_1_prt_2_2_prt_l1_3_prt_ll2_4_prt_lll2 | mpp5992_1_prt_2_2_prt_l1_3_prt_ll2 | t | 4 + mpp5992_1_prt_2_2_prt_l2_3_prt_ll1_4_prt_lll1 | mpp5992_1_prt_2_2_prt_l2_3_prt_ll1 | t | 4 + mpp5992_1_prt_2_2_prt_l2_3_prt_ll1_4_prt_lll2 | mpp5992_1_prt_2_2_prt_l2_3_prt_ll1 | t | 4 + mpp5992_1_prt_2_2_prt_l2_3_prt_ll2_4_prt_lll1 | mpp5992_1_prt_2_2_prt_l2_3_prt_ll2 | t | 4 + mpp5992_1_prt_2_2_prt_l2_3_prt_ll2_4_prt_lll2 | mpp5992_1_prt_2_2_prt_l2_3_prt_ll2 | t | 4 + mpp5992_1_prt_3_2_prt_l1_3_prt_ll1_4_prt_lll1 | mpp5992_1_prt_3_2_prt_l1_3_prt_ll1 | t | 4 + mpp5992_1_prt_3_2_prt_l1_3_prt_ll1_4_prt_lll2 | mpp5992_1_prt_3_2_prt_l1_3_prt_ll1 | t | 4 + mpp5992_1_prt_3_2_prt_l1_3_prt_ll2_4_prt_lll1 | mpp5992_1_prt_3_2_prt_l1_3_prt_ll2 | t | 4 + mpp5992_1_prt_3_2_prt_l1_3_prt_ll2_4_prt_lll2 | mpp5992_1_prt_3_2_prt_l1_3_prt_ll2 | t | 4 + mpp5992_1_prt_3_2_prt_l2_3_prt_ll1_4_prt_lll1 | mpp5992_1_prt_3_2_prt_l2_3_prt_ll1 | t | 4 + mpp5992_1_prt_3_2_prt_l2_3_prt_ll1_4_prt_lll2 | mpp5992_1_prt_3_2_prt_l2_3_prt_ll1 | t | 4 + mpp5992_1_prt_3_2_prt_l2_3_prt_ll2_4_prt_lll1 | mpp5992_1_prt_3_2_prt_l2_3_prt_ll2 | t | 4 + mpp5992_1_prt_3_2_prt_l2_3_prt_ll2_4_prt_lll2 | mpp5992_1_prt_3_2_prt_l2_3_prt_ll2 | t | 4 + mpp5992_1_prt_foo1_2_prt_l1_3_prt_ll1_4_prt_lll1 | mpp5992_1_prt_foo1_2_prt_l1_3_prt_ll1 | t | 4 + mpp5992_1_prt_foo1_2_prt_l1_3_prt_ll1_4_prt_lll2 | mpp5992_1_prt_foo1_2_prt_l1_3_prt_ll1 | t | 4 + mpp5992_1_prt_foo1_2_prt_l1_3_prt_ll2_4_prt_lll1 | mpp5992_1_prt_foo1_2_prt_l1_3_prt_ll2 | t | 4 + mpp5992_1_prt_foo1_2_prt_l1_3_prt_ll2_4_prt_lll2 | mpp5992_1_prt_foo1_2_prt_l1_3_prt_ll2 | t | 4 + mpp5992_1_prt_foo1_2_prt_l2_3_prt_ll1_4_prt_lll1 | mpp5992_1_prt_foo1_2_prt_l2_3_prt_ll1 | t | 4 + mpp5992_1_prt_foo1_2_prt_l2_3_prt_ll1_4_prt_lll2 | mpp5992_1_prt_foo1_2_prt_l2_3_prt_ll1 | t | 4 + mpp5992_1_prt_foo1_2_prt_l2_3_prt_ll2_4_prt_lll1 | mpp5992_1_prt_foo1_2_prt_l2_3_prt_ll2 | t | 4 + mpp5992_1_prt_foo1_2_prt_l2_3_prt_ll2_4_prt_lll2 | mpp5992_1_prt_foo1_2_prt_l2_3_prt_ll2 | t | 4 + mpp5992_1_prt_foo1_2_prt_l3_3_prt_ll1_4_prt_lll1 | mpp5992_1_prt_foo1_2_prt_l3_3_prt_ll1 | t | 4 + mpp5992_1_prt_foo1_2_prt_l3_3_prt_ll1_4_prt_lll2 | mpp5992_1_prt_foo1_2_prt_l3_3_prt_ll1 | t | 4 + mpp5992_1_prt_foo1_2_prt_l3_3_prt_ll2_4_prt_lll1 | mpp5992_1_prt_foo1_2_prt_l3_3_prt_ll2 | t | 4 + mpp5992_1_prt_foo1_2_prt_l3_3_prt_ll2_4_prt_lll2 | mpp5992_1_prt_foo1_2_prt_l3_3_prt_ll2 | t | 4 + mpp5992_1_prt_foo2_2_prt_l1_3_prt_ll1_4_prt_lll1 | mpp5992_1_prt_foo2_2_prt_l1_3_prt_ll1 | t | 4 + mpp5992_1_prt_foo2_2_prt_l1_3_prt_ll1_4_prt_lll2 | mpp5992_1_prt_foo2_2_prt_l1_3_prt_ll1 | t | 4 + mpp5992_1_prt_foo2_2_prt_l1_3_prt_ll2_4_prt_lll1 | mpp5992_1_prt_foo2_2_prt_l1_3_prt_ll2 | t | 4 + mpp5992_1_prt_foo2_2_prt_l1_3_prt_ll2_4_prt_lll2 | mpp5992_1_prt_foo2_2_prt_l1_3_prt_ll2 | t | 4 + mpp5992_1_prt_foo2_2_prt_l2_3_prt_ll1_4_prt_lll1 | mpp5992_1_prt_foo2_2_prt_l2_3_prt_ll1 | t | 4 + mpp5992_1_prt_foo2_2_prt_l2_3_prt_ll1_4_prt_lll2 | mpp5992_1_prt_foo2_2_prt_l2_3_prt_ll1 | t | 4 + mpp5992_1_prt_foo2_2_prt_l2_3_prt_ll2_4_prt_lll1 | mpp5992_1_prt_foo2_2_prt_l2_3_prt_ll2 | t | 4 + mpp5992_1_prt_foo2_2_prt_l2_3_prt_ll2_4_prt_lll2 | mpp5992_1_prt_foo2_2_prt_l2_3_prt_ll2 | t | 4 + mpp5992_1_prt_foo2_2_prt_l3_3_prt_ll1_4_prt_lll1 | mpp5992_1_prt_foo2_2_prt_l3_3_prt_ll1 | t | 4 + mpp5992_1_prt_foo2_2_prt_l3_3_prt_ll1_4_prt_lll2 | mpp5992_1_prt_foo2_2_prt_l3_3_prt_ll1 | t | 4 + mpp5992_1_prt_foo2_2_prt_l3_3_prt_ll2_4_prt_lll1 | mpp5992_1_prt_foo2_2_prt_l3_3_prt_ll2 | t | 4 + mpp5992_1_prt_foo2_2_prt_l3_3_prt_ll2_4_prt_lll2 | mpp5992_1_prt_foo2_2_prt_l3_3_prt_ll2 | t | 4 + mpp5992_1_prt_foo3_2_prt_l1_3_prt_ll1_4_prt_lll1 | mpp5992_1_prt_foo3_2_prt_l1_3_prt_ll1 | t | 4 + mpp5992_1_prt_foo3_2_prt_l1_3_prt_ll1_4_prt_lll2 | mpp5992_1_prt_foo3_2_prt_l1_3_prt_ll1 | t | 4 + mpp5992_1_prt_foo3_2_prt_l1_3_prt_ll2_4_prt_lll1 | mpp5992_1_prt_foo3_2_prt_l1_3_prt_ll2 | t | 4 + mpp5992_1_prt_foo3_2_prt_l1_3_prt_ll2_4_prt_lll2 | mpp5992_1_prt_foo3_2_prt_l1_3_prt_ll2 | t | 4 + mpp5992_1_prt_foo3_2_prt_l2_3_prt_ll1_4_prt_lll1 | mpp5992_1_prt_foo3_2_prt_l2_3_prt_ll1 | t | 4 + mpp5992_1_prt_foo3_2_prt_l2_3_prt_ll1_4_prt_lll2 | mpp5992_1_prt_foo3_2_prt_l2_3_prt_ll1 | t | 4 + mpp5992_1_prt_foo3_2_prt_l2_3_prt_ll2_4_prt_lll1 | mpp5992_1_prt_foo3_2_prt_l2_3_prt_ll2 | t | 4 + mpp5992_1_prt_foo3_2_prt_l2_3_prt_ll2_4_prt_lll2 | mpp5992_1_prt_foo3_2_prt_l2_3_prt_ll2 | t | 4 + mpp5992_1_prt_foo3_2_prt_l3_3_prt_ll1_4_prt_lll1 | mpp5992_1_prt_foo3_2_prt_l3_3_prt_ll1 | t | 4 + mpp5992_1_prt_foo3_2_prt_l3_3_prt_ll1_4_prt_lll2 | mpp5992_1_prt_foo3_2_prt_l3_3_prt_ll1 | t | 4 + mpp5992_1_prt_foo3_2_prt_l3_3_prt_ll2_4_prt_lll1 | mpp5992_1_prt_foo3_2_prt_l3_3_prt_ll2 | t | 4 + mpp5992_1_prt_foo3_2_prt_l3_3_prt_ll2_4_prt_lll2 | mpp5992_1_prt_foo3_2_prt_l3_3_prt_ll2 | t | 4 +(112 rows) + +select relname, relam, pg_get_expr(relpartbound, oid) from pg_class where relname like 'mpp5992%'; + relname | relam | pg_get_expr +--------------------------------------------------+-------+-------------------------------------------------- + mpp5992 | 7166 | + mpp5992_1_prt_1 | 7166 | FOR VALUES FROM ('01-01-2007') TO ('01-01-2008') + mpp5992_1_prt_1_2_prt_l1 | 7166 | FOR VALUES IN (1, 2, 3, 4, 5) + mpp5992_1_prt_1_2_prt_l1_3_prt_ll1 | 7166 | FOR VALUES IN ('Engineering') + mpp5992_1_prt_1_2_prt_l1_3_prt_ll1_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_1_2_prt_l1_3_prt_ll1_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_1_2_prt_l1_3_prt_ll2 | 7166 | FOR VALUES IN ('QA') + mpp5992_1_prt_1_2_prt_l1_3_prt_ll2_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_1_2_prt_l1_3_prt_ll2_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_1_2_prt_l2 | 7166 | FOR VALUES IN (6, 7, 8, 9, 10) + mpp5992_1_prt_1_2_prt_l2_3_prt_ll1 | 7166 | FOR VALUES IN ('Engineering') + mpp5992_1_prt_1_2_prt_l2_3_prt_ll1_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_1_2_prt_l2_3_prt_ll1_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_1_2_prt_l2_3_prt_ll2 | 7166 | FOR VALUES IN ('QA') + mpp5992_1_prt_1_2_prt_l2_3_prt_ll2_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_1_2_prt_l2_3_prt_ll2_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_2 | 7166 | FOR VALUES FROM ('01-01-2008') TO ('01-01-2009') + mpp5992_1_prt_2_2_prt_l1 | 7166 | FOR VALUES IN (1, 2, 3, 4, 5) + mpp5992_1_prt_2_2_prt_l1_3_prt_ll1 | 7166 | FOR VALUES IN ('Engineering') + mpp5992_1_prt_2_2_prt_l1_3_prt_ll1_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_2_2_prt_l1_3_prt_ll1_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_2_2_prt_l1_3_prt_ll2 | 7166 | FOR VALUES IN ('QA') + mpp5992_1_prt_2_2_prt_l1_3_prt_ll2_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_2_2_prt_l1_3_prt_ll2_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_2_2_prt_l2 | 7166 | FOR VALUES IN (6, 7, 8, 9, 10) + mpp5992_1_prt_2_2_prt_l2_3_prt_ll1 | 7166 | FOR VALUES IN ('Engineering') + mpp5992_1_prt_2_2_prt_l2_3_prt_ll1_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_2_2_prt_l2_3_prt_ll1_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_2_2_prt_l2_3_prt_ll2 | 7166 | FOR VALUES IN ('QA') + mpp5992_1_prt_2_2_prt_l2_3_prt_ll2_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_2_2_prt_l2_3_prt_ll2_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_3 | 7166 | FOR VALUES FROM ('01-01-2009') TO ('01-01-2010') + mpp5992_1_prt_3_2_prt_l1 | 7166 | FOR VALUES IN (1, 2, 3, 4, 5) + mpp5992_1_prt_3_2_prt_l1_3_prt_ll1 | 7166 | FOR VALUES IN ('Engineering') + mpp5992_1_prt_3_2_prt_l1_3_prt_ll1_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_3_2_prt_l1_3_prt_ll1_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_3_2_prt_l1_3_prt_ll2 | 7166 | FOR VALUES IN ('QA') + mpp5992_1_prt_3_2_prt_l1_3_prt_ll2_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_3_2_prt_l1_3_prt_ll2_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_3_2_prt_l2 | 7166 | FOR VALUES IN (6, 7, 8, 9, 10) + mpp5992_1_prt_3_2_prt_l2_3_prt_ll1 | 7166 | FOR VALUES IN ('Engineering') + mpp5992_1_prt_3_2_prt_l2_3_prt_ll1_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_3_2_prt_l2_3_prt_ll1_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_3_2_prt_l2_3_prt_ll2 | 7166 | FOR VALUES IN ('QA') + mpp5992_1_prt_3_2_prt_l2_3_prt_ll2_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_3_2_prt_l2_3_prt_ll2_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_foo1 | 7166 | FOR VALUES FROM ('01-01-2011') TO ('01-01-2012') + mpp5992_1_prt_foo1_2_prt_l1 | 7166 | FOR VALUES IN (1, 2, 3) + mpp5992_1_prt_foo1_2_prt_l1_3_prt_ll1 | 7166 | FOR VALUES IN ('Engineering') + mpp5992_1_prt_foo1_2_prt_l1_3_prt_ll1_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_foo1_2_prt_l1_3_prt_ll1_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_foo1_2_prt_l1_3_prt_ll2 | 7166 | FOR VALUES IN ('QA') + mpp5992_1_prt_foo1_2_prt_l1_3_prt_ll2_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_foo1_2_prt_l1_3_prt_ll2_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_foo1_2_prt_l2 | 7166 | FOR VALUES IN (4, 5, 6) + mpp5992_1_prt_foo1_2_prt_l2_3_prt_ll1 | 7166 | FOR VALUES IN ('Engineering') + mpp5992_1_prt_foo1_2_prt_l2_3_prt_ll1_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_foo1_2_prt_l2_3_prt_ll1_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_foo1_2_prt_l2_3_prt_ll2 | 7166 | FOR VALUES IN ('QA') + mpp5992_1_prt_foo1_2_prt_l2_3_prt_ll2_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_foo1_2_prt_l2_3_prt_ll2_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_foo1_2_prt_l3 | 7166 | FOR VALUES IN (7, 8, 9, 10) + mpp5992_1_prt_foo1_2_prt_l3_3_prt_ll1 | 7166 | FOR VALUES IN ('Engineering') + mpp5992_1_prt_foo1_2_prt_l3_3_prt_ll1_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_foo1_2_prt_l3_3_prt_ll1_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_foo1_2_prt_l3_3_prt_ll2 | 7166 | FOR VALUES IN ('QA') + mpp5992_1_prt_foo1_2_prt_l3_3_prt_ll2_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_foo1_2_prt_l3_3_prt_ll2_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_foo2 | 7166 | FOR VALUES FROM ('01-01-2012') TO ('01-01-2013') + mpp5992_1_prt_foo2_2_prt_l1 | 7166 | FOR VALUES IN (1, 2, 3) + mpp5992_1_prt_foo2_2_prt_l1_3_prt_ll1 | 7166 | FOR VALUES IN ('Engineering') + mpp5992_1_prt_foo2_2_prt_l1_3_prt_ll1_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_foo2_2_prt_l1_3_prt_ll1_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_foo2_2_prt_l1_3_prt_ll2 | 7166 | FOR VALUES IN ('QA') + mpp5992_1_prt_foo2_2_prt_l1_3_prt_ll2_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_foo2_2_prt_l1_3_prt_ll2_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_foo2_2_prt_l2 | 7166 | FOR VALUES IN (4, 5, 6) + mpp5992_1_prt_foo2_2_prt_l2_3_prt_ll1 | 7166 | FOR VALUES IN ('Engineering') + mpp5992_1_prt_foo2_2_prt_l2_3_prt_ll1_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_foo2_2_prt_l2_3_prt_ll1_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_foo2_2_prt_l2_3_prt_ll2 | 7166 | FOR VALUES IN ('QA') + mpp5992_1_prt_foo2_2_prt_l2_3_prt_ll2_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_foo2_2_prt_l2_3_prt_ll2_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_foo2_2_prt_l3 | 7166 | FOR VALUES IN (7, 8, 9, 10) + mpp5992_1_prt_foo2_2_prt_l3_3_prt_ll1 | 7166 | FOR VALUES IN ('Engineering') + mpp5992_1_prt_foo2_2_prt_l3_3_prt_ll1_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_foo2_2_prt_l3_3_prt_ll1_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_foo2_2_prt_l3_3_prt_ll2 | 7166 | FOR VALUES IN ('QA') + mpp5992_1_prt_foo2_2_prt_l3_3_prt_ll2_4_prt_lll1 | 7166 | FOR VALUES IN ('M') + mpp5992_1_prt_foo2_2_prt_l3_3_prt_ll2_4_prt_lll2 | 7166 | FOR VALUES IN ('F') + mpp5992_1_prt_foo3 | 7024 | FOR VALUES FROM ('01-01-2013') TO ('01-01-2014') + mpp5992_1_prt_foo3_2_prt_l1 | 7024 | FOR VALUES IN (1, 2, 3) + mpp5992_1_prt_foo3_2_prt_l1_3_prt_ll1 | 7024 | FOR VALUES IN ('Engineering') + mpp5992_1_prt_foo3_2_prt_l1_3_prt_ll1_4_prt_lll1 | 7024 | FOR VALUES IN ('M') + mpp5992_1_prt_foo3_2_prt_l1_3_prt_ll1_4_prt_lll2 | 7024 | FOR VALUES IN ('F') + mpp5992_1_prt_foo3_2_prt_l1_3_prt_ll2 | 7024 | FOR VALUES IN ('QA') + mpp5992_1_prt_foo3_2_prt_l1_3_prt_ll2_4_prt_lll1 | 7024 | FOR VALUES IN ('M') + mpp5992_1_prt_foo3_2_prt_l1_3_prt_ll2_4_prt_lll2 | 7024 | FOR VALUES IN ('F') + mpp5992_1_prt_foo3_2_prt_l2 | 7024 | FOR VALUES IN (4, 5, 6) + mpp5992_1_prt_foo3_2_prt_l2_3_prt_ll1 | 7024 | FOR VALUES IN ('Engineering') + mpp5992_1_prt_foo3_2_prt_l2_3_prt_ll1_4_prt_lll1 | 7024 | FOR VALUES IN ('M') + mpp5992_1_prt_foo3_2_prt_l2_3_prt_ll1_4_prt_lll2 | 7024 | FOR VALUES IN ('F') + mpp5992_1_prt_foo3_2_prt_l2_3_prt_ll2 | 7024 | FOR VALUES IN ('QA') + mpp5992_1_prt_foo3_2_prt_l2_3_prt_ll2_4_prt_lll1 | 7024 | FOR VALUES IN ('M') + mpp5992_1_prt_foo3_2_prt_l2_3_prt_ll2_4_prt_lll2 | 7024 | FOR VALUES IN ('F') + mpp5992_1_prt_foo3_2_prt_l3 | 7024 | FOR VALUES IN (7, 8, 9, 10) + mpp5992_1_prt_foo3_2_prt_l3_3_prt_ll1 | 7024 | FOR VALUES IN ('Engineering') + mpp5992_1_prt_foo3_2_prt_l3_3_prt_ll1_4_prt_lll1 | 7024 | FOR VALUES IN ('M') + mpp5992_1_prt_foo3_2_prt_l3_3_prt_ll1_4_prt_lll2 | 7024 | FOR VALUES IN ('F') + mpp5992_1_prt_foo3_2_prt_l3_3_prt_ll2 | 7024 | FOR VALUES IN ('QA') + mpp5992_1_prt_foo3_2_prt_l3_3_prt_ll2_4_prt_lll1 | 7024 | FOR VALUES IN ('M') + mpp5992_1_prt_foo3_2_prt_l3_3_prt_ll2_4_prt_lll2 | 7024 | FOR VALUES IN ('F') +(112 rows) + +select relid::regclass, level, template from gp_partition_template where relid = 'mpp5992'::regclass; + relid | level | template +---------+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + mpp5992 | 3 | {GPPARTITIONDEFINITION :partDefElems ({GPPARTDEFELEM :partName lll1 :boundSpec {GPPARTITIONLISTSPEC :partValues (({A_CONST :val "M" :location 133}))} :subSpec <> :isDefault false :options <> :accessMethod <> :tablespacename <> :colencs <>} {GPPARTDEFELEM :partName lll2 :boundSpec {GPPARTITIONLISTSPEC :partValues (({A_CONST :val "F" :location 165}))} :subSpec <> :isDefault false :options <> :accessMethod <> :tablespacename <> :colencs <>}) :encClauses <> :isTemplate true} + mpp5992 | 2 | {GPPARTITIONDEFINITION :partDefElems ({GPPARTDEFELEM :partName ll1 :boundSpec {GPPARTITIONLISTSPEC :partValues (({A_CONST :val "Engineering" :location 108}))} :subSpec <> :isDefault false :options <> :accessMethod <> :tablespacename <> :colencs <>} {GPPARTDEFELEM :partName ll2 :boundSpec {GPPARTITIONLISTSPEC :partValues (({A_CONST :val "QA" :location 149}))} :subSpec <> :isDefault false :options <> :accessMethod <> :tablespacename <> :colencs <>}) :encClauses <> :isTemplate true} + mpp5992 | 1 | {GPPARTITIONDEFINITION :partDefElems ({GPPARTDEFELEM :partName l1 :boundSpec {GPPARTITIONLISTSPEC :partValues (({A_CONST :val 1 :location 72}) ({A_CONST :val 2 :location 74}) ({A_CONST :val 3 :location 76}))} :subSpec <> :isDefault false :options <> :accessMethod <> :tablespacename <> :colencs <>} {GPPARTDEFELEM :partName l2 :boundSpec {GPPARTITIONLISTSPEC :partValues (({A_CONST :val 4 :location 105}) ({A_CONST :val 5 :location 107}) ({A_CONST :val 6 :location 109}))} :subSpec <> :isDefault false :options <> :accessMethod <> :tablespacename <> :colencs <>} {GPPARTDEFELEM :partName l3 :boundSpec {GPPARTITIONLISTSPEC :partValues (({A_CONST :val 7 :location 137}) ({A_CONST :val 8 :location 139}) ({A_CONST :val 9 :location 141}) ({A_CONST :val 10 :location 143}))} :subSpec <> :isDefault false :options <> :accessMethod <> :tablespacename <> :colencs <>}) :encClauses <> :isTemplate true} +(3 rows) + +-- MPP-10223: split subpartitions +CREATE TABLE MPP10223pk +( +rnc VARCHAR(100), +wbts VARCHAR(100), +axc VARCHAR(100), +vptt VARCHAR(100), +vcct VARCHAR(100), +agg_level CHAR(5), +period_start_time TIMESTAMP WITH TIME ZONE, +load_time TIMESTAMP WITH TIME ZONE DEFAULT now(), +interval INTEGER, +totcellsegress double precision, +totcellsingress double precision, + + CONSTRAINT "axc_vcct1_atmvcct_pk_test2" +PRIMARY KEY (rnc,wbts,axc,vptt,vcct,agg_level,period_start_time) +) + +DISTRIBUTED BY (rnc,wbts,axc,vptt,vcct) + +PARTITION BY LIST (AGG_LEVEL) + SUBPARTITION BY RANGE (PERIOD_START_TIME) +( + PARTITION min15part VALUES ('15min') + ( + SUBPARTITION P_FUTURE START (date '2001-01-01') INCLUSIVE, + SUBPARTITION P_ENDPART START (date '2999-12-30') INCLUSIVE + END (date '2999-12-31') EXCLUSIVE + ), + PARTITION hourpart VALUES ('hour') + ( + SUBPARTITION P20100622 START (date '2010-06-22') INCLUSIVE, + SUBPARTITION P20100623 START (date '2010-06-23') INCLUSIVE, + SUBPARTITION P20100624 START (date '2010-06-24') INCLUSIVE, + SUBPARTITION P20100625 START (date '2010-06-25') INCLUSIVE, + SUBPARTITION P20100626 START (date '2010-06-26') INCLUSIVE, + SUBPARTITION P_FUTURE START (date '2001-01-01') INCLUSIVE, + SUBPARTITION P_ENDPART START (date '2999-12-30') INCLUSIVE + END (date '2999-12-31') EXCLUSIVE + ), + PARTITION daypart VALUES ('day') + ( + SUBPARTITION P20100622 START (date '2010-06-22') INCLUSIVE, + SUBPARTITION P20100623 START (date '2010-06-23') INCLUSIVE, + SUBPARTITION P20100624 START (date '2010-06-24') INCLUSIVE, + SUBPARTITION P20100625 START (date '2010-06-25') INCLUSIVE, + SUBPARTITION P20100626 START (date '2010-06-26') INCLUSIVE, + SUBPARTITION P_FUTURE START (date '2001-01-01') INCLUSIVE, + SUBPARTITION P_ENDPART START (date '2999-12-30') INCLUSIVE + END (date '2999-12-31') EXCLUSIVE + ) +); +-- MPP-10421: works -- can re-use name for non-DEFAULT partitions, and +-- primary key problems fixed +ALTER TABLE MPP10223pk + ALTER PARTITION min15part +SPLIT PARTITION P_FUTURE AT ('2010-06-25') +INTO (PARTITION P20010101, PARTITION P_FUTURE); +drop table mpp10223pk; +-- rebuild the table without a primary key +CREATE TABLE MPP10223 +( +rnc VARCHAR(100), +wbts VARCHAR(100), +axc VARCHAR(100), +vptt VARCHAR(100), +vcct VARCHAR(100), +agg_level CHAR(5), +period_start_time TIMESTAMP WITH TIME ZONE, +load_time TIMESTAMP WITH TIME ZONE DEFAULT now(), +interval INTEGER, +totcellsegress double precision, +totcellsingress double precision +) + +DISTRIBUTED BY (rnc,wbts,axc,vptt,vcct) + +PARTITION BY LIST (AGG_LEVEL) + SUBPARTITION BY RANGE (PERIOD_START_TIME) +( + PARTITION min15part VALUES ('15min') + ( + SUBPARTITION P_FUTURE START (date '2001-01-01') INCLUSIVE, + SUBPARTITION P_ENDPART START (date '2999-12-30') INCLUSIVE + END (date '2999-12-31') EXCLUSIVE + ), + PARTITION hourpart VALUES ('hour') + ( + SUBPARTITION P20100622 START (date '2010-06-22') INCLUSIVE, + SUBPARTITION P20100623 START (date '2010-06-23') INCLUSIVE, + SUBPARTITION P20100624 START (date '2010-06-24') INCLUSIVE, + SUBPARTITION P20100625 START (date '2010-06-25') INCLUSIVE, + SUBPARTITION P20100626 START (date '2010-06-26') INCLUSIVE, + SUBPARTITION P_FUTURE START (date '2001-01-01') INCLUSIVE, + SUBPARTITION P_ENDPART START (date '2999-12-30') INCLUSIVE + END (date '2999-12-31') EXCLUSIVE + ), + PARTITION daypart VALUES ('day') + ( + SUBPARTITION P20100622 START (date '2010-06-22') INCLUSIVE, + SUBPARTITION P20100623 START (date '2010-06-23') INCLUSIVE, + SUBPARTITION P20100624 START (date '2010-06-24') INCLUSIVE, + SUBPARTITION P20100625 START (date '2010-06-25') INCLUSIVE, + SUBPARTITION P20100626 START (date '2010-06-26') INCLUSIVE, + SUBPARTITION P_FUTURE START (date '2001-01-01') INCLUSIVE, + SUBPARTITION P_ENDPART START (date '2999-12-30') INCLUSIVE + END (date '2999-12-31') EXCLUSIVE + ) +); +-- this works +ALTER TABLE MPP10223 + ALTER PARTITION min15part +SPLIT PARTITION P_FUTURE AT ('2010-06-25') +INTO (PARTITION P20010101, PARTITION P_FUTURE2); +select * from pg_partition_tree('mpp10223'); + relid | parentrelid | isleaf | level +------------------------------------------+--------------------------+--------+------- + mpp10223 | | f | 0 + mpp10223_1_prt_min15part | mpp10223 | f | 1 + mpp10223_1_prt_hourpart | mpp10223 | f | 1 + mpp10223_1_prt_daypart | mpp10223 | f | 1 + mpp10223_1_prt_min15part_2_prt_p_endpart | mpp10223_1_prt_min15part | t | 2 + mpp10223_1_prt_min15part_2_prt_p20010101 | mpp10223_1_prt_min15part | t | 2 + mpp10223_1_prt_min15part_2_prt_p_future2 | mpp10223_1_prt_min15part | t | 2 + mpp10223_1_prt_hourpart_2_prt_p_future | mpp10223_1_prt_hourpart | t | 2 + mpp10223_1_prt_hourpart_2_prt_p20100622 | mpp10223_1_prt_hourpart | t | 2 + mpp10223_1_prt_hourpart_2_prt_p20100623 | mpp10223_1_prt_hourpart | t | 2 + mpp10223_1_prt_hourpart_2_prt_p20100624 | mpp10223_1_prt_hourpart | t | 2 + mpp10223_1_prt_hourpart_2_prt_p20100625 | mpp10223_1_prt_hourpart | t | 2 + mpp10223_1_prt_hourpart_2_prt_p20100626 | mpp10223_1_prt_hourpart | t | 2 + mpp10223_1_prt_hourpart_2_prt_p_endpart | mpp10223_1_prt_hourpart | t | 2 + mpp10223_1_prt_daypart_2_prt_p_future | mpp10223_1_prt_daypart | t | 2 + mpp10223_1_prt_daypart_2_prt_p20100622 | mpp10223_1_prt_daypart | t | 2 + mpp10223_1_prt_daypart_2_prt_p20100623 | mpp10223_1_prt_daypart | t | 2 + mpp10223_1_prt_daypart_2_prt_p20100624 | mpp10223_1_prt_daypart | t | 2 + mpp10223_1_prt_daypart_2_prt_p20100625 | mpp10223_1_prt_daypart | t | 2 + mpp10223_1_prt_daypart_2_prt_p20100626 | mpp10223_1_prt_daypart | t | 2 + mpp10223_1_prt_daypart_2_prt_p_endpart | mpp10223_1_prt_daypart | t | 2 +(21 rows) + +select relname, pg_get_expr(relpartbound, oid) from pg_class where relname like 'mpp10223%'; + relname | pg_get_expr +------------------------------------------+-------------------------------------------------------------------------------------- + mpp10223 | + mpp10223_1_prt_daypart | FOR VALUES IN ('day ') + mpp10223_1_prt_daypart_2_prt_p20100622 | FOR VALUES FROM ('Tue Jun 22 00:00:00 2010 PDT') TO ('Wed Jun 23 00:00:00 2010 PDT') + mpp10223_1_prt_daypart_2_prt_p20100623 | FOR VALUES FROM ('Wed Jun 23 00:00:00 2010 PDT') TO ('Thu Jun 24 00:00:00 2010 PDT') + mpp10223_1_prt_daypart_2_prt_p20100624 | FOR VALUES FROM ('Thu Jun 24 00:00:00 2010 PDT') TO ('Fri Jun 25 00:00:00 2010 PDT') + mpp10223_1_prt_daypart_2_prt_p20100625 | FOR VALUES FROM ('Fri Jun 25 00:00:00 2010 PDT') TO ('Sat Jun 26 00:00:00 2010 PDT') + mpp10223_1_prt_daypart_2_prt_p20100626 | FOR VALUES FROM ('Sat Jun 26 00:00:00 2010 PDT') TO ('Mon Dec 30 00:00:00 2999 PST') + mpp10223_1_prt_daypart_2_prt_p_endpart | FOR VALUES FROM ('Mon Dec 30 00:00:00 2999 PST') TO ('Tue Dec 31 00:00:00 2999 PST') + mpp10223_1_prt_daypart_2_prt_p_future | FOR VALUES FROM ('Mon Jan 01 00:00:00 2001 PST') TO ('Tue Jun 22 00:00:00 2010 PDT') + mpp10223_1_prt_hourpart | FOR VALUES IN ('hour ') + mpp10223_1_prt_hourpart_2_prt_p20100622 | FOR VALUES FROM ('Tue Jun 22 00:00:00 2010 PDT') TO ('Wed Jun 23 00:00:00 2010 PDT') + mpp10223_1_prt_hourpart_2_prt_p20100623 | FOR VALUES FROM ('Wed Jun 23 00:00:00 2010 PDT') TO ('Thu Jun 24 00:00:00 2010 PDT') + mpp10223_1_prt_hourpart_2_prt_p20100624 | FOR VALUES FROM ('Thu Jun 24 00:00:00 2010 PDT') TO ('Fri Jun 25 00:00:00 2010 PDT') + mpp10223_1_prt_hourpart_2_prt_p20100625 | FOR VALUES FROM ('Fri Jun 25 00:00:00 2010 PDT') TO ('Sat Jun 26 00:00:00 2010 PDT') + mpp10223_1_prt_hourpart_2_prt_p20100626 | FOR VALUES FROM ('Sat Jun 26 00:00:00 2010 PDT') TO ('Mon Dec 30 00:00:00 2999 PST') + mpp10223_1_prt_hourpart_2_prt_p_endpart | FOR VALUES FROM ('Mon Dec 30 00:00:00 2999 PST') TO ('Tue Dec 31 00:00:00 2999 PST') + mpp10223_1_prt_hourpart_2_prt_p_future | FOR VALUES FROM ('Mon Jan 01 00:00:00 2001 PST') TO ('Tue Jun 22 00:00:00 2010 PDT') + mpp10223_1_prt_min15part | FOR VALUES IN ('15min') + mpp10223_1_prt_min15part_2_prt_p20010101 | FOR VALUES FROM ('Mon Jan 01 00:00:00 2001 PST') TO ('Fri Jun 25 00:00:00 2010 PDT') + mpp10223_1_prt_min15part_2_prt_p_endpart | FOR VALUES FROM ('Mon Dec 30 00:00:00 2999 PST') TO ('Tue Dec 31 00:00:00 2999 PST') + mpp10223_1_prt_min15part_2_prt_p_future2 | FOR VALUES FROM ('Fri Jun 25 00:00:00 2010 PDT') TO ('Mon Dec 30 00:00:00 2999 PST') +(21 rows) + +-- simpler version +create table mpp10223b (a int, b int , d int) +partition by range (b) +subpartition by range (d) +(partition p1 start (1) end (10) +(subpartition sp2 start (20) end (30))); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +-- MPP-10421: allow re-use sp2 for non-DEFAULT partition +alter table mpp10223b alter partition p1 +split partition for (20) at (25) +into (partition sp2, partition sp3); +select relname, pg_get_expr(relpartbound, oid) from pg_class where relname like 'mpp10223b%'; + relname | pg_get_expr +------------------------------+------------------------------ + mpp10223b | + mpp10223b_1_prt_p1 | FOR VALUES FROM (1) TO (10) + mpp10223b_1_prt_p1_2_prt_sp2 | FOR VALUES FROM (20) TO (25) + mpp10223b_1_prt_p1_2_prt_sp3 | FOR VALUES FROM (25) TO (30) +(4 rows) + +-- MPP-10480: dump templates (but don't use "foo") +create table MPP10480 (a int, b int, d int) +partition by range (b) +subpartition by range(d) +subpartition template (start (1) end (10) every (1)) +(start (20) end (30) every (1)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +select relid::regclass, level, template from gp_partition_template where relid = 'MPP10480'::regclass; + relid | level | template +----------+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + mpp10480 | 1 | {GPPARTITIONDEFINITION :partDefElems ({GPPARTDEFELEM :partName <> :boundSpec {GPPARTITIONRANGESPEC :partStart {GPPARTITIONRANGEITEM :val ({A_CONST :val 1 :location 122}) :edge 1} :partEnd {GPPARTITIONRANGEITEM :val ({A_CONST :val 10 :location 130}) :edge 2} :partEvery ({A_CONST :val 1 :location 141})} :subSpec <> :isDefault false :options <> :accessMethod <> :tablespacename <> :colencs <>}) :encClauses <> :isTemplate true} +(1 row) + +-- MPP-10421: fix SPLIT of partitions with PRIMARY KEY constraint/indexes +CREATE TABLE mpp10321a +( + rnc VARCHAR(100), + wbts VARCHAR(100), + axc VARCHAR(100), + vptt VARCHAR(100), + vcct VARCHAR(100), + agg_level CHAR(5), + period_start_time TIMESTAMP WITH TIME ZONE, + load_time TIMESTAMP WITH TIME ZONE DEFAULT now(), + interval INTEGER, + totcellsegress double precision, + totcellsingress double precision, + CONSTRAINT "mpp10321a_pk" +PRIMARY KEY (rnc,wbts,axc,vptt,vcct,agg_level,period_start_time) +) +DISTRIBUTED BY (rnc,wbts,axc,vptt,vcct) +PARTITION BY LIST (AGG_LEVEL) + SUBPARTITION BY RANGE (PERIOD_START_TIME) +( + PARTITION min15part VALUES ('15min') + ( + SUBPARTITION P_FUTURE START (date '2001-01-01') INCLUSIVE, + SUBPARTITION P_ENDPART START (date '2999-12-30') INCLUSIVE + END (date '2999-12-31') EXCLUSIVE + ), + PARTITION hourpart VALUES ('hour') + ( + SUBPARTITION P20100622 START (date '2010-06-22') INCLUSIVE, + SUBPARTITION P_ENDPART START (date '2999-12-30') INCLUSIVE + END (date '2999-12-31') EXCLUSIVE + ) +); +ALTER TABLE mpp10321a +ALTER PARTITION min15part +SPLIT PARTITION P_FUTURE AT ('2010-06-25') +INTO (PARTITION P20010101, PARTITION P_FUTURE); +DROP TABLE mpp10321a; +-- test for default partition with boundary spec +create table bhagp_range (a int, b int) +distributed by (a) +partition by range (b) +( + default partition x + start (0) inclusive + end (2) exclusive + every (1) +); +ERROR: syntax error at or near "start" +LINE 6: start (0) inclusive + ^ +create table bhagp_list (a int, b int) +distributed by (a) +partition by list (b) +( + default partition x + values (1,2) +); +ERROR: syntax error at or near "values" +LINE 6: values (1,2) + ^ +-- more coverage tests +-- bad partition by type +create table cov1 (a int, b int) +distributed by (a) +partition by (b) +( +start (1) end (10) every (1) +); +ERROR: syntax error at or near "(" +LINE 3: partition by (b) + ^ +-- bad partition by type +create table cov1 (a int, b int) +distributed by (a) +partition by funky (b) +( +start (1) end (10) every (1) +); +ERROR: unrecognized partitioning strategy "funky" +drop table cov1; +ERROR: table "cov1" does not exist +create table cov1 (a int, b int) +distributed by (a) +partition by range (b) +( +start (1) end (10) every (1) +); +-- syntax error +alter table cov1 drop partition for (funky(1)); +ERROR: syntax error at or near ")" +LINE 1: alter table cov1 drop partition for (funky(1)); + ^ +-- no rank for default +alter table cov1 drop default partition for (1); +ERROR: cannot specify a name, rank, or value for a DEFAULT partition in this context +-- no default +alter table cov1 split default partition at (9); +ERROR: DEFAULT partition of relation "cov1" does not exist +alter table cov1 drop default partition; +ERROR: DEFAULT partition of relation "cov1" does not exist +-- cannot add except by name +alter table cov1 add partition for (1); +ERROR: can only ADD a partition by name +-- bad template +alter table cov1 set subpartition template (values (1,2) (values (2,3))); +ERROR: template cannot contain specification for child partition +-- create and drop default partition in one statement! +alter table cov1 add default partition def1, drop default partition; +drop table cov1; +-- every 5 (1) now disallowed... +create table cov1 (a int, b int) +distributed by (a) +partition by range (b) +( +start (1) end(20) every 5 (1) +); +ERROR: syntax error at or near "5" +LINE 5: start (1) end(20) every 5 (1) + ^ +drop table if exists cov1; +NOTICE: table "cov1" does not exist, skipping +create table cov1 (a int, b int) +distributed by (a) +partition by list (b) +( +partition p1 values (1,2,3,4,5,6,7,8) +); +-- bad split +alter table cov1 split partition p1 at (5,50); +ERROR: AT clause parameter is not a member of the target partition specification +-- good split +alter table cov1 split partition p1 at (5,6,7) +into (partition p1, partition p2); +select relname, pg_get_expr(relpartbound, oid, false) from pg_class where relname like 'cov1%'; + relname | pg_get_expr +---------------+------------------------------- + cov1 | + cov1_1_prt_p1 | FOR VALUES IN (1, 2, 3, 4, 8) + cov1_1_prt_p2 | FOR VALUES IN (5, 6, 7) +(3 rows) + +drop table cov1; +-- MPP-11120 +-- ADD PARTITION didn't explicitly specify the distribution policy in the +-- CreateStmt distributedBy field and as such we followed the behaviour encoded +-- in transformDistributedBy(). Unfortunately, it chooses to set the +-- distribution policy to that of the primary key if the distribution policy +-- is not explicitly set. +create table tbl11120 ( + a int, + b int, + c int, + primary key (a,b,c) +) +distributed by (a) +partition by range (b) +( + default partition default_partition, + partition p1 start (1) end (2) +); +insert into tbl11120 values(1,2,3); +select * from tbl11120; -- expected: (1,2,3) +NOTICE: One or more columns in the following table(s) do not have statistics: tbl11120 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + a | b | c +---+---+--- + 1 | 2 | 3 +(1 row) + +delete from tbl11120 where a=1 and b=2 and c=3; -- this should delete the row in tbl11120 +select * from tbl11120; -- expected, no rows +NOTICE: One or more columns in the following table(s) do not have statistics: tbl11120 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + a | b | c +---+---+--- +(0 rows) + +insert into tbl11120 values(1,2,3); -- reinsert data +-- all partitions should have same distribution policy +select relname, distkey as distribution_attributes from +gp_distribution_policy p, pg_class c +where p.localoid = c.oid and relname like 'tbl11120%' order by p.localoid; + relname | distribution_attributes +----------------------------------+------------------------- + tbl11120 | 1 + tbl11120_1_prt_default_partition | 1 + tbl11120_1_prt_p1 | 1 +(3 rows) + +alter table tbl11120 split default partition + start (3) + end (4) + into (partition p2, default partition); +select relname, distkey as distribution_attributes from +gp_distribution_policy p, pg_class c where p.localoid = c.oid and +relname like 'tbl11120%' order by p.localoid; + relname | distribution_attributes +----------------------------------+------------------------- + tbl11120 | 1 + tbl11120_1_prt_p1 | 1 + tbl11120_1_prt_p2 | 1 + tbl11120_1_prt_default_partition | 1 +(4 rows) + +delete from tbl11120 where a=1 and b=2 and c=3; -- this should delete the row in tbl11120 +select * from tbl11120; -- expected, no rows! But we see the row. Wrong results! +NOTICE: One or more columns in the following table(s) do not have statistics: tbl11120 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + a | b | c +---+---+--- +(0 rows) + +alter table tbl11120 drop partition default_partition; +alter table tbl11120 add partition foo start(10) end(20); +select relname, distkey as distribution_attributes from +gp_distribution_policy p, pg_class c where p.localoid = c.oid and +relname like 'tbl11120%' order by p.localoid; + relname | distribution_attributes +--------------------+------------------------- + tbl11120 | 1 + tbl11120_1_prt_p1 | 1 + tbl11120_1_prt_p2 | 1 + tbl11120_1_prt_foo | 1 +(4 rows) + +drop table tbl11120; +-- MPP-6979: EXCHANGE partitions - fix namespaces if they differ +-- new schema +create schema mpp6979dummy; +create table mpp6979part(a int, b int) +partition by range(b) +( +start (1) end (10) every (1) +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +-- append-only table in new schema +create table mpp6979dummy.mpp6979tab(like mpp6979part) with (appendonly=true); +NOTICE: table doesn't have 'DISTRIBUTED BY' clause, defaulting to distribution columns from LIKE table +-- check that table and all parts in public schema +select relname, nspname, relispartition from pg_class c, pg_namespace n +where c.relnamespace = n.oid and relname like ('mpp6979%'); + relname | nspname | relispartition +---------------------+--------------+---------------- + mpp6979part | public | f + mpp6979part_1_prt_1 | public | t + mpp6979part_1_prt_2 | public | t + mpp6979part_1_prt_3 | public | t + mpp6979part_1_prt_4 | public | t + mpp6979part_1_prt_5 | public | t + mpp6979part_1_prt_6 | public | t + mpp6979part_1_prt_7 | public | t + mpp6979part_1_prt_8 | public | t + mpp6979part_1_prt_9 | public | t + mpp6979tab | mpp6979dummy | f +(11 rows) + +-- note that we have heap partitions in public, and ao table in mpp6979dummy +select nspname, relname, amname +from pg_class pc +inner join pg_namespace ns on pc.relnamespace=ns.oid +left join pg_am am on am.oid = pc.relam +where relname like ('mpp6979%'); + nspname | relname | amname +--------------+---------------------+-------- + public | mpp6979part | + public | mpp6979part_1_prt_1 | heap + public | mpp6979part_1_prt_2 | heap + public | mpp6979part_1_prt_3 | heap + public | mpp6979part_1_prt_4 | heap + public | mpp6979part_1_prt_5 | heap + public | mpp6979part_1_prt_6 | heap + public | mpp6979part_1_prt_7 | heap + public | mpp6979part_1_prt_8 | heap + public | mpp6979part_1_prt_9 | heap + mpp6979dummy | mpp6979tab | ao_row +(11 rows) + +-- exchange the partition with the ao table. +-- Now we have an ao partition and mpp6979tab is heap! +alter table mpp6979part exchange partition for (1) +with table mpp6979dummy.mpp6979tab; +-- after the exchange, all partitions are still in public +select relname, nspname, relispartition from pg_class c, pg_namespace n +where c.relnamespace = n.oid and relname like ('mpp6979%'); + relname | nspname | relispartition +---------------------+--------------+---------------- + mpp6979part | public | f + mpp6979part_1_prt_1 | public | t + mpp6979part_1_prt_2 | public | t + mpp6979part_1_prt_3 | public | t + mpp6979part_1_prt_4 | public | t + mpp6979part_1_prt_5 | public | t + mpp6979part_1_prt_6 | public | t + mpp6979part_1_prt_7 | public | t + mpp6979part_1_prt_8 | public | t + mpp6979part_1_prt_9 | public | t + mpp6979tab | mpp6979dummy | f +(11 rows) + +-- the rank 1 partition is ao, but still in public, and +-- table mpp6979tab is now heap, but still in mpp6979dummy +select relname, nspname, relispartition, amname +from pg_class c inner join pg_namespace n on c.relnamespace = n.oid +left join pg_am am on am.oid = c.relam +where relname like ('mpp6979%'); + relname | nspname | relispartition | amname +---------------------+--------------+----------------+-------- + mpp6979part | public | f | + mpp6979part_1_prt_1 | public | t | ao_row + mpp6979part_1_prt_2 | public | t | heap + mpp6979part_1_prt_3 | public | t | heap + mpp6979part_1_prt_4 | public | t | heap + mpp6979part_1_prt_5 | public | t | heap + mpp6979part_1_prt_6 | public | t | heap + mpp6979part_1_prt_7 | public | t | heap + mpp6979part_1_prt_8 | public | t | heap + mpp6979part_1_prt_9 | public | t | heap + mpp6979tab | mpp6979dummy | f | heap +(11 rows) + +drop table mpp6979part; +drop table mpp6979dummy.mpp6979tab; +drop schema mpp6979dummy; +-- MPP-7898: +create table parent_s + (a int, b text) + distributed by (a); + +insert into parent_s values + (1, 'one'); +-- Try to create a table that mixes inheritance and partitioning. +-- Correct behavior: ERROR +create table child_r + ( c int, d int) + inherits (parent_s) + partition by range(d) + ( + start (0) + end (2) + every (1) + ); +ERROR: cannot create partitioned table as inheritance child + -- If (incorrectly) the previous statement works, the next one is + -- likely to fail with in unexpected internal error. This is residual + -- issue MPP-7898. +insert into child_r values + (0, 'from r', 0, 0); +ERROR: relation "child_r" does not exist +LINE 1: insert into child_r values + ^ +drop table if exists parent_s cascade; --ignore +drop table if exists child_r cascade; --ignore +NOTICE: table "child_r" does not exist, skipping +create table parent_r + ( a int, b text, c int, d int ) + distributed by (a) + partition by range(d) + ( + start (0) + end (2) + every (1) + ); + +insert into parent_r values + (0, 'from r', 0, 0); +create table parent_s + ( a int, b text, c int, d int ) + distributed by (a); + +insert into parent_s values + (1, 'from s', 555, 555); +create table child_t + ( ) + inherits (parent_s) + distributed by (a); +insert into child_t values + (0, 'from t', 666, 666); +-- Try to exchange in the child and parent. +-- Correct behavior: ERROR in both cases. +alter table parent_r exchange partition for (1) with table child_t; +ERROR: cannot attach inheritance child as partition +alter table parent_r exchange partition for (1) with table parent_s; +ERROR: cannot attach inheritance parent as partition +drop table child_t cascade; --ignore +drop table parent_s cascade; --ignore +drop table parent_r cascade; --ignore +-- MPP-7898 end. +-- ( MPP-13750 +CREATE TABLE s (id int, date date, amt decimal(10,2), units int) +DISTRIBUTED BY (id) +PARTITION BY RANGE (date) +( START (date '2008-01-01') INCLUSIVE + END (date '2008-01-02') EXCLUSIVE + EVERY (INTERVAL '1 day') ); +create index s_i on s(amt) + where (id > 1) + ; +create index s_j on s(units) + where (id <= 1) + ; +create index s_i_expr on s(log(units)); +alter table s add partition s_test + start(date '2008-01-03') end (date '2008-01-05'); +alter table s split partition for (date '2008-01-03') at (date '2008-01-04') + into (partition s_test, partition s_test2); +select + relname, + (select count(distinct content) - 1 + from gp_segment_configuration) - count(*) as missing, + count(distinct relid) oid_count +from ( + select gp_execution_segment(), oid, relname + from gp_dist_random('pg_class') + ) seg_class(segid, relid, relname) +where relname ~ '^s_' +group by relname; + relname | missing | oid_count +---------------------------+---------+----------- + s_1_prt_1_units_idx | 0 | 1 + s_1_prt_s_test_units_idx1 | 0 | 1 + s_i_expr | 0 | 1 + s_j | 0 | 1 + s_1_prt_s_test | 0 | 1 + s_1_prt_s_test2_log_idx | 0 | 1 + s_1_prt_s_test_amt_idx1 | 0 | 1 + s_1_prt_s_test_log_idx1 | 0 | 1 + s_i | 0 | 1 + s_1_prt_1 | 0 | 1 + s_1_prt_1_amt_idx | 0 | 1 + s_1_prt_1_log_idx | 0 | 1 + s_1_prt_s_test2 | 0 | 1 + s_1_prt_s_test2_amt_idx | 0 | 1 + s_1_prt_s_test2_units_idx | 0 | 1 +(15 rows) + +drop table s cascade; +-- MPP-13750 ) +-- MPP-14471 start +-- No unenforceable PK/UK constraints! (UNIQUE INDEXes still allowed; tested above) +drop table if exists tc cascade; +NOTICE: table "tc" does not exist, skipping +drop table if exists cc cascade; +NOTICE: table "cc" does not exist, skipping +drop table if exists at cascade; +NOTICE: table "at" does not exist, skipping +create table tc + (a int, b int, c int, primary key(a) ) + distributed by (a) + partition by range (b) + ( + default partition d, + start (0) inclusive end(100) inclusive every (50) + ); +ERROR: unique constraint on partitioned table must include all partitioning columns +DETAIL: PRIMARY KEY constraint on table "tc" lacks column "b" which is part of the partition key. +create table cc + (a int primary key, b int, c int) + distributed by (a) + partition by range (b) + ( + default partition d, + start (0) inclusive end(100) inclusive every (50) + ); +ERROR: unique constraint on partitioned table must include all partitioning columns +DETAIL: PRIMARY KEY constraint on table "cc" lacks column "b" which is part of the partition key. +create table at + (a int, b int, c int) + distributed by (a) + partition by range (b) + ( + default partition d, + start (0) inclusive end(100) inclusive every (50) + ); +alter table at + add primary key (a); +ERROR: unique constraint on partitioned table must include all partitioning columns +DETAIL: PRIMARY KEY constraint on table "at" lacks column "b" which is part of the partition key. +-- MPP-14471 end +-- MPP-17606 (using table "at" from above) +alter table at + alter column b + type numeric; +ERROR: cannot alter column "b" because it is part of the partition key of relation "at" + +-- MPP-17606 end +-- MPP-17707 start +create table mpp17707 +( d int, p int ,x text) +with (appendonly = true) +distributed by (d) +partition by range (p) +(start (0) end (3) every (2)); +-- Create a expression index on the partitioned table +create index idx_abc on mpp17707(upper(x)); +-- split partition 1 of table +alter table mpp17707 split partition for (0) at (1) + into (partition x1, partition x2); +-- MPP-17707 end +-- MPP-17814 start +drop table if exists plst2 cascade; +NOTICE: table "plst2" does not exist, skipping +-- positive; bug was that it failed whereas it should succeed +create type plst2_partkey as (a integer, c integer); +create table plst2 + ( + b integer not null, + d plst2_partkey + ) + distributed by (b) + partition by list (d) + ( + partition p1 values ( CAST('(1,2)' as plst2_partkey), CAST('(3,4)' as plst2_partkey) ), + partition p2 values ( CAST('(5,6)' as plst2_partkey) ), + partition p3 values ( CAST('(2,1)' as plst2_partkey) ) + ); +\d+ plst2 + Partitioned table "public.plst2" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------------+-----------+----------+---------+----------+--------------+------------- + b | integer | | not null | | plain | | + d | plst2_partkey | | | | extended | | +Partition key: LIST (d) +Partitions: plst2_1_prt_p1 FOR VALUES IN ('(1,2)', '(3,4)'), + plst2_1_prt_p2 FOR VALUES IN ('(5,6)'), + plst2_1_prt_p3 FOR VALUES IN ('(2,1)') +Distributed by: (b) + +drop table if exists plst2 cascade; +--negative; test legitimate failure +create table plst2 + ( + b integer not null, + d plst2_partkey + ) + distributed by (b) + partition by list (d) + ( + partition p1 values ( CAST('(1,2)' as plst2_partkey), CAST('(3,4)' as plst2_partkey) ), + partition p2 values ( CAST('(5,6)' as plst2_partkey) ), + partition p3 values ( CAST('(1,2)' as plst2_partkey) ) + ); +ERROR: partition "plst2_1_prt_p3" would overlap partition "plst2_1_prt_p1" +LINE 11: partition p3 values ( CAST('(1,2)' as plst2_partkey)... + ^ +-- postive; make sure inner part duplicates are accepted and quietly removed. +drop table if exists plst2; +NOTICE: table "plst2" does not exist, skipping +drop type plst2_partkey; +create type plst2_partkey as (a int, b int); +create table plst2 + ( d int, c plst2_partkey) + distributed by (d) + partition by list (c) + ( + partition p0 values ( CAST('(1,2)' as plst2_partkey), CAST('(3,4)' as plst2_partkey) ), + partition p1 values ( CAST('(4,3)' as plst2_partkey), CAST('(2,1)' as plst2_partkey) ), + partition p2 values ( CAST('(4,4)' as plst2_partkey), CAST('(5,5)' as plst2_partkey), CAST('(4,4)' as plst2_partkey), CAST('(5,5)' as plst2_partkey), CAST('(4,4)' as plst2_partkey), CAST('(5,5)' as plst2_partkey)), + partition p3 values (CAST('(4,5)' as plst2_partkey), CAST('(5,6)' as plst2_partkey)) + ); +-- positive; make sure legitimate alters work. +alter table plst2 add partition p4 values (CAST('(5,4)' as plst2_partkey), CAST('(6,5)' as plst2_partkey)); +alter table plst2 add partition p5 values (CAST('(7,8)' as plst2_partkey), CAST('(7,8)' as plst2_partkey)); +\d+ plst2 + Partitioned table "public.plst2" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------------+-----------+----------+---------+----------+--------------+------------- + d | integer | | | | plain | | + c | plst2_partkey | | | | extended | | +Partition key: LIST (c) +Partitions: plst2_1_prt_p0 FOR VALUES IN ('(1,2)', '(3,4)'), + plst2_1_prt_p1 FOR VALUES IN ('(4,3)', '(2,1)'), + plst2_1_prt_p2 FOR VALUES IN ('(4,4)', '(5,5)'), + plst2_1_prt_p3 FOR VALUES IN ('(4,5)', '(5,6)'), + plst2_1_prt_p4 FOR VALUES IN ('(5,4)', '(6,5)'), + plst2_1_prt_p5 FOR VALUES IN ('(7,8)') +Distributed by: (d) + +-- negative; make sure conflicting alters fail. +alter table plst2 add partition p6 values (CAST('(7,8)' as plst2_partkey), CAST('(2,1)' as plst2_partkey)); +ERROR: partition "plst2_1_prt_p6" would overlap partition "plst2_1_prt_p5" +LINE 1: alter table plst2 add partition p6 values (CAST('(7,8)' as p... + ^ +drop table if exists plst2; +-- MPP-17814 end +-- MPP-18441 +create table s_heap (i1 int, t1 text, t2 text, i2 int, i3 int, n1 numeric, b1 bool) +partition by list (t1) + (partition abc values('abc0', 'abc1', 'abc2')); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into s_heap (t1, i1, i2, i3, n1, b1) select 'abc0', 1, 1, 1, 2.3, true + from generate_series(1, 5); +alter table s_heap drop column t2; +alter table s_heap drop column i3; +-- create co table for exchange +create table s_heap_ex_abc (i1 int, t1 text, f1 float, i2 int, n1 numeric, b1 bool) + WITH (appendonly=true, orientation=column, compresstype=zlib); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +alter table s_heap_ex_abc drop column f1; +insert into s_heap_ex_abc select 1, 'abc1', 2, 2, true from generate_series(1, 5); +-- exchange partition +alter table s_heap exchange partition abc with table s_heap_ex_abc; +alter table s_heap exchange partition abc with table s_heap_ex_abc; +drop table s_heap, s_heap_ex_abc; +-- MPP-18441 end +-- MPP-18443 +create table s_heap (i1 int, t1 text, i2 int , i3 int, n1 numeric,b1 bool) +partition by list (t1) + (partition def values('def0', 'def1', 'def2', 'def3', 'def4', 'def5', 'def6', 'def7', 'def8', 'def9')); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into s_heap(t1, i1, i2, i3, n1, b1) + select 'def0', 1, 1, 1, 2.3 , true from generate_series(1, 5); +alter table s_heap drop column i3; +create index s_heap_index on s_heap (i2); +alter table s_heap split partition def + at ('def0', 'def1', 'def2', 'def3', 'def4') into (partition def5, partition def0); +select * from s_heap_1_prt_def0; + i1 | t1 | i2 | n1 | b1 +----+------+----+-----+---- + 1 | def0 | 1 | 2.3 | t + 1 | def0 | 1 | 2.3 | t + 1 | def0 | 1 | 2.3 | t + 1 | def0 | 1 | 2.3 | t + 1 | def0 | 1 | 2.3 | t +(5 rows) + +drop table s_heap; +-- MPP-18443 end +-- MPP-18445 +create table s_heap_ao ( i1 int, t1 text, i2 int , i3 int, n1 numeric,b1 bool) +partition by list (t1) + (partition def values('def0', 'def1', 'def2', 'def3', 'def4', 'def5', 'def6', 'def7', 'def8', 'def9') + with (appendonly=true, orientation=row)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into s_heap_ao(t1, i1, i2, i3, n1, b1) + select 'def4', 1, 1, 1, 2.3, true from generate_series(1, 2); +insert into s_heap_ao(t1, i1, i2, i3, n1, b1) + select 'def5', 1, 1, 1, 2.3, true from generate_series(1, 2); +alter table s_heap_ao drop column i3; +create index s_heap_ao_index on s_heap_ao (i2); +alter table s_heap_ao split partition def + at ('def0', 'def1', 'def2', 'def3', 'def4') into (partition def5, partition def0); +select * from s_heap_ao_1_prt_def0; + i1 | t1 | i2 | n1 | b1 +----+------+----+-----+---- + 1 | def4 | 1 | 2.3 | t + 1 | def4 | 1 | 2.3 | t +(2 rows) + +drop table s_heap_ao; +-- MPP-18445 end +-- MPP-18456 +create table s_heap_co (i1 int, t1 text, i2 int, i3 int, n1 numeric, b1 bool) +partition by list (t1) + (partition def values('def0', 'def1', 'def2', 'def3', 'def4', 'def5', 'def6', 'def7', 'def8', 'def9') + with (appendonly=true, orientation=column)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into s_heap_co(t1, i1, i2, i3, n1, b1) + select 'def4', 1,1, 1, 2.3, true from generate_series(1, 2); +insert into s_heap_co(t1, i1, i2, i3, n1, b1) + select 'def5', 1,1, 1, 2.3, true from generate_series(1, 2); +alter table s_heap_co drop column i3; +create index s_heap_co_index on s_heap_co (i2); +alter table s_heap_co split partition def + at ('def0', 'def1', 'def2', 'def3', 'def4') into (partition def5, partition def0); +select * from s_heap_co_1_prt_def0; + i1 | t1 | i2 | n1 | b1 +----+------+----+-----+---- + 1 | def4 | 1 | 2.3 | t + 1 | def4 | 1 | 2.3 | t +(2 rows) + +drop table s_heap_co; +-- MPP-18456 end +-- MPP-18457, MPP-18415 +CREATE TABLE non_ws_phone_leads ( + lead_key integer NOT NULL ENCODING (compresstype=zlib,compresslevel=1,blocksize=32768), + source_system_lead_id character varying(60) NOT NULL ENCODING (compresstype=zlib,compresslevel=1,blocksize=32768), + dim_event_type_key smallint NOT NULL ENCODING (compresstype=zlib,compresslevel=1,blocksize=32768), + dim_site_key integer NOT NULL ENCODING (compresstype=zlib,compresslevel=1,blocksize=32768), + dim_date_key integer NOT NULL ENCODING (compresstype=zlib,compresslevel=1,blocksize=32768), + dim_time_key integer NOT NULL ENCODING (compresstype=zlib,compresslevel=1,blocksize=32768), + dim_phone_number_key integer NOT NULL ENCODING (compresstype=zlib,compresslevel=1,blocksize=32768), + duration_second smallint NOT NULL ENCODING (compresstype=zlib,compresslevel=1,blocksize=32768), + dim_program_key smallint NOT NULL ENCODING (compresstype=zlib,compresslevel=1,blocksize=32768), + dim_call_status_key integer NOT NULL ENCODING (compresstype=zlib,compresslevel=1,blocksize=32768), + dim_phone_department_set_key smallint NOT NULL ENCODING (compresstype=zlib,compresslevel=1,blocksize=32768), + dim_phone_channel_set_key smallint NOT NULL ENCODING (compresstype=zlib,compresslevel=1,blocksize=32768), + dim_phone_provider_key smallint NOT NULL ENCODING (compresstype=zlib,compresslevel=1,blocksize=32768), + dim_phone_ad_set_key smallint NOT NULL ENCODING (compresstype=zlib,compresslevel=1,blocksize=32768) +) +WITH (appendonly=true, compresstype=zlib, orientation=column) DISTRIBUTED BY (dim_site_key ,dim_date_key) PARTITION BY RANGE(dim_date_key) + ( + PARTITION p_max START (2451545) END (9999999) WITH (tablename='non_ws_phone_leads_1_prt_p_max', orientation=column, appendonly=true ) + COLUMN lead_key ENCODING (compresstype=zlib, compresslevel=1, blocksize=32768) + COLUMN source_system_lead_id ENCODING (compresstype=zlib, compresslevel=1, blocksize=32768) + COLUMN dim_event_type_key ENCODING (compresstype=zlib, compresslevel=1, blocksize=32768) + COLUMN dim_site_key ENCODING (compresstype=zlib, compresslevel=1, blocksize=32768) + COLUMN dim_date_key ENCODING (compresstype=zlib, compresslevel=1, blocksize=32768) + COLUMN dim_time_key ENCODING (compresstype=zlib, compresslevel=1, blocksize=32768) + COLUMN dim_phone_number_key ENCODING (compresstype=zlib, compresslevel=1, blocksize=32768) + COLUMN duration_second ENCODING (compresstype=zlib, compresslevel=1, blocksize=32768) + COLUMN dim_program_key ENCODING (compresstype=zlib, compresslevel=1, blocksize=32768) + COLUMN dim_call_status_key ENCODING (compresstype=zlib, compresslevel=1, blocksize=32768) + COLUMN dim_phone_department_set_key ENCODING (compresstype=zlib, compresslevel=1, blocksize=32768) + COLUMN dim_phone_channel_set_key ENCODING (compresstype=zlib, compresslevel=1, blocksize=32768) + COLUMN dim_phone_provider_key ENCODING (compresstype=zlib, compresslevel=1, blocksize=32768) + COLUMN dim_phone_ad_set_key ENCODING (compresstype=zlib, compresslevel=1, blocksize=32768) + ); +INSERT INTO non_ws_phone_leads VALUES (63962490, 'CA6qOEyxOmNJUQC7', 5058, 999901, 2455441, 40435, 999904, 207, 79, 2, 9901, 9901, 1, 9901); +CREATE TABLE dim_phone_numbers ( + dim_phone_number_key integer NOT NULL, + media_tracker_description character varying(40) NOT NULL, + formatted_phone_number character varying(20) NOT NULL, + source_system_phone_number_id character varying(100) NOT NULL, + last_modified_date timestamp without time zone NOT NULL +) DISTRIBUTED BY (dim_phone_number_key); +ALTER TABLE ONLY dim_phone_numbers + ADD CONSTRAINT dim_phone_numbers_pk1 PRIMARY KEY (dim_phone_number_key); +INSERT INTO dim_phone_numbers VALUES (999902, 'test', '800-123-4568', '8001234568', '2012-09-25 13:34:35.037637'); +INSERT INTO dim_phone_numbers VALUES (999904, 'test', '(800) 123-4570', '8001234570', '2012-09-25 13:34:35.148104'); +INSERT INTO dim_phone_numbers VALUES (999903, 'test', '(800) 123-4569', '8001234569', '2012-09-25 13:34:35.093523'); +INSERT INTO dim_phone_numbers VALUES (999901, 'test', '(800)123-4567', '8001234567', '2012-09-25 13:34:34.781042'); +INSERT INTO dim_phone_numbers SELECT gs.*, dim_phone_numbers.media_tracker_description, dim_phone_numbers.formatted_phone_number, dim_phone_numbers.source_system_phone_number_id, dim_phone_numbers.last_modified_date FROM dim_phone_numbers, generate_series(1,100000) gs WHERE dim_phone_numbers.dim_phone_number_key = 999901; +ANALYZE dim_phone_numbers; +-- Table NON_WS_PHONE_LEADS has two distribution keys +-- Equality condition with constant on one distribution key +-- Redistribute over Append +SELECT pl.duration_Second , pl.dim_program_Key, PL.DIM_SITE_KEY, PL.DIM_DATE_KEY +FROM NON_WS_PHONE_LEADS PL +LEFT outer JOIN DIM_PHONE_NUMBERS DPN +ON PL.DIM_PHONE_NUMBER_KEY = DPN.DIM_PHONE_NUMBER_KEY +WHERE pl.SOURCE_SYSTEM_LEAD_ID = 'CA6qOEyxOmNJUQC7' +AND PL.DIM_DATE_KEY = 2455441; +NOTICE: One or more columns in the following table(s) do not have statistics: non_ws_phone_leads +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + duration_second | dim_program_key | dim_site_key | dim_date_key +-----------------+-----------------+--------------+-------------- + 207 | 79 | 999901 | 2455441 +(1 row) + +-- Table NON_WS_PHONE_LEADS has two distribution keys +-- Equality conditions with constants on all distribution keys +-- Redistribute over Append +SELECT pl.duration_Second , pl.dim_program_Key, PL.DIM_SITE_KEY, PL.DIM_DATE_KEY +FROM NON_WS_PHONE_LEADS PL +LEFT outer JOIN DIM_PHONE_NUMBERS DPN +ON PL.DIM_PHONE_NUMBER_KEY = DPN.DIM_PHONE_NUMBER_KEY +WHERE pl.SOURCE_SYSTEM_LEAD_ID = 'CA6qOEyxOmNJUQC7' +AND PL.DIM_DATE_KEY = 2455441 +AND PL.dim_site_key = 999901; +NOTICE: One or more columns in the following table(s) do not have statistics: non_ws_phone_leads +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + duration_second | dim_program_key | dim_site_key | dim_date_key +-----------------+-----------------+--------------+-------------- + 207 | 79 | 999901 | 2455441 +(1 row) + +-- Table NON_WS_PHONE_LEADS has two distribution keys +-- Broadcast over Append +SELECT pl.duration_Second , pl.dim_program_Key, PL.DIM_SITE_KEY, PL.DIM_DATE_KEY +FROM NON_WS_PHONE_LEADS PL +JOIN DIM_PHONE_NUMBERS DPN +ON PL.DIM_PHONE_NUMBER_KEY = DPN.DIM_PHONE_NUMBER_KEY +WHERE pl.SOURCE_SYSTEM_LEAD_ID = 'CA6qOEyxOmNJUQC7' +AND PL.DIM_DATE_KEY = 2455441 +AND PL.dim_site_key = 999901; +NOTICE: One or more columns in the following table(s) do not have statistics: non_ws_phone_leads +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + duration_second | dim_program_key | dim_site_key | dim_date_key +-----------------+-----------------+--------------+-------------- + 207 | 79 | 999901 | 2455441 +(1 row) + +-- Join condition uses functions +-- Broadcast over Append +SELECT pl.duration_Second , pl.dim_program_Key, PL.DIM_SITE_KEY, PL.DIM_DATE_KEY +FROM NON_WS_PHONE_LEADS PL +JOIN DIM_PHONE_NUMBERS DPN +ON PL.DIM_PHONE_NUMBER_KEY + 1 = DPN.DIM_PHONE_NUMBER_KEY + 1 +WHERE pl.SOURCE_SYSTEM_LEAD_ID = 'CA6qOEyxOmNJUQC7' +AND PL.DIM_DATE_KEY = 2455441 +AND PL.dim_site_key = 999901; +NOTICE: One or more columns in the following table(s) do not have statistics: non_ws_phone_leads +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + duration_second | dim_program_key | dim_site_key | dim_date_key +-----------------+-----------------+--------------+-------------- + 207 | 79 | 999901 | 2455441 +(1 row) + +-- Equality condition with constant on one distribution key +-- Redistribute over Append +-- Accessing a varchar in the SELECT clause should cause a SIGSEGV +SELECT pl.duration_Second , pl.dim_program_Key, PL.DIM_SITE_KEY, PL.DIM_DATE_KEY, source_system_lead_id +FROM NON_WS_PHONE_LEADS PL +LEFT outer JOIN DIM_PHONE_NUMBERS DPN +ON PL.DIM_PHONE_NUMBER_KEY = DPN.DIM_PHONE_NUMBER_KEY +WHERE pl.SOURCE_SYSTEM_LEAD_ID = 'CA6qOEyxOmNJUQC7' +AND PL.DIM_DATE_KEY = 2455441; +NOTICE: One or more columns in the following table(s) do not have statistics: non_ws_phone_leads +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + duration_second | dim_program_key | dim_site_key | dim_date_key | source_system_lead_id +-----------------+-----------------+--------------+--------------+----------------------- + 207 | 79 | 999901 | 2455441 | CA6qOEyxOmNJUQC7 +(1 row) + +DROP TABLE non_ws_phone_leads; +DROP TABLE dim_phone_numbers; +set optimizer to on; +set optimizer_disable_dynamic_table_scan to on; +-- Equality condition with a constant expression on one distribution key +drop table if exists foo_p; +NOTICE: table "foo_p" does not exist, skipping +drop table if exists bar; +NOTICE: table "bar" does not exist, skipping +create table foo_p( a int, b int, k int, t text, p int) distributed by (a,b) partition by range(p) ( start(0) end(10) every (2), default partition other); +create table bar( a int, b int, k int, t text, p int) distributed by (a); +insert into foo_p select i, i % 10, i , i || 'SOME NUMBER SOME NUMBER', i % 10 from generate_series(1, 1000) i; +insert into bar select i % 7, i % 6, i % 9, i || 'SOME NUMBER', i % 4 from generate_series(1, 100) i; +insert into bar select i % 7, i % 6, i % 9, i || 'SOME NUMBER', i % 4 from generate_series(1, 10000) i; +insert into bar select i % 7, i % 6, i % 9, i || 'SOME NUMBER', i % 4 from generate_series(1, 10000) i; +analyze foo_p; +analyze bar; +set optimizer_segments = 3; +set optimizer_nestloop_factor = 1.0; +explain select foo_p.b, foo_p.t from foo_p left outer join bar on foo_p.a = bar.k where foo_p.t is not null and foo_p.a = (array[1])[1]; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Hash Right Join (cost=0.00..863.16 rows=2237 width=30) + Hash Cond: (bar.k = foo_p_1_prt_2.a) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.50 rows=2237 width=4) + -> Seq Scan on bar (cost=0.00..431.47 rows=746 width=4) + Filter: (k = 1) + -> Hash (cost=431.04..431.04 rows=1 width=34) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.04 rows=1 width=34) + -> Append (cost=0.00..431.04 rows=1 width=34) + -> Seq Scan on foo_p_1_prt_2 (cost=0.00..431.04 rows=1 width=34) + Filter: ((NOT (t IS NULL)) AND (a = 1)) + -> Seq Scan on foo_p_1_prt_3 (cost=0.00..431.04 rows=1 width=34) + Filter: ((NOT (t IS NULL)) AND (a = 1)) + -> Seq Scan on foo_p_1_prt_4 (cost=0.00..431.04 rows=1 width=34) + Filter: ((NOT (t IS NULL)) AND (a = 1)) + -> Seq Scan on foo_p_1_prt_5 (cost=0.00..431.04 rows=1 width=34) + Filter: ((NOT (t IS NULL)) AND (a = 1)) + -> Seq Scan on foo_p_1_prt_6 (cost=0.00..431.04 rows=1 width=34) + Filter: ((NOT (t IS NULL)) AND (a = 1)) + -> Seq Scan on foo_p_1_prt_other (cost=0.00..431.04 rows=1 width=34) + Filter: ((NOT (t IS NULL)) AND (a = 1)) + Optimizer: GPORCA +(21 rows) + +reset optimizer_segments; +drop table if exists foo_p; +drop table if exists bar; +-- MPP-18457, MPP-18415 end +drop table if exists pnx; +NOTICE: table "pnx" does not exist, skipping +create table pnx + (x int , y text) + distributed randomly + partition by list (y) + ( + partition a values ('x1', 'x2'), + partition c values ('x3', 'x4') + ); +insert into pnx values + (1,'x1'), + (2,'x2'), + (3,'x3'), + (4,'x4'); +select tableoid::regclass, * +from pnx; + tableoid | x | y +-------------+---+---- + pnx_1_prt_c | 4 | x4 + pnx_1_prt_a | 1 | x1 + pnx_1_prt_a | 2 | x2 + pnx_1_prt_c | 3 | x3 +(4 rows) + +alter table pnx + split partition a at ('x1') + into (partition b, partition c); +ERROR: relation "pnx_1_prt_c" already exists +select tableoid::regclass, * +from pnx; + tableoid | x | y +-------------+---+---- + pnx_1_prt_c | 4 | x4 + pnx_1_prt_a | 1 | x1 + pnx_1_prt_a | 2 | x2 + pnx_1_prt_c | 3 | x3 +(4 rows) + +select tableoid::regclass, * +from pnx +where y = 'x1'; +NOTICE: One or more columns in the following table(s) do not have statistics: pnx +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + tableoid | x | y +-------------+---+---- + pnx_1_prt_a | 1 | x1 +(1 row) + +select tableoid::regclass, * +from pnx +where x = 1; +NOTICE: One or more columns in the following table(s) do not have statistics: pnx +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + tableoid | x | y +-------------+---+---- + pnx_1_prt_a | 1 | x1 +(1 row) + +drop table if exists pxn; +NOTICE: table "pxn" does not exist, skipping +create table pxn + (x int , y text) + distributed randomly + partition by list (y) + ( + partition a values ('x1', 'x2'), + partition c values ('x3', 'x4') + ); +insert into pxn values + (1,'x1'), + (2,'x2'), + (3,'x3'), + (4,'x4'); +select tableoid::regclass, * +from pxn; + tableoid | x | y +-------------+---+---- + pxn_1_prt_a | 1 | x1 + pxn_1_prt_c | 3 | x3 + pxn_1_prt_a | 2 | x2 + pxn_1_prt_c | 4 | x4 +(4 rows) + +alter table pxn + split partition a at ('x1') + into (partition c, partition b); +ERROR: relation "pxn_1_prt_c" already exists +select tableoid::regclass, * +from pxn; + tableoid | x | y +-------------+---+---- + pxn_1_prt_a | 1 | x1 + pxn_1_prt_c | 3 | x3 + pxn_1_prt_c | 4 | x4 + pxn_1_prt_a | 2 | x2 +(4 rows) + +select tableoid::regclass, * +from pxn +where y = 'x2'; +NOTICE: One or more columns in the following table(s) do not have statistics: pxn +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + tableoid | x | y +-------------+---+---- + pxn_1_prt_a | 2 | x2 +(1 row) + +select tableoid::regclass, * +from pxn +where x = 2; +NOTICE: One or more columns in the following table(s) do not have statistics: pxn +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + tableoid | x | y +-------------+---+---- + pxn_1_prt_a | 2 | x2 +(1 row) + +drop table if exists pxn; +create table pxn + (x int , y int) + distributed randomly + partition by range (y) + ( + partition a start (0) end (10), + partition c start (11) end (20) + ); +insert into pxn values + (4,4), + (9,9), + (14,14), + (19,19); +select tableoid::regclass, * +from pxn; + tableoid | x | y +-------------+----+---- + pxn_1_prt_a | 4 | 4 + pxn_1_prt_a | 9 | 9 + pxn_1_prt_c | 19 | 19 + pxn_1_prt_c | 14 | 14 +(4 rows) + +alter table pxn + split partition a at (5) + into (partition b, partition c); +ERROR: relation "pxn_1_prt_c" already exists +select tableoid::regclass, * +from pxn; + tableoid | x | y +-------------+----+---- + pxn_1_prt_a | 4 | 4 + pxn_1_prt_a | 9 | 9 + pxn_1_prt_c | 19 | 19 + pxn_1_prt_c | 14 | 14 +(4 rows) + +select tableoid::regclass, * +from pxn +where y = 4; +NOTICE: One or more columns in the following table(s) do not have statistics: pxn +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + tableoid | x | y +-------------+---+--- + pxn_1_prt_a | 4 | 4 +(1 row) + +select tableoid::regclass, * +from pxn +where x = 4; +NOTICE: One or more columns in the following table(s) do not have statistics: pxn +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + tableoid | x | y +-------------+---+--- + pxn_1_prt_a | 4 | 4 +(1 row) + +drop table if exists pxn; +create table pxn + (x int , y int) + distributed randomly + partition by range (y) + ( + partition a start (0) end (10), + partition c start (11) end (20) + ); +insert into pxn values + (4,4), + (9,9), + (14,14), + (19,19); +select tableoid::regclass, * +from pxn; + tableoid | x | y +-------------+----+---- + pxn_1_prt_c | 14 | 14 + pxn_1_prt_c | 19 | 19 + pxn_1_prt_a | 4 | 4 + pxn_1_prt_a | 9 | 9 +(4 rows) + +alter table pxn + split partition a at (5) + into (partition c, partition b); +ERROR: relation "pxn_1_prt_c" already exists +select tableoid::regclass, * +from pxn; + tableoid | x | y +-------------+----+---- + pxn_1_prt_c | 14 | 14 + pxn_1_prt_c | 19 | 19 + pxn_1_prt_a | 4 | 4 + pxn_1_prt_a | 9 | 9 +(4 rows) + +select tableoid::regclass, * +from pxn +where y = 9; +NOTICE: One or more columns in the following table(s) do not have statistics: pxn +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + tableoid | x | y +-------------+---+--- + pxn_1_prt_a | 9 | 9 +(1 row) + +select tableoid::regclass, * +from pxn +where x = 9; +NOTICE: One or more columns in the following table(s) do not have statistics: pxn +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + tableoid | x | y +-------------+---+--- + pxn_1_prt_a | 9 | 9 +(1 row) + +-- MPP-18359 end +-- MPP-19105 +-- Base partitions with trailing dropped columns +create table parttest_t ( + a int, + b int, + c char, + d varchar(50) +) distributed by (c) +partition by range (a) +( + partition p1 start(1) end(5), + partition p2 start(5) +); +-- Drop column +alter table parttest_t drop column d; +-- Alter table split partition +alter table parttest_t split partition for(1) at (2) into (partition p11, partition p22); +insert into parttest_t values(1,2,'a'); +select * from parttest_t; +NOTICE: One or more columns in the following table(s) do not have statistics: parttest_t +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + a | b | c +---+---+--- + 1 | 2 | a +(1 row) + +-- END MPP-19105 +reset optimizer_nestloop_factor; +-- Sub-partition insertion with checking if the user provided correct leaf part +create table part_tab ( i int, j int) distributed by (i) partition by range(j) (start(0) end(10) every(2)); +-- Wrong part +insert into part_tab_1_prt_1 values(5,5); +ERROR: new row for relation "part_tab_1_prt_1" violates partition constraint (seg2 172.18.0.2:7004 pid=22128) +DETAIL: Failing row contains (5, 5). +select * from part_tab; +NOTICE: One or more columns in the following table(s) do not have statistics: part_tab +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + i | j +---+--- +(0 rows) + +select * from part_tab_1_prt_1; + i | j +---+--- +(0 rows) + +insert into part_tab_1_prt_2 values(5,5); +ERROR: new row for relation "part_tab_1_prt_2" violates partition constraint (seg2 172.18.0.2:7004 pid=22128) +DETAIL: Failing row contains (5, 5). +select * from part_tab; +NOTICE: One or more columns in the following table(s) do not have statistics: part_tab +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + i | j +---+--- +(0 rows) + +select * from part_tab_1_prt_2; + i | j +---+--- +(0 rows) + +-- Right part +insert into part_tab_1_prt_3 values(5,5); +analyze part_tab; +select * from part_tab; + i | j +---+--- + 5 | 5 +(1 row) + +select * from part_tab_1_prt_3; + i | j +---+--- + 5 | 5 +(1 row) + +-- Root part +insert into part_tab values(5,5); +select * from part_tab; + i | j +---+--- + 5 | 5 + 5 | 5 +(2 rows) + +drop table if exists input1; +NOTICE: table "input1" does not exist, skipping +create table input1 (x int, y int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'x' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into input1 select i, i from (select generate_series(1,10) as i) as t; +drop table if exists input2; +NOTICE: table "input2" does not exist, skipping +create table input2 (x int, y int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'x' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into input2 select i, i from (select generate_series(1,10) as i) as t; +-- Multiple range table entries in the plan +insert into part_tab_1_prt_1 select i1.x, i2.y from input1 as i1 join input2 as i2 on i1.x = i2.x where i2.y = 5; +ERROR: new row for relation "part_tab_1_prt_1" violates partition constraint (seg2 172.18.0.2:7004 pid=22128) +DETAIL: Failing row contains (5, 5). +analyze part_tab; +select * from part_tab; + i | j +---+--- + 5 | 5 + 5 | 5 +(2 rows) + +select * from part_tab_1_prt_1; + i | j +---+--- +(0 rows) + +insert into part_tab_1_prt_2 select i1.x, i2.y from input1 as i1 join input2 as i2 on i1.x = i2.x where i2.y = 5; +ERROR: new row for relation "part_tab_1_prt_2" violates partition constraint (seg2 172.18.0.2:7004 pid=22128) +DETAIL: Failing row contains (5, 5). +select * from part_tab; + i | j +---+--- + 5 | 5 + 5 | 5 +(2 rows) + +select * from part_tab_1_prt_2; + i | j +---+--- +(0 rows) + +-- Right part +insert into part_tab_1_prt_3 select i1.x, i2.y from input1 as i1 join input2 as i2 on i1.x = i2.x where i1.x between 4 and 5; +select * from part_tab; + i | j +---+--- + 4 | 4 + 5 | 5 + 5 | 5 + 5 | 5 +(4 rows) + +select * from part_tab_1_prt_3; + i | j +---+--- + 4 | 4 + 5 | 5 + 5 | 5 + 5 | 5 +(4 rows) + +-- Root part but no matching part for i2.y == 10 +insert into part_tab select i1.x, i2.y from input1 as i1 join input2 as i2 on i1.x = i2.x; +ERROR: no partition of relation "part_tab" found for row (seg2 172.18.0.2:7004 pid=22128) +DETAIL: Partition key of the failing row contains (j) = (10). +select * from part_tab; + i | j +---+--- + 4 | 4 + 5 | 5 + 5 | 5 + 5 | 5 +(4 rows) + +-- Root part +insert into part_tab select i1.x, i2.y from input1 as i1 join input2 as i2 on i1.x = i2.x where i2.y < 10; +select * from part_tab; + i | j +---+--- + 1 | 1 + 5 | 5 + 5 | 5 + 5 | 5 + 5 | 5 + 6 | 6 + 9 | 9 + 2 | 2 + 3 | 3 + 4 | 4 + 4 | 4 + 7 | 7 + 8 | 8 +(13 rows) + +-- Multi-level partitioning +create table deep_part ( i int, j int, k int, s char(5)) +distributed by (i) +partition by list(s) +subpartition by range (j) subpartition template (start(1) end(10) every(2)) +subpartition by range (k) subpartition template (start(1) end(10) every(2)) +(partition female values('F'), partition male values('M')) +; +-- Intermediate partition insert is allowed +insert into deep_part_1_prt_male_2_prt_2 values(1,3,1,'M'); +-- but only if it's the right partition. +insert into deep_part_1_prt_male_2_prt_2 values(1,1,1,'M'); +ERROR: new row for relation "deep_part_1_prt_male_2_prt_2" violates partition constraint (seg1 172.18.0.2:7003 pid=22127) +DETAIL: Failing row contains (1, 1, 1, M ). +-- Wrong sub-partition (inserting a female value in male partition) +insert into deep_part_1_prt_male_2_prt_2_3_prt_2 values (1, 1, 1, 'F'); +ERROR: new row for relation "deep_part_1_prt_male_2_prt_2_3_prt_2" violates partition constraint (seg1 172.18.0.2:7003 pid=22127) +DETAIL: Failing row contains (1, 1, 1, F ). +select * from deep_part; + i | j | k | s +---+---+---+------- + 1 | 3 | 1 | M +(1 row) + +-- Correct leaf part +insert into deep_part_1_prt_male_2_prt_1_3_prt_1 values (1, 1, 1, 'M'); +analyze deep_part; +select * from deep_part; + i | j | k | s +---+---+---+------- + 1 | 1 | 1 | M + 1 | 3 | 1 | M +(2 rows) + +select * from deep_part_1_prt_male_2_prt_1_3_prt_1; + i | j | k | s +---+---+---+------- + 1 | 1 | 1 | M +(1 row) + +-- Root part of a multi-level partitioned table +insert into deep_part values (1, 1, 1, 'M'); +select * from deep_part; + i | j | k | s +---+---+---+------- + 1 | 1 | 1 | M + 1 | 1 | 1 | M + 1 | 3 | 1 | M +(3 rows) + +select * from deep_part_1_prt_male_2_prt_1_3_prt_1; + i | j | k | s +---+---+---+------- + 1 | 1 | 1 | M + 1 | 1 | 1 | M +(2 rows) + +insert into deep_part values (1, 1, 1, 'F'); +select * from deep_part; + i | j | k | s +---+---+---+------- + 1 | 1 | 1 | F + 1 | 1 | 1 | M + 1 | 1 | 1 | M + 1 | 3 | 1 | M +(4 rows) + +select * from deep_part_1_prt_female_2_prt_1_3_prt_1; + i | j | k | s +---+---+---+------- + 1 | 1 | 1 | F +(1 row) + +insert into deep_part values (5, 5, 5, 'M'); +select * from deep_part; + i | j | k | s +---+---+---+------- + 5 | 5 | 5 | M + 1 | 1 | 1 | F + 1 | 1 | 1 | M + 1 | 1 | 1 | M + 1 | 3 | 1 | M +(5 rows) + +select * from deep_part_1_prt_male_2_prt_3_3_prt_3; + i | j | k | s +---+---+---+------- + 5 | 5 | 5 | M +(1 row) + +insert into deep_part values (9, 9, 9, 'F'); +select * from deep_part; + i | j | k | s +---+---+---+------- + 9 | 9 | 9 | F + 5 | 5 | 5 | M + 1 | 1 | 1 | F + 1 | 1 | 1 | M + 1 | 1 | 1 | M + 1 | 3 | 1 | M +(6 rows) + +select * from deep_part_1_prt_female_2_prt_5_3_prt_5; + i | j | k | s +---+---+---+------- + 9 | 9 | 9 | F +(1 row) + +-- Out of range partition +insert into deep_part values (9, 9, 10, 'F'); +ERROR: no partition of relation "deep_part_1_prt_female_2_prt_5" found for row (seg2 172.18.0.2:7004 pid=22128) +DETAIL: Partition key of the failing row contains (k) = (10). +select * from deep_part; + i | j | k | s +---+---+---+------- + 1 | 1 | 1 | F + 1 | 1 | 1 | M + 1 | 1 | 1 | M + 1 | 3 | 1 | M + 9 | 9 | 9 | F + 5 | 5 | 5 | M +(6 rows) + +drop table input2; +drop table input1; +-- Avoid TupleDesc leak when COPY partition table from files +-- This also covers the bug reported in MPP-9548 where insertion +-- into a dropped/added column yielded incorrect results +drop table if exists pt_td_leak; +NOTICE: table "pt_td_leak" does not exist, skipping +CREATE TABLE pt_td_leak +( +col1 int, +col2 int, +col3 int +) +distributed by (col1) +partition by range(col2) +( + partition part1 start(1) end(5), + partition part2 start(5) end(10) +); +insert into pt_td_leak select i,i,i from generate_series(1,9) i; +copy pt_td_leak to '/tmp/pt_td_leak.out' csv; +NOTICE: One or more columns in the following table(s) do not have statistics: pt_td_leak +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. +alter table pt_td_leak drop column col3; +alter table pt_td_leak add column col3 int default 7; +drop table if exists pt_td_leak_exchange; +NOTICE: table "pt_td_leak_exchange" does not exist, skipping +CREATE TABLE pt_td_leak_exchange ( col1 int, col2 int, col3 int) distributed by (col1); +alter table pt_td_leak exchange partition part2 with table pt_td_leak_exchange; +insert into pt_td_leak values(1,8,1); +copy pt_td_leak from '/tmp/pt_td_leak.out' with delimiter ','; +select * from pt_td_leak where col1 = 5; +NOTICE: One or more columns in the following table(s) do not have statistics: pt_td_leak +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + col1 | col2 | col3 +------+------+------ + 5 | 5 | 5 +(1 row) + +-- Check that data inserted into dropped/added column is correct +select * from pt_td_leak where col3 = 1; +NOTICE: One or more columns in the following table(s) do not have statistics: pt_td_leak +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + col1 | col2 | col3 +------+------+------ + 1 | 1 | 1 + 1 | 8 | 1 +(2 rows) + +drop table pt_td_leak; +drop table pt_td_leak_exchange; +-- +-- Test COPY, when distribution keys have different attribute numbers, +-- because of dropped columns +-- +CREATE TABLE pt_dropped_col_distkey (i int, to_be_dropped text, t text) +DISTRIBUTED BY (t) PARTITION BY RANGE (i) (START (1) END(10) EVERY (5)); +INSERT INTO pt_dropped_col_distkey SELECT g, 'dropped' || g, 'before drop ' || g FROM generate_series(1, 7) g; +ALTER TABLE pt_dropped_col_distkey DROP COLUMN to_be_dropped; +-- This new partition won't have the dropped column. Because the distribution +-- key was after the dropped column, the attribute number of the distribution +-- key column will be different in this partition and the parent. +ALTER TABLE pt_dropped_col_distkey ADD PARTITION pt_dropped_col_distkey_new_part START (10) END (100); +INSERT INTO pt_dropped_col_distkey SELECT g, 'after drop ' || g FROM generate_series(8, 15) g; +SELECT * FROM pt_dropped_col_distkey ORDER BY i; +NOTICE: One or more columns in the following table(s) do not have statistics: pt_dropped_col_distkey +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + i | t +----+--------------- + 1 | before drop 1 + 2 | before drop 2 + 3 | before drop 3 + 4 | before drop 4 + 5 | before drop 5 + 6 | before drop 6 + 7 | before drop 7 + 8 | after drop 8 + 9 | after drop 9 + 10 | after drop 10 + 11 | after drop 11 + 12 | after drop 12 + 13 | after drop 13 + 14 | after drop 14 + 15 | after drop 15 +(15 rows) + +COPY pt_dropped_col_distkey TO '/tmp/pt_dropped_col_distkey.out'; +NOTICE: One or more columns in the following table(s) do not have statistics: pt_dropped_col_distkey +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. +DELETE FROM pt_dropped_col_distkey; +COPY pt_dropped_col_distkey FROM '/tmp/pt_dropped_col_distkey.out'; +SELECT * FROM pt_dropped_col_distkey ORDER BY i; +NOTICE: One or more columns in the following table(s) do not have statistics: pt_dropped_col_distkey +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + i | t +----+--------------- + 1 | before drop 1 + 2 | before drop 2 + 3 | before drop 3 + 4 | before drop 4 + 5 | before drop 5 + 6 | before drop 6 + 7 | before drop 7 + 8 | after drop 8 + 9 | after drop 9 + 10 | after drop 10 + 11 | after drop 11 + 12 | after drop 12 + 13 | after drop 13 + 14 | after drop 14 + 15 | after drop 15 +(15 rows) + +-- don't drop the table, so that we have a partitioned table like this still +-- in the database, when we test pg_upgrade later. +-- +-- Test split default partition while per tuple memory context is reset +-- +drop table if exists test_split_part cascade; +NOTICE: table "test_split_part" does not exist, skipping +CREATE TABLE test_split_part ( log_id int NOT NULL, f_array int[] NOT NULL) +DISTRIBUTED BY (log_id) +PARTITION BY RANGE(log_id) +( + START (1::int) END (100::int) EVERY (5) WITH (appendonly=false), + PARTITION "Old" START (101::int) END (201::int) WITH (appendonly=false), + DEFAULT PARTITION other_log_ids WITH (appendonly=false) +); +insert into test_split_part (log_id , f_array) select id, '{10}' from generate_series(1,1000) id; +ALTER TABLE test_split_part SPLIT DEFAULT PARTITION START (201) INCLUSIVE END (301) EXCLUSIVE INTO (PARTITION "New", DEFAULT PARTITION); +-- In GPDB 6 and below, an automatic array type was only created for the root +-- partition. Nowadays we rely on upstream partitioning code, which creates +-- an array type for all partition. +select typname, typtype, typcategory from pg_type where typname like '%test_split_part%' and typcategory = 'A'; + typname | typtype | typcategory +--------------------------------------+---------+------------- + _test_split_part | b | A + _test_split_part_1_prt_2 | b | A + _test_split_part_1_prt_3 | b | A + _test_split_part_1_prt_4 | b | A + _test_split_part_1_prt_5 | b | A + _test_split_part_1_prt_6 | b | A + _test_split_part_1_prt_7 | b | A + _test_split_part_1_prt_8 | b | A + _test_split_part_1_prt_9 | b | A + _test_split_part_1_prt_10 | b | A + _test_split_part_1_prt_11 | b | A + _test_split_part_1_prt_12 | b | A + _test_split_part_1_prt_13 | b | A + _test_split_part_1_prt_14 | b | A + _test_split_part_1_prt_15 | b | A + _test_split_part_1_prt_16 | b | A + _test_split_part_1_prt_17 | b | A + _test_split_part_1_prt_18 | b | A + _test_split_part_1_prt_19 | b | A + _test_split_part_1_prt_20 | b | A + _test_split_part_1_prt_21 | b | A + _test_split_part_1_prt_Old | b | A + _test_split_part_1_prt_New | b | A + _test_split_part_1_prt_other_log_ids | b | A +(24 rows) + +select array_agg(test_split_part) from test_split_part where log_id = 500; + array_agg +---------------- + {"(500,{10})"} +(1 row) + +select array_agg(test_split_part_1_prt_other_log_ids) from test_split_part_1_prt_other_log_ids where log_id = 500; + array_agg +---------------- + {"(500,{10})"} +(1 row) + +-- Originally reported in MPP-7232 +create table mpp7232a (a int, b int) distributed by (a) partition by range (b) (start (1) end (3) every (1)); +\d+ mpp7232a + Partitioned table "public.mpp7232a" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + a | integer | | | | plain | | + b | integer | | | | plain | | +Partition key: RANGE (b) +Partitions: mpp7232a_1_prt_1 FOR VALUES FROM (1) TO (2), + mpp7232a_1_prt_2 FOR VALUES FROM (2) TO (3) +Distributed by: (a) + +alter table mpp7232a rename partition for (1) to alpha; +alter table mpp7232a rename partition for (2) to bravo; +\d+ mpp7232a + Partitioned table "public.mpp7232a" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + a | integer | | | | plain | | + b | integer | | | | plain | | +Partition key: RANGE (b) +Partitions: mpp7232a_1_prt_alpha FOR VALUES FROM (1) TO (2), + mpp7232a_1_prt_bravo FOR VALUES FROM (2) TO (3) +Distributed by: (a) + +create table mpp7232b (a int, b int) distributed by (a) partition by range (b) (partition alpha start (1) end (3) every (1)); +alter table mpp7232b rename partition for (1) to foo; +\d+ mpp7232b + Partitioned table "public.mpp7232b" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + a | integer | | | | plain | | + b | integer | | | | plain | | +Partition key: RANGE (b) +Partitions: mpp7232b_1_prt_alpha_2 FOR VALUES FROM (2) TO (3), + mpp7232b_1_prt_foo FOR VALUES FROM (1) TO (2) +Distributed by: (a) + +-- Test .. WITH (tablename = ..) syntax. +create table mpp17740 (a integer, b integer, e date) with (appendonly = true, orientation = column) +distributed by (a) +partition by range(e) +( + partition mpp17740_20120523 start ('2012-05-23'::date) inclusive end ('2012-05-24'::date) exclusive with (tablename = 'mpp17740_20120523', appendonly = true), + partition mpp17740_20120524 start ('2012-05-24'::date) inclusive end ('2012-05-25'::date) exclusive with (tablename = 'mpp17740_20120524', appendonly = true) +); +select relname, pg_get_expr(relpartbound, oid) from pg_class where relname like 'mpp17740%'; + relname | pg_get_expr +-------------------+-------------------------------------------------- + mpp17740 | + mpp17740_20120523 | FOR VALUES FROM ('05-23-2012') TO ('05-24-2012') + mpp17740_20120524 | FOR VALUES FROM ('05-24-2012') TO ('05-25-2012') +(3 rows) + +alter table mpp17740 add partition mpp17740_20120520 start ('2012-05-20'::date) inclusive end ('2012-05-21'::date) exclusive with (tablename = 'mpp17740_20120520', appendonly=true); +select relname, pg_get_expr(relpartbound, oid) from pg_class where relname like 'mpp17740%'; + relname | pg_get_expr +-------------------+-------------------------------------------------- + mpp17740 | + mpp17740_20120520 | FOR VALUES FROM ('05-20-2012') TO ('05-21-2012') + mpp17740_20120523 | FOR VALUES FROM ('05-23-2012') TO ('05-24-2012') + mpp17740_20120524 | FOR VALUES FROM ('05-24-2012') TO ('05-25-2012') +(4 rows) + +-- Test mix of add and drop various column before split, and exchange partition at the end +create table sales (pkid serial, option1 int, option2 int, option3 int, constraint partable_pkey primary key(pkid, option3)) +distributed by (pkid) partition by range (option3) +( + partition aa start(1) end(100), + partition bb start(101) end(200), + partition cc start(201) end (300) +); +-- should error out since no subpartition in sales. +alter table sales add partition dd start(301) end(300) + ( subpartition opt1_1 VALUES (1), + subpartition opt1_2 VALUES (2) ); +ERROR: subpartition specification provided but table doesn't have SUBPARTITION BY clause +LINE 2: ( subpartition opt1_1 VALUES (1), + ^ +-- root partition (and only root) should have relfrozenxid as 0 +select relname, relkind from pg_class where relkind in ('r', 'p') and relname like 'sales%' and relfrozenxid=0; + relname | relkind +----------------------------+--------- + sales_1_prt_4 | p + sales_1_prt_5 | p + sales | p + sales_1_prt_outlying_dates | p + sales_1_prt_2 | p + sales_1_prt_3 | p + sales | p +(7 rows) + +select gp_segment_id, relname, relkind from gp_dist_random('pg_class') where relkind in ('r', 'p') and relname like 'sales%' and relfrozenxid=0; + gp_segment_id | relname | relkind +---------------+----------------------------+--------- + 1 | sales_1_prt_3 | p + 1 | sales_1_prt_4 | p + 1 | sales_1_prt_5 | p + 1 | sales | p + 1 | sales_1_prt_2 | p + 1 | sales_1_prt_outlying_dates | p + 1 | sales | p + 2 | sales_1_prt_5 | p + 2 | sales | p + 2 | sales | p + 2 | sales_1_prt_2 | p + 2 | sales_1_prt_3 | p + 2 | sales_1_prt_4 | p + 2 | sales_1_prt_outlying_dates | p + 0 | sales_1_prt_3 | p + 0 | sales_1_prt_4 | p + 0 | sales_1_prt_5 | p + 0 | sales | p + 0 | sales_1_prt_2 | p + 0 | sales_1_prt_outlying_dates | p + 0 | sales | p +(21 rows) + +alter table sales add column tax float; +-- root partition (and only root) continues to have relfrozenxid as 0 +select relname, relkind from pg_class where relkind in ('r', 'p') and relname like 'sales%' and relfrozenxid=0; + relname | relkind +----------------------------+--------- + sales_1_prt_4 | p + sales_1_prt_5 | p + sales | p + sales_1_prt_outlying_dates | p + sales_1_prt_2 | p + sales_1_prt_3 | p + sales | p +(7 rows) + +select gp_segment_id, relname, relkind from gp_dist_random('pg_class') where relkind in ('r', 'p') and relname like 'sales%' and relfrozenxid=0; + gp_segment_id | relname | relkind +---------------+----------------------------+--------- + 2 | sales_1_prt_5 | p + 2 | sales | p + 2 | sales | p + 2 | sales_1_prt_2 | p + 2 | sales_1_prt_3 | p + 2 | sales_1_prt_4 | p + 2 | sales_1_prt_outlying_dates | p + 0 | sales_1_prt_3 | p + 0 | sales_1_prt_4 | p + 0 | sales_1_prt_5 | p + 0 | sales | p + 0 | sales_1_prt_2 | p + 0 | sales_1_prt_outlying_dates | p + 0 | sales | p + 1 | sales_1_prt_3 | p + 1 | sales_1_prt_4 | p + 1 | sales_1_prt_5 | p + 1 | sales | p + 1 | sales_1_prt_2 | p + 1 | sales_1_prt_outlying_dates | p + 1 | sales | p +(21 rows) + +alter table sales drop column tax; +create table newpart(like sales); +NOTICE: table doesn't have 'DISTRIBUTED BY' clause, defaulting to distribution columns from LIKE table +alter table newpart add constraint newpart_pkey primary key(pkid, option3); +alter table sales split partition for(1) at (50) into (partition aa1, partition aa2); +select table_schema, table_name, constraint_name, constraint_type + from information_schema.table_constraints + where table_name in ('sales', 'newpart') + and constraint_name in ('partable_pkey', 'newpart_pkey') + order by table_name desc; + table_schema | table_name | constraint_name | constraint_type +--------------+------------+-----------------+----------------- + public | sales | partable_pkey | PRIMARY KEY + public | newpart | newpart_pkey | PRIMARY KEY +(2 rows) + +alter table sales exchange partition for (101) with table newpart; +select * from sales order by pkid; +NOTICE: One or more columns in the following table(s) do not have statistics: sales +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + pkid | option1 | option2 | option3 +------+---------+---------+--------- +(0 rows) + +-- Create exchange table before drop column, make sure the consistency check still exist +create table newpart2(like sales); +NOTICE: table doesn't have 'DISTRIBUTED BY' clause, defaulting to distribution columns from LIKE table +alter table sales drop column option2; +alter table sales exchange partition for (101) with table newpart2; +ERROR: table "newpart2" contains column "option2" not found in parent "sales" +DETAIL: The new partition may contain only the columns present in parent. +select * from sales order by pkid; +NOTICE: One or more columns in the following table(s) do not have statistics: sales +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + pkid | option1 | option3 +------+---------+--------- +(0 rows) + +drop table sales cascade; +NOTICE: drop cascades to default value for column pkid of table newpart +-- Exchage partition table with a table having dropped column +create table exchange_part(a int, b int) partition by range(b) (start (0) end (10) every (5)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +create table exchange1(a int, c int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +alter table exchange1 drop column c; +alter table exchange_part exchange partition for (1) with table exchange1; +copy exchange_part from STDIN DELIMITER as '|'; +select * from exchange_part; +NOTICE: One or more columns in the following table(s) do not have statistics: exchange_part +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + a | b +------+--- + 9810 | 2 + 9827 | 1 + 9828 | 2 + 9831 | 3 + 9817 | 5 + 9818 | 6 + 9825 | 9 + 9843 | 7 + 9844 | 8 + 9794 | 1 + 9797 | 3 + 9799 | 4 + 9808 | 1 + 9801 | 5 + 9802 | 6 + 9803 | 7 + 9806 | 8 + 9807 | 9 + 9822 | 7 + 9824 | 8 + 9836 | 5 + 9840 | 6 + 9795 | 2 + 9814 | 3 + 9815 | 4 + 9832 | 4 +(26 rows) + +drop table exchange_part; +drop table exchange1; +-- Ensure that new partitions get the correct attributes (MPP17110) +CREATE TABLE pt_tab_encode (a int, b text) +with (appendonly=true, orientation=column, compresstype=zlib, compresslevel=1) +distributed by (a) +partition by list(b) (partition s_abc values ('abc') with (appendonly=true, orientation=column, compresstype=zlib, compresslevel=1)); +alter table pt_tab_encode add partition "s_xyz" values ('xyz') WITH (appendonly=true, orientation=column, compresstype=zlib, compresslevel=1); +select relname, pg_get_expr(relpartbound, oid) from pg_class where relname like 'pt_tab_encode%'; + relname | pg_get_expr +---------------------------+----------------------- + pt_tab_encode | + pt_tab_encode_1_prt_s_abc | FOR VALUES IN ('abc') + pt_tab_encode_1_prt_s_xyz | FOR VALUES IN ('xyz') +(3 rows) + +select gp_segment_id, attrelid::regclass, attnum, filenum, attoptions from pg_attribute_encoding where attrelid = 'pt_tab_encode_1_prt_s_abc'::regclass; + gp_segment_id | attrelid | attnum | filenum | attoptions +---------------+---------------------------+--------+---------+----------------------------------------------------- + -1 | pt_tab_encode_1_prt_s_abc | 1 | 1 | {compresstype=zlib,compresslevel=1,blocksize=32768} + -1 | pt_tab_encode_1_prt_s_abc | 2 | 2 | {compresstype=zlib,compresslevel=1,blocksize=32768} +(2 rows) + +select gp_segment_id, attrelid::regclass, attnum, filenum, attoptions from gp_dist_random('pg_attribute_encoding') where attrelid = 'pt_tab_encode_1_prt_s_abc'::regclass order by 1,3 limit 5; + gp_segment_id | attrelid | attnum | filenum | attoptions +---------------+---------------------------+--------+---------+----------------------------------------------------- + 0 | pt_tab_encode_1_prt_s_abc | 1 | 1 | {compresstype=zlib,compresslevel=1,blocksize=32768} + 0 | pt_tab_encode_1_prt_s_abc | 2 | 2 | {compresstype=zlib,compresslevel=1,blocksize=32768} + 1 | pt_tab_encode_1_prt_s_abc | 1 | 1 | {compresstype=zlib,compresslevel=1,blocksize=32768} + 1 | pt_tab_encode_1_prt_s_abc | 2 | 2 | {compresstype=zlib,compresslevel=1,blocksize=32768} + 2 | pt_tab_encode_1_prt_s_abc | 1 | 1 | {compresstype=zlib,compresslevel=1,blocksize=32768} +(5 rows) + +select gp_segment_id, attrelid::regclass, attnum, filenum, attoptions from pg_attribute_encoding where attrelid = 'pt_tab_encode_1_prt_s_xyz'::regclass; + gp_segment_id | attrelid | attnum | filenum | attoptions +---------------+---------------------------+--------+---------+----------------------------------------------------- + -1 | pt_tab_encode_1_prt_s_xyz | 1 | 1 | {compresstype=zlib,compresslevel=1,blocksize=32768} + -1 | pt_tab_encode_1_prt_s_xyz | 2 | 2 | {compresstype=zlib,compresslevel=1,blocksize=32768} +(2 rows) + +select gp_segment_id, attrelid::regclass, attnum, filenum, attoptions from gp_dist_random('pg_attribute_encoding') where attrelid = 'pt_tab_encode_1_prt_s_xyz'::regclass order by 1,3 limit 5; + gp_segment_id | attrelid | attnum | filenum | attoptions +---------------+---------------------------+--------+---------+----------------------------------------------------- + 0 | pt_tab_encode_1_prt_s_xyz | 1 | 1 | {compresstype=zlib,compresslevel=1,blocksize=32768} + 0 | pt_tab_encode_1_prt_s_xyz | 2 | 2 | {compresstype=zlib,compresslevel=1,blocksize=32768} + 1 | pt_tab_encode_1_prt_s_xyz | 1 | 1 | {compresstype=zlib,compresslevel=1,blocksize=32768} + 1 | pt_tab_encode_1_prt_s_xyz | 2 | 2 | {compresstype=zlib,compresslevel=1,blocksize=32768} + 2 | pt_tab_encode_1_prt_s_xyz | 1 | 1 | {compresstype=zlib,compresslevel=1,blocksize=32768} +(5 rows) + +select c.oid::regclass, relkind, amname, reloptions from pg_class c left join pg_am am on am.oid = relam where c.oid = 'pt_tab_encode_1_prt_s_abc'::regclass; + oid | relkind | amname | reloptions +---------------------------+---------+-----------+------------------------------------- + pt_tab_encode_1_prt_s_abc | r | ao_column | {compresstype=zlib,compresslevel=1} +(1 row) + +select c.oid::regclass, relkind, amname, reloptions from pg_class c left join pg_am am on am.oid = relam where c.oid = 'pt_tab_encode_1_prt_s_xyz'::regclass; + oid | relkind | amname | reloptions +---------------------------+---------+-----------+------------------------------------- + pt_tab_encode_1_prt_s_xyz | r | ao_column | {compresstype=zlib,compresslevel=1} +(1 row) + +-- Ensure that only the correct type of partitions can be added +create table at_range (a int) partition by range (a) (start(1) end(5)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +create table at_list (i int) partition by list(i) (partition p1 values(1)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +alter table at_list add partition foo2 start(6) end (10); +ERROR: invalid boundary specification for LIST partition +LINE 1: alter table at_list add partition foo2 start(6) end (10); + ^ +alter table at_range add partition test values(5); +ERROR: invalid boundary specification for RANGE partition +LINE 1: alter table at_range add partition test values(5); + ^ +-- Ensure array type for the non-partition table is there after partition exchange. +CREATE TABLE pt_xchg(a int) PARTITION BY RANGE(a) (START(1) END(4) EVERY (2)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +create table xchg_tab1(a int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE SCHEMA xchg_schema; +create table xchg_schema.xchg_tab2(a int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +alter table pt_xchg exchange partition for (1) with table xchg_tab1; +alter table pt_xchg exchange partition for (3) with table xchg_schema.xchg_tab2; +select a.typowner=b.typowner from pg_type a join pg_type b on true where a.typname = 'xchg_tab1' and b.typname = '_xchg_tab1'; + ?column? +---------- + t +(1 row) + +select nspname from pg_namespace join pg_type on pg_namespace.oid = pg_type.typnamespace where pg_type.typname = 'xchg_tab1' or pg_type.typname = '_xchg_tab1'; + nspname +--------- + public + public +(2 rows) + +select nspname from pg_namespace join pg_type on pg_namespace.oid = pg_type.typnamespace where pg_type.typname = 'xchg_tab2' or pg_type.typname = '_xchg_tab2'; + nspname +------------- + xchg_schema + xchg_schema +(2 rows) + +select typname from pg_type where typelem = 'xchg_tab1'::regtype; + typname +------------ + _xchg_tab1 +(1 row) + +select typname from pg_type where typelem = 'xchg_schema.xchg_tab2'::regtype; + typname +------------ + _xchg_tab2 +(1 row) + +select typname from pg_type where typarray = '_xchg_tab1'::regtype; + typname +----------- + xchg_tab1 +(1 row) + +select typname from pg_type where typarray = 'xchg_schema._xchg_tab2'::regtype; + typname +----------- + xchg_tab2 +(1 row) + +alter table pt_xchg exchange partition for (1) with table xchg_tab1; +select a.typowner=b.typowner from pg_type a join pg_type b on true where a.typname = 'xchg_tab1' and b.typname = '_xchg_tab1'; + ?column? +---------- + t +(1 row) + +select nspname from pg_namespace join pg_type on pg_namespace.oid = pg_type.typnamespace where pg_type.typname = 'xchg_tab1' or pg_type.typname = '_xchg_tab1'; + nspname +--------- + public + public +(2 rows) + +select typname from pg_type where typelem = 'xchg_tab1'::regtype; + typname +------------ + _xchg_tab1 +(1 row) + +select typname from pg_type where typarray = '_xchg_tab1'::regtype; + typname +----------- + xchg_tab1 +(1 row) + +DROP SCHEMA xchg_schema CASCADE; +NOTICE: drop cascades to table xchg_schema.xchg_tab2 +-- Test with an incomplete operator class. Create a custom operator class and +-- only define equality on it. You can't do much with that. +-- +-- Before GPDB 7, Cloudberry used to allow creating the table, but you got an +-- error when inserting to it. Nowadays we rely on PostgreSQL partitioning +-- code, which rejects it at CREATE TABLE already. +create type employee_type as (empid int, empname text); +create function emp_equal(employee_type, employee_type) returns boolean + as 'select $1.empid = $2.empid;' + language sql + immutable + returns null on null input; +create operator = ( + leftarg = employee_type, + rightarg = employee_type, + procedure = emp_equal +); +create operator class employee_incomplete_op_class default for type employee_type + using btree as + operator 3 =; +create table employee_table(timest date, user_id numeric(16,0) not null, tag1 char(5), emp employee_type) + distributed by (user_id) + partition by list(emp) + (partition part1 values('(1, ''foo'')'::employee_type), partition part2 values('(2, ''foo'')'::employee_type)); +ERROR: operator class "employee_incomplete_op_class" of access method btree is missing support function 1 for type employee_type +-- Test partition table with ACL. +-- We grant default SELECT permission to a new user, this new user should be +-- able to SELECT from any partition table we create later. +-- (https://github.com/greenplum-db/gpdb/issues/9524) +DROP TABLE IF EXISTS user_prt_acl_append.t_part_acl; +NOTICE: schema "user_prt_acl_append" does not exist, skipping +NOTICE: schema "user_prt_acl_append" does not exist, skipping (seg1 172.18.0.2:7003 pid=22127) +NOTICE: schema "user_prt_acl_append" does not exist, skipping (seg2 172.18.0.2:7004 pid=22128) +NOTICE: schema "user_prt_acl_append" does not exist, skipping (seg0 172.18.0.2:7002 pid=22126) +DROP SCHEMA IF EXISTS user_prt_acl_append; +NOTICE: schema "user_prt_acl_append" does not exist, skipping +DROP ROLE IF EXISTS user_prt_acl_append; +NOTICE: role "user_prt_acl_append" does not exist, skipping +CREATE ROLE user_prt_acl_append; +NOTICE: resource queue required -- using default resource queue "pg_default" +CREATE SCHEMA schema_part_acl_append; +GRANT USAGE ON SCHEMA schema_part_acl_append TO user_prt_acl_append; +ALTER DEFAULT PRIVILEGES IN SCHEMA schema_part_acl_append GRANT SELECT ON TABLES TO user_prt_acl_append; +CREATE TABLE schema_part_acl_append.t_part_acl (dt date) +PARTITION BY RANGE (dt) +( + START (date '2019-12-01') INCLUSIVE + END (date '2020-02-01') EXCLUSIVE + EVERY (INTERVAL '1 month') +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'dt' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +INSERT INTO schema_part_acl_append.t_part_acl VALUES (date '2019-12-01'), (date '2020-01-31'); +-- check if parent and child table have same relacl +SELECT relname FROM pg_class +WHERE relname LIKE 't_part_acl%' + AND relacl = (SELECT relacl FROM pg_class WHERE relname = 't_part_acl'); + relname +-------------------- + t_part_acl + t_part_acl_1_prt_1 + t_part_acl_1_prt_2 +(3 rows) + +-- check if new user can SELECT all data +SET ROLE user_prt_acl_append; +SELECT * FROM schema_part_acl_append.t_part_acl; +NOTICE: One or more columns in the following table(s) do not have statistics: t_part_acl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + dt +------------ + 12-01-2019 + 01-31-2020 +(2 rows) + +RESET ROLE; +-- we don't drop the table, schema and role here in order to test upgrade +-- +-- Github issue: https://github.com/apache/cloudberry/issues/547 +-- Test COPY FROM on partitions tables. +-- +create table t_issue_547_aoco(a int, b int) partition by range(b) (start(1) end(34) every(1)) using ao_column distributed by (a); +\copy t_issue_547_aoco from 'data/partition_copy.csv' (format csv); +analyze t_issue_547_aoco; +select count(*) from t_issue_547_aoco; + count +------- + 1001 +(1 row) + +create table t_issue_547_ao(a int, b int) partition by range(b) (start(1) end(34) every(1)) using ao_row distributed by (a); +\copy t_issue_547_ao from 'data/partition_copy.csv' (format csv); +analyze t_issue_547_ao; +select count(*) from t_issue_547_ao; + count +------- + 1001 +(1 row) + +drop table t_issue_547_aoco; +drop table t_issue_547_ao; +-- test on commit behavior used on partition table +-- test on commit delete rows +begin; +create temp table temp_parent (a int) partition by range(a) (start(1) end(10) every(10)) on commit delete rows; +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into temp_parent select i from generate_series(1, 5) i; +select count(*) from temp_parent; +NOTICE: One or more columns in the following table(s) do not have statistics: temp_parent +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + count +------- + 5 +(1 row) + +commit; +-- DELETE ROWS will not cascaded to its partitions when we use DELETE ROWS behavior +select count(*) from temp_parent; +NOTICE: One or more columns in the following table(s) do not have statistics: temp_parent +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + count +------- + 5 +(1 row) + +drop table temp_parent; +-- test on commit drop +begin; +create temp table temp_parent (a int) partition by range(a) (start(1) end(10) every(1)) on commit drop; +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into temp_parent select i from generate_series(1, 5) i; +select count(*) from pg_class where relname like 'temp_parent_%'; + count +------- + 9 +(1 row) + +commit; +-- no relations remain in this case. +select count(*) from pg_class where relname like 'temp_parent_%'; + count +------- + 0 +(1 row) + +-- check ATTACH PARTITION on parent table with different distribution policy +CREATE EXTENSION IF NOT EXISTS gp_debug_numsegments; +SELECT gp_debug_set_create_table_default_numsegments(1); + gp_debug_set_create_table_default_numsegments +----------------------------------------------- + 1 +(1 row) + +CREATE TABLE expanded_parent(a int, b int) PARTITION BY RANGE(b) (START (0) END (6) EVERY (3)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE expanded_parent2(a int, b int) PARTITION BY RANGE(b) (START (0) END (6) EVERY (3)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE unexpanded_parent(a int, b int) PARTITION BY RANGE(b) (START (0) END (6) EVERY (3)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE unexpanded_attach(a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE unexpanded_attach2(a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE expanded_attach(a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE expanded_attach2(a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +SELECT gp_debug_reset_create_table_default_numsegments(); + gp_debug_reset_create_table_default_numsegments +------------------------------------------------- + +(1 row) + +-- attaching unexpanded partition to expanded table should fail +ALTER TABLE expanded_parent EXPAND TABLE; +ALTER TABLE expanded_parent ATTACH PARTITION unexpanded_attach FOR VALUES FROM (6) TO (9); +ERROR: distribution policy for "unexpanded_attach" must be the same as that for "expanded_parent" +-- attaching unexpanded partition to expanded table with partition prepare should fail +ALTER TABLE expanded_parent2 EXPAND PARTITION PREPARE; +ALTER TABLE expanded_parent2 ATTACH PARTITION unexpanded_attach2 FOR VALUES FROM (6) TO (9); +ERROR: distribution policy for "unexpanded_attach2" must be the same as that for "expanded_parent2" +-- attaching expanded partition to unexpanded table should fail +ALTER TABLE expanded_attach EXPAND TABLE; +ALTER TABLE unexpanded_parent ATTACH PARTITION expanded_attach FOR VALUES FROM (6) TO (9); +ERROR: distribution policy for "expanded_attach" must be the same as that for "unexpanded_parent" +-- attaching expanded partition to expanded table should succeed +ALTER TABLE expanded_attach2 EXPAND TABLE; +ALTER TABLE expanded_parent2 ATTACH PARTITION expanded_attach2 FOR VALUES FROM (6) TO (9); +ALTER TABLE expanded_parent ATTACH PARTITION expanded_attach FOR VALUES FROM (6) TO (9); +-- cleanup +DROP TABLE expanded_parent; +DROP TABLE expanded_parent2; +DROP TABLE unexpanded_parent; +DROP TABLE unexpanded_attach; +DROP TABLE unexpanded_attach2; +-- +-- Verify inheritance behavior of new partition child using various syntax +-- +-- set owner for partition root (should be inherited except for ATTACH, EXCHANGE) +CREATE ROLE part_inherit_role CREATEROLE; +NOTICE: resource queue required -- using default resource queue "pg_default" +GRANT CREATE ON SCHEMA public TO part_inherit_role; +CREATE ROLE part_inherit_other_role IN ROLE part_inherit_role; +NOTICE: resource queue required -- using default resource queue "pg_default" +CREATE ROLE part_inherit_priv_role; +NOTICE: resource queue required -- using default resource queue "pg_default" +CREATE ROLE part_inherit_attach_priv_role; +NOTICE: resource queue required -- using default resource queue "pg_default" +CREATE ROLE part_inherit_exchange_out_priv_role; +NOTICE: resource queue required -- using default resource queue "pg_default" +SET ROLE part_inherit_role; +CREATE TABLE part_inherit ( + a int, + b int, +-- non-partition constraint should be inherited except for ATTACH, EXCHANGE + CONSTRAINT con1 CHECK (a >= 0) +) +PARTITION BY RANGE (a) +SUBPARTITION BY RANGE (b) +SUBPARTITION TEMPLATE +(SUBPARTITION l2_child START(10100) END(10200)) +(DEFAULT PARTITION l1_default, + PARTITION l1_child1 START (0) END (100), + PARTITION l1_to_split START (100) END (200), + PARTITION l1_to_exchange START (200) END (300)) +--AM and reloption should be inherited except for ATTACH, EXCHANGE +WITH (appendonly = TRUE, compresslevel = 7); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +-- Set more properties for the root. +-- index are inherited +CREATE INDEX part_inherit_i on part_inherit(a); +-- privileges are inherited except for ATTACH, EXCHANGE +GRANT UPDATE ON part_inherit TO part_inherit_priv_role; +-- triggers are inherited except for subpartitions +-- FIXME: In 6X we used to not inherit triggers at all, in 7X we start to inherit +-- trigger like the upstream, but the subpartitions created from the subpartition +-- template still don't inherit the triggers. We should fix that. +CREATE FUNCTION part_inherit_trig() RETURNS TRIGGER LANGUAGE plpgsql + AS $$ BEGIN RETURN NULL; END $$; +CREATE TRIGGER part_inherit_tg AFTER INSERT ON part_inherit + FOR EACH ROW EXECUTE FUNCTION part_inherit_trig(); +-- rules are not inherited +CREATE RULE part_inherit_rule AS ON UPDATE TO part_inherit DO INSERT INTO part_inherit values(1); +-- row-level security policies are not inherited +ALTER TABLE part_inherit ENABLE ROW LEVEL SECURITY; +-- Check the current status +SELECT c.relname, + c.reloptions, + c.relkind, + a.amname as am, + c.relhasindex as hasindex, + r.rolname as owner, + c.relacl as acl, + c.relchecks as numchecks, + c.relhasrules as hasrules, + c.relhastriggers as hastriggers, + c.relrowsecurity as rowsecurity +FROM pg_class c join pg_roles r on c.relowner = r.oid + join pg_am a on c.relam = a.oid +WHERE c.relname LIKE 'part_inherit%' AND + c.relkind NOT IN ('i', 'I'); + relname | reloptions | relkind | am | hasindex | owner | acl | numchecks | hasrules | hastriggers | rowsecurity +--------------------------------------------------+-------------------+---------+--------+----------+-------------------+------------------------------------------------------------------------------------------+-----------+----------+-------------+------------- + part_inherit_1_prt_l1_to_exchange_2_prt_l2_child | {compresslevel=7} | r | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit | {compresslevel=7} | p | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | t | t | t + part_inherit_1_prt_l1_default | {compresslevel=7} | p | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_1_prt_l1_child1 | {compresslevel=7} | p | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_1_prt_l1_to_split | {compresslevel=7} | p | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_1_prt_l1_to_exchange | {compresslevel=7} | p | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_1_prt_l1_default_2_prt_l2_child | {compresslevel=7} | r | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_1_prt_l1_child1_2_prt_l2_child | {compresslevel=7} | r | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_1_prt_l1_to_split_2_prt_l2_child | {compresslevel=7} | r | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f +(9 rows) + +-- Now create child partitions in various forms +-- set an alternative role +SET ROLE part_inherit_other_role; +-- CREATE TABLE PARTITION OF +CREATE TABLE part_inherit_partof PARTITION OF part_inherit FOR VALUES FROM (300) TO (400); +NOTICE: table has parent, setting distribution columns to match parent table +SELECT c.relname, + c.reloptions, + c.relkind, + a.amname as am, + c.relhasindex as hasindex, + r.rolname as owner, + c.relacl as acl, + c.relchecks as numchecks, + c.relhasrules as hasrules, + c.relhastriggers as hastriggers, + c.relrowsecurity as rowsecurity +FROM pg_class c join pg_roles r on c.relowner = r.oid + join pg_am a on c.relam = a.oid +WHERE c.relname = 'part_inherit_partof'; + relname | reloptions | relkind | am | hasindex | owner | acl | numchecks | hasrules | hastriggers | rowsecurity +---------------------+-------------------+---------+--------+----------+-------------------------+------------------------------------------------------------------------------------------+-----------+----------+-------------+------------- + part_inherit_partof | {compresslevel=7} | r | ao_row | t | part_inherit_other_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f +(1 row) + +-- Now create child partitions in various forms +-- ATTACH PARTITION +-- error if the partition-to-be doesn't have the same constraint as the parent. +CREATE TABLE part_inherit_attach(a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +ALTER TABLE part_inherit ATTACH PARTITION part_inherit_attach FOR VALUES FROM (400) TO (500); +ERROR: child table is missing constraint "con1" +DROP TABLE part_inherit_attach; +-- good case: have the same constraint as parent. Can have other constraint too. +CREATE TABLE part_inherit_attach(a int, b int, CONSTRAINT con1 CHECK (a>=0), CONSTRAINT con2 CHECK (b>=0)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +-- reloptions and AM ('heap' which is different than the future parent) will be kept +ALTER TABLE part_inherit_attach SET (fillfactor=30); +-- privilege will be kept +GRANT UPDATE ON part_inherit_attach TO part_inherit_attach_priv_role; +-- do the attach +ALTER TABLE part_inherit ATTACH PARTITION part_inherit_attach FOR VALUES FROM (400) TO (500); +SELECT c.relname, + c.reloptions, + c.relkind, + a.amname as am, + c.relhasindex as hasindex, + r.rolname as owner, + c.relacl as acl, + c.relchecks as numchecks, + c.relhasrules as hasrules, + c.relhastriggers as hastriggers, + c.relrowsecurity as rowsecurity +FROM pg_class c join pg_roles r on c.relowner = r.oid + join pg_am a on c.relam = a.oid +WHERE c.relname = 'part_inherit_attach'; + relname | reloptions | relkind | am | hasindex | owner | acl | numchecks | hasrules | hastriggers | rowsecurity +---------------------+-----------------+---------+------+----------+-------------------------+-------------------------------------------------------------------------------------------------------------------+-----------+----------+-------------+------------- + part_inherit_attach | {fillfactor=30} | r | heap | t | part_inherit_other_role | {part_inherit_other_role=arwdDxt/part_inherit_other_role,part_inherit_attach_priv_role=w/part_inherit_other_role} | 2 | f | t | f +(1 row) + +-- ADD PARTITION +ALTER TABLE part_inherit ADD PARTITION added START(500) END(600); +SELECT c.relname, + c.reloptions, + c.relkind, + a.amname as am, + c.relhasindex as hasindex, + r.rolname as owner, + c.relacl as acl, + c.relchecks as numchecks, + c.relhasrules as hasrules, + c.relhastriggers as hastriggers, + c.relrowsecurity as rowsecurity +FROM pg_class c join pg_roles r on c.relowner = r.oid + join pg_am a on c.relam = a.oid +WHERE c.relname LIKE 'part_inherit_1_prt_added%' AND + c.relkind NOT IN ('i', 'I'); + relname | reloptions | relkind | am | hasindex | owner | acl | numchecks | hasrules | hastriggers | rowsecurity +-----------------------------------------+-------------------+---------+--------+----------+-------------------+------------------------------------------------------------------------------------------+-----------+----------+-------------+------------- + part_inherit_1_prt_added | {compresslevel=7} | p | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_1_prt_added_2_prt_l2_child | {compresslevel=7} | r | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f +(2 rows) + +-- EXCHANGE PARTITION - same behavior as ATTACH PARTITION +-- error if the partition-to-be doesn't have the same constraint as the parent. +CREATE TABLE part_inherit_exchange_out(a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +ALTER TABLE part_inherit_1_prt_l1_to_exchange EXCHANGE PARTITION l2_child WITH TABLE part_inherit_exchange_out; +ERROR: child table is missing constraint "con1" +DROP TABLE part_inherit_exchange_out; +-- good case: have the same constraint as parent. Can have other constraint too. +CREATE TABLE part_inherit_exchange_out(a int, b int, CONSTRAINT con1 CHECK (a>=0), CONSTRAINT con2 CHECK (b>=0)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +-- reloptions and AM ('heap' which is different than the future parent) will be kept +ALTER TABLE part_inherit_exchange_out SET (fillfactor=30); +-- privilege will be kept +GRANT UPDATE ON part_inherit_exchange_out TO part_inherit_exchange_out_priv_role; +-- do the exchange +ALTER TABLE part_inherit_1_prt_l1_to_exchange EXCHANGE PARTITION l2_child WITH TABLE part_inherit_exchange_out; +SELECT c.relname, + c.reloptions, + c.relkind, + a.amname as am, + c.relhasindex as hasindex, + r.rolname as owner, + c.relacl as acl, + c.relchecks as numchecks, + c.relhasrules as hasrules, + c.relhastriggers as hastriggers, + c.relrowsecurity as rowsecurity +FROM pg_class c join pg_roles r on c.relowner = r.oid + join pg_am a on c.relam = a.oid +WHERE (c.relname LIKE 'part_inherit_1_prt_l1_to_exchange%' OR c.relname = 'part_inherit_exchange_out') + AND c.relkind NOT IN ('i', 'I'); + relname | reloptions | relkind | am | hasindex | owner | acl | numchecks | hasrules | hastriggers | rowsecurity +--------------------------------------------------+-------------------+---------+--------+----------+-------------------------+-------------------------------------------------------------------------------------------------------------------------+-----------+----------+-------------+------------- + part_inherit_1_prt_l1_to_exchange | {compresslevel=7} | p | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_1_prt_l1_to_exchange_2_prt_l2_child | {fillfactor=30} | r | heap | t | part_inherit_other_role | {part_inherit_other_role=arwdDxt/part_inherit_other_role,part_inherit_exchange_out_priv_role=w/part_inherit_other_role} | 2 | f | t | f + part_inherit_exchange_out | {compresslevel=7} | r | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f +(3 rows) + +-- SPLIT PARTITION +ALTER TABLE part_inherit_1_prt_l1_to_split SPLIT PARTITION l2_child AT (10150) INTO (PARTITION split1, PARTITION split2); +SELECT c.relname, + c.reloptions, + c.relkind, + a.amname as am, + c.relhasindex as hasindex, + r.rolname as owner, + c.relacl as acl, + c.relchecks as numchecks, + c.relhasrules as hasrules, + c.relhastriggers as hastriggers, + c.relrowsecurity as rowsecurity +FROM pg_class c join pg_roles r on c.relowner = r.oid + join pg_am a on c.relam = a.oid +WHERE c.relname LIKE 'part_inherit_1_prt_l1_to_split%' AND + c.relkind NOT IN ('i', 'I'); + relname | reloptions | relkind | am | hasindex | owner | acl | numchecks | hasrules | hastriggers | rowsecurity +---------------------------------------------+-------------------+---------+--------+----------+-------------------+------------------------------------------------------------------------------------------+-----------+----------+-------------+------------- + part_inherit_1_prt_l1_to_split | {compresslevel=7} | p | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_1_prt_l1_to_split_2_prt_split2 | {compresslevel=7} | r | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_1_prt_l1_to_split_2_prt_split1 | {compresslevel=7} | r | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f +(3 rows) + +-- Now print everything for comparison +SELECT c.relname, + c.reloptions, + c.relkind, + a.amname as am, + c.relhasindex as hasindex, + r.rolname as owner, + c.relacl as acl, + c.relchecks as numchecks, + c.relhasrules as hasrules, + c.relhastriggers as hastriggers, + c.relrowsecurity as rowsecurity +FROM pg_class c join pg_roles r on c.relowner = r.oid + join pg_am a on c.relam = a.oid +WHERE c.relname LIKE 'part_inherit%' AND + c.relkind NOT IN ('i', 'I'); + relname | reloptions | relkind | am | hasindex | owner | acl | numchecks | hasrules | hastriggers | rowsecurity +--------------------------------------------------+-------------------+---------+--------+----------+-------------------------+-------------------------------------------------------------------------------------------------------------------------+-----------+----------+-------------+------------- + part_inherit | {compresslevel=7} | p | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | t | t | t + part_inherit_1_prt_l1_default | {compresslevel=7} | p | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_partof | {compresslevel=7} | r | ao_row | t | part_inherit_other_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_1_prt_l1_child1 | {compresslevel=7} | p | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_1_prt_l1_to_split | {compresslevel=7} | p | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_1_prt_l1_to_exchange | {compresslevel=7} | p | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_1_prt_l1_default_2_prt_l2_child | {compresslevel=7} | r | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_attach | {fillfactor=30} | r | heap | t | part_inherit_other_role | {part_inherit_other_role=arwdDxt/part_inherit_other_role,part_inherit_attach_priv_role=w/part_inherit_other_role} | 2 | f | t | f + part_inherit_1_prt_l1_child1_2_prt_l2_child | {compresslevel=7} | r | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_1_prt_added | {compresslevel=7} | p | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_1_prt_l1_to_split_2_prt_split2 | {compresslevel=7} | r | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_1_prt_added_2_prt_l2_child | {compresslevel=7} | r | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_1_prt_l1_to_exchange_2_prt_l2_child | {fillfactor=30} | r | heap | t | part_inherit_other_role | {part_inherit_other_role=arwdDxt/part_inherit_other_role,part_inherit_exchange_out_priv_role=w/part_inherit_other_role} | 2 | f | t | f + part_inherit_exchange_out | {compresslevel=7} | r | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f + part_inherit_1_prt_l1_to_split_2_prt_split1 | {compresslevel=7} | r | ao_row | t | part_inherit_role | {part_inherit_role=arwdDxt/part_inherit_role,part_inherit_priv_role=w/part_inherit_role} | 1 | f | t | f +(15 rows) + +RESET ROLE; +DROP TABLE part_inherit; +DROP FUNCTION part_inherit_trig CASCADE; +DROP TABLE part_inherit_exchange_out; +REVOKE CREATE ON SCHEMA public FROM part_inherit_role; +DROP ROLE part_inherit_role; +DROP ROLE part_inherit_other_role; +DROP ROLE part_inherit_priv_role; +DROP ROLE part_inherit_attach_priv_role; +DROP ROLE part_inherit_exchange_out_priv_role; +--Test cases for data selection from range partitioned tables with predicate on date or timestamp type------------- +drop table if exists test_rangePartition; +NOTICE: table "test_rangepartition" does not exist, skipping +create table public.test_rangePartition +(datedday date) + WITH ( + appendonly=false + ) + PARTITION BY RANGE(datedday) +( + PARTITION pn_20221022 START ('2022-10-22'::date) END ('2022-10-23'::date), + PARTITION pn_20221023 START ('2022-10-23'::date) END ('2022-10-24'::date), + DEFAULT PARTITION pdefault + ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'datedday' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into public.test_rangePartition(datedday) +select ('2022-10-22'::date) +union +select ('2022-10-23'::date); +--Test case with condition on date and timestamp +explain (costs off) select max(datedday) from public.test_rangePartition where datedday='2022-10-23' or datedday=('2022-10-23'::date -interval '1 day'); +NOTICE: One or more columns in the following table(s) do not have statistics: test_rangepartition +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------- + Finalize Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Partial Aggregate + -> Append + -> Seq Scan on test_rangepartition_1_prt_pn_20221022 + Filter: ((datedday = '10-23-2022'::date) OR (datedday = 'Sat Oct 22 00:00:00 2022'::timestamp without time zone)) + -> Seq Scan on test_rangepartition_1_prt_pn_20221023 + Filter: ((datedday = '10-23-2022'::date) OR (datedday = 'Sat Oct 22 00:00:00 2022'::timestamp without time zone)) + Optimizer: GPORCA +(9 rows) + +select max(datedday) from public.test_rangePartition where datedday='2022-10-23' or datedday=('2022-10-23'::date -interval '1 day'); +NOTICE: One or more columns in the following table(s) do not have statistics: test_rangepartition +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + max +------------ + 10-23-2022 +(1 row) + +--Test case with condition on date and timestamp +explain (costs off) select max(datedday) from public.test_rangePartition where datedday='2022-10-23' or datedday='2022-10-22'; +NOTICE: One or more columns in the following table(s) do not have statistics: test_rangepartition +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Finalize Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Partial Aggregate + -> Append + -> Seq Scan on test_rangepartition_1_prt_pn_20221022 + Filter: ((datedday = '10-23-2022'::date) OR (datedday = '10-22-2022'::date)) + -> Seq Scan on test_rangepartition_1_prt_pn_20221023 + Filter: ((datedday = '10-23-2022'::date) OR (datedday = '10-22-2022'::date)) + Optimizer: GPORCA +(9 rows) + +select max(datedday) from public.test_rangePartition where datedday='2022-10-23' or datedday='2022-10-22'; +NOTICE: One or more columns in the following table(s) do not have statistics: test_rangepartition +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + max +------------ + 10-23-2022 +(1 row) + +--Test case with condition on timestamp and timestamp +explain (costs off) select max(datedday) from public.test_rangePartition where datedday=('2022-10-23'::date -interval '0 day') or datedday=('2022-10-23'::date -interval '1 day'); +NOTICE: One or more columns in the following table(s) do not have statistics: test_rangepartition +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Finalize Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Partial Aggregate + -> Append + -> Seq Scan on test_rangepartition_1_prt_pn_20221022 + Filter: ((datedday = 'Sun Oct 23 00:00:00 2022'::timestamp without time zone) OR (datedday = 'Sat Oct 22 00:00:00 2022'::timestamp without time zone)) + -> Seq Scan on test_rangepartition_1_prt_pn_20221023 + Filter: ((datedday = 'Sun Oct 23 00:00:00 2022'::timestamp without time zone) OR (datedday = 'Sat Oct 22 00:00:00 2022'::timestamp without time zone)) + Optimizer: GPORCA +(9 rows) + +select max(datedday) from public.test_rangePartition where datedday=('2022-10-23'::date -interval '0 day') or datedday=('2022-10-23'::date -interval '1 day'); +NOTICE: One or more columns in the following table(s) do not have statistics: test_rangepartition +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + max +------------ + 10-23-2022 +(1 row) + +--Test case with condition on date and timestamp +explain (costs off) select datedday from public.test_rangePartition where datedday='2022-10-23' or datedday=('2022-10-23'::date -interval '1 day'); +NOTICE: One or more columns in the following table(s) do not have statistics: test_rangepartition +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Append + -> Seq Scan on test_rangepartition_1_prt_pn_20221022 + Filter: ((datedday = '10-23-2022'::date) OR (datedday = 'Sat Oct 22 00:00:00 2022'::timestamp without time zone)) + -> Seq Scan on test_rangepartition_1_prt_pn_20221023 + Filter: ((datedday = '10-23-2022'::date) OR (datedday = 'Sat Oct 22 00:00:00 2022'::timestamp without time zone)) + Optimizer: GPORCA +(7 rows) + +select datedday from public.test_rangePartition where datedday='2022-10-23' or datedday=('2022-10-23'::date -interval '1 day'); +NOTICE: One or more columns in the following table(s) do not have statistics: test_rangepartition +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + datedday +------------ + 10-23-2022 + 10-22-2022 +(2 rows) + +drop table test_rangePartition; +--Test cases for data selection from List partitioned tables with predicate on date or timestamp type------------- +drop table if exists test_listPartition; +NOTICE: table "test_listpartition" does not exist, skipping +create table test_listPartition (i int, d date) + partition by list(d) + (partition p1 values('2022-10-22'), partition p2 values('2022-10-23'), + default partition pdefault ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into test_listPartition values(1,'2022-10-22'); +insert into test_listPartition values(2,'2022-10-23'); +insert into test_listPartition values(3,'2022-10-24'); +--Test case with condition on date and timestamp +explain (costs off) select max(d) from test_listPartition where d='2022-10-23' or d=('2022-10-23'::date -interval '1 day'); +NOTICE: One or more columns in the following table(s) do not have statistics: test_listpartition +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- + Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Append + -> Seq Scan on test_listpartition_1_prt_p1 + Filter: ((d = '10-23-2022'::date) OR (d = 'Sat Oct 22 00:00:00 2022'::timestamp without time zone)) + -> Seq Scan on test_listpartition_1_prt_p2 + Filter: ((d = '10-23-2022'::date) OR (d = 'Sat Oct 22 00:00:00 2022'::timestamp without time zone)) + Optimizer: GPORCA +(8 rows) + +select max(d) from test_listPartition where d='2022-10-23' or d=('2022-10-23'::date -interval '1 day'); +NOTICE: One or more columns in the following table(s) do not have statistics: test_listpartition +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + max +------------ + 10-23-2022 +(1 row) + +--Test case with condition on date and date +explain (costs off) select max(d) from test_listPartition where d='2022-10-23' or d='2022-10-22'; +NOTICE: One or more columns in the following table(s) do not have statistics: test_listpartition +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +------------------------------------------------------------------------------------ + Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Append + -> Seq Scan on test_listpartition_1_prt_p1 + Filter: ((d = '10-23-2022'::date) OR (d = '10-22-2022'::date)) + -> Seq Scan on test_listpartition_1_prt_p2 + Filter: ((d = '10-23-2022'::date) OR (d = '10-22-2022'::date)) + Optimizer: GPORCA +(8 rows) + +select max(d) from test_listPartition where d='2022-10-23' or d='2022-10-22'; +NOTICE: One or more columns in the following table(s) do not have statistics: test_listpartition +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + max +------------ + 10-23-2022 +(1 row) + +--Test case with condition on timestamp and timestamp +explain (costs off) select max(d) from test_listPartition where d=('2022-10-23'::date -interval '0 day') or d=('2022-10-23'::date -interval '1 day'); +NOTICE: One or more columns in the following table(s) do not have statistics: test_listpartition +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------- + Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Append + -> Seq Scan on test_listpartition_1_prt_p1 + Filter: ((d = 'Sun Oct 23 00:00:00 2022'::timestamp without time zone) OR (d = 'Sat Oct 22 00:00:00 2022'::timestamp without time zone)) + -> Seq Scan on test_listpartition_1_prt_p2 + Filter: ((d = 'Sun Oct 23 00:00:00 2022'::timestamp without time zone) OR (d = 'Sat Oct 22 00:00:00 2022'::timestamp without time zone)) + Optimizer: GPORCA +(8 rows) + +select max(d) from test_listPartition where d=('2022-10-23'::date -interval '0 day') or d=('2022-10-23'::date -interval '1 day'); +NOTICE: One or more columns in the following table(s) do not have statistics: test_listpartition +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + max +------------ + 10-23-2022 +(1 row) + +--Test case with condition on timestamp and timestamp +explain (costs off) select d from test_listPartition where d='2022-10-23' or d=('2022-10-23'::date -interval '1 day'); +NOTICE: One or more columns in the following table(s) do not have statistics: test_listpartition +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Append + -> Seq Scan on test_listpartition_1_prt_p1 + Filter: ((d = '10-23-2022'::date) OR (d = 'Sat Oct 22 00:00:00 2022'::timestamp without time zone)) + -> Seq Scan on test_listpartition_1_prt_p2 + Filter: ((d = '10-23-2022'::date) OR (d = 'Sat Oct 22 00:00:00 2022'::timestamp without time zone)) + Optimizer: GPORCA +(7 rows) + +select d from test_listPartition where d='2022-10-23' or d=('2022-10-23'::date -interval '1 day'); +NOTICE: One or more columns in the following table(s) do not have statistics: test_listpartition +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + d +------------ + 10-23-2022 + 10-22-2022 +(2 rows) + +drop table test_listPartition; +-- test guc gp_max_partition_level +drop table p3_sales; +ERROR: table "p3_sales" does not exist +set gp_max_partition_level = 2; +CREATE TABLE p3_sales (id int, year int, month int, day int, +region text) +DISTRIBUTED BY (id) +PARTITION BY RANGE (year) + SUBPARTITION BY RANGE (month) + SUBPARTITION TEMPLATE ( + START (1) END (3) EVERY (1), + DEFAULT SUBPARTITION other_months ) + SUBPARTITION BY LIST (region) + SUBPARTITION TEMPLATE ( + SUBPARTITION usa VALUES ('usa'), + SUBPARTITION europe VALUES ('europe'), + DEFAULT SUBPARTITION other_regions ) +( START (2010) END (2012) EVERY (1), + DEFAULT PARTITION outlying_years ); +ERROR: Exceeds maximum configured partitioning level of 2 +set gp_max_partition_level = 3; +CREATE TABLE p3_sales (id int, year int, month int, day int, +region text) +DISTRIBUTED BY (id) +PARTITION BY RANGE (year) + SUBPARTITION BY RANGE (month) + SUBPARTITION TEMPLATE ( + START (1) END (3) EVERY (1), + DEFAULT SUBPARTITION other_months ) + SUBPARTITION BY LIST (region) + SUBPARTITION TEMPLATE ( + SUBPARTITION usa VALUES ('usa'), + SUBPARTITION europe VALUES ('europe'), + DEFAULT SUBPARTITION other_regions ) +( START (2010) END (2012) EVERY (1), + DEFAULT PARTITION outlying_years ); +drop table p3_sales; +set gp_max_partition_level = 0; +CREATE TABLE p3_sales (id int, year int, month int, day int, +region text) +DISTRIBUTED BY (id) +PARTITION BY RANGE (year) + SUBPARTITION BY RANGE (month) + SUBPARTITION TEMPLATE ( + START (1) END (3) EVERY (1), + DEFAULT SUBPARTITION other_months ) + SUBPARTITION BY LIST (region) + SUBPARTITION TEMPLATE ( + SUBPARTITION usa VALUES ('usa'), + SUBPARTITION europe VALUES ('europe'), + DEFAULT SUBPARTITION other_regions ) +( START (2010) END (2012) EVERY (1), + DEFAULT PARTITION outlying_years ); +drop table p3_sales; +-- We should not allow subpartition by clause when creating empty partition hierarchy +-- Should error out +CREATE TABLE empty_partition_disallow_subpartition(i int, j int) +PARTITION BY range(i) SUBPARTITION BY range(j); +ERROR: SUBPARTITION BY clause is not allowed when no partitions specified at depth 1 +-- Check with other Partition syntax +CREATE TABLE empty_partition_disallow_subpartition_2(i int, j int) + DISTRIBUTED BY (i) PARTITION BY range(i) SUBPARTITION BY range(j); +ERROR: SUBPARTITION BY clause is not allowed when no partitions specified at depth 1 +-- Should work fine for empty hierarchy when subpartition is not specified +CREATE TABLE empty_partition(i int, j int) PARTITION BY range(i); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +-- Check with other Partition syntax +CREATE TABLE empty_partition2(i int, j int) DISTRIBUTED BY (i) PARTITION BY range(i); +-- https://github.com/apache/cloudberry/issues/795 +CREATE TABLE t_issue_795_par ( + name character varying, + last_modified_date timestamp without time zone +) +WITH (appendoptimized=true, orientation=column, compresslevel=1) +DISTRIBUTED BY (name) +PARTITION BY RANGE (last_modified_date) +( + PARTITION partition_202411 START ('2024-11-01 00:00:00') INCLUSIVE END ('2024-12-01 00:00:00') EXCLUSIVE, + PARTITION partition_max START ('2024-12-01 00:00:00') INCLUSIVE END (MAXVALUE) +); +\d+ t_issue_795_par + Partitioned table "public.t_issue_795_par" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Compression Type | Compression Level | Block Size | Description +--------------------+-----------------------------+-----------+----------+---------+----------+--------------+------------------+-------------------+------------+------------- + name | character varying | | | | extended | | zlib | 1 | 32768 | + last_modified_date | timestamp without time zone | | | | plain | | zlib | 1 | 32768 | +Partition key: RANGE (last_modified_date) +Partitions: t_issue_795_par_1_prt_partition_202411 FOR VALUES FROM ('Fri Nov 01 00:00:00 2024') TO ('Sun Dec 01 00:00:00 2024'), + t_issue_795_par_1_prt_partition_max FOR VALUES FROM ('Sun Dec 01 00:00:00 2024') TO (MAXVALUE) +Distributed by: (name) +Options: compresslevel=1 + +DROP TABLE t_issue_795_par; +-- test the row-level security +DROP USER IF EXISTS new_user_append; +NOTICE: role "new_user_append" does not exist, skipping +create user new_user_append; +NOTICE: resource queue required -- using default resource queue "pg_default" +create table foo_part_rls ( a int, b int, c int) distributed by (a) +partition by range(b) (start(0) end(100) every(20), default partition other_part); +insert into foo_part_rls select i,i*10,i*100 from generate_series(1,5)i; +insert into foo_part_rls values (NULL,50,500);; +insert into foo_part_rls values (NULL,60,NULL); +insert into foo_part_rls values (NULL,70,NULL); +insert into foo_part_rls values (NULL,NULL,600); +insert into foo_part_rls values (NULL,NULL,700); +analyze foo_part_rls; +grant select on foo_part_rls to new_user_append; +alter table foo_part_rls enable row level security; +create policy p1 on foo_part_rls using (a * 10 = b and c > 300); +set session authorization new_user_append; +explain select * from foo_part_rls; + QUERY PLAN +--------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..6.38 rows=18 width=12) + -> Append (cost=0.00..6.14 rows=6 width=12) + -> Seq Scan on foo_part_rls_1_prt_2 foo_part_rls_1 (cost=0.00..1.02 rows=1 width=12) + Filter: ((c > 300) AND ((a * 10) = b)) + -> Seq Scan on foo_part_rls_1_prt_3 foo_part_rls_2 (cost=0.00..1.02 rows=1 width=12) + Filter: ((c > 300) AND ((a * 10) = b)) + -> Seq Scan on foo_part_rls_1_prt_4 foo_part_rls_3 (cost=0.00..1.02 rows=1 width=12) + Filter: ((c > 300) AND ((a * 10) = b)) + -> Seq Scan on foo_part_rls_1_prt_5 foo_part_rls_4 (cost=0.00..1.02 rows=1 width=12) + Filter: ((c > 300) AND ((a * 10) = b)) + -> Seq Scan on foo_part_rls_1_prt_6 foo_part_rls_5 (cost=0.00..1.02 rows=1 width=12) + Filter: ((c > 300) AND ((a * 10) = b)) + -> Seq Scan on foo_part_rls_1_prt_other_part foo_part_rls_6 (cost=0.00..1.02 rows=1 width=12) + Filter: ((c > 300) AND ((a * 10) = b)) + Optimizer: Postgres query optimizer +(15 rows) + +select * from foo_part_rls; + a | b | c +---+----+----- + 5 | 50 | 500 + 4 | 40 | 400 +(2 rows) + +reset session authorization; +drop policy p1 on foo_part_rls; +drop table foo_part_rls cascade; +drop user new_user; +ERROR: role "new_user" does not exist +-- test index-only scan +create table pt(dist int, pt1 text, pt2 text, pt3 text, ptid int) DISTRIBUTED BY (dist) +PARTITION BY RANGE(ptid) (START (0) END (5) EVERY (1), DEFAULT PARTITION junk_data); +create table pt1(dist int, pt1 text, pt2 text, pt3 text, ptid int) DISTRIBUTED BY (dist) +PARTITION BY RANGE(ptid) (START (0) END (5) EVERY (1), DEFAULT PARTITION junk_data); +create table pt2(dist int, tid int, t1 text, t2 text); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'dist' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +create index pt1_idx on pt using btree (pt1); +create index ptid_idx on pt using btree (ptid); +create index ptid_pt1_idx on pt using btree (ptid, pt1); +insert into pt select i, 'hello' || i, 'world', 'drop this', i % 6 from generate_series(0,53) i; +insert into pt2 select i, i % 6, 'hello' || i, 'bar' from generate_series(0,1) i; +insert into pt1 select * from pt; +NOTICE: One or more columns in the following table(s) do not have statistics: pt +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. +insert into pt1 select dist, pt1, pt2, pt3, ptid-100 from pt; +NOTICE: One or more columns in the following table(s) do not have statistics: pt +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. +alter table pt1 set with(REORGANIZE=false) DISTRIBUTED RANDOMLY; +vacuum analyze pt; +analyze pt1; +analyze pt2; +explain (costs off, timing off, summary off, analyze) select * from pt where ptid in (select tid from pt2 where t1 = 'hello' || tid); + QUERY PLAN +--------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (actual rows=18 loops=1) + -> Hash Semi Join (actual rows=8 loops=1) + Hash Cond: (pt_1_prt_2.ptid = pt2.tid) + Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 2 of 524288 buckets. + -> Append (actual rows=8 loops=1) + Partition Selectors: $0 + -> Seq Scan on pt_1_prt_2 (actual rows=5 loops=1) + -> Seq Scan on pt_1_prt_3 (actual rows=3 loops=1) + -> Seq Scan on pt_1_prt_4 (never executed) + -> Seq Scan on pt_1_prt_5 (never executed) + -> Seq Scan on pt_1_prt_6 (never executed) + -> Seq Scan on pt_1_prt_junk_data (never executed) + -> Hash (actual rows=2 loops=1) + Buckets: 524288 Batches: 1 Memory Usage: 4097kB + -> Partition Selector (selector id: $0) (actual rows=2 loops=1) + -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) + -> Seq Scan on pt2 (actual rows=2 loops=1) + Filter: (t1 = ('hello'::text || (tid)::text)) + Optimizer: GPORCA +(19 rows) + +select * from pt where ptid in (select tid from pt2 where t1 = 'hello' || tid); + dist | pt1 | pt2 | pt3 | ptid +------+---------+-------+-----------+------ + 18 | hello18 | world | drop this | 0 + 24 | hello24 | world | drop this | 0 + 42 | hello42 | world | drop this | 0 + 7 | hello7 | world | drop this | 1 + 19 | hello19 | world | drop this | 1 + 37 | hello37 | world | drop this | 1 + 0 | hello0 | world | drop this | 0 + 12 | hello12 | world | drop this | 0 + 30 | hello30 | world | drop this | 0 + 36 | hello36 | world | drop this | 0 + 48 | hello48 | world | drop this | 0 + 1 | hello1 | world | drop this | 1 + 31 | hello31 | world | drop this | 1 + 49 | hello49 | world | drop this | 1 + 6 | hello6 | world | drop this | 0 + 13 | hello13 | world | drop this | 1 + 25 | hello25 | world | drop this | 1 + 43 | hello43 | world | drop this | 1 +(18 rows) + +explain (costs off, timing off, summary off, analyze) select ptid from pt where ptid in (select tid from pt2 where t1 = 'hello' || tid) and pt1 = 'hello1'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (actual rows=1 loops=1) + -> Hash Right Semi Join (actual rows=1 loops=1) + Hash Cond: (pt_1_prt_2.ptid = pt2.tid) + Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 1 of 524288 buckets. + -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) + -> Seq Scan on pt2 (actual rows=2 loops=1) + Filter: (t1 = ('hello'::text || (tid)::text)) + -> Hash (actual rows=1 loops=1) + Buckets: 524288 Batches: 1 Memory Usage: 4097kB + -> Append (actual rows=1 loops=1) + -> Index Scan using pt_1_prt_2_pt1_idx on pt_1_prt_2 (actual rows=0 loops=1) + Index Cond: (pt1 = 'hello1'::text) + -> Index Scan using pt_1_prt_3_pt1_idx on pt_1_prt_3 (actual rows=1 loops=1) + Index Cond: (pt1 = 'hello1'::text) + -> Index Scan using pt_1_prt_4_pt1_idx on pt_1_prt_4 (actual rows=0 loops=1) + Index Cond: (pt1 = 'hello1'::text) + -> Index Scan using pt_1_prt_5_pt1_idx on pt_1_prt_5 (actual rows=0 loops=1) + Index Cond: (pt1 = 'hello1'::text) + -> Index Scan using pt_1_prt_6_pt1_idx on pt_1_prt_6 (actual rows=0 loops=1) + Index Cond: (pt1 = 'hello1'::text) + -> Index Scan using pt_1_prt_junk_data_pt1_idx on pt_1_prt_junk_data (actual rows=0 loops=1) + Index Cond: (pt1 = 'hello1'::text) + Optimizer: GPORCA +(23 rows) + +select ptid from pt where ptid in (select tid from pt2 where t1 = 'hello' || tid) and pt1 = 'hello1'; + ptid +------ + 1 +(1 row) + +drop table pt; +drop table pt1; +drop table pt2; +-- test bitmap heap/bitmap index scan +CREATE TABLE rp_multi_inds (a int, b int, c int) DISTRIBUTED BY (a) PARTITION BY RANGE (b); +CREATE TABLE rp_multi_inds_part1 PARTITION OF rp_multi_inds FOR VALUES FROM (MINVALUE) TO (10); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE rp_multi_inds_part2 PARTITION OF rp_multi_inds FOR VALUES FROM (10) TO (20); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE rp_multi_inds_part3 PARTITION OF rp_multi_inds FOR VALUES FROM (4201) TO (4203); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO rp_multi_inds VALUES (0, 0, 0), (11, 11, 11), (4201, 4201, 4201); +analyze rp_multi_inds; +-- Create an index only on the selected partition +CREATE INDEX other_idx ON rp_multi_inds_part2 USING btree(b); +-- Create indexes on root table +CREATE INDEX rp_btree_idx ON rp_multi_inds USING btree(c); +CREATE INDEX rp_bitmap_idx ON rp_multi_inds USING bitmap(b); +-- Expect a plan that only uses the two indexes inherited from root +SET optimizer_enable_dynamictablescan TO off; +EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM rp_multi_inds WHERE b = 11 AND (c = 11 OR c = 4201); + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Output: a, b, c + -> Append + -> Bitmap Heap Scan on public.rp_multi_inds_part2 + Output: a, b, c + Recheck Cond: (((rp_multi_inds_part2.c = 11) OR (rp_multi_inds_part2.c = 4201)) AND (rp_multi_inds_part2.b = 11)) + -> BitmapAnd + -> BitmapOr + -> Bitmap Index Scan on rp_multi_inds_part2_c_idx + Index Cond: (rp_multi_inds_part2.c = 11) + -> Bitmap Index Scan on rp_multi_inds_part2_c_idx + Index Cond: (rp_multi_inds_part2.c = 4201) + -> Bitmap Index Scan on rp_multi_inds_part2_b_idx + Index Cond: (rp_multi_inds_part2.b = 11) + Settings: optimizer = 'on' + Optimizer: GPORCA +(16 rows) + +RESET optimizer_enable_dynamictablescan; +drop table rp_multi_inds; diff --git a/src/test/regress/expected/partition_join.out b/src/test/regress/expected/partition_join.out index 46f0649a8a7..3e77b1fbe3b 100644 --- a/src/test/regress/expected/partition_join.out +++ b/src/test/regress/expected/partition_join.out @@ -2473,12 +2473,12 @@ SELECT COUNT(*) FROM prt1_l t1 LEFT JOIN LATERAL (SELECT t1.b AS t1b, t2.* FROM prt2_l t2) s ON t1.a = s.b AND t1.b = s.a AND t1.c = s.c WHERE s.t1b = s.a; -ERROR: could not pull up equivalence class using projected target list (pathkeys.c:1615) +ERROR: could not pull up equivalence class using projected target list (pathkeys.c:1618) SELECT COUNT(*) FROM prt1_l t1 LEFT JOIN LATERAL (SELECT t1.b AS t1b, t2.* FROM prt2_l t2) s ON t1.a = s.b AND t1.b = s.a AND t1.c = s.c WHERE s.t1b = s.a; -ERROR: could not pull up equivalence class using projected target list (pathkeys.c:1615) +ERROR: could not pull up equivalence class using projected target list (pathkeys.c:1618) RESET max_parallel_workers_per_gather; -- join with one side empty EXPLAIN (COSTS OFF) @@ -4143,54 +4143,33 @@ SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = -- semi join EXPLAIN (COSTS OFF) SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; - QUERY PLAN --------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Merge Key: t1.a -> Sort Sort Key: t1.a -> Append - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) - -> Seq Scan on plt2_adv_p1 t2_1 - -> Hash - -> Seq Scan on plt1_adv_p1 t1_1 - Filter: (b < 10) - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice3; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) - -> Seq Scan on plt2_adv_p2 t2_2 - -> Hash - -> Seq Scan on plt1_adv_p2 t1_2 - Filter: (b < 10) - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice4; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) - -> Seq Scan on plt2_adv_p3 t2_3 - -> Hash - -> Seq Scan on plt1_adv_p3 t1_3 - Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3 t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) Optimizer: Postgres query optimizer -(45 rows) +(24 rows) SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; a | b | c @@ -4373,54 +4352,33 @@ SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = -- semi join EXPLAIN (COSTS OFF) SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; - QUERY PLAN --------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Merge Key: t1.a -> Sort Sort Key: t1.a -> Append - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) - -> Seq Scan on plt2_adv_p1 t2_1 - -> Hash - -> Seq Scan on plt1_adv_p1 t1_1 - Filter: (b < 10) - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice3; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) - -> Seq Scan on plt2_adv_p2 t2_2 - -> Hash - -> Seq Scan on plt1_adv_p2 t1_2 - Filter: (b < 10) - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice4; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) - -> Seq Scan on plt2_adv_p3 t2_3 - -> Hash - -> Seq Scan on plt1_adv_p3 t1_3 - Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3 t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) Optimizer: Postgres query optimizer -(45 rows) +(24 rows) SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; a | b | c @@ -4640,39 +4598,29 @@ SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = -- semi join EXPLAIN (COSTS OFF) SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; - QUERY PLAN ------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Merge Key: t1.a -> Sort Sort Key: t1.a - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: ((t2.a = t1.a) AND (t2.c = t1.c)) - -> Append - Partition Selectors: $0 - -> Seq Scan on plt2_adv_p1 t2_1 - -> Seq Scan on plt2_adv_p2_1 t2_2 - -> Seq Scan on plt2_adv_p2_2 t2_3 - -> Seq Scan on plt2_adv_p3 t2_4 - -> Hash - -> Partition Selector (selector id: $0) - -> Result - -> Append - -> Seq Scan on plt1_adv_p1 t1_1 - Filter: (b < 10) - -> Seq Scan on plt1_adv_p2 t1_2 - Filter: (b < 10) - -> Seq Scan on plt1_adv_p3 t1_3 - Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2.a = t1.a) AND (t2.c = t1.c)) + -> Append + -> Seq Scan on plt2_adv_p1 t2_1 + -> Seq Scan on plt2_adv_p2_1 t2_2 + -> Seq Scan on plt2_adv_p2_2 t2_3 + -> Seq Scan on plt2_adv_p3 t2_4 + -> Hash + -> Append + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) Optimizer: Postgres query optimizer -(30 rows) +(20 rows) -- left join EXPLAIN (COSTS OFF) @@ -4817,54 +4765,33 @@ SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = -- semi join EXPLAIN (COSTS OFF) SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; - QUERY PLAN --------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Merge Key: t1.a -> Sort Sort Key: t1.a -> Append - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) - -> Seq Scan on plt2_adv_p1 t2_1 - -> Hash - -> Seq Scan on plt1_adv_p1_null t1_1 - Filter: (b < 10) - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice3; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) - -> Seq Scan on plt2_adv_p2 t2_2 - -> Hash - -> Seq Scan on plt1_adv_p2 t1_2 - Filter: (b < 10) - -> Result - -> Unique - Group Key: (RowIdExpr) - -> Sort - Sort Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice4; segments: 3) - Hash Key: (RowIdExpr) - -> Hash Join - Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) - -> Seq Scan on plt2_adv_p3_null t2_3 - -> Hash - -> Seq Scan on plt1_adv_p3 t1_3 - Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1_null t1_1 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3_null t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) Optimizer: Postgres query optimizer -(45 rows) +(24 rows) SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; a | b | c @@ -6255,8 +6182,8 @@ EXPLAIN(COSTS OFF) SELECT COUNT(*) FROM t1_1_prt_1 JOIN t2 USING(id); (8 rows) EXPLAIN(COSTS OFF) SELECT COUNT(*) FROM t1 JOIN t2 USING(id); - QUERY PLAN ------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------- Aggregate -> Gather Motion 3:1 (slice1; segments: 3) -> Hash Join diff --git a/src/test/regress/expected/partition_join_optimizer.out b/src/test/regress/expected/partition_join_optimizer.out new file mode 100644 index 00000000000..3e77b1fbe3b --- /dev/null +++ b/src/test/regress/expected/partition_join_optimizer.out @@ -0,0 +1,6200 @@ +-- +-- PARTITION_JOIN +-- Test partitionwise join between partitioned tables +-- +-- Disable ORCA since it does support partition-wise joins +set optimizer to off; +-- Enable partitionwise join, which by default is disabled. +SET enable_partitionwise_join to true; +-- Also enable Nested Loop and Merge Joins, which are disabled by default in +-- GPDB, to get plans more similar to upstream's. +set enable_nestloop to true; +set enable_mergejoin to true; +-- +-- partitioned by a single column +-- +CREATE TABLE prt1 (a int, b int, c varchar) PARTITION BY RANGE(a); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE prt1_p1 PARTITION OF prt1 FOR VALUES FROM (0) TO (250); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt1_p3 PARTITION OF prt1 FOR VALUES FROM (500) TO (600); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt1_p2 PARTITION OF prt1 FOR VALUES FROM (250) TO (500); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO prt1 SELECT i, i % 25, to_char(i, 'FM0000') FROM generate_series(0, 599) i WHERE i % 2 = 0; +CREATE INDEX iprt1_p1_a on prt1_p1(a); +CREATE INDEX iprt1_p2_a on prt1_p2(a); +CREATE INDEX iprt1_p3_a on prt1_p3(a); +ANALYZE prt1; +CREATE TABLE prt2 (a int, b int, c varchar) PARTITION BY RANGE(b); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE prt2_p1 PARTITION OF prt2 FOR VALUES FROM (0) TO (250); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt2_p2 PARTITION OF prt2 FOR VALUES FROM (250) TO (500); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt2_p3 PARTITION OF prt2 FOR VALUES FROM (500) TO (600); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO prt2 SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(0, 599) i WHERE i % 3 = 0; +CREATE INDEX iprt2_p1_b on prt2_p1(b); +CREATE INDEX iprt2_p2_b on prt2_p2(b); +CREATE INDEX iprt2_p3_b on prt2_p3(b); +ANALYZE prt2; +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +--------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Join + Hash Cond: (t2_1.b = t1_1.a) + -> Seq Scan on prt2_p1 t2_1 + -> Hash + -> Broadcast Motion 3:3 (slice2; segments: 3) + -> Seq Scan on prt1_p1 t1_1 + Filter: (b = 0) + -> Hash Join + Hash Cond: (t2_2.b = t1_2.a) + -> Seq Scan on prt2_p2 t2_2 + -> Hash + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Seq Scan on prt1_p2 t1_2 + Filter: (b = 0) + -> Hash Join + Hash Cond: (t2_3.b = t1_3.a) + -> Seq Scan on prt2_p3 t2_3 + -> Hash + -> Broadcast Motion 3:3 (slice4; segments: 3) + -> Seq Scan on prt1_p3 t1_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(27 rows) + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b; + a | c | b | c +-----+------+-----+------ + 0 | 0000 | 0 | 0000 + 150 | 0150 | 150 | 0150 + 300 | 0300 | 300 | 0300 + 450 | 0450 | 450 | 0450 +(4 rows) + +-- left outer join, 3-way +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM prt1 t1 + LEFT JOIN prt1 t2 ON t1.a = t2.a + LEFT JOIN prt1 t3 ON t2.a = t3.a; + QUERY PLAN +-------------------------------------------------------------------- + Finalize Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Partial Aggregate + -> Append + -> Hash Right Join + Hash Cond: (t2_1.a = t1_1.a) + -> Hash Left Join + Hash Cond: (t2_1.a = t3_1.a) + -> Seq Scan on prt1_p1 t2_1 + -> Hash + -> Seq Scan on prt1_p1 t3_1 + -> Hash + -> Seq Scan on prt1_p1 t1_1 + -> Hash Right Join + Hash Cond: (t2_2.a = t1_2.a) + -> Hash Left Join + Hash Cond: (t2_2.a = t3_2.a) + -> Seq Scan on prt1_p2 t2_2 + -> Hash + -> Seq Scan on prt1_p2 t3_2 + -> Hash + -> Seq Scan on prt1_p2 t1_2 + -> Hash Right Join + Hash Cond: (t2_3.a = t1_3.a) + -> Hash Left Join + Hash Cond: (t2_3.a = t3_3.a) + -> Seq Scan on prt1_p3 t2_3 + -> Hash + -> Seq Scan on prt1_p3 t3_3 + -> Hash + -> Seq Scan on prt1_p3 t1_3 + Optimizer: Postgres query optimizer +(32 rows) + +SELECT COUNT(*) FROM prt1 t1 + LEFT JOIN prt1 t2 ON t1.a = t2.a + LEFT JOIN prt1 t3 ON t2.a = t3.a; + count +------- + 300 +(1 row) + +-- left outer join, with whole-row reference; partitionwise join does not apply +EXPLAIN (COSTS OFF) +SELECT t1, t2 FROM prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t2.b + -> Sort + Sort Key: t1.a, t2.b + -> Hash Right Join + Hash Cond: (t2.b = t1.a) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t2.b + -> Append + -> Seq Scan on prt2_p1 t2_1 + -> Seq Scan on prt2_p2 t2_2 + -> Seq Scan on prt2_p3 t2_3 + -> Hash + -> Append + -> Seq Scan on prt1_p1 t1_1 + Filter: (b = 0) + -> Seq Scan on prt1_p2 t1_2 + Filter: (b = 0) + -> Seq Scan on prt1_p3 t1_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(21 rows) + +SELECT t1, t2 FROM prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; + t1 | t2 +--------------+-------------- + (0,0,0000) | (0,0,0000) + (50,0,0050) | + (100,0,0100) | + (150,0,0150) | (0,150,0150) + (200,0,0200) | + (250,0,0250) | + (300,0,0300) | (0,300,0300) + (350,0,0350) | + (400,0,0400) | + (450,0,0450) | (0,450,0450) + (500,0,0500) | + (550,0,0550) | +(12 rows) + +-- right outer join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1 RIGHT JOIN prt2 t2 ON t1.a = t2.b WHERE t2.a = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t2.b + -> Sort + Sort Key: t1.a, t2.b + -> Append + -> Hash Right Join + Hash Cond: (t1_1.a = t2_1.b) + -> Seq Scan on prt1_p1 t1_1 + -> Hash + -> Redistribute Motion 1:3 (slice2; segments: 1) + Hash Key: t2_1.b + -> Seq Scan on prt2_p1 t2_1 + Filter: (a = 0) + -> Hash Right Join + Hash Cond: (t1_2.a = t2_2.b) + -> Seq Scan on prt1_p2 t1_2 + -> Hash + -> Redistribute Motion 1:3 (slice3; segments: 1) + Hash Key: t2_2.b + -> Seq Scan on prt2_p2 t2_2 + Filter: (a = 0) + -> Hash Right Join + Hash Cond: (t1_3.a = t2_3.b) + -> Seq Scan on prt1_p3 t1_3 + -> Hash + -> Redistribute Motion 1:3 (slice4; segments: 1) + Hash Key: t2_3.b + -> Seq Scan on prt2_p3 t2_3 + Filter: (a = 0) + Optimizer: Postgres query optimizer +(30 rows) + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1 RIGHT JOIN prt2 t2 ON t1.a = t2.b WHERE t2.a = 0 ORDER BY t1.a, t2.b; + a | c | b | c +-----+------+-----+------ + 0 | 0000 | 0 | 0000 + 150 | 0150 | 150 | 0150 + 300 | 0300 | 300 | 0300 + 450 | 0450 | 450 | 0450 + | | 75 | 0075 + | | 225 | 0225 + | | 375 | 0375 + | | 525 | 0525 +(8 rows) + +-- full outer join, with placeholder vars +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 50 phv, * FROM prt1 WHERE prt1.b = 0) t1 FULL JOIN (SELECT 75 phv, * FROM prt2 WHERE prt2.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b; + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: prt1.a, prt2.b + -> Sort + Sort Key: prt1.a, prt2.b + -> Append + -> Hash Full Join + Hash Cond: (prt1_1.a = prt2_1.b) + Filter: (((50) = prt1_1.a) OR ((75) = prt2_1.b)) + -> Seq Scan on prt1_p1 prt1_1 + Filter: (b = 0) + -> Hash + -> Redistribute Motion 1:3 (slice2; segments: 1) + Hash Key: prt2_1.b + -> Seq Scan on prt2_p1 prt2_1 + Filter: (a = 0) + -> Hash Full Join + Hash Cond: (prt1_2.a = prt2_2.b) + Filter: (((50) = prt1_2.a) OR ((75) = prt2_2.b)) + -> Seq Scan on prt1_p2 prt1_2 + Filter: (b = 0) + -> Hash + -> Redistribute Motion 1:3 (slice3; segments: 1) + Hash Key: prt2_2.b + -> Seq Scan on prt2_p2 prt2_2 + Filter: (a = 0) + -> Hash Full Join + Hash Cond: (prt1_3.a = prt2_3.b) + Filter: (((50) = prt1_3.a) OR ((75) = prt2_3.b)) + -> Seq Scan on prt1_p3 prt1_3 + Filter: (b = 0) + -> Hash + -> Redistribute Motion 1:3 (slice4; segments: 1) + Hash Key: prt2_3.b + -> Seq Scan on prt2_p3 prt2_3 + Filter: (a = 0) + Optimizer: Postgres query optimizer +(36 rows) + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 50 phv, * FROM prt1 WHERE prt1.b = 0) t1 FULL JOIN (SELECT 75 phv, * FROM prt2 WHERE prt2.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b; + a | c | b | c +----+------+----+------ + 50 | 0050 | | + | | 75 | 0075 +(2 rows) + +-- Join with pruned partitions from joining relations +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.a < 450 AND t2.b > 250 AND t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Hash Join + Hash Cond: (t2.b = t1.a) + -> Seq Scan on prt2_p2 t2 + Filter: ((b > 250) AND (b < 450)) + -> Hash + -> Broadcast Motion 3:3 (slice2; segments: 3) + -> Seq Scan on prt1_p2 t1 + Filter: ((a < 450) AND (a > 250) AND (b = 0)) + Optimizer: Postgres query optimizer +(13 rows) + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.a < 450 AND t2.b > 250 AND t1.b = 0 ORDER BY t1.a, t2.b; + a | c | b | c +-----+------+-----+------ + 300 | 0300 | 300 | 0300 +(1 row) + +-- Currently we can't do partitioned join if nullable-side partitions are pruned +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: prt1.a, prt2.b + -> Sort + Sort Key: prt1.a, prt2.b + -> Hash Right Join + Hash Cond: (prt2.b = prt1.a) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: prt2.b + -> Append + -> Seq Scan on prt2_p2 prt2_1 + Filter: (b > 250) + -> Seq Scan on prt2_p3 prt2_2 + Filter: (b > 250) + -> Hash + -> Append + -> Seq Scan on prt1_p1 prt1_1 + Filter: ((a < 450) AND (b = 0)) + -> Seq Scan on prt1_p2 prt1_2 + Filter: ((a < 450) AND (b = 0)) + Optimizer: Postgres query optimizer +(20 rows) + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; + a | c | b | c +-----+------+-----+------ + 0 | 0000 | | + 50 | 0050 | | + 100 | 0100 | | + 150 | 0150 | | + 200 | 0200 | | + 250 | 0250 | | + 300 | 0300 | 300 | 0300 + 350 | 0350 | | + 400 | 0400 | | +(9 rows) + +-- Currently we can't do partitioned join if nullable-side partitions are pruned +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 FULL JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 OR t2.a = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: prt1.a, prt2.b + -> Sort + Sort Key: prt1.a, prt2.b + -> Hash Full Join + Hash Cond: (prt1.a = prt2.b) + Filter: ((prt1.b = 0) OR (prt2.a = 0)) + -> Append + -> Seq Scan on prt1_p1 prt1_1 + Filter: (a < 450) + -> Seq Scan on prt1_p2 prt1_2 + Filter: (a < 450) + -> Hash + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: prt2.b + -> Append + -> Seq Scan on prt2_p2 prt2_1 + Filter: (b > 250) + -> Seq Scan on prt2_p3 prt2_2 + Filter: (b > 250) + Optimizer: Postgres query optimizer +(21 rows) + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 FULL JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 OR t2.a = 0 ORDER BY t1.a, t2.b; + a | c | b | c +-----+------+-----+------ + 0 | 0000 | | + 50 | 0050 | | + 100 | 0100 | | + 150 | 0150 | | + 200 | 0200 | | + 250 | 0250 | | + 300 | 0300 | 300 | 0300 + 350 | 0350 | | + 400 | 0400 | | + | | 375 | 0375 + | | 450 | 0450 + | | 525 | 0525 +(12 rows) + +-- Semi-join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t2.b FROM prt2 t2 WHERE t2.a = 0) AND t1.b = 0 ORDER BY t1.a; + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Semi Join + Hash Cond: (t1_1.a = t2_1.b) + -> Seq Scan on prt1_p1 t1_1 + Filter: (b = 0) + -> Hash + -> Redistribute Motion 1:3 (slice2; segments: 1) + Hash Key: t2_1.b + -> Seq Scan on prt2_p1 t2_1 + Filter: (a = 0) + -> Hash Semi Join + Hash Cond: (t1_2.a = t2_2.b) + -> Seq Scan on prt1_p2 t1_2 + Filter: (b = 0) + -> Hash + -> Redistribute Motion 1:3 (slice3; segments: 1) + Hash Key: t2_2.b + -> Seq Scan on prt2_p2 t2_2 + Filter: (a = 0) + -> Nested Loop Semi Join + Join Filter: (t1_3.a = t2_3.b) + -> Seq Scan on prt1_p3 t1_3 + Filter: (b = 0) + -> Materialize + -> Redistribute Motion 1:3 (slice4; segments: 1) + Hash Key: t2_3.b + -> Seq Scan on prt2_p3 t2_3 + Filter: (a = 0) + Optimizer: Postgres query optimizer +(33 rows) + +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t2.b FROM prt2 t2 WHERE t2.a = 0) AND t1.b = 0 ORDER BY t1.a; + a | b | c +-----+---+------ + 0 | 0 | 0000 + 150 | 0 | 0150 + 300 | 0 | 0300 + 450 | 0 | 0450 +(4 rows) + +-- Anti-join with aggregates +EXPLAIN (COSTS OFF) +SELECT sum(t1.a), avg(t1.a), sum(t1.b), avg(t1.b) FROM prt1 t1 WHERE NOT EXISTS (SELECT 1 FROM prt2 t2 WHERE t1.a = t2.b); + QUERY PLAN +------------------------------------------------------------------------------------ + Finalize Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Partial Aggregate + -> Append + -> Hash Anti Join + Hash Cond: (t1_1.a = t2_1.b) + -> Seq Scan on prt1_p1 t1_1 + -> Hash + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t2_1.b + -> Seq Scan on prt2_p1 t2_1 + -> Hash Anti Join + Hash Cond: (t1_2.a = t2_2.b) + -> Seq Scan on prt1_p2 t1_2 + -> Hash + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t2_2.b + -> Seq Scan on prt2_p2 t2_2 + -> Hash Anti Join + Hash Cond: (t1_3.a = t2_3.b) + -> Seq Scan on prt1_p3 t1_3 + -> Hash + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: t2_3.b + -> Seq Scan on prt2_p3 t2_3 + Optimizer: Postgres query optimizer +(26 rows) + +SELECT sum(t1.a), avg(t1.a), sum(t1.b), avg(t1.b) FROM prt1 t1 WHERE NOT EXISTS (SELECT 1 FROM prt2 t2 WHERE t1.a = t2.b); + sum | avg | sum | avg +-------+----------------------+------+--------------------- + 60000 | 300.0000000000000000 | 2400 | 12.0000000000000000 +(1 row) + +-- lateral reference +-- GPDB_12_MERGE_FEATURE_NOT_SUPPORTED +-- If lateral_relids of RelOptInfo for a inner path is not null, the inner path needs +-- params of outer path. So We can not add motion above inner path. +-- however, in left join, outer path can not be replicated. We can not generate path for left join, +-- So hit the error: could not devise a query plan for the given query. +EXPLAIN (COSTS OFF) +SELECT * FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t3.a AS t3a, least(t1.a,t2.a,t3.b) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss + ON t1.a = ss.t2a WHERE t1.b = 0 ORDER BY t1.a; +ERROR: could not devise a query plan for the given query (pathnode.c:285) +SELECT * FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t3.a AS t3a, least(t1.a,t2.a,t3.b) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss + ON t1.a = ss.t2a WHERE t1.b = 0 ORDER BY t1.a; +ERROR: could not devise a query plan for the given query (pathnode.c:285) +EXPLAIN (COSTS OFF) +SELECT t1.a, ss.t2a, ss.t2c FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t3.a AS t3a, t2.b t2b, t2.c t2c, least(t1.a,t2.a,t3.b) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss + ON t1.c = ss.t2c WHERE (t1.b + coalesce(ss.t2b, 0)) = 0 ORDER BY t1.a; + QUERY PLAN +------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Hash Left Join + Hash Cond: ((t1.c)::text = (t2.c)::text) + Filter: ((t1.b + COALESCE(t2.b, 0)) = 0) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t1.c + -> Append + -> Seq Scan on prt1_p1 t1_1 + -> Seq Scan on prt1_p2 t1_2 + -> Seq Scan on prt1_p3 t1_3 + -> Hash + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t2.c + -> Append + -> Hash Join + Hash Cond: (t2_1.a = t3_1.b) + -> Seq Scan on prt1_p1 t2_1 + -> Hash + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: t3_1.b + -> Seq Scan on prt2_p1 t3_1 + -> Hash Join + Hash Cond: (t2_2.a = t3_2.b) + -> Seq Scan on prt1_p2 t2_2 + -> Hash + -> Redistribute Motion 3:3 (slice5; segments: 3) + Hash Key: t3_2.b + -> Seq Scan on prt2_p2 t3_2 + -> Hash Join + Hash Cond: (t2_3.a = t3_3.b) + -> Seq Scan on prt1_p3 t2_3 + -> Hash + -> Redistribute Motion 3:3 (slice6; segments: 3) + Hash Key: t3_3.b + -> Seq Scan on prt2_p3 t3_3 + Optimizer: Postgres query optimizer +(39 rows) + +SELECT t1.a, ss.t2a, ss.t2c FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t3.a AS t3a, t2.b t2b, t2.c t2c, least(t1.a,t2.a,t3.a) FROM prt1 t2 JOIN prt2 t3 ON (t2.a = t3.b)) ss + ON t1.c = ss.t2c WHERE (t1.b + coalesce(ss.t2b, 0)) = 0 ORDER BY t1.a; + a | t2a | t2c +-----+-----+------ + 0 | 0 | 0000 + 50 | | + 100 | | + 150 | 150 | 0150 + 200 | | + 250 | | + 300 | 300 | 0300 + 350 | | + 400 | | + 450 | 450 | 0450 + 500 | | + 550 | | +(12 rows) + +SET max_parallel_workers_per_gather = 0; +-- If there are lateral references to the other relation in sample scan, +-- we cannot generate a partitionwise join. +EXPLAIN (COSTS OFF) +SELECT * FROM prt1 t1 JOIN LATERAL + (SELECT * FROM prt1 t2 TABLESAMPLE SYSTEM (t1.a) REPEATABLE(t1.b)) s + ON t1.a = s.a; + QUERY PLAN +--------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Nested Loop + -> Append + -> Seq Scan on prt1_p1 t1_1 + -> Seq Scan on prt1_p2 t1_2 + -> Seq Scan on prt1_p3 t1_3 + -> Append + -> Sample Scan on prt1_p1 t2_1 + Sampling: system (t1.a) REPEATABLE (t1.b) + Filter: (t1.a = a) + -> Sample Scan on prt1_p2 t2_2 + Sampling: system (t1.a) REPEATABLE (t1.b) + Filter: (t1.a = a) + -> Sample Scan on prt1_p3 t2_3 + Sampling: system (t1.a) REPEATABLE (t1.b) + Filter: (t1.a = a) + Optimizer: Postgres query optimizer +(17 rows) + +-- If there are lateral references to the other relation in scan's restriction +-- clauses, we cannot generate a partitionwise join. +EXPLAIN (COSTS OFF) +SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b = s.a; + QUERY PLAN +--------------------------------------------------------------------------- + Finalize Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Partial Aggregate + -> Nested Loop + -> Broadcast Motion 3:3 (slice2; segments: 3) + -> Append + -> Seq Scan on prt1_p1 t1_1 + -> Seq Scan on prt1_p2 t1_2 + -> Seq Scan on prt1_p3 t1_3 + -> Append + -> Index Scan using iprt2_p1_b on prt2_p1 t2_1 + Index Cond: (b = t1.a) + Filter: (t1.b = a) + -> Index Scan using iprt2_p2_b on prt2_p2 t2_2 + Index Cond: (b = t1.a) + Filter: (t1.b = a) + -> Index Scan using iprt2_p3_b on prt2_p3 t2_3 + Index Cond: (b = t1.a) + Filter: (t1.b = a) + Optimizer: Postgres query optimizer +(20 rows) + +SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b = s.a; + count +------- + 100 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b = s.b; + QUERY PLAN +-------------------------------------------------------------------------------- + Finalize Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Partial Aggregate + -> Nested Loop + -> Broadcast Motion 3:3 (slice2; segments: 3) + -> Append + -> Seq Scan on prt1_p1 t1_1 + -> Seq Scan on prt1_p2 t1_2 + -> Seq Scan on prt1_p3 t1_3 + -> Append + -> Index Only Scan using iprt2_p1_b on prt2_p1 t2_1 + Index Cond: (b = t1.a) + Filter: (b = t1.b) + -> Index Only Scan using iprt2_p2_b on prt2_p2 t2_2 + Index Cond: (b = t1.a) + Filter: (b = t1.b) + -> Index Only Scan using iprt2_p3_b on prt2_p3 t2_3 + Index Cond: (b = t1.a) + Filter: (b = t1.b) + Optimizer: Postgres query optimizer +(20 rows) + +SELECT count(*) FROM prt1 t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2 t2) s + ON t1.a = s.b WHERE s.t1b = s.b; + count +------- + 5 +(1 row) + +RESET max_parallel_workers_per_gather; +-- bug with inadequate sort key representation +SET enable_partitionwise_aggregate TO true; +SET enable_hashjoin TO false; +EXPLAIN (COSTS OFF) +SELECT a, b FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) + WHERE a BETWEEN 490 AND 510 + GROUP BY 1, 2 ORDER BY 1, 2; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: (COALESCE(prt1.a, p2.a)), (COALESCE(prt1.b, p2.b)) + -> GroupAggregate + Group Key: (COALESCE(prt1.a, p2.a)), (COALESCE(prt1.b, p2.b)) + -> Sort + Sort Key: (COALESCE(prt1.a, p2.a)), (COALESCE(prt1.b, p2.b)) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: (COALESCE(prt1.a, p2.a)), (COALESCE(prt1.b, p2.b)) + -> Append + -> Merge Full Join + Merge Cond: ((prt1_1.a = p2_1.a) AND (prt1_1.b = p2_1.b)) + Filter: ((COALESCE(prt1_1.a, p2_1.a) >= 490) AND (COALESCE(prt1_1.a, p2_1.a) <= 510)) + -> Sort + Sort Key: prt1_1.a, prt1_1.b + -> Seq Scan on prt1_p1 prt1_1 + -> Sort + Sort Key: p2_1.a, p2_1.b + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: p2_1.a + -> Seq Scan on prt2_p1 p2_1 + -> Merge Full Join + Merge Cond: ((prt1_2.a = p2_2.a) AND (prt1_2.b = p2_2.b)) + Filter: ((COALESCE(prt1_2.a, p2_2.a) >= 490) AND (COALESCE(prt1_2.a, p2_2.a) <= 510)) + -> Sort + Sort Key: prt1_2.a, prt1_2.b + -> Seq Scan on prt1_p2 prt1_2 + -> Sort + Sort Key: p2_2.a, p2_2.b + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: p2_2.a + -> Seq Scan on prt2_p2 p2_2 + -> Merge Full Join + Merge Cond: ((prt1_3.a = p2_3.a) AND (prt1_3.b = p2_3.b)) + Filter: ((COALESCE(prt1_3.a, p2_3.a) >= 490) AND (COALESCE(prt1_3.a, p2_3.a) <= 510)) + -> Sort + Sort Key: prt1_3.a, prt1_3.b + -> Seq Scan on prt1_p3 prt1_3 + -> Sort + Sort Key: p2_3.a, p2_3.b + -> Redistribute Motion 3:3 (slice5; segments: 3) + Hash Key: p2_3.a + -> Seq Scan on prt2_p3 p2_3 + Optimizer: Postgres query optimizer +(43 rows) + +SELECT a, b FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) + WHERE a BETWEEN 490 AND 510 + GROUP BY 1, 2 ORDER BY 1, 2; + a | b +-----+---- + 490 | 15 + 492 | 17 + 494 | 19 + 495 | 20 + 496 | 21 + 498 | 23 + 500 | 0 + 501 | 1 + 502 | 2 + 504 | 4 + 506 | 6 + 507 | 7 + 508 | 8 + 510 | 10 +(14 rows) + +RESET enable_partitionwise_aggregate; +RESET enable_hashjoin; +-- +-- partitioned by expression +-- +CREATE TABLE prt1_e (a int, b int, c int) PARTITION BY RANGE(((a + b)/2)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE prt1_e_p1 PARTITION OF prt1_e FOR VALUES FROM (0) TO (250); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt1_e_p2 PARTITION OF prt1_e FOR VALUES FROM (250) TO (500); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt1_e_p3 PARTITION OF prt1_e FOR VALUES FROM (500) TO (600); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO prt1_e SELECT i, i, i % 25 FROM generate_series(0, 599, 2) i; +CREATE INDEX iprt1_e_p1_ab2 on prt1_e_p1(((a+b)/2)); +CREATE INDEX iprt1_e_p2_ab2 on prt1_e_p2(((a+b)/2)); +CREATE INDEX iprt1_e_p3_ab2 on prt1_e_p3(((a+b)/2)); +ANALYZE prt1_e; +CREATE TABLE prt2_e (a int, b int, c int) PARTITION BY RANGE(((b + a)/2)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE prt2_e_p1 PARTITION OF prt2_e FOR VALUES FROM (0) TO (250); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt2_e_p2 PARTITION OF prt2_e FOR VALUES FROM (250) TO (500); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt2_e_p3 PARTITION OF prt2_e FOR VALUES FROM (500) TO (600); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO prt2_e SELECT i, i, i % 25 FROM generate_series(0, 599, 3) i; +ANALYZE prt2_e; +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_e t1, prt2_e t2 WHERE (t1.a + t1.b)/2 = (t2.b + t2.a)/2 AND t1.c = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t2.b + -> Sort + Sort Key: t1.a, t2.b + -> Append + -> Hash Join + Hash Cond: (((t2_1.b + t2_1.a) / 2) = ((t1_1.a + t1_1.b) / 2)) + -> Seq Scan on prt2_e_p1 t2_1 + -> Hash + -> Broadcast Motion 3:3 (slice2; segments: 3) + -> Seq Scan on prt1_e_p1 t1_1 + Filter: (c = 0) + -> Hash Join + Hash Cond: (((t2_2.b + t2_2.a) / 2) = ((t1_2.a + t1_2.b) / 2)) + -> Seq Scan on prt2_e_p2 t2_2 + -> Hash + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Seq Scan on prt1_e_p2 t1_2 + Filter: (c = 0) + -> Hash Join + Hash Cond: (((t2_3.b + t2_3.a) / 2) = ((t1_3.a + t1_3.b) / 2)) + -> Seq Scan on prt2_e_p3 t2_3 + -> Hash + -> Broadcast Motion 3:3 (slice4; segments: 3) + -> Seq Scan on prt1_e_p3 t1_3 + Filter: (c = 0) + Optimizer: Postgres query optimizer +(27 rows) + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_e t1, prt2_e t2 WHERE (t1.a + t1.b)/2 = (t2.b + t2.a)/2 AND t1.c = 0 ORDER BY t1.a, t2.b; + a | c | b | c +-----+---+-----+--- + 0 | 0 | 0 | 0 + 150 | 0 | 150 | 0 + 300 | 0 | 300 | 0 + 450 | 0 | 450 | 0 +(4 rows) + +-- +-- N-way join +-- +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM prt1 t1, prt2 t2, prt1_e t3 WHERE t1.a = t2.b AND t1.a = (t3.a + t3.b)/2 AND t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +--------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Join + Hash Cond: (((t3_1.a + t3_1.b) / 2) = t1_1.a) + -> Seq Scan on prt1_e_p1 t3_1 + -> Hash + -> Broadcast Motion 3:3 (slice2; segments: 3) + -> Hash Join + Hash Cond: (t2_1.b = t1_1.a) + -> Seq Scan on prt2_p1 t2_1 + -> Hash + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Seq Scan on prt1_p1 t1_1 + Filter: (b = 0) + -> Hash Join + Hash Cond: (((t3_2.a + t3_2.b) / 2) = t1_2.a) + -> Seq Scan on prt1_e_p2 t3_2 + -> Hash + -> Broadcast Motion 3:3 (slice4; segments: 3) + -> Hash Join + Hash Cond: (t2_2.b = t1_2.a) + -> Seq Scan on prt2_p2 t2_2 + -> Hash + -> Broadcast Motion 3:3 (slice5; segments: 3) + -> Seq Scan on prt1_p2 t1_2 + Filter: (b = 0) + -> Hash Join + Hash Cond: (((t3_3.a + t3_3.b) / 2) = t1_3.a) + -> Seq Scan on prt1_e_p3 t3_3 + -> Hash + -> Broadcast Motion 3:3 (slice6; segments: 3) + -> Hash Join + Hash Cond: (t2_3.b = t1_3.a) + -> Seq Scan on prt2_p3 t2_3 + -> Hash + -> Broadcast Motion 3:3 (slice7; segments: 3) + -> Seq Scan on prt1_p3 t1_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(42 rows) + +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM prt1 t1, prt2 t2, prt1_e t3 WHERE t1.a = t2.b AND t1.a = (t3.a + t3.b)/2 AND t1.b = 0 ORDER BY t1.a, t2.b; + a | c | b | c | ?column? | c +-----+------+-----+------+----------+--- + 0 | 0000 | 0 | 0000 | 0 | 0 + 150 | 0150 | 150 | 0150 | 300 | 0 + 300 | 0300 | 300 | 0300 | 600 | 0 + 450 | 0450 | 450 | 0450 | 900 | 0 +(4 rows) + +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) LEFT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t1.b = 0 ORDER BY t1.a, t2.b, t3.a + t3.b; + QUERY PLAN +------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t2.b, ((t3.a + t3.b)) + -> Sort + Sort Key: t1.a, t2.b, ((t3.a + t3.b)) + -> Append + -> Hash Right Join + Hash Cond: (((t3_1.a + t3_1.b) / 2) = t1_1.a) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: ((t3_1.a + t3_1.b) / 2) + -> Seq Scan on prt1_e_p1 t3_1 + -> Hash + -> Hash Right Join + Hash Cond: (t2_1.b = t1_1.a) + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t2_1.b + -> Seq Scan on prt2_p1 t2_1 + -> Hash + -> Seq Scan on prt1_p1 t1_1 + Filter: (b = 0) + -> Hash Right Join + Hash Cond: (((t3_2.a + t3_2.b) / 2) = t1_2.a) + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: ((t3_2.a + t3_2.b) / 2) + -> Seq Scan on prt1_e_p2 t3_2 + -> Hash + -> Hash Right Join + Hash Cond: (t2_2.b = t1_2.a) + -> Redistribute Motion 3:3 (slice5; segments: 3) + Hash Key: t2_2.b + -> Seq Scan on prt2_p2 t2_2 + -> Hash + -> Seq Scan on prt1_p2 t1_2 + Filter: (b = 0) + -> Hash Right Join + Hash Cond: (((t3_3.a + t3_3.b) / 2) = t1_3.a) + -> Redistribute Motion 3:3 (slice6; segments: 3) + Hash Key: ((t3_3.a + t3_3.b) / 2) + -> Seq Scan on prt1_e_p3 t3_3 + -> Hash + -> Hash Right Join + Hash Cond: (t2_3.b = t1_3.a) + -> Redistribute Motion 3:3 (slice7; segments: 3) + Hash Key: t2_3.b + -> Seq Scan on prt2_p3 t2_3 + -> Hash + -> Seq Scan on prt1_p3 t1_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(48 rows) + +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) LEFT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t1.b = 0 ORDER BY t1.a, t2.b, t3.a + t3.b; + a | c | b | c | ?column? | c +-----+------+-----+------+----------+--- + 0 | 0000 | 0 | 0000 | 0 | 0 + 50 | 0050 | | | 100 | 0 + 100 | 0100 | | | 200 | 0 + 150 | 0150 | 150 | 0150 | 300 | 0 + 200 | 0200 | | | 400 | 0 + 250 | 0250 | | | 500 | 0 + 300 | 0300 | 300 | 0300 | 600 | 0 + 350 | 0350 | | | 700 | 0 + 400 | 0400 | | | 800 | 0 + 450 | 0450 | 450 | 0450 | 900 | 0 + 500 | 0500 | | | 1000 | 0 + 550 | 0550 | | | 1100 | 0 +(12 rows) + +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b; + QUERY PLAN +------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t2.b, ((t3.a + t3.b)) + -> Sort + Sort Key: t1.a, t2.b, ((t3.a + t3.b)) + -> Append + -> Hash Right Join + Hash Cond: (t2_1.b = t1_1.a) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t2_1.b + -> Seq Scan on prt2_p1 t2_1 + -> Hash + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t1_1.a + -> Hash Right Join + Hash Cond: (t1_1.a = ((t3_1.a + t3_1.b) / 2)) + -> Seq Scan on prt1_p1 t1_1 + -> Hash + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: ((t3_1.a + t3_1.b) / 2) + -> Seq Scan on prt1_e_p1 t3_1 + Filter: (c = 0) + -> Hash Right Join + Hash Cond: (t2_2.b = t1_2.a) + -> Redistribute Motion 3:3 (slice5; segments: 3) + Hash Key: t2_2.b + -> Seq Scan on prt2_p2 t2_2 + -> Hash + -> Redistribute Motion 3:3 (slice6; segments: 3) + Hash Key: t1_2.a + -> Hash Right Join + Hash Cond: (t1_2.a = ((t3_2.a + t3_2.b) / 2)) + -> Seq Scan on prt1_p2 t1_2 + -> Hash + -> Redistribute Motion 3:3 (slice7; segments: 3) + Hash Key: ((t3_2.a + t3_2.b) / 2) + -> Seq Scan on prt1_e_p2 t3_2 + Filter: (c = 0) + -> Hash Right Join + Hash Cond: (t2_3.b = t1_3.a) + -> Redistribute Motion 3:3 (slice8; segments: 3) + Hash Key: t2_3.b + -> Seq Scan on prt2_p3 t2_3 + -> Hash + -> Redistribute Motion 3:3 (slice9; segments: 3) + Hash Key: t1_3.a + -> Hash Right Join + Hash Cond: (t1_3.a = ((t3_3.a + t3_3.b) / 2)) + -> Seq Scan on prt1_p3 t1_3 + -> Hash + -> Redistribute Motion 3:3 (slice10; segments: 3) + Hash Key: ((t3_3.a + t3_3.b) / 2) + -> Seq Scan on prt1_e_p3 t3_3 + Filter: (c = 0) + Optimizer: Postgres query optimizer +(54 rows) + +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b; + a | c | b | c | ?column? | c +-----+------+-----+------+----------+--- + 0 | 0000 | 0 | 0000 | 0 | 0 + 50 | 0050 | | | 100 | 0 + 100 | 0100 | | | 200 | 0 + 150 | 0150 | 150 | 0150 | 300 | 0 + 200 | 0200 | | | 400 | 0 + 250 | 0250 | | | 500 | 0 + 300 | 0300 | 300 | 0300 | 600 | 0 + 350 | 0350 | | | 700 | 0 + 400 | 0400 | | | 800 | 0 + 450 | 0450 | 450 | 0450 | 900 | 0 + 500 | 0500 | | | 1000 | 0 + 550 | 0550 | | | 1100 | 0 +(12 rows) + +-- +-- 3-way full join +-- +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) FULL JOIN prt2 p3(b,a,c) USING (a, b) + WHERE a BETWEEN 490 AND 510; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------- + Finalize Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Partial Aggregate + -> Append + -> Hash Full Join + Hash Cond: ((COALESCE(prt1_1.a, p2_1.a) = p3_1.a) AND (COALESCE(prt1_1.b, p2_1.b) = p3_1.b)) + Filter: ((COALESCE(COALESCE(prt1_1.a, p2_1.a), p3_1.a) >= 490) AND (COALESCE(COALESCE(prt1_1.a, p2_1.a), p3_1.a) <= 510)) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: COALESCE(prt1_1.b, p2_1.b) + -> Hash Full Join + Hash Cond: ((prt1_1.a = p2_1.a) AND (prt1_1.b = p2_1.b)) + -> Seq Scan on prt1_p1 prt1_1 + -> Hash + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: p2_1.a + -> Seq Scan on prt2_p1 p2_1 + -> Hash + -> Seq Scan on prt2_p1 p3_1 + -> Hash Full Join + Hash Cond: ((COALESCE(prt1_2.a, p2_2.a) = p3_2.a) AND (COALESCE(prt1_2.b, p2_2.b) = p3_2.b)) + Filter: ((COALESCE(COALESCE(prt1_2.a, p2_2.a), p3_2.a) >= 490) AND (COALESCE(COALESCE(prt1_2.a, p2_2.a), p3_2.a) <= 510)) + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: COALESCE(prt1_2.b, p2_2.b) + -> Hash Full Join + Hash Cond: ((prt1_2.a = p2_2.a) AND (prt1_2.b = p2_2.b)) + -> Seq Scan on prt1_p2 prt1_2 + -> Hash + -> Redistribute Motion 3:3 (slice5; segments: 3) + Hash Key: p2_2.a + -> Seq Scan on prt2_p2 p2_2 + -> Hash + -> Seq Scan on prt2_p2 p3_2 + -> Hash Full Join + Hash Cond: ((COALESCE(prt1_3.a, p2_3.a) = p3_3.a) AND (COALESCE(prt1_3.b, p2_3.b) = p3_3.b)) + Filter: ((COALESCE(COALESCE(prt1_3.a, p2_3.a), p3_3.a) >= 490) AND (COALESCE(COALESCE(prt1_3.a, p2_3.a), p3_3.a) <= 510)) + -> Redistribute Motion 3:3 (slice6; segments: 3) + Hash Key: COALESCE(prt1_3.b, p2_3.b) + -> Hash Full Join + Hash Cond: ((prt1_3.a = p2_3.a) AND (prt1_3.b = p2_3.b)) + -> Seq Scan on prt1_p3 prt1_3 + -> Hash + -> Redistribute Motion 3:3 (slice7; segments: 3) + Hash Key: p2_3.a + -> Seq Scan on prt2_p3 p2_3 + -> Hash + -> Seq Scan on prt2_p3 p3_3 + Optimizer: Postgres query optimizer +(47 rows) + +SELECT COUNT(*) FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) FULL JOIN prt2 p3(b,a,c) USING (a, b) + WHERE a BETWEEN 490 AND 510; + count +------- + 14 +(1 row) + +-- +-- 4-way full join +-- +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) FULL JOIN prt2 p3(b,a,c) USING (a, b) FULL JOIN prt1 p4 (a,b,c) USING (a, b) + WHERE a BETWEEN 490 AND 510; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Finalize Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Partial Aggregate + -> Append + -> Hash Full Join + Hash Cond: ((COALESCE(COALESCE(prt1_1.a, p2_1.a), p3_1.a) = p4_1.a) AND (COALESCE(COALESCE(prt1_1.b, p2_1.b), p3_1.b) = p4_1.b)) + Filter: ((COALESCE(COALESCE(COALESCE(prt1_1.a, p2_1.a), p3_1.a), p4_1.a) >= 490) AND (COALESCE(COALESCE(COALESCE(prt1_1.a, p2_1.a), p3_1.a), p4_1.a) <= 510)) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: COALESCE(COALESCE(prt1_1.a, p2_1.a), p3_1.a) + -> Hash Full Join + Hash Cond: ((COALESCE(prt1_1.a, p2_1.a) = p3_1.a) AND (COALESCE(prt1_1.b, p2_1.b) = p3_1.b)) + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: COALESCE(prt1_1.b, p2_1.b) + -> Hash Full Join + Hash Cond: ((prt1_1.a = p2_1.a) AND (prt1_1.b = p2_1.b)) + -> Seq Scan on prt1_p1 prt1_1 + -> Hash + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: p2_1.a + -> Seq Scan on prt2_p1 p2_1 + -> Hash + -> Seq Scan on prt2_p1 p3_1 + -> Hash + -> Seq Scan on prt1_p1 p4_1 + -> Hash Full Join + Hash Cond: ((COALESCE(COALESCE(prt1_2.a, p2_2.a), p3_2.a) = p4_2.a) AND (COALESCE(COALESCE(prt1_2.b, p2_2.b), p3_2.b) = p4_2.b)) + Filter: ((COALESCE(COALESCE(COALESCE(prt1_2.a, p2_2.a), p3_2.a), p4_2.a) >= 490) AND (COALESCE(COALESCE(COALESCE(prt1_2.a, p2_2.a), p3_2.a), p4_2.a) <= 510)) + -> Redistribute Motion 3:3 (slice5; segments: 3) + Hash Key: COALESCE(COALESCE(prt1_2.a, p2_2.a), p3_2.a) + -> Hash Full Join + Hash Cond: ((COALESCE(prt1_2.a, p2_2.a) = p3_2.a) AND (COALESCE(prt1_2.b, p2_2.b) = p3_2.b)) + -> Redistribute Motion 3:3 (slice6; segments: 3) + Hash Key: COALESCE(prt1_2.b, p2_2.b) + -> Hash Full Join + Hash Cond: ((prt1_2.a = p2_2.a) AND (prt1_2.b = p2_2.b)) + -> Seq Scan on prt1_p2 prt1_2 + -> Hash + -> Redistribute Motion 3:3 (slice7; segments: 3) + Hash Key: p2_2.a + -> Seq Scan on prt2_p2 p2_2 + -> Hash + -> Seq Scan on prt2_p2 p3_2 + -> Hash + -> Seq Scan on prt1_p2 p4_2 + -> Hash Full Join + Hash Cond: ((COALESCE(COALESCE(prt1_3.a, p2_3.a), p3_3.a) = p4_3.a) AND (COALESCE(COALESCE(prt1_3.b, p2_3.b), p3_3.b) = p4_3.b)) + Filter: ((COALESCE(COALESCE(COALESCE(prt1_3.a, p2_3.a), p3_3.a), p4_3.a) >= 490) AND (COALESCE(COALESCE(COALESCE(prt1_3.a, p2_3.a), p3_3.a), p4_3.a) <= 510)) + -> Redistribute Motion 3:3 (slice8; segments: 3) + Hash Key: COALESCE(COALESCE(prt1_3.a, p2_3.a), p3_3.a) + -> Hash Full Join + Hash Cond: ((COALESCE(prt1_3.a, p2_3.a) = p3_3.a) AND (COALESCE(prt1_3.b, p2_3.b) = p3_3.b)) + -> Redistribute Motion 3:3 (slice9; segments: 3) + Hash Key: COALESCE(prt1_3.b, p2_3.b) + -> Hash Full Join + Hash Cond: ((prt1_3.a = p2_3.a) AND (prt1_3.b = p2_3.b)) + -> Seq Scan on prt1_p3 prt1_3 + -> Hash + -> Redistribute Motion 3:3 (slice10; segments: 3) + Hash Key: p2_3.a + -> Seq Scan on prt2_p3 p2_3 + -> Hash + -> Seq Scan on prt2_p3 p3_3 + -> Hash + -> Seq Scan on prt1_p3 p4_3 + Optimizer: Postgres query optimizer +(65 rows) + +SELECT COUNT(*) FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b) FULL JOIN prt2 p3(b,a,c) USING (a, b) FULL JOIN prt1 p4 (a,b,c) USING (a, b) + WHERE a BETWEEN 490 AND 510; + count +------- + 14 +(1 row) + +-- Cases with non-nullable expressions in subquery results; +-- make sure these go to null as expected +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.phv, t2.b, t2.phv, t3.a + t3.b, t3.phv FROM ((SELECT 50 phv, * FROM prt1 WHERE prt1.b = 0) t1 FULL JOIN (SELECT 75 phv, * FROM prt2 WHERE prt2.a = 0) t2 ON (t1.a = t2.b)) FULL JOIN (SELECT 50 phv, * FROM prt1_e WHERE prt1_e.c = 0) t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t1.a = t1.phv OR t2.b = t2.phv OR (t3.a + t3.b)/2 = t3.phv ORDER BY t1.a, t2.b, t3.a + t3.b; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: prt1.a, prt2.b, ((prt1_e.a + prt1_e.b)) + -> Sort + Sort Key: prt1.a, prt2.b, ((prt1_e.a + prt1_e.b)) + -> Append + -> Hash Full Join + Hash Cond: (prt1_1.a = ((prt1_e_1.a + prt1_e_1.b) / 2)) + Filter: ((prt1_1.a = (50)) OR (prt2_1.b = (75)) OR (((prt1_e_1.a + prt1_e_1.b) / 2) = (50))) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: prt1_1.a + -> Hash Full Join + Hash Cond: (prt1_1.a = prt2_1.b) + -> Seq Scan on prt1_p1 prt1_1 + Filter: (b = 0) + -> Hash + -> Redistribute Motion 1:3 (slice3; segments: 1) + Hash Key: prt2_1.b + -> Seq Scan on prt2_p1 prt2_1 + Filter: (a = 0) + -> Hash + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: ((prt1_e_1.a + prt1_e_1.b) / 2) + -> Seq Scan on prt1_e_p1 prt1_e_1 + Filter: (c = 0) + -> Hash Full Join + Hash Cond: (prt1_2.a = ((prt1_e_2.a + prt1_e_2.b) / 2)) + Filter: ((prt1_2.a = (50)) OR (prt2_2.b = (75)) OR (((prt1_e_2.a + prt1_e_2.b) / 2) = (50))) + -> Redistribute Motion 3:3 (slice5; segments: 3) + Hash Key: prt1_2.a + -> Hash Full Join + Hash Cond: (prt1_2.a = prt2_2.b) + -> Seq Scan on prt1_p2 prt1_2 + Filter: (b = 0) + -> Hash + -> Redistribute Motion 1:3 (slice6; segments: 1) + Hash Key: prt2_2.b + -> Seq Scan on prt2_p2 prt2_2 + Filter: (a = 0) + -> Hash + -> Redistribute Motion 3:3 (slice7; segments: 3) + Hash Key: ((prt1_e_2.a + prt1_e_2.b) / 2) + -> Seq Scan on prt1_e_p2 prt1_e_2 + Filter: (c = 0) + -> Hash Full Join + Hash Cond: (prt1_3.a = ((prt1_e_3.a + prt1_e_3.b) / 2)) + Filter: ((prt1_3.a = (50)) OR (prt2_3.b = (75)) OR (((prt1_e_3.a + prt1_e_3.b) / 2) = (50))) + -> Redistribute Motion 3:3 (slice8; segments: 3) + Hash Key: prt1_3.a + -> Hash Full Join + Hash Cond: (prt1_3.a = prt2_3.b) + -> Seq Scan on prt1_p3 prt1_3 + Filter: (b = 0) + -> Hash + -> Redistribute Motion 1:3 (slice9; segments: 1) + Hash Key: prt2_3.b + -> Seq Scan on prt2_p3 prt2_3 + Filter: (a = 0) + -> Hash + -> Redistribute Motion 3:3 (slice10; segments: 3) + Hash Key: ((prt1_e_3.a + prt1_e_3.b) / 2) + -> Seq Scan on prt1_e_p3 prt1_e_3 + Filter: (c = 0) + Optimizer: Postgres query optimizer +(63 rows) + +SELECT t1.a, t1.phv, t2.b, t2.phv, t3.a + t3.b, t3.phv FROM ((SELECT 50 phv, * FROM prt1 WHERE prt1.b = 0) t1 FULL JOIN (SELECT 75 phv, * FROM prt2 WHERE prt2.a = 0) t2 ON (t1.a = t2.b)) FULL JOIN (SELECT 50 phv, * FROM prt1_e WHERE prt1_e.c = 0) t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t1.a = t1.phv OR t2.b = t2.phv OR (t3.a + t3.b)/2 = t3.phv ORDER BY t1.a, t2.b, t3.a + t3.b; + a | phv | b | phv | ?column? | phv +----+-----+----+-----+----------+----- + 50 | 50 | | | 100 | 50 + | | 75 | 75 | | +(2 rows) + +-- Semi-join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1, prt1_e t2 WHERE t1.a = 0 AND t1.b = (t2.a + t2.b)/2) AND t1.b = 0 ORDER BY t1.a; + QUERY PLAN +---------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> HashAggregate + Group Key: (RowIdExpr) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: (RowIdExpr) + -> Nested Loop + Join Filter: (t1_2.a = t1_5.b) + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t1_5.b + -> Hash Join + Hash Cond: (((t2_1.a + t2_1.b) / 2) = t1_5.b) + -> Seq Scan on prt1_e_p1 t2_1 + -> Hash + -> Broadcast Motion 1:3 (slice4; segments: 1) + -> Seq Scan on prt2_p1 t1_5 + Filter: (a = 0) + -> Materialize + -> Index Scan using iprt1_p1_a on prt1_p1 t1_2 + Index Cond: (a = ((t2_1.a + t2_1.b) / 2)) + Filter: (b = 0) + -> HashAggregate + Group Key: (RowIdExpr) + -> Redistribute Motion 3:3 (slice5; segments: 3) + Hash Key: (RowIdExpr) + -> Nested Loop + Join Filter: (t1_3.a = t1_6.b) + -> Redistribute Motion 3:3 (slice6; segments: 3) + Hash Key: t1_6.b + -> Hash Join + Hash Cond: (((t2_2.a + t2_2.b) / 2) = t1_6.b) + -> Seq Scan on prt1_e_p2 t2_2 + -> Hash + -> Broadcast Motion 1:3 (slice7; segments: 1) + -> Seq Scan on prt2_p2 t1_6 + Filter: (a = 0) + -> Materialize + -> Index Scan using iprt1_p2_a on prt1_p2 t1_3 + Index Cond: (a = ((t2_2.a + t2_2.b) / 2)) + Filter: (b = 0) + -> Nested Loop + Join Filter: (t1_4.a = t1_7.b) + -> Redistribute Motion 3:3 (slice8; segments: 3) + Hash Key: t1_7.b + -> HashAggregate + Group Key: t1_7.b + -> Redistribute Motion 3:3 (slice9; segments: 3) + Hash Key: t1_7.b + -> Hash Join + Hash Cond: (((t2_3.a + t2_3.b) / 2) = t1_7.b) + -> Seq Scan on prt1_e_p3 t2_3 + -> Hash + -> Broadcast Motion 1:3 (slice10; segments: 1) + -> Seq Scan on prt2_p3 t1_7 + Filter: (a = 0) + -> Index Scan using iprt1_p3_a on prt1_p3 t1_4 + Index Cond: (a = ((t2_3.a + t2_3.b) / 2)) + Filter: (b = 0) + Optimizer: Postgres query optimizer +(62 rows) + +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1, prt1_e t2 WHERE t1.a = 0 AND t1.b = (t2.a + t2.b)/2) AND t1.b = 0 ORDER BY t1.a; + a | b | c +-----+---+------ + 0 | 0 | 0000 + 150 | 0 | 0150 + 300 | 0 | 0300 + 450 | 0 | 0450 +(4 rows) + +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.c = 0)) AND t1.b = 0 ORDER BY t1.a; + QUERY PLAN +---------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> HashAggregate + Group Key: (RowIdExpr) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: (RowIdExpr) + -> Nested Loop + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t1_6.b + -> Hash Semi Join + Hash Cond: (t1_6.b = ((t1_9.a + t1_9.b) / 2)) + -> Seq Scan on prt2_p1 t1_6 + -> Hash + -> Broadcast Motion 3:3 (slice4; segments: 3) + -> Seq Scan on prt1_e_p1 t1_9 + Filter: (c = 0) + -> Materialize + -> Index Scan using iprt1_p1_a on prt1_p1 t1_3 + Index Cond: (a = t1_6.b) + Filter: (b = 0) + -> HashAggregate + Group Key: (RowIdExpr) + -> Redistribute Motion 3:3 (slice5; segments: 3) + Hash Key: (RowIdExpr) + -> Nested Loop + -> Redistribute Motion 3:3 (slice6; segments: 3) + Hash Key: t1_7.b + -> Hash Semi Join + Hash Cond: (t1_7.b = ((t1_10.a + t1_10.b) / 2)) + -> Seq Scan on prt2_p2 t1_7 + -> Hash + -> Broadcast Motion 3:3 (slice7; segments: 3) + -> Seq Scan on prt1_e_p2 t1_10 + Filter: (c = 0) + -> Materialize + -> Index Scan using iprt1_p2_a on prt1_p2 t1_4 + Index Cond: (a = t1_7.b) + Filter: (b = 0) + -> HashAggregate + Group Key: (RowIdExpr) + -> Redistribute Motion 3:3 (slice8; segments: 3) + Hash Key: (RowIdExpr) + -> Nested Loop + -> Redistribute Motion 3:3 (slice9; segments: 3) + Hash Key: t1_8.b + -> Hash Semi Join + Hash Cond: (t1_8.b = ((t1_11.a + t1_11.b) / 2)) + -> Seq Scan on prt2_p3 t1_8 + -> Hash + -> Broadcast Motion 3:3 (slice10; segments: 3) + -> Seq Scan on prt1_e_p3 t1_11 + Filter: (c = 0) + -> Materialize + -> Index Scan using iprt1_p3_a on prt1_p3 t1_5 + Index Cond: (a = t1_8.b) + Filter: (b = 0) + Optimizer: Postgres query optimizer +(60 rows) + +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.c = 0)) AND t1.b = 0 ORDER BY t1.a; + a | b | c +-----+---+------ + 0 | 0 | 0000 + 150 | 0 | 0150 + 300 | 0 | 0300 + 450 | 0 | 0450 +(4 rows) + +-- test merge joins +SET enable_hashjoin TO off; +SET enable_nestloop TO off; +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.c = 0)) AND t1.b = 0 ORDER BY t1.a; + QUERY PLAN +--------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> HashAggregate + Group Key: (RowIdExpr) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: (RowIdExpr) + -> Merge Join + Merge Cond: (t1_6.b = t1_3.a) + -> Merge Semi Join + Merge Cond: (t1_6.b = (((t1_9.a + t1_9.b) / 2))) + -> Sort + Sort Key: t1_6.b + -> Seq Scan on prt2_p1 t1_6 + -> Sort + Sort Key: (((t1_9.a + t1_9.b) / 2)) + -> Result + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Seq Scan on prt1_e_p1 t1_9 + Filter: (c = 0) + -> Sort + Sort Key: t1_3.a + -> Broadcast Motion 3:3 (slice4; segments: 3) + -> Seq Scan on prt1_p1 t1_3 + Filter: (b = 0) + -> HashAggregate + Group Key: (RowIdExpr) + -> Redistribute Motion 3:3 (slice5; segments: 3) + Hash Key: (RowIdExpr) + -> Merge Join + Merge Cond: (t1_7.b = t1_4.a) + -> Merge Semi Join + Merge Cond: (t1_7.b = (((t1_10.a + t1_10.b) / 2))) + -> Sort + Sort Key: t1_7.b + -> Seq Scan on prt2_p2 t1_7 + -> Sort + Sort Key: (((t1_10.a + t1_10.b) / 2)) + -> Result + -> Broadcast Motion 3:3 (slice6; segments: 3) + -> Seq Scan on prt1_e_p2 t1_10 + Filter: (c = 0) + -> Sort + Sort Key: t1_4.a + -> Broadcast Motion 3:3 (slice7; segments: 3) + -> Seq Scan on prt1_p2 t1_4 + Filter: (b = 0) + -> HashAggregate + Group Key: (RowIdExpr) + -> Redistribute Motion 3:3 (slice8; segments: 3) + Hash Key: (RowIdExpr) + -> Merge Join + Merge Cond: (t1_8.b = t1_5.a) + -> Merge Semi Join + Merge Cond: (t1_8.b = (((t1_11.a + t1_11.b) / 2))) + -> Sort + Sort Key: t1_8.b + -> Seq Scan on prt2_p3 t1_8 + -> Sort + Sort Key: (((t1_11.a + t1_11.b) / 2)) + -> Result + -> Broadcast Motion 3:3 (slice9; segments: 3) + -> Seq Scan on prt1_e_p3 t1_11 + Filter: (c = 0) + -> Sort + Sort Key: t1_5.a + -> Broadcast Motion 3:3 (slice10; segments: 3) + -> Seq Scan on prt1_p3 t1_5 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(72 rows) + +SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.c = 0)) AND t1.b = 0 ORDER BY t1.a; + a | b | c +-----+---+------ + 0 | 0 | 0000 + 150 | 0 | 0150 + 300 | 0 | 0300 + 450 | 0 | 0450 +(4 rows) + +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b; + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t2.b, ((t3.a + t3.b)) + -> Sort + Sort Key: t1.a, t2.b, ((t3.a + t3.b)) + -> Append + -> Merge Left Join + Merge Cond: (t1_1.a = t2_1.b) + -> Sort + Sort Key: t1_1.a + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t1_1.a + -> Merge Left Join + Merge Cond: ((((t3_1.a + t3_1.b) / 2)) = t1_1.a) + -> Sort + Sort Key: (((t3_1.a + t3_1.b) / 2)) + -> Result + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: ((t3_1.a + t3_1.b) / 2) + -> Seq Scan on prt1_e_p1 t3_1 + Filter: (c = 0) + -> Sort + Sort Key: t1_1.a + -> Seq Scan on prt1_p1 t1_1 + -> Sort + Sort Key: t2_1.b + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: t2_1.b + -> Seq Scan on prt2_p1 t2_1 + -> Merge Left Join + Merge Cond: (t1_2.a = t2_2.b) + -> Sort + Sort Key: t1_2.a + -> Redistribute Motion 3:3 (slice5; segments: 3) + Hash Key: t1_2.a + -> Merge Left Join + Merge Cond: ((((t3_2.a + t3_2.b) / 2)) = t1_2.a) + -> Sort + Sort Key: (((t3_2.a + t3_2.b) / 2)) + -> Result + -> Redistribute Motion 3:3 (slice6; segments: 3) + Hash Key: ((t3_2.a + t3_2.b) / 2) + -> Seq Scan on prt1_e_p2 t3_2 + Filter: (c = 0) + -> Sort + Sort Key: t1_2.a + -> Seq Scan on prt1_p2 t1_2 + -> Sort + Sort Key: t2_2.b + -> Redistribute Motion 3:3 (slice7; segments: 3) + Hash Key: t2_2.b + -> Seq Scan on prt2_p2 t2_2 + -> Merge Left Join + Merge Cond: (t1_3.a = t2_3.b) + -> Sort + Sort Key: t1_3.a + -> Redistribute Motion 3:3 (slice8; segments: 3) + Hash Key: t1_3.a + -> Merge Left Join + Merge Cond: ((((t3_3.a + t3_3.b) / 2)) = t1_3.a) + -> Sort + Sort Key: (((t3_3.a + t3_3.b) / 2)) + -> Result + -> Redistribute Motion 3:3 (slice9; segments: 3) + Hash Key: ((t3_3.a + t3_3.b) / 2) + -> Seq Scan on prt1_e_p3 t3_3 + Filter: (c = 0) + -> Sort + Sort Key: t1_3.a + -> Seq Scan on prt1_p3 t1_3 + -> Sort + Sort Key: t2_3.b + -> Redistribute Motion 3:3 (slice10; segments: 3) + Hash Key: t2_3.b + -> Seq Scan on prt2_p3 t2_3 + Optimizer: Postgres query optimizer +(75 rows) + +SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b; + a | c | b | c | ?column? | c +-----+------+-----+------+----------+--- + 0 | 0000 | 0 | 0000 | 0 | 0 + 50 | 0050 | | | 100 | 0 + 100 | 0100 | | | 200 | 0 + 150 | 0150 | 150 | 0150 | 300 | 0 + 200 | 0200 | | | 400 | 0 + 250 | 0250 | | | 500 | 0 + 300 | 0300 | 300 | 0300 | 600 | 0 + 350 | 0350 | | | 700 | 0 + 400 | 0400 | | | 800 | 0 + 450 | 0450 | 450 | 0450 | 900 | 0 + 500 | 0500 | | | 1000 | 0 + 550 | 0550 | | | 1100 | 0 +(12 rows) + +-- MergeAppend on nullable column +-- This should generate a partitionwise join, but currently fails to +EXPLAIN (COSTS OFF) +SELECT t1.a, t2.b FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: prt1.a, prt2.b + -> Sort + Sort Key: prt1.a, prt2.b + -> Merge Left Join + Merge Cond: (prt1.a = prt2.b) + -> Sort + Sort Key: prt1.a + -> Append + -> Seq Scan on prt1_p1 prt1_1 + Filter: ((a < 450) AND (b = 0)) + -> Seq Scan on prt1_p2 prt1_2 + Filter: ((a < 450) AND (b = 0)) + -> Sort + Sort Key: prt2.b + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: prt2.b + -> Append + -> Seq Scan on prt2_p2 prt2_1 + Filter: (b > 250) + -> Seq Scan on prt2_p3 prt2_2 + Filter: (b > 250) + Optimizer: Postgres query optimizer +(23 rows) + +SELECT t1.a, t2.b FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; + a | b +-----+----- + 0 | + 50 | + 100 | + 150 | + 200 | + 250 | + 300 | 300 + 350 | + 400 | +(9 rows) + +-- merge join when expression with whole-row reference needs to be sorted; +-- partitionwise join does not apply +EXPLAIN (COSTS OFF) +SELECT t1.a, t2.b FROM prt1 t1, prt2 t2 WHERE t1::text = t2::text AND t1.a = t2.b ORDER BY t1.a; + QUERY PLAN +----------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Merge Join + Merge Cond: ((t1.a = t2.b) AND (((((t1.*)::prt1))::text) = ((((t2.*)::prt2))::text))) + -> Sort + Sort Key: t1.a, ((((t1.*)::prt1))::text) + -> Result + -> Append + Partition Selectors: $0 + -> Seq Scan on prt1_p1 t1_1 + -> Seq Scan on prt1_p2 t1_2 + -> Seq Scan on prt1_p3 t1_3 + -> Sort + Sort Key: t2.b, ((((t2.*)::prt2))::text) + -> Result + -> Partition Selector (selector id: $0) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t2.b + -> Append + -> Seq Scan on prt2_p1 t2_1 + -> Seq Scan on prt2_p2 t2_2 + -> Seq Scan on prt2_p3 t2_3 + Optimizer: Postgres query optimizer +(23 rows) + +SELECT t1.a, t2.b FROM prt1 t1, prt2 t2 WHERE t1::text = t2::text AND t1.a = t2.b ORDER BY t1.a; + a | b +----+---- + 0 | 0 + 6 | 6 + 12 | 12 + 18 | 18 + 24 | 24 +(5 rows) + +RESET enable_hashjoin; +RESET enable_nestloop; +-- +-- partitioned by multiple columns +-- +CREATE TABLE prt1_m (a int, b int, c int) PARTITION BY RANGE(a, ((a + b)/2)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE prt1_m_p1 PARTITION OF prt1_m FOR VALUES FROM (0, 0) TO (250, 250); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt1_m_p2 PARTITION OF prt1_m FOR VALUES FROM (250, 250) TO (500, 500); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt1_m_p3 PARTITION OF prt1_m FOR VALUES FROM (500, 500) TO (600, 600); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO prt1_m SELECT i, i, i % 25 FROM generate_series(0, 599, 2) i; +ANALYZE prt1_m; +CREATE TABLE prt2_m (a int, b int, c int) PARTITION BY RANGE(((b + a)/2), b); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE prt2_m_p1 PARTITION OF prt2_m FOR VALUES FROM (0, 0) TO (250, 250); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt2_m_p2 PARTITION OF prt2_m FOR VALUES FROM (250, 250) TO (500, 500); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt2_m_p3 PARTITION OF prt2_m FOR VALUES FROM (500, 500) TO (600, 600); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO prt2_m SELECT i, i, i % 25 FROM generate_series(0, 599, 3) i; +ANALYZE prt2_m; +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_m WHERE prt1_m.c = 0) t1 FULL JOIN (SELECT * FROM prt2_m WHERE prt2_m.c = 0) t2 ON (t1.a = (t2.b + t2.a)/2 AND t2.b = (t1.a + t1.b)/2) ORDER BY t1.a, t2.b; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: prt1_m.a, prt2_m.b + -> Sort + Sort Key: prt1_m.a, prt2_m.b + -> Append + -> Hash Full Join + Hash Cond: ((prt1_m_1.a = ((prt2_m_1.b + prt2_m_1.a) / 2)) AND (((prt1_m_1.a + prt1_m_1.b) / 2) = prt2_m_1.b)) + -> Seq Scan on prt1_m_p1 prt1_m_1 + Filter: (c = 0) + -> Hash + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: ((prt2_m_1.b + prt2_m_1.a) / 2) + -> Seq Scan on prt2_m_p1 prt2_m_1 + Filter: (c = 0) + -> Hash Full Join + Hash Cond: ((prt1_m_2.a = ((prt2_m_2.b + prt2_m_2.a) / 2)) AND (((prt1_m_2.a + prt1_m_2.b) / 2) = prt2_m_2.b)) + -> Seq Scan on prt1_m_p2 prt1_m_2 + Filter: (c = 0) + -> Hash + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: ((prt2_m_2.b + prt2_m_2.a) / 2) + -> Seq Scan on prt2_m_p2 prt2_m_2 + Filter: (c = 0) + -> Hash Full Join + Hash Cond: ((prt1_m_3.a = ((prt2_m_3.b + prt2_m_3.a) / 2)) AND (((prt1_m_3.a + prt1_m_3.b) / 2) = prt2_m_3.b)) + -> Seq Scan on prt1_m_p3 prt1_m_3 + Filter: (c = 0) + -> Hash + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: ((prt2_m_3.b + prt2_m_3.a) / 2) + -> Seq Scan on prt2_m_p3 prt2_m_3 + Filter: (c = 0) + Optimizer: Postgres query optimizer +(33 rows) + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_m WHERE prt1_m.c = 0) t1 FULL JOIN (SELECT * FROM prt2_m WHERE prt2_m.c = 0) t2 ON (t1.a = (t2.b + t2.a)/2 AND t2.b = (t1.a + t1.b)/2) ORDER BY t1.a, t2.b; + a | c | b | c +-----+---+-----+--- + 0 | 0 | 0 | 0 + 50 | 0 | | + 100 | 0 | | + 150 | 0 | 150 | 0 + 200 | 0 | | + 250 | 0 | | + 300 | 0 | 300 | 0 + 350 | 0 | | + 400 | 0 | | + 450 | 0 | 450 | 0 + 500 | 0 | | + 550 | 0 | | + | | 75 | 0 + | | 225 | 0 + | | 375 | 0 + | | 525 | 0 +(16 rows) + +-- +-- tests for list partitioned tables. +-- +CREATE TABLE plt1 (a int, b int, c text) PARTITION BY LIST(c); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE plt1_p1 PARTITION OF plt1 FOR VALUES IN ('0000', '0003', '0004', '0010'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt1_p2 PARTITION OF plt1 FOR VALUES IN ('0001', '0005', '0002', '0009'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt1_p3 PARTITION OF plt1 FOR VALUES IN ('0006', '0007', '0008', '0011'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO plt1 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 2) i; +ANALYZE plt1; +CREATE TABLE plt2 (a int, b int, c text) PARTITION BY LIST(c); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE plt2_p1 PARTITION OF plt2 FOR VALUES IN ('0000', '0003', '0004', '0010'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt2_p2 PARTITION OF plt2 FOR VALUES IN ('0001', '0005', '0002', '0009'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt2_p3 PARTITION OF plt2 FOR VALUES IN ('0006', '0007', '0008', '0011'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO plt2 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 3) i; +ANALYZE plt2; +-- +-- list partitioned by expression +-- +CREATE TABLE plt1_e (a int, b int, c text) PARTITION BY LIST(ltrim(c, 'A')); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE plt1_e_p1 PARTITION OF plt1_e FOR VALUES IN ('0000', '0003', '0004', '0010'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt1_e_p2 PARTITION OF plt1_e FOR VALUES IN ('0001', '0005', '0002', '0009'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt1_e_p3 PARTITION OF plt1_e FOR VALUES IN ('0006', '0007', '0008', '0011'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO plt1_e SELECT i, i, 'A' || to_char(i/50, 'FM0000') FROM generate_series(0, 599, 2) i; +ANALYZE plt1_e; +-- test partition matching with N-way join +EXPLAIN (COSTS OFF) +SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM plt1 t1, plt2 t2, plt1_e t3 WHERE t1.b = t2.b AND t1.c = t2.c AND ltrim(t3.c, 'A') = t1.c GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2.c, t3.c; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.c, t3.c + -> GroupAggregate + Group Key: t1.c, t3.c + -> Sort + Sort Key: t1.c, t3.c + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t1.c, t3.c + -> Append + -> Hash Join + Hash Cond: (ltrim(t3_1.c, 'A'::text) = t1_1.c) + -> Seq Scan on plt1_e_p1 t3_1 + -> Hash + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Hash Join + Hash Cond: ((t2_1.b = t1_1.b) AND (t2_1.c = t1_1.c)) + -> Broadcast Motion 3:3 (slice4; segments: 3) + -> Seq Scan on plt2_p1 t2_1 + -> Hash + -> Seq Scan on plt1_p1 t1_1 + -> Hash Join + Hash Cond: (ltrim(t3_2.c, 'A'::text) = t1_2.c) + -> Seq Scan on plt1_e_p2 t3_2 + -> Hash + -> Broadcast Motion 3:3 (slice5; segments: 3) + -> Hash Join + Hash Cond: ((t2_2.b = t1_2.b) AND (t2_2.c = t1_2.c)) + -> Broadcast Motion 3:3 (slice6; segments: 3) + -> Seq Scan on plt2_p2 t2_2 + -> Hash + -> Seq Scan on plt1_p2 t1_2 + -> Hash Join + Hash Cond: (ltrim(t3_3.c, 'A'::text) = t1_3.c) + -> Seq Scan on plt1_e_p3 t3_3 + -> Hash + -> Broadcast Motion 3:3 (slice7; segments: 3) + -> Hash Join + Hash Cond: ((t2_3.b = t1_3.b) AND (t2_3.c = t1_3.c)) + -> Broadcast Motion 3:3 (slice8; segments: 3) + -> Seq Scan on plt2_p3 t2_3 + -> Hash + -> Seq Scan on plt1_p3 t1_3 + Optimizer: Postgres query optimizer +(43 rows) + +SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM plt1 t1, plt2 t2, plt1_e t3 WHERE t1.b = t2.b AND t1.c = t2.c AND ltrim(t3.c, 'A') = t1.c GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2.c, t3.c; + avg | avg | avg | c | c | c +----------------------+----------------------+-----------------------+------+------+------- + 24.0000000000000000 | 24.0000000000000000 | 48.0000000000000000 | 0000 | 0000 | A0000 + 75.0000000000000000 | 75.0000000000000000 | 148.0000000000000000 | 0001 | 0001 | A0001 + 123.0000000000000000 | 123.0000000000000000 | 248.0000000000000000 | 0002 | 0002 | A0002 + 174.0000000000000000 | 174.0000000000000000 | 348.0000000000000000 | 0003 | 0003 | A0003 + 225.0000000000000000 | 225.0000000000000000 | 448.0000000000000000 | 0004 | 0004 | A0004 + 273.0000000000000000 | 273.0000000000000000 | 548.0000000000000000 | 0005 | 0005 | A0005 + 324.0000000000000000 | 324.0000000000000000 | 648.0000000000000000 | 0006 | 0006 | A0006 + 375.0000000000000000 | 375.0000000000000000 | 748.0000000000000000 | 0007 | 0007 | A0007 + 423.0000000000000000 | 423.0000000000000000 | 848.0000000000000000 | 0008 | 0008 | A0008 + 474.0000000000000000 | 474.0000000000000000 | 948.0000000000000000 | 0009 | 0009 | A0009 + 525.0000000000000000 | 525.0000000000000000 | 1048.0000000000000000 | 0010 | 0010 | A0010 + 573.0000000000000000 | 573.0000000000000000 | 1148.0000000000000000 | 0011 | 0011 | A0011 +(12 rows) + +-- joins where one of the relations is proven empty +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.a = 1 AND t1.a = 2; + QUERY PLAN +------------------------------------- + Result + One-Time Filter: false + Optimizer: Postgres query optimizer +(3 rows) + +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a = 1 AND a = 2) t1 LEFT JOIN prt2 t2 ON t1.a = t2.b; + QUERY PLAN +------------------------------------- + Result + One-Time Filter: false + Optimizer: Postgres query optimizer +(3 rows) + +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a = 1 AND a = 2) t1 RIGHT JOIN prt2 t2 ON t1.a = t2.b, prt1 t3 WHERE t2.b = t3.a; + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Left Join + Hash Cond: (t2.b = a) + -> Append + -> Hash Join + Hash Cond: (t3_1.a = t2_1.b) + -> Seq Scan on prt1_p1 t3_1 + -> Hash + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t2_1.b + -> Seq Scan on prt2_p1 t2_1 + -> Hash Join + Hash Cond: (t3_2.a = t2_2.b) + -> Seq Scan on prt1_p2 t3_2 + -> Hash + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t2_2.b + -> Seq Scan on prt2_p2 t2_2 + -> Hash Join + Hash Cond: (t3_3.a = t2_3.b) + -> Seq Scan on prt1_p3 t3_3 + -> Hash + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: t2_3.b + -> Seq Scan on prt2_p3 t2_3 + -> Hash + -> Result + One-Time Filter: false + Optimizer: Postgres query optimizer +(29 rows) + +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a = 1 AND a = 2) t1 FULL JOIN prt2 t2 ON t1.a = t2.b WHERE t2.a = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +-------------------------------------------------- + Gather Motion 1:1 (slice1; segments: 1) + Merge Key: a, t2.b + -> Sort + Sort Key: a, t2.b + -> Hash Left Join + Hash Cond: (t2.b = a) + -> Append + -> Seq Scan on prt2_p1 t2_1 + Filter: (a = 0) + -> Seq Scan on prt2_p2 t2_2 + Filter: (a = 0) + -> Seq Scan on prt2_p3 t2_3 + Filter: (a = 0) + -> Hash + -> Result + One-Time Filter: false + Optimizer: Postgres query optimizer +(17 rows) + +-- +-- tests for hash partitioned tables. +-- +CREATE TABLE pht1 (a int, b int, c text) PARTITION BY HASH(c); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE pht1_p1 PARTITION OF pht1 FOR VALUES WITH (MODULUS 3, REMAINDER 0); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE pht1_p2 PARTITION OF pht1 FOR VALUES WITH (MODULUS 3, REMAINDER 1); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE pht1_p3 PARTITION OF pht1 FOR VALUES WITH (MODULUS 3, REMAINDER 2); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO pht1 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 2) i; +ANALYZE pht1; +CREATE TABLE pht2 (a int, b int, c text) PARTITION BY HASH(c); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE pht2_p1 PARTITION OF pht2 FOR VALUES WITH (MODULUS 3, REMAINDER 0); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE pht2_p2 PARTITION OF pht2 FOR VALUES WITH (MODULUS 3, REMAINDER 1); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE pht2_p3 PARTITION OF pht2 FOR VALUES WITH (MODULUS 3, REMAINDER 2); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO pht2 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 3) i; +ANALYZE pht2; +-- +-- hash partitioned by expression +-- +CREATE TABLE pht1_e (a int, b int, c text) PARTITION BY HASH(ltrim(c, 'A')); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE pht1_e_p1 PARTITION OF pht1_e FOR VALUES WITH (MODULUS 3, REMAINDER 0); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE pht1_e_p2 PARTITION OF pht1_e FOR VALUES WITH (MODULUS 3, REMAINDER 1); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE pht1_e_p3 PARTITION OF pht1_e FOR VALUES WITH (MODULUS 3, REMAINDER 2); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO pht1_e SELECT i, i, 'A' || to_char(i/50, 'FM0000') FROM generate_series(0, 299, 2) i; +ANALYZE pht1_e; +-- test partition matching with N-way join +EXPLAIN (COSTS OFF) +SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM pht1 t1, pht2 t2, pht1_e t3 WHERE t1.b = t2.b AND t1.c = t2.c AND ltrim(t3.c, 'A') = t1.c GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2.c, t3.c; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.c, t3.c + -> GroupAggregate + Group Key: t1.c, t3.c + -> Sort + Sort Key: t1.c, t3.c + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t1.c, t3.c + -> Append + -> Hash Join + Hash Cond: ((t1_1.b = t2_1.b) AND (t1_1.c = t2_1.c)) + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t1_1.c + -> Seq Scan on pht1_p1 t1_1 + -> Hash + -> Hash Join + Hash Cond: (t2_1.c = ltrim(t3_1.c, 'A'::text)) + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: t2_1.c + -> Seq Scan on pht2_p1 t2_1 + -> Hash + -> Redistribute Motion 3:3 (slice5; segments: 3) + Hash Key: ltrim(t3_1.c, 'A'::text) + -> Seq Scan on pht1_e_p1 t3_1 + -> Hash Join + Hash Cond: (t1_2.c = ltrim(t3_2.c, 'A'::text)) + -> Broadcast Motion 3:3 (slice6; segments: 3) + -> Hash Join + Hash Cond: ((t2_2.b = t1_2.b) AND (t2_2.c = t1_2.c)) + -> Broadcast Motion 3:3 (slice7; segments: 3) + -> Seq Scan on pht2_p2 t2_2 + -> Hash + -> Seq Scan on pht1_p2 t1_2 + -> Hash + -> Seq Scan on pht1_e_p2 t3_2 + -> Hash Join + Hash Cond: (ltrim(t3_3.c, 'A'::text) = t1_3.c) + -> Seq Scan on pht1_e_p3 t3_3 + -> Hash + -> Broadcast Motion 3:3 (slice8; segments: 3) + -> Hash Join + Hash Cond: ((t2_3.b = t1_3.b) AND (t2_3.c = t1_3.c)) + -> Broadcast Motion 3:3 (slice9; segments: 3) + -> Seq Scan on pht2_p3 t2_3 + -> Hash + -> Seq Scan on pht1_p3 t1_3 + Optimizer: Postgres query optimizer +(47 rows) + +SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM pht1 t1, pht2 t2, pht1_e t3 WHERE t1.b = t2.b AND t1.c = t2.c AND ltrim(t3.c, 'A') = t1.c GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2.c, t3.c; + avg | avg | avg | c | c | c +----------------------+----------------------+----------------------+------+------+------- + 24.0000000000000000 | 24.0000000000000000 | 48.0000000000000000 | 0000 | 0000 | A0000 + 75.0000000000000000 | 75.0000000000000000 | 148.0000000000000000 | 0001 | 0001 | A0001 + 123.0000000000000000 | 123.0000000000000000 | 248.0000000000000000 | 0002 | 0002 | A0002 + 174.0000000000000000 | 174.0000000000000000 | 348.0000000000000000 | 0003 | 0003 | A0003 + 225.0000000000000000 | 225.0000000000000000 | 448.0000000000000000 | 0004 | 0004 | A0004 + 273.0000000000000000 | 273.0000000000000000 | 548.0000000000000000 | 0005 | 0005 | A0005 +(6 rows) + +-- test default partition behavior for range +ALTER TABLE prt1 DETACH PARTITION prt1_p3; +ALTER TABLE prt1 ATTACH PARTITION prt1_p3 DEFAULT; +ANALYZE prt1; +ALTER TABLE prt2 DETACH PARTITION prt2_p3; +ALTER TABLE prt2 ATTACH PARTITION prt2_p3 DEFAULT; +ANALYZE prt2; +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +--------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Join + Hash Cond: (t2_1.b = t1_1.a) + -> Seq Scan on prt2_p1 t2_1 + -> Hash + -> Broadcast Motion 3:3 (slice2; segments: 3) + -> Seq Scan on prt1_p1 t1_1 + Filter: (b = 0) + -> Hash Join + Hash Cond: (t2_2.b = t1_2.a) + -> Seq Scan on prt2_p2 t2_2 + -> Hash + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Seq Scan on prt1_p2 t1_2 + Filter: (b = 0) + -> Hash Join + Hash Cond: (t2_3.b = t1_3.a) + -> Seq Scan on prt2_p3 t2_3 + -> Hash + -> Broadcast Motion 3:3 (slice4; segments: 3) + -> Seq Scan on prt1_p3 t1_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(27 rows) + +-- test default partition behavior for list +ALTER TABLE plt1 DETACH PARTITION plt1_p3; +ALTER TABLE plt1 ATTACH PARTITION plt1_p3 DEFAULT; +ANALYZE plt1; +ALTER TABLE plt2 DETACH PARTITION plt2_p3; +ALTER TABLE plt2 ATTACH PARTITION plt2_p3 DEFAULT; +ANALYZE plt2; +EXPLAIN (COSTS OFF) +SELECT avg(t1.a), avg(t2.b), t1.c, t2.c FROM plt1 t1 RIGHT JOIN plt2 t2 ON t1.c = t2.c WHERE t1.a % 25 = 0 GROUP BY t1.c, t2.c ORDER BY t1.c, t2.c; + QUERY PLAN +--------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.c + -> Sort + Sort Key: t1.c + -> Finalize HashAggregate + Group Key: t1.c + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t1.c + -> Streaming Partial HashAggregate + Group Key: t1.c + -> Append + -> Hash Join + Hash Cond: (t2_1.c = t1_1.c) + -> Seq Scan on plt2_p1 t2_1 + -> Hash + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Seq Scan on plt1_p1 t1_1 + Filter: ((a % 25) = 0) + -> Hash Join + Hash Cond: (t2_2.c = t1_2.c) + -> Seq Scan on plt2_p2 t2_2 + -> Hash + -> Broadcast Motion 3:3 (slice4; segments: 3) + -> Seq Scan on plt1_p2 t1_2 + Filter: ((a % 25) = 0) + -> Hash Join + Hash Cond: (t2_3.c = t1_3.c) + -> Seq Scan on plt2_p3 t2_3 + -> Hash + -> Broadcast Motion 3:3 (slice5; segments: 3) + -> Seq Scan on plt1_p3 t1_3 + Filter: ((a % 25) = 0) + Optimizer: Postgres query optimizer +(33 rows) + +-- +-- multiple levels of partitioning +-- +CREATE TABLE prt1_l (a int, b int, c varchar) PARTITION BY RANGE(a); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE prt1_l_p1 PARTITION OF prt1_l FOR VALUES FROM (0) TO (250); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt1_l_p2 PARTITION OF prt1_l FOR VALUES FROM (250) TO (500) PARTITION BY LIST (c); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt1_l_p2_p1 PARTITION OF prt1_l_p2 FOR VALUES IN ('0000', '0001'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt1_l_p2_p2 PARTITION OF prt1_l_p2 FOR VALUES IN ('0002', '0003'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt1_l_p3 PARTITION OF prt1_l FOR VALUES FROM (500) TO (600) PARTITION BY RANGE (b); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt1_l_p3_p1 PARTITION OF prt1_l_p3 FOR VALUES FROM (0) TO (13); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt1_l_p3_p2 PARTITION OF prt1_l_p3 FOR VALUES FROM (13) TO (25); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO prt1_l SELECT i, i % 25, to_char(i % 4, 'FM0000') FROM generate_series(0, 599, 2) i; +ANALYZE prt1_l; +CREATE TABLE prt2_l (a int, b int, c varchar) PARTITION BY RANGE(b); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE prt2_l_p1 PARTITION OF prt2_l FOR VALUES FROM (0) TO (250); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt2_l_p2 PARTITION OF prt2_l FOR VALUES FROM (250) TO (500) PARTITION BY LIST (c); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt2_l_p2_p1 PARTITION OF prt2_l_p2 FOR VALUES IN ('0000', '0001'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt2_l_p2_p2 PARTITION OF prt2_l_p2 FOR VALUES IN ('0002', '0003'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt2_l_p3 PARTITION OF prt2_l FOR VALUES FROM (500) TO (600) PARTITION BY RANGE (a); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt2_l_p3_p1 PARTITION OF prt2_l_p3 FOR VALUES FROM (0) TO (13); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt2_l_p3_p2 PARTITION OF prt2_l_p3 FOR VALUES FROM (13) TO (25); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO prt2_l SELECT i % 25, i, to_char(i % 4, 'FM0000') FROM generate_series(0, 599, 3) i; +ANALYZE prt2_l; +-- inner join, qual covering only top-level partitions +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1, prt2_l t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +--------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Join + Hash Cond: (t2_1.b = t1_1.a) + -> Seq Scan on prt2_l_p1 t2_1 + -> Hash + -> Broadcast Motion 3:3 (slice2; segments: 3) + -> Seq Scan on prt1_l_p1 t1_1 + Filter: (b = 0) + -> Hash Join + Hash Cond: (t2_3.b = t1_3.a) + -> Append + -> Seq Scan on prt2_l_p2_p1 t2_3 + -> Seq Scan on prt2_l_p2_p2 t2_4 + -> Hash + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Append + -> Seq Scan on prt1_l_p2_p1 t1_3 + Filter: (b = 0) + -> Seq Scan on prt1_l_p2_p2 t1_4 + Filter: (b = 0) + -> Hash Join + Hash Cond: (t2_6.b = t1_5.a) + -> Append + -> Seq Scan on prt2_l_p3_p1 t2_6 + -> Seq Scan on prt2_l_p3_p2 t2_7 + -> Hash + -> Broadcast Motion 3:3 (slice4; segments: 3) + -> Seq Scan on prt1_l_p3_p1 t1_5 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(34 rows) + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1, prt2_l t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b; + a | c | b | c +-----+------+-----+------ + 0 | 0000 | 0 | 0000 + 150 | 0002 | 150 | 0002 + 300 | 0000 | 300 | 0000 + 450 | 0002 | 450 | 0002 +(4 rows) + +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 LEFT JOIN prt2_l t2 ON t1.a = t2.b AND t1.c = t2.c WHERE t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t2.b + -> Sort + Sort Key: t1.a, t2.b + -> Append + -> Hash Right Join + Hash Cond: ((t2_1.b = t1_1.a) AND ((t2_1.c)::text = (t1_1.c)::text)) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t2_1.b + -> Seq Scan on prt2_l_p1 t2_1 + -> Hash + -> Seq Scan on prt1_l_p1 t1_1 + Filter: (b = 0) + -> Hash Right Join + Hash Cond: ((t2_2.b = t1_2.a) AND ((t2_2.c)::text = (t1_2.c)::text)) + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t2_2.b + -> Seq Scan on prt2_l_p2_p1 t2_2 + -> Hash + -> Seq Scan on prt1_l_p2_p1 t1_2 + Filter: (b = 0) + -> Hash Right Join + Hash Cond: ((t2_3.b = t1_3.a) AND ((t2_3.c)::text = (t1_3.c)::text)) + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: t2_3.b + -> Seq Scan on prt2_l_p2_p2 t2_3 + -> Hash + -> Seq Scan on prt1_l_p2_p2 t1_3 + Filter: (b = 0) + -> Hash Right Join + Hash Cond: ((t2_5.b = t1_4.a) AND ((t2_5.c)::text = (t1_4.c)::text)) + -> Redistribute Motion 3:3 (slice5; segments: 3) + Hash Key: t2_5.b, t2_5.c + -> Append + -> Seq Scan on prt2_l_p3_p1 t2_5 + -> Seq Scan on prt2_l_p3_p2 t2_6 + -> Hash + -> Redistribute Motion 3:3 (slice6; segments: 3) + Hash Key: t1_4.a, t1_4.c + -> Seq Scan on prt1_l_p3_p1 t1_4 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(42 rows) + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 LEFT JOIN prt2_l t2 ON t1.a = t2.b AND t1.c = t2.c WHERE t1.b = 0 ORDER BY t1.a, t2.b; + a | c | b | c +-----+------+-----+------ + 0 | 0000 | 0 | 0000 + 50 | 0002 | | + 100 | 0000 | | + 150 | 0002 | 150 | 0002 + 200 | 0000 | | + 250 | 0002 | | + 300 | 0000 | 300 | 0000 + 350 | 0002 | | + 400 | 0000 | | + 450 | 0002 | 450 | 0002 + 500 | 0000 | | + 550 | 0002 | | +(12 rows) + +-- right join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 RIGHT JOIN prt2_l t2 ON t1.a = t2.b AND t1.c = t2.c WHERE t2.a = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t2.b + -> Sort + Sort Key: t1.a, t2.b + -> Append + -> Hash Right Join + Hash Cond: ((t1_1.a = t2_1.b) AND ((t1_1.c)::text = (t2_1.c)::text)) + -> Seq Scan on prt1_l_p1 t1_1 + -> Hash + -> Redistribute Motion 1:3 (slice2; segments: 1) + Hash Key: t2_1.b + -> Seq Scan on prt2_l_p1 t2_1 + Filter: (a = 0) + -> Hash Right Join + Hash Cond: ((t1_2.a = t2_2.b) AND ((t1_2.c)::text = (t2_2.c)::text)) + -> Seq Scan on prt1_l_p2_p1 t1_2 + -> Hash + -> Redistribute Motion 1:3 (slice3; segments: 1) + Hash Key: t2_2.b + -> Seq Scan on prt2_l_p2_p1 t2_2 + Filter: (a = 0) + -> Hash Right Join + Hash Cond: ((t1_3.a = t2_3.b) AND ((t1_3.c)::text = (t2_3.c)::text)) + -> Seq Scan on prt1_l_p2_p2 t1_3 + -> Hash + -> Redistribute Motion 1:3 (slice4; segments: 1) + Hash Key: t2_3.b + -> Seq Scan on prt2_l_p2_p2 t2_3 + Filter: (a = 0) + -> Hash Right Join + Hash Cond: ((t1_5.a = t2_4.b) AND ((t1_5.c)::text = (t2_4.c)::text)) + -> Redistribute Motion 3:3 (slice5; segments: 3) + Hash Key: 0 + -> Append + -> Seq Scan on prt1_l_p3_p1 t1_5 + -> Seq Scan on prt1_l_p3_p2 t1_6 + -> Hash + -> Seq Scan on prt2_l_p3_p1 t2_4 + Filter: (a = 0) + Optimizer: Postgres query optimizer +(40 rows) + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 RIGHT JOIN prt2_l t2 ON t1.a = t2.b AND t1.c = t2.c WHERE t2.a = 0 ORDER BY t1.a, t2.b; + a | c | b | c +-----+------+-----+------ + 0 | 0000 | 0 | 0000 + 150 | 0002 | 150 | 0002 + 300 | 0000 | 300 | 0000 + 450 | 0002 | 450 | 0002 + | | 75 | 0003 + | | 225 | 0001 + | | 375 | 0003 + | | 525 | 0001 +(8 rows) + +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE prt1_l.b = 0) t1 FULL JOIN (SELECT * FROM prt2_l WHERE prt2_l.a = 0) t2 ON (t1.a = t2.b AND t1.c = t2.c) ORDER BY t1.a, t2.b; + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: prt1_l.a, prt2_l.b + -> Sort + Sort Key: prt1_l.a, prt2_l.b + -> Append + -> Hash Full Join + Hash Cond: ((prt1_l_1.a = prt2_l_1.b) AND ((prt1_l_1.c)::text = (prt2_l_1.c)::text)) + -> Seq Scan on prt1_l_p1 prt1_l_1 + Filter: (b = 0) + -> Hash + -> Redistribute Motion 1:3 (slice2; segments: 1) + Hash Key: prt2_l_1.b + -> Seq Scan on prt2_l_p1 prt2_l_1 + Filter: (a = 0) + -> Hash Full Join + Hash Cond: ((prt1_l_2.a = prt2_l_2.b) AND ((prt1_l_2.c)::text = (prt2_l_2.c)::text)) + -> Seq Scan on prt1_l_p2_p1 prt1_l_2 + Filter: (b = 0) + -> Hash + -> Redistribute Motion 1:3 (slice3; segments: 1) + Hash Key: prt2_l_2.b + -> Seq Scan on prt2_l_p2_p1 prt2_l_2 + Filter: (a = 0) + -> Hash Full Join + Hash Cond: ((prt1_l_3.a = prt2_l_3.b) AND ((prt1_l_3.c)::text = (prt2_l_3.c)::text)) + -> Seq Scan on prt1_l_p2_p2 prt1_l_3 + Filter: (b = 0) + -> Hash + -> Redistribute Motion 1:3 (slice4; segments: 1) + Hash Key: prt2_l_3.b + -> Seq Scan on prt2_l_p2_p2 prt2_l_3 + Filter: (a = 0) + -> Hash Full Join + Hash Cond: ((prt1_l_4.a = prt2_l_4.b) AND ((prt1_l_4.c)::text = (prt2_l_4.c)::text)) + -> Redistribute Motion 3:3 (slice5; segments: 3) + Hash Key: 0 + -> Seq Scan on prt1_l_p3_p1 prt1_l_4 + Filter: (b = 0) + -> Hash + -> Seq Scan on prt2_l_p3_p1 prt2_l_4 + Filter: (a = 0) + Optimizer: Postgres query optimizer +(42 rows) + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE prt1_l.b = 0) t1 FULL JOIN (SELECT * FROM prt2_l WHERE prt2_l.a = 0) t2 ON (t1.a = t2.b AND t1.c = t2.c) ORDER BY t1.a, t2.b; + a | c | b | c +-----+------+-----+------ + 0 | 0000 | 0 | 0000 + 50 | 0002 | | + 100 | 0000 | | + 150 | 0002 | 150 | 0002 + 200 | 0000 | | + 250 | 0002 | | + 300 | 0000 | 300 | 0000 + 350 | 0002 | | + 400 | 0000 | | + 450 | 0002 | 450 | 0002 + 500 | 0000 | | + 550 | 0002 | | + | | 75 | 0003 + | | 225 | 0001 + | | 375 | 0003 + | | 525 | 0001 +(16 rows) + +-- lateral partitionwise join +-- GPDB_12_MERGE_FEATURE_NOT_SUPPORTED +-- If lateral_relids of RelOptInfo for a inner path is not null, the inner path needs +-- params of outer path. So We can not add motion above inner path. +-- however, in left join, outer path can not be replicated. We can not generate path for left join, +-- So hit the error: could not devise a query plan for the given query. +EXPLAIN (COSTS OFF) +SELECT * FROM prt1_l t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t2.c AS t2c, t2.b AS t2b, t3.b AS t3b, least(t1.a,t2.a,t3.b) FROM prt1_l t2 JOIN prt2_l t3 ON (t2.a = t3.b AND t2.c = t3.c)) ss + ON t1.a = ss.t2a AND t1.c = ss.t2c WHERE t1.b = 0 ORDER BY t1.a; +ERROR: could not devise a query plan for the given query (pathnode.c:285) +SELECT * FROM prt1_l t1 LEFT JOIN LATERAL + (SELECT t2.a AS t2a, t2.c AS t2c, t2.b AS t2b, t3.b AS t3b, least(t1.a,t2.a,t3.b) FROM prt1_l t2 JOIN prt2_l t3 ON (t2.a = t3.b AND t2.c = t3.c)) ss + ON t1.a = ss.t2a AND t1.c = ss.t2c WHERE t1.b = 0 ORDER BY t1.a; +ERROR: could not devise a query plan for the given query (pathnode.c:285) +SET max_parallel_workers_per_gather = 0; +-- If there are lateral references to the other relation in sample scan, +-- we cannot generate a partitionwise join. +EXPLAIN (COSTS OFF) +SELECT * FROM prt1_l t1 JOIN LATERAL + (SELECT * FROM prt1_l t2 TABLESAMPLE SYSTEM (t1.a) REPEATABLE(t1.b)) s + ON t1.a = s.a AND t1.b = s.b AND t1.c = s.c; + QUERY PLAN +---------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Nested Loop + -> Append + -> Seq Scan on prt1_l_p1 t1_1 + -> Seq Scan on prt1_l_p2_p1 t1_2 + -> Seq Scan on prt1_l_p2_p2 t1_3 + -> Seq Scan on prt1_l_p3_p1 t1_4 + -> Seq Scan on prt1_l_p3_p2 t1_5 + -> Append + -> Sample Scan on prt1_l_p1 t2_1 + Sampling: system (t1.a) REPEATABLE (t1.b) + Filter: ((t1.a = a) AND (t1.b = b) AND ((t1.c)::text = (c)::text)) + -> Sample Scan on prt1_l_p2_p1 t2_2 + Sampling: system (t1.a) REPEATABLE (t1.b) + Filter: ((t1.a = a) AND (t1.b = b) AND ((t1.c)::text = (c)::text)) + -> Sample Scan on prt1_l_p2_p2 t2_3 + Sampling: system (t1.a) REPEATABLE (t1.b) + Filter: ((t1.a = a) AND (t1.b = b) AND ((t1.c)::text = (c)::text)) + -> Sample Scan on prt1_l_p3_p1 t2_4 + Sampling: system (t1.a) REPEATABLE (t1.b) + Filter: ((t1.a = a) AND (t1.b = b) AND ((t1.c)::text = (c)::text)) + -> Sample Scan on prt1_l_p3_p2 t2_5 + Sampling: system (t1.a) REPEATABLE (t1.b) + Filter: ((t1.a = a) AND (t1.b = b) AND ((t1.c)::text = (c)::text)) + Optimizer: Postgres query optimizer +(25 rows) + +-- If there are lateral references to the other relation in scan's restriction +-- clauses, we cannot generate a partitionwise join. +EXPLAIN (COSTS OFF) +SELECT COUNT(*) FROM prt1_l t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2_l t2) s + ON t1.a = s.b AND t1.b = s.a AND t1.c = s.c + WHERE s.t1b = s.a; +ERROR: could not pull up equivalence class using projected target list (pathkeys.c:1618) +SELECT COUNT(*) FROM prt1_l t1 LEFT JOIN LATERAL + (SELECT t1.b AS t1b, t2.* FROM prt2_l t2) s + ON t1.a = s.b AND t1.b = s.a AND t1.c = s.c + WHERE s.t1b = s.a; +ERROR: could not pull up equivalence class using projected target list (pathkeys.c:1618) +RESET max_parallel_workers_per_gather; +-- join with one side empty +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE a = 1 AND a = 2) t1 RIGHT JOIN prt2_l t2 ON t1.a = t2.b AND t1.b = t2.a AND t1.c = t2.c; + QUERY PLAN +------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Left Join + Hash Cond: ((t2.b = a) AND (t2.a = b) AND ((t2.c)::text = (c)::text)) + -> Append + -> Seq Scan on prt2_l_p1 t2_1 + -> Seq Scan on prt2_l_p2_p1 t2_2 + -> Seq Scan on prt2_l_p2_p2 t2_3 + -> Seq Scan on prt2_l_p3_p1 t2_4 + -> Seq Scan on prt2_l_p3_p2 t2_5 + -> Hash + -> Result + One-Time Filter: false + Optimizer: Postgres query optimizer +(13 rows) + +-- Test case to verify proper handling of subqueries in a partitioned delete. +-- The weird-looking lateral join is just there to force creation of a +-- nestloop parameter within the subquery, which exposes the problem if the +-- planner fails to make multiple copies of the subquery as appropriate. +EXPLAIN (COSTS OFF) +DELETE FROM prt1_l +WHERE EXISTS ( + SELECT 1 + FROM int4_tbl, + LATERAL (SELECT int4_tbl.f1 FROM int8_tbl LIMIT 2) ss + WHERE prt1_l.c IS NULL); + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Delete on prt1_l + Delete on prt1_l_p1 prt1_l_1 + Delete on prt1_l_p3_p1 prt1_l_2 + Delete on prt1_l_p3_p2 prt1_l_3 + -> Explicit Redistribute Motion 1:3 (slice1; segments: 1) + -> Nested Loop Semi Join + -> Gather Motion 3:1 (slice2; segments: 3) + -> Append + -> Seq Scan on prt1_l_p1 prt1_l_1 + Filter: (c IS NULL) + -> Seq Scan on prt1_l_p3_p1 prt1_l_2 + Filter: (c IS NULL) + -> Seq Scan on prt1_l_p3_p2 prt1_l_3 + Filter: (c IS NULL) + -> Materialize + -> Nested Loop + -> Gather Motion 3:1 (slice3; segments: 3) + -> Seq Scan on int4_tbl + -> Materialize + -> Subquery Scan on ss + -> Limit + -> Result + -> Materialize + -> Gather Motion 3:1 (slice4; segments: 3) + -> Seq Scan on int8_tbl + Optimizer: Postgres query optimizer +(26 rows) + +-- +-- negative testcases +-- +CREATE TABLE prt1_n (a int, b int, c varchar) PARTITION BY RANGE(c); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE prt1_n_p1 PARTITION OF prt1_n FOR VALUES FROM ('0000') TO ('0250'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt1_n_p2 PARTITION OF prt1_n FOR VALUES FROM ('0250') TO ('0500'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO prt1_n SELECT i, i, to_char(i, 'FM0000') FROM generate_series(0, 499, 2) i; +ANALYZE prt1_n; +CREATE TABLE prt2_n (a int, b int, c text) PARTITION BY LIST(c); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE prt2_n_p1 PARTITION OF prt2_n FOR VALUES IN ('0000', '0003', '0004', '0010', '0006', '0007'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt2_n_p2 PARTITION OF prt2_n FOR VALUES IN ('0001', '0005', '0002', '0009', '0008', '0011'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO prt2_n SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 2) i; +ANALYZE prt2_n; +CREATE TABLE prt3_n (a int, b int, c text) PARTITION BY LIST(c); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE prt3_n_p1 PARTITION OF prt3_n FOR VALUES IN ('0000', '0004', '0006', '0007'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt3_n_p2 PARTITION OF prt3_n FOR VALUES IN ('0001', '0002', '0008', '0010'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt3_n_p3 PARTITION OF prt3_n FOR VALUES IN ('0003', '0005', '0009', '0011'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO prt2_n SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 599, 2) i; +ANALYZE prt3_n; +CREATE TABLE prt4_n (a int, b int, c text) PARTITION BY RANGE(a); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE prt4_n_p1 PARTITION OF prt4_n FOR VALUES FROM (0) TO (300); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt4_n_p2 PARTITION OF prt4_n FOR VALUES FROM (300) TO (500); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt4_n_p3 PARTITION OF prt4_n FOR VALUES FROM (500) TO (600); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO prt4_n SELECT i, i, to_char(i, 'FM0000') FROM generate_series(0, 599, 2) i; +ANALYZE prt4_n; +-- partitionwise join can not be applied if the partition ranges differ +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt4_n t2 WHERE t1.a = t2.a; + QUERY PLAN +---------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Join + Hash Cond: (t1.a = t2.a) + -> Append + Partition Selectors: $0 + -> Seq Scan on prt1_p1 t1_1 + -> Seq Scan on prt1_p2 t1_2 + -> Seq Scan on prt1_p3 t1_3 + -> Hash + -> Partition Selector (selector id: $0) + -> Append + -> Seq Scan on prt4_n_p1 t2_1 + -> Seq Scan on prt4_n_p2 t2_2 + -> Seq Scan on prt4_n_p3 t2_3 + Optimizer: Postgres query optimizer +(15 rows) + +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt4_n t2, prt2 t3 WHERE t1.a = t2.a and t1.a = t3.b; + QUERY PLAN +------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Join + Hash Cond: (t2.a = t1.a) + -> Append + Partition Selectors: $0 + -> Seq Scan on prt4_n_p1 t2_1 + -> Seq Scan on prt4_n_p2 t2_2 + -> Seq Scan on prt4_n_p3 t2_3 + -> Hash + -> Partition Selector (selector id: $0) + -> Append + -> Hash Join + Hash Cond: (t1_1.a = t3_1.b) + -> Seq Scan on prt1_p1 t1_1 + -> Hash + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t3_1.b + -> Seq Scan on prt2_p1 t3_1 + -> Hash Join + Hash Cond: (t1_2.a = t3_2.b) + -> Seq Scan on prt1_p2 t1_2 + -> Hash + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t3_2.b + -> Seq Scan on prt2_p2 t3_2 + -> Hash Join + Hash Cond: (t1_3.a = t3_3.b) + -> Seq Scan on prt1_p3 t1_3 + -> Hash + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: t3_3.b + -> Seq Scan on prt2_p3 t3_3 + Optimizer: Postgres query optimizer +(33 rows) + +-- partitionwise join can not be applied if there are no equi-join conditions +-- between partition keys +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1 LEFT JOIN prt2 t2 ON (t1.a < t2.b); + QUERY PLAN +--------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Nested Loop Left Join + Join Filter: (t1.a < t2.b) + -> Append + -> Seq Scan on prt1_p1 t1_1 + -> Seq Scan on prt1_p2 t1_2 + -> Seq Scan on prt1_p3 t1_3 + -> Materialize + -> Broadcast Motion 3:3 (slice2; segments: 3) + -> Append + -> Seq Scan on prt2_p1 t2_1 + -> Seq Scan on prt2_p2 t2_2 + -> Seq Scan on prt2_p3 t2_3 + Optimizer: Postgres query optimizer +(14 rows) + +-- equi-join with join condition on partial keys does not qualify for +-- partitionwise join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_m t1, prt2_m t2 WHERE t1.a = (t2.b + t2.a)/2; + QUERY PLAN +------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Join + Hash Cond: (t1.a = ((t2.b + t2.a) / 2)) + -> Append + Partition Selectors: $0 + -> Seq Scan on prt1_m_p1 t1_1 + -> Seq Scan on prt1_m_p2 t1_2 + -> Seq Scan on prt1_m_p3 t1_3 + -> Hash + -> Partition Selector (selector id: $0) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: ((t2.b + t2.a) / 2) + -> Append + -> Seq Scan on prt2_m_p1 t2_1 + -> Seq Scan on prt2_m_p2 t2_2 + -> Seq Scan on prt2_m_p3 t2_3 + Optimizer: Postgres query optimizer +(17 rows) + +-- equi-join between out-of-order partition key columns does not qualify for +-- partitionwise join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_m t1 LEFT JOIN prt2_m t2 ON t1.a = t2.b; + QUERY PLAN +------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Left Join + Hash Cond: (t1.a = t2.b) + -> Append + -> Seq Scan on prt1_m_p1 t1_1 + -> Seq Scan on prt1_m_p2 t1_2 + -> Seq Scan on prt1_m_p3 t1_3 + -> Hash + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t2.b + -> Append + -> Seq Scan on prt2_m_p1 t2_1 + -> Seq Scan on prt2_m_p2 t2_2 + -> Seq Scan on prt2_m_p3 t2_3 + Optimizer: Postgres query optimizer +(15 rows) + +-- equi-join between non-key columns does not qualify for partitionwise join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_m t1 LEFT JOIN prt2_m t2 ON t1.c = t2.c; + QUERY PLAN +------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Left Join + Hash Cond: (t1.c = t2.c) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t1.c + -> Append + -> Seq Scan on prt1_m_p1 t1_1 + -> Seq Scan on prt1_m_p2 t1_2 + -> Seq Scan on prt1_m_p3 t1_3 + -> Hash + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t2.c + -> Append + -> Seq Scan on prt2_m_p1 t2_1 + -> Seq Scan on prt2_m_p2 t2_2 + -> Seq Scan on prt2_m_p3 t2_3 + Optimizer: Postgres query optimizer +(17 rows) + +-- partitionwise join can not be applied for a join between list and range +-- partitioned tables +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_n t1 LEFT JOIN prt2_n t2 ON (t1.c = t2.c); + QUERY PLAN +------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Right Join + Hash Cond: (t2.c = (t1.c)::text) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t2.c + -> Append + -> Seq Scan on prt2_n_p1 t2_1 + -> Seq Scan on prt2_n_p2 t2_2 + -> Hash + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t1.c + -> Append + -> Seq Scan on prt1_n_p1 t1_1 + -> Seq Scan on prt1_n_p2 t1_2 + Optimizer: Postgres query optimizer +(15 rows) + +-- partitionwise join can not be applied between tables with different +-- partition lists +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_n t1 JOIN prt2_n t2 ON (t1.c = t2.c) JOIN plt1 t3 ON (t1.c = t3.c); + QUERY PLAN +------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Join + Hash Cond: ((t1.c)::text = t2.c) + -> Hash Join + Hash Cond: (t3.c = (t1.c)::text) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t3.c + -> Append + -> Seq Scan on plt1_p1 t3_1 + -> Seq Scan on plt1_p2 t3_2 + -> Seq Scan on plt1_p3 t3_3 + -> Hash + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t1.c + -> Append + -> Seq Scan on prt1_n_p1 t1_1 + -> Seq Scan on prt1_n_p2 t1_2 + -> Hash + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: t2.c + -> Append + -> Seq Scan on prt2_n_p1 t2_1 + -> Seq Scan on prt2_n_p2 t2_2 + Optimizer: Postgres query optimizer +(24 rows) + +-- partitionwise join can not be applied for a join between key column and +-- non-key column +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_n t1 FULL JOIN prt1 t2 ON (t1.c = t2.c); + QUERY PLAN +------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Full Join + Hash Cond: ((t2.c)::text = (t1.c)::text) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t2.c + -> Append + -> Seq Scan on prt1_p1 t2_1 + -> Seq Scan on prt1_p2 t2_2 + -> Seq Scan on prt1_p3 t2_3 + -> Hash + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t1.c + -> Append + -> Seq Scan on prt1_n_p1 t1_1 + -> Seq Scan on prt1_n_p2 t1_2 + Optimizer: Postgres query optimizer +(16 rows) + +-- +-- Test some other plan types in a partitionwise join (unfortunately, +-- we need larger tables to get the planner to choose these plan types) +-- +create temp table prtx1 (a integer, b integer, c integer) + partition by range (a); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +create temp table prtx1_1 partition of prtx1 for values from (1) to (11); +NOTICE: table has parent, setting distribution columns to match parent table +create temp table prtx1_2 partition of prtx1 for values from (11) to (21); +NOTICE: table has parent, setting distribution columns to match parent table +create temp table prtx1_3 partition of prtx1 for values from (21) to (31); +NOTICE: table has parent, setting distribution columns to match parent table +create temp table prtx2 (a integer, b integer, c integer) + partition by range (a); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +create temp table prtx2_1 partition of prtx2 for values from (1) to (11); +NOTICE: table has parent, setting distribution columns to match parent table +create temp table prtx2_2 partition of prtx2 for values from (11) to (21); +NOTICE: table has parent, setting distribution columns to match parent table +create temp table prtx2_3 partition of prtx2 for values from (21) to (31); +NOTICE: table has parent, setting distribution columns to match parent table +insert into prtx1 select 1 + i%30, i, i + from generate_series(1,1000) i; +insert into prtx2 select 1 + i%30, i, i + from generate_series(1,500) i, generate_series(1,10) j; +create index on prtx2 (b); +create index on prtx2 (c); +analyze prtx1; +analyze prtx2; +explain (costs off) +select * from prtx1 +where not exists (select 1 from prtx2 + where prtx2.a=prtx1.a and prtx2.b=prtx1.b and prtx2.c=123) + and a<20 and c=120; + QUERY PLAN +-------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Append + -> Hash Anti Join + Hash Cond: ((prtx1_1.a = prtx2_1.a) AND (prtx1_1.b = prtx2_1.b)) + -> Seq Scan on prtx1_1 + Filter: ((a < 20) AND (c = 120)) + -> Hash + -> Bitmap Heap Scan on prtx2_1 + Recheck Cond: (c = 123) + -> Bitmap Index Scan on prtx2_1_c_idx + Index Cond: (c = 123) + -> Hash Right Anti Join + Hash Cond: ((prtx2_2.a = prtx1_2.a) AND (prtx2_2.b = prtx1_2.b)) + -> Seq Scan on prtx2_2 + Filter: (c = 123) + -> Hash + -> Seq Scan on prtx1_2 + Filter: ((a < 20) AND (c = 120)) + Optimizer: Postgres query optimizer +(19 rows) + +select * from prtx1 +where not exists (select 1 from prtx2 + where prtx2.a=prtx1.a and prtx2.b=prtx1.b and prtx2.c=123) + and a<20 and c=120; + a | b | c +---+-----+----- + 1 | 120 | 120 +(1 row) + +explain (costs off) +select * from prtx1 +where not exists (select 1 from prtx2 + where prtx2.a=prtx1.a and (prtx2.b=prtx1.b+1 or prtx2.c=99)) + and a<20 and c=91; + QUERY PLAN +-------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Append + -> Hash Right Anti Join + Hash Cond: (prtx2_1.a = prtx1_1.a) + Join Filter: ((prtx2_1.b = (prtx1_1.b + 1)) OR (prtx2_1.c = 99)) + -> Seq Scan on prtx2_1 + -> Hash + -> Seq Scan on prtx1_1 + Filter: ((a < 20) AND (c = 91)) + -> Hash Right Anti Join + Hash Cond: (prtx2_2.a = prtx1_2.a) + Join Filter: ((prtx2_2.b = (prtx1_2.b + 1)) OR (prtx2_2.c = 99)) + -> Seq Scan on prtx2_2 + -> Hash + -> Seq Scan on prtx1_2 + Filter: ((a < 20) AND (c = 91)) + Optimizer: Postgres query optimizer +(17 rows) + +select * from prtx1 +where not exists (select 1 from prtx2 + where prtx2.a=prtx1.a and (prtx2.b=prtx1.b+1 or prtx2.c=99)) + and a<20 and c=91; + a | b | c +---+----+---- + 2 | 91 | 91 +(1 row) + +-- +-- Test advanced partition-matching algorithm for partitioned join +-- +-- Tests for range-partitioned tables +CREATE TABLE prt1_adv (a int, b int, c varchar) PARTITION BY RANGE (a); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE prt1_adv_p1 PARTITION OF prt1_adv FOR VALUES FROM (100) TO (200); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt1_adv_p2 PARTITION OF prt1_adv FOR VALUES FROM (200) TO (300); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt1_adv_p3 PARTITION OF prt1_adv FOR VALUES FROM (300) TO (400); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE INDEX prt1_adv_a_idx ON prt1_adv (a); +INSERT INTO prt1_adv SELECT i, i % 25, to_char(i, 'FM0000') FROM generate_series(100, 399) i; +ANALYZE prt1_adv; +CREATE TABLE prt2_adv (a int, b int, c varchar) PARTITION BY RANGE (b); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE prt2_adv_p1 PARTITION OF prt2_adv FOR VALUES FROM (100) TO (150); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt2_adv_p2 PARTITION OF prt2_adv FOR VALUES FROM (200) TO (300); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt2_adv_p3 PARTITION OF prt2_adv FOR VALUES FROM (350) TO (500); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE INDEX prt2_adv_b_idx ON prt2_adv (b); +INSERT INTO prt2_adv_p1 SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(100, 149) i; +INSERT INTO prt2_adv_p2 SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(200, 299) i; +INSERT INTO prt2_adv_p3 SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(350, 499) i; +ANALYZE prt2_adv; +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +--------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Join + Hash Cond: (t2_1.b = t1_1.a) + -> Seq Scan on prt2_adv_p1 t2_1 + -> Hash + -> Broadcast Motion 3:3 (slice2; segments: 3) + -> Seq Scan on prt1_adv_p1 t1_1 + Filter: (b = 0) + -> Hash Join + Hash Cond: (t2_2.b = t1_2.a) + -> Seq Scan on prt2_adv_p2 t2_2 + -> Hash + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Seq Scan on prt1_adv_p2 t1_2 + Filter: (b = 0) + -> Hash Join + Hash Cond: (t2_3.b = t1_3.a) + -> Seq Scan on prt2_adv_p3 t2_3 + -> Hash + -> Broadcast Motion 3:3 (slice4; segments: 3) + -> Seq Scan on prt1_adv_p3 t1_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(27 rows) + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + a | c | b | c +-----+------+-----+------ + 100 | 0100 | 100 | 0100 + 125 | 0125 | 125 | 0125 + 200 | 0200 | 200 | 0200 + 225 | 0225 | 225 | 0225 + 250 | 0250 | 250 | 0250 + 275 | 0275 | 275 | 0275 + 350 | 0350 | 350 | 0350 + 375 | 0375 | 375 | 0375 +(8 rows) + +-- GPDB_13_MERGE_FIXME: The query uses GPDB specific plan to do semi join. +-- The logic behind it is to convert the semi join to inner join and +-- deduplicate the rows. I attempt to implement right semi join for hash +-- join, like right out join to left out join. The problem is that the +-- inner table to build hash table on segment may overlap with other +-- segments. Shall we deserve to implement right semi join correctly? +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; + QUERY PLAN +--------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Result + -> Unique + Group Key: (RowIdExpr) + -> Sort + Sort Key: (RowIdExpr) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: (RowIdExpr) + -> Hash Join + Hash Cond: (t2_1.b = t1_1.a) + -> Seq Scan on prt2_adv_p1 t2_1 + -> Hash + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Seq Scan on prt1_adv_p1 t1_1 + Filter: (b = 0) + -> Result + -> Unique + Group Key: (RowIdExpr) + -> Sort + Sort Key: (RowIdExpr) + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: (RowIdExpr) + -> Hash Join + Hash Cond: (t2_2.b = t1_2.a) + -> Seq Scan on prt2_adv_p2 t2_2 + -> Hash + -> Broadcast Motion 3:3 (slice5; segments: 3) + -> Seq Scan on prt1_adv_p2 t1_2 + Filter: (b = 0) + -> Result + -> Unique + Group Key: (RowIdExpr) + -> Sort + Sort Key: (RowIdExpr) + -> Redistribute Motion 3:3 (slice6; segments: 3) + Hash Key: (RowIdExpr) + -> Hash Join + Hash Cond: (t2_3.b = t1_3.a) + -> Seq Scan on prt2_adv_p3 t2_3 + -> Hash + -> Broadcast Motion 3:3 (slice7; segments: 3) + -> Seq Scan on prt1_adv_p3 t1_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(48 rows) + +SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; + a | b | c +-----+---+------ + 100 | 0 | 0100 + 125 | 0 | 0125 + 200 | 0 | 0200 + 225 | 0 | 0225 + 250 | 0 | 0250 + 275 | 0 | 0275 + 350 | 0 | 0350 + 375 | 0 | 0375 +(8 rows) + +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t2.b + -> Sort + Sort Key: t1.a, t2.b + -> Append + -> Hash Right Join + Hash Cond: (t2_1.b = t1_1.a) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t2_1.b + -> Seq Scan on prt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on prt1_adv_p1 t1_1 + Filter: (b = 0) + -> Hash Right Join + Hash Cond: (t2_2.b = t1_2.a) + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t2_2.b + -> Seq Scan on prt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on prt1_adv_p2 t1_2 + Filter: (b = 0) + -> Hash Right Join + Hash Cond: (t2_3.b = t1_3.a) + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: t2_3.b + -> Seq Scan on prt2_adv_p3 t2_3 + -> Hash + -> Seq Scan on prt1_adv_p3 t1_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(30 rows) + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + a | c | b | c +-----+------+-----+------ + 100 | 0100 | 100 | 0100 + 125 | 0125 | 125 | 0125 + 150 | 0150 | | + 175 | 0175 | | + 200 | 0200 | 200 | 0200 + 225 | 0225 | 225 | 0225 + 250 | 0250 | 250 | 0250 + 275 | 0275 | 275 | 0275 + 300 | 0300 | | + 325 | 0325 | | + 350 | 0350 | 350 | 0350 + 375 | 0375 | 375 | 0375 +(12 rows) + +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; + QUERY PLAN +------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Right Anti Join + Hash Cond: (t2_1.b = t1_1.a) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t2_1.b + -> Seq Scan on prt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on prt1_adv_p1 t1_1 + Filter: (b = 0) + -> Hash Right Anti Join + Hash Cond: (t2_2.b = t1_2.a) + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t2_2.b + -> Seq Scan on prt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on prt1_adv_p2 t1_2 + Filter: (b = 0) + -> Hash Right Anti Join + Hash Cond: (t2_3.b = t1_3.a) + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: t2_3.b + -> Seq Scan on prt2_adv_p3 t2_3 + -> Hash + -> Seq Scan on prt1_adv_p3 t1_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(30 rows) + +SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; + a | b | c +-----+---+------ + 150 | 0 | 0150 + 175 | 0 | 0175 + 300 | 0 | 0300 + 325 | 0 | 0325 +(4 rows) + +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 175 phv, * FROM prt1_adv WHERE prt1_adv.b = 0) t1 FULL JOIN (SELECT 425 phv, * FROM prt2_adv WHERE prt2_adv.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b; + QUERY PLAN +-------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: prt1_adv.a, prt2_adv.b + -> Sort + Sort Key: prt1_adv.a, prt2_adv.b + -> Append + -> Hash Full Join + Hash Cond: (prt1_adv_1.a = prt2_adv_1.b) + Filter: (((175) = prt1_adv_1.a) OR ((425) = prt2_adv_1.b)) + -> Seq Scan on prt1_adv_p1 prt1_adv_1 + Filter: (b = 0) + -> Hash + -> Redistribute Motion 1:3 (slice2; segments: 1) + Hash Key: prt2_adv_1.b + -> Seq Scan on prt2_adv_p1 prt2_adv_1 + Filter: (a = 0) + -> Hash Full Join + Hash Cond: (prt1_adv_2.a = prt2_adv_2.b) + Filter: (((175) = prt1_adv_2.a) OR ((425) = prt2_adv_2.b)) + -> Seq Scan on prt1_adv_p2 prt1_adv_2 + Filter: (b = 0) + -> Hash + -> Redistribute Motion 1:3 (slice3; segments: 1) + Hash Key: prt2_adv_2.b + -> Seq Scan on prt2_adv_p2 prt2_adv_2 + Filter: (a = 0) + -> Hash Full Join + Hash Cond: (prt2_adv_3.b = prt1_adv_3.a) + Filter: (((175) = prt1_adv_3.a) OR ((425) = prt2_adv_3.b)) + -> Seq Scan on prt2_adv_p3 prt2_adv_3 + Filter: (a = 0) + -> Hash + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: 0 + -> Seq Scan on prt1_adv_p3 prt1_adv_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(36 rows) + +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 175 phv, * FROM prt1_adv WHERE prt1_adv.b = 0) t1 FULL JOIN (SELECT 425 phv, * FROM prt2_adv WHERE prt2_adv.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b; + a | c | b | c +-----+------+-----+------ + 175 | 0175 | | + | | 425 | 0425 +(2 rows) + +-- Test cases where one side has an extra partition +CREATE TABLE prt2_adv_extra PARTITION OF prt2_adv FOR VALUES FROM (500) TO (MAXVALUE); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO prt2_adv SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(500, 599) i; +ANALYZE prt2_adv; +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +--------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Join + Hash Cond: (t2_1.b = t1_1.a) + -> Seq Scan on prt2_adv_p1 t2_1 + -> Hash + -> Broadcast Motion 3:3 (slice2; segments: 3) + -> Seq Scan on prt1_adv_p1 t1_1 + Filter: (b = 0) + -> Hash Join + Hash Cond: (t2_2.b = t1_2.a) + -> Seq Scan on prt2_adv_p2 t2_2 + -> Hash + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Seq Scan on prt1_adv_p2 t1_2 + Filter: (b = 0) + -> Hash Join + Hash Cond: (t2_3.b = t1_3.a) + -> Seq Scan on prt2_adv_p3 t2_3 + -> Hash + -> Broadcast Motion 3:3 (slice4; segments: 3) + -> Seq Scan on prt1_adv_p3 t1_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(27 rows) + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + a | c | b | c +-----+------+-----+------ + 100 | 0100 | 100 | 0100 + 125 | 0125 | 125 | 0125 + 200 | 0200 | 200 | 0200 + 225 | 0225 | 225 | 0225 + 250 | 0250 | 250 | 0250 + 275 | 0275 | 275 | 0275 + 350 | 0350 | 350 | 0350 + 375 | 0375 | 375 | 0375 +(8 rows) + +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; + QUERY PLAN +--------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Result + -> Unique + Group Key: (RowIdExpr) + -> Sort + Sort Key: (RowIdExpr) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: (RowIdExpr) + -> Hash Join + Hash Cond: (t2_1.b = t1_1.a) + -> Seq Scan on prt2_adv_p1 t2_1 + -> Hash + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Seq Scan on prt1_adv_p1 t1_1 + Filter: (b = 0) + -> Result + -> Unique + Group Key: (RowIdExpr) + -> Sort + Sort Key: (RowIdExpr) + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: (RowIdExpr) + -> Hash Join + Hash Cond: (t2_2.b = t1_2.a) + -> Seq Scan on prt2_adv_p2 t2_2 + -> Hash + -> Broadcast Motion 3:3 (slice5; segments: 3) + -> Seq Scan on prt1_adv_p2 t1_2 + Filter: (b = 0) + -> Result + -> Unique + Group Key: (RowIdExpr) + -> Sort + Sort Key: (RowIdExpr) + -> Redistribute Motion 3:3 (slice6; segments: 3) + Hash Key: (RowIdExpr) + -> Hash Join + Hash Cond: (t2_3.b = t1_3.a) + -> Seq Scan on prt2_adv_p3 t2_3 + -> Hash + -> Broadcast Motion 3:3 (slice7; segments: 3) + -> Seq Scan on prt1_adv_p3 t1_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(48 rows) + +SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; + a | b | c +-----+---+------ + 100 | 0 | 0100 + 125 | 0 | 0125 + 200 | 0 | 0200 + 225 | 0 | 0225 + 250 | 0 | 0250 + 275 | 0 | 0275 + 350 | 0 | 0350 + 375 | 0 | 0375 +(8 rows) + +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t2.b + -> Sort + Sort Key: t1.a, t2.b + -> Append + -> Hash Right Join + Hash Cond: (t2_1.b = t1_1.a) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t2_1.b + -> Seq Scan on prt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on prt1_adv_p1 t1_1 + Filter: (b = 0) + -> Hash Right Join + Hash Cond: (t2_2.b = t1_2.a) + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t2_2.b + -> Seq Scan on prt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on prt1_adv_p2 t1_2 + Filter: (b = 0) + -> Hash Right Join + Hash Cond: (t2_3.b = t1_3.a) + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: t2_3.b + -> Seq Scan on prt2_adv_p3 t2_3 + -> Hash + -> Seq Scan on prt1_adv_p3 t1_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(30 rows) + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + a | c | b | c +-----+------+-----+------ + 100 | 0100 | 100 | 0100 + 125 | 0125 | 125 | 0125 + 150 | 0150 | | + 175 | 0175 | | + 200 | 0200 | 200 | 0200 + 225 | 0225 | 225 | 0225 + 250 | 0250 | 250 | 0250 + 275 | 0275 | 275 | 0275 + 300 | 0300 | | + 325 | 0325 | | + 350 | 0350 | 350 | 0350 + 375 | 0375 | 375 | 0375 +(12 rows) + +-- left join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.b, t1.c, t2.a, t2.c FROM prt2_adv t1 LEFT JOIN prt1_adv t2 ON (t1.b = t2.a) WHERE t1.a = 0 ORDER BY t1.b, t2.a; + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.b, t2.a + -> Sort + Sort Key: t1.b, t2.a + -> Hash Right Join + Hash Cond: (t2.a = t1.b) + -> Append + Partition Selectors: $0 + -> Seq Scan on prt1_adv_p1 t2_1 + -> Seq Scan on prt1_adv_p2 t2_2 + -> Seq Scan on prt1_adv_p3 t2_3 + -> Hash + -> Partition Selector (selector id: $0) + -> Redistribute Motion 1:3 (slice2; segments: 1) + Hash Key: t1.b + -> Append + -> Seq Scan on prt2_adv_p1 t1_1 + Filter: (a = 0) + -> Seq Scan on prt2_adv_p2 t1_2 + Filter: (a = 0) + -> Seq Scan on prt2_adv_p3 t1_3 + Filter: (a = 0) + -> Seq Scan on prt2_adv_extra t1_4 + Filter: (a = 0) + Optimizer: Postgres query optimizer +(25 rows) + +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; + QUERY PLAN +------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Right Anti Join + Hash Cond: (t2_1.b = t1_1.a) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t2_1.b + -> Seq Scan on prt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on prt1_adv_p1 t1_1 + Filter: (b = 0) + -> Hash Right Anti Join + Hash Cond: (t2_2.b = t1_2.a) + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t2_2.b + -> Seq Scan on prt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on prt1_adv_p2 t1_2 + Filter: (b = 0) + -> Hash Right Anti Join + Hash Cond: (t2_3.b = t1_3.a) + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: t2_3.b + -> Seq Scan on prt2_adv_p3 t2_3 + -> Hash + -> Seq Scan on prt1_adv_p3 t1_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(30 rows) + +SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; + a | b | c +-----+---+------ + 150 | 0 | 0150 + 175 | 0 | 0175 + 300 | 0 | 0300 + 325 | 0 | 0325 +(4 rows) + +-- anti join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt2_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt1_adv t2 WHERE t1.b = t2.a) AND t1.a = 0 ORDER BY t1.b; + QUERY PLAN +------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.b + -> Sort + Sort Key: t1.b + -> Hash Right Anti Join + Hash Cond: (t2.a = t1.b) + -> Append + -> Seq Scan on prt1_adv_p1 t2_1 + -> Seq Scan on prt1_adv_p2 t2_2 + -> Seq Scan on prt1_adv_p3 t2_3 + -> Hash + -> Redistribute Motion 1:3 (slice2; segments: 1) + Hash Key: t1.b + -> Append + -> Seq Scan on prt2_adv_p1 t1_1 + Filter: (a = 0) + -> Seq Scan on prt2_adv_p2 t1_2 + Filter: (a = 0) + -> Seq Scan on prt2_adv_p3 t1_3 + Filter: (a = 0) + -> Seq Scan on prt2_adv_extra t1_4 + Filter: (a = 0) + Optimizer: Postgres query optimizer +(23 rows) + +-- full join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 175 phv, * FROM prt1_adv WHERE prt1_adv.b = 0) t1 FULL JOIN (SELECT 425 phv, * FROM prt2_adv WHERE prt2_adv.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b; + QUERY PLAN +------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: prt1_adv.a, prt2_adv.b + -> Sort + Sort Key: prt1_adv.a, prt2_adv.b + -> Hash Full Join + Hash Cond: (prt2_adv.b = prt1_adv.a) + Filter: (((175) = prt1_adv.a) OR ((425) = prt2_adv.b)) + -> Append + -> Seq Scan on prt2_adv_p1 prt2_adv_1 + Filter: (a = 0) + -> Seq Scan on prt2_adv_p2 prt2_adv_2 + Filter: (a = 0) + -> Seq Scan on prt2_adv_p3 prt2_adv_3 + Filter: (a = 0) + -> Seq Scan on prt2_adv_extra prt2_adv_4 + Filter: (a = 0) + -> Hash + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: 0 + -> Append + -> Seq Scan on prt1_adv_p1 prt1_adv_1 + Filter: (b = 0) + -> Seq Scan on prt1_adv_p2 prt1_adv_2 + Filter: (b = 0) + -> Seq Scan on prt1_adv_p3 prt1_adv_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(27 rows) + +-- 3-way join where not every pair of relations can do partitioned join +EXPLAIN (COSTS OFF) +SELECT t1.b, t1.c, t2.a, t2.c, t3.a, t3.c FROM prt2_adv t1 LEFT JOIN prt1_adv t2 ON (t1.b = t2.a) INNER JOIN prt1_adv t3 ON (t1.b = t3.a) WHERE t1.a = 0 ORDER BY t1.b, t2.a, t3.a; + QUERY PLAN +------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.b, t2.a + -> Sort + Sort Key: t1.b, t2.a + -> Append + -> Hash Right Join + Hash Cond: (t2_1.a = t1_1.b) + -> Seq Scan on prt1_adv_p1 t2_1 + -> Hash + -> Hash Join + Hash Cond: (t3_1.a = t1_1.b) + -> Seq Scan on prt1_adv_p1 t3_1 + -> Hash + -> Redistribute Motion 1:3 (slice2; segments: 1) + Hash Key: t1_1.b + -> Seq Scan on prt2_adv_p1 t1_1 + Filter: (a = 0) + -> Hash Right Join + Hash Cond: (t2_2.a = t1_2.b) + -> Seq Scan on prt1_adv_p2 t2_2 + -> Hash + -> Hash Join + Hash Cond: (t3_2.a = t1_2.b) + -> Seq Scan on prt1_adv_p2 t3_2 + -> Hash + -> Redistribute Motion 1:3 (slice3; segments: 1) + Hash Key: t1_2.b + -> Seq Scan on prt2_adv_p2 t1_2 + Filter: (a = 0) + -> Hash Right Join + Hash Cond: (t2_3.a = t1_3.b) + -> Seq Scan on prt1_adv_p3 t2_3 + -> Hash + -> Hash Join + Hash Cond: (t3_3.a = t1_3.b) + -> Seq Scan on prt1_adv_p3 t3_3 + -> Hash + -> Redistribute Motion 1:3 (slice4; segments: 1) + Hash Key: t1_3.b + -> Seq Scan on prt2_adv_p3 t1_3 + Filter: (a = 0) + Optimizer: Postgres query optimizer +(42 rows) + +SELECT t1.b, t1.c, t2.a, t2.c, t3.a, t3.c FROM prt2_adv t1 LEFT JOIN prt1_adv t2 ON (t1.b = t2.a) INNER JOIN prt1_adv t3 ON (t1.b = t3.a) WHERE t1.a = 0 ORDER BY t1.b, t2.a, t3.a; + b | c | a | c | a | c +-----+------+-----+------+-----+------ + 100 | 0100 | 100 | 0100 | 100 | 0100 + 125 | 0125 | 125 | 0125 | 125 | 0125 + 200 | 0200 | 200 | 0200 | 200 | 0200 + 225 | 0225 | 225 | 0225 | 225 | 0225 + 250 | 0250 | 250 | 0250 | 250 | 0250 + 275 | 0275 | 275 | 0275 | 275 | 0275 + 350 | 0350 | 350 | 0350 | 350 | 0350 + 375 | 0375 | 375 | 0375 | 375 | 0375 +(8 rows) + +DROP TABLE prt2_adv_extra; +-- Test cases where a partition on one side matches multiple partitions on +-- the other side; we currently can't do partitioned join in such cases +ALTER TABLE prt2_adv DETACH PARTITION prt2_adv_p3; +-- Split prt2_adv_p3 into two partitions so that prt1_adv_p3 matches both +CREATE TABLE prt2_adv_p3_1 PARTITION OF prt2_adv FOR VALUES FROM (350) TO (375); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt2_adv_p3_2 PARTITION OF prt2_adv FOR VALUES FROM (375) TO (500); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO prt2_adv SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(350, 499) i; +ANALYZE prt2_adv; +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +--------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Hash Join + Hash Cond: (t2.b = t1.a) + -> Append + Partition Selectors: $0 + -> Seq Scan on prt2_adv_p1 t2_1 + -> Seq Scan on prt2_adv_p2 t2_2 + -> Seq Scan on prt2_adv_p3_1 t2_3 + -> Seq Scan on prt2_adv_p3_2 t2_4 + -> Hash + -> Partition Selector (selector id: $0) + -> Broadcast Motion 3:3 (slice2; segments: 3) + -> Append + -> Seq Scan on prt1_adv_p1 t1_1 + Filter: (b = 0) + -> Seq Scan on prt1_adv_p2 t1_2 + Filter: (b = 0) + -> Seq Scan on prt1_adv_p3 t1_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(23 rows) + +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; + QUERY PLAN +------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> HashAggregate + Group Key: (RowIdExpr) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: (RowIdExpr) + -> Hash Join + Hash Cond: (t2.b = t1.a) + -> Append + Partition Selectors: $0 + -> Seq Scan on prt2_adv_p1 t2_1 + -> Seq Scan on prt2_adv_p2 t2_2 + -> Seq Scan on prt2_adv_p3_1 t2_3 + -> Seq Scan on prt2_adv_p3_2 t2_4 + -> Hash + -> Partition Selector (selector id: $0) + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Result + -> Append + -> Seq Scan on prt1_adv_p1 t1_1 + Filter: (b = 0) + -> Seq Scan on prt1_adv_p2 t1_2 + Filter: (b = 0) + -> Seq Scan on prt1_adv_p3 t1_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(28 rows) + +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t2.b + -> Sort + Sort Key: t1.a, t2.b + -> Hash Right Join + Hash Cond: (t2.b = t1.a) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t2.b + -> Append + -> Seq Scan on prt2_adv_p1 t2_1 + -> Seq Scan on prt2_adv_p2 t2_2 + -> Seq Scan on prt2_adv_p3_1 t2_3 + -> Seq Scan on prt2_adv_p3_2 t2_4 + -> Hash + -> Append + -> Seq Scan on prt1_adv_p1 t1_1 + Filter: (b = 0) + -> Seq Scan on prt1_adv_p2 t1_2 + Filter: (b = 0) + -> Seq Scan on prt1_adv_p3 t1_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(22 rows) + +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM prt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; + QUERY PLAN +------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Hash Right Anti Join + Hash Cond: (t2.b = t1.a) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t2.b + -> Append + -> Seq Scan on prt2_adv_p1 t2_1 + -> Seq Scan on prt2_adv_p2 t2_2 + -> Seq Scan on prt2_adv_p3_1 t2_3 + -> Seq Scan on prt2_adv_p3_2 t2_4 + -> Hash + -> Append + -> Seq Scan on prt1_adv_p1 t1_1 + Filter: (b = 0) + -> Seq Scan on prt1_adv_p2 t1_2 + Filter: (b = 0) + -> Seq Scan on prt1_adv_p3 t1_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(22 rows) + +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 175 phv, * FROM prt1_adv WHERE prt1_adv.b = 0) t1 FULL JOIN (SELECT 425 phv, * FROM prt2_adv WHERE prt2_adv.a = 0) t2 ON (t1.a = t2.b) WHERE t1.phv = t1.a OR t2.phv = t2.b ORDER BY t1.a, t2.b; + QUERY PLAN +------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: prt1_adv.a, prt2_adv.b + -> Sort + Sort Key: prt1_adv.a, prt2_adv.b + -> Hash Full Join + Hash Cond: (prt2_adv.b = prt1_adv.a) + Filter: (((175) = prt1_adv.a) OR ((425) = prt2_adv.b)) + -> Append + -> Seq Scan on prt2_adv_p1 prt2_adv_1 + Filter: (a = 0) + -> Seq Scan on prt2_adv_p2 prt2_adv_2 + Filter: (a = 0) + -> Seq Scan on prt2_adv_p3_1 prt2_adv_3 + Filter: (a = 0) + -> Seq Scan on prt2_adv_p3_2 prt2_adv_4 + Filter: (a = 0) + -> Hash + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: 0 + -> Append + -> Seq Scan on prt1_adv_p1 prt1_adv_1 + Filter: (b = 0) + -> Seq Scan on prt1_adv_p2 prt1_adv_2 + Filter: (b = 0) + -> Seq Scan on prt1_adv_p3 prt1_adv_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(27 rows) + +DROP TABLE prt2_adv_p3_1; +DROP TABLE prt2_adv_p3_2; +ANALYZE prt2_adv; +-- Test default partitions +ALTER TABLE prt1_adv DETACH PARTITION prt1_adv_p1; +-- Change prt1_adv_p1 to the default partition +ALTER TABLE prt1_adv ATTACH PARTITION prt1_adv_p1 DEFAULT; +ALTER TABLE prt1_adv DETACH PARTITION prt1_adv_p3; +ANALYZE prt1_adv; +-- We can do partitioned join even if only one of relations has the default +-- partition +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +--------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Join + Hash Cond: (t2_1.b = t1_2.a) + -> Seq Scan on prt2_adv_p1 t2_1 + -> Hash + -> Broadcast Motion 3:3 (slice2; segments: 3) + -> Seq Scan on prt1_adv_p1 t1_2 + Filter: (b = 0) + -> Hash Join + Hash Cond: (t2_2.b = t1_1.a) + -> Seq Scan on prt2_adv_p2 t2_2 + -> Hash + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Seq Scan on prt1_adv_p2 t1_1 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(20 rows) + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + a | c | b | c +-----+------+-----+------ + 100 | 0100 | 100 | 0100 + 125 | 0125 | 125 | 0125 + 200 | 0200 | 200 | 0200 + 225 | 0225 | 225 | 0225 + 250 | 0250 | 250 | 0250 + 275 | 0275 | 275 | 0275 +(6 rows) + +-- Restore prt1_adv_p3 +ALTER TABLE prt1_adv ATTACH PARTITION prt1_adv_p3 FOR VALUES FROM (300) TO (400); +ANALYZE prt1_adv; +-- Restore prt2_adv_p3 +ALTER TABLE prt2_adv ATTACH PARTITION prt2_adv_p3 FOR VALUES FROM (350) TO (500); +ANALYZE prt2_adv; +-- Partitioned join can't be applied because the default partition of prt1_adv +-- matches prt2_adv_p1 and prt2_adv_p3 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +--------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Hash Join + Hash Cond: (t2.b = t1.a) + -> Append + Partition Selectors: $0 + -> Seq Scan on prt2_adv_p1 t2_1 + -> Seq Scan on prt2_adv_p2 t2_2 + -> Seq Scan on prt2_adv_p3 t2_3 + -> Hash + -> Partition Selector (selector id: $0) + -> Broadcast Motion 3:3 (slice2; segments: 3) + -> Append + -> Seq Scan on prt1_adv_p2 t1_1 + Filter: (b = 0) + -> Seq Scan on prt1_adv_p3 t1_2 + Filter: (b = 0) + -> Seq Scan on prt1_adv_p1 t1_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(22 rows) + +ALTER TABLE prt2_adv DETACH PARTITION prt2_adv_p3; +-- Change prt2_adv_p3 to the default partition +ALTER TABLE prt2_adv ATTACH PARTITION prt2_adv_p3 DEFAULT; +ANALYZE prt2_adv; +-- Partitioned join can't be applied because the default partition of prt1_adv +-- matches prt2_adv_p1 and prt2_adv_p3 +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +--------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Hash Join + Hash Cond: (t2.b = t1.a) + -> Append + Partition Selectors: $0 + -> Seq Scan on prt2_adv_p1 t2_1 + -> Seq Scan on prt2_adv_p2 t2_2 + -> Seq Scan on prt2_adv_p3 t2_3 + -> Hash + -> Partition Selector (selector id: $0) + -> Broadcast Motion 3:3 (slice2; segments: 3) + -> Append + -> Seq Scan on prt1_adv_p2 t1_1 + Filter: (b = 0) + -> Seq Scan on prt1_adv_p3 t1_2 + Filter: (b = 0) + -> Seq Scan on prt1_adv_p1 t1_3 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(22 rows) + +DROP TABLE prt1_adv_p3; +ANALYZE prt1_adv; +DROP TABLE prt2_adv_p3; +ANALYZE prt2_adv; +CREATE TABLE prt3_adv (a int, b int, c varchar) PARTITION BY RANGE (a); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE prt3_adv_p1 PARTITION OF prt3_adv FOR VALUES FROM (200) TO (300); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt3_adv_p2 PARTITION OF prt3_adv FOR VALUES FROM (300) TO (400); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE INDEX prt3_adv_a_idx ON prt3_adv (a); +INSERT INTO prt3_adv SELECT i, i % 25, to_char(i, 'FM0000') FROM generate_series(200, 399) i; +ANALYZE prt3_adv; +-- GPDB_13_MERGE_FIXME: The total cost of MergeJoin is much less than one of +-- its children, while the hash join must consider all total costs of its +-- children. The instinct is that merge join with 2 SORT operators for the +-- tables should be slower than hash join. Not sure how it happens. +-- We should review the plans after MERGE. +-- 3-way join to test the default partition of a join relation +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c, t3.a, t3.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) LEFT JOIN prt3_adv t3 ON (t1.a = t3.a) WHERE t1.b = 0 ORDER BY t1.a, t2.b, t3.a; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t2.b, t3.a + -> Sort + Sort Key: t1.a, t2.b, t3.a + -> Append + -> Hash Right Join + Hash Cond: (t2_2.b = t1_1.a) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t2_2.b + -> Seq Scan on prt2_adv_p2 t2_2 + -> Hash + -> Hash Right Join + Hash Cond: (t3_1.a = t1_1.a) + -> Seq Scan on prt3_adv_p1 t3_1 + -> Hash + -> Seq Scan on prt1_adv_p2 t1_1 + Filter: (b = 0) + -> Hash Right Join + Hash Cond: (t2_1.b = t1_2.a) + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t2_1.b + -> Seq Scan on prt2_adv_p1 t2_1 + -> Hash + -> Merge Right Join + Merge Cond: (t3_2.a = t1_2.a) + -> Index Scan using prt3_adv_p2_a_idx on prt3_adv_p2 t3_2 + -> Sort + Sort Key: t1_2.a + -> Seq Scan on prt1_adv_p1 t1_2 + Filter: (b = 0) + Optimizer: Postgres query optimizer +(31 rows) + +SELECT t1.a, t1.c, t2.b, t2.c, t3.a, t3.c FROM prt1_adv t1 LEFT JOIN prt2_adv t2 ON (t1.a = t2.b) LEFT JOIN prt3_adv t3 ON (t1.a = t3.a) WHERE t1.b = 0 ORDER BY t1.a, t2.b, t3.a; + a | c | b | c | a | c +-----+------+-----+------+-----+------ + 100 | 0100 | 100 | 0100 | | + 125 | 0125 | 125 | 0125 | | + 150 | 0150 | | | | + 175 | 0175 | | | | + 200 | 0200 | 200 | 0200 | 200 | 0200 + 225 | 0225 | 225 | 0225 | 225 | 0225 + 250 | 0250 | 250 | 0250 | 250 | 0250 + 275 | 0275 | 275 | 0275 | 275 | 0275 +(8 rows) + +DROP TABLE prt1_adv; +DROP TABLE prt2_adv; +DROP TABLE prt3_adv; +-- Test interaction of partitioned join with partition pruning +CREATE TABLE prt1_adv (a int, b int, c varchar) PARTITION BY RANGE (a); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE prt1_adv_p1 PARTITION OF prt1_adv FOR VALUES FROM (100) TO (200); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt1_adv_p2 PARTITION OF prt1_adv FOR VALUES FROM (200) TO (300); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt1_adv_p3 PARTITION OF prt1_adv FOR VALUES FROM (300) TO (400); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE INDEX prt1_adv_a_idx ON prt1_adv (a); +INSERT INTO prt1_adv SELECT i, i % 25, to_char(i, 'FM0000') FROM generate_series(100, 399) i; +ANALYZE prt1_adv; +CREATE TABLE prt2_adv (a int, b int, c varchar) PARTITION BY RANGE (b); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE prt2_adv_p1 PARTITION OF prt2_adv FOR VALUES FROM (100) TO (200); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE prt2_adv_p2 PARTITION OF prt2_adv FOR VALUES FROM (200) TO (400); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE INDEX prt2_adv_b_idx ON prt2_adv (b); +INSERT INTO prt2_adv SELECT i % 25, i, to_char(i, 'FM0000') FROM generate_series(100, 399) i; +ANALYZE prt2_adv; +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.a < 300 AND t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +--------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Join + Hash Cond: (t2_1.b = t1_1.a) + -> Seq Scan on prt2_adv_p1 t2_1 + Filter: (b < 300) + -> Hash + -> Broadcast Motion 3:3 (slice2; segments: 3) + -> Seq Scan on prt1_adv_p1 t1_1 + Filter: ((a < 300) AND (b = 0)) + -> Hash Join + Hash Cond: (t2_2.b = t1_2.a) + -> Seq Scan on prt2_adv_p2 t2_2 + Filter: (b < 300) + -> Hash + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Seq Scan on prt1_adv_p2 t1_2 + Filter: ((a < 300) AND (b = 0)) + Optimizer: Postgres query optimizer +(22 rows) + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.a < 300 AND t1.b = 0 ORDER BY t1.a, t2.b; + a | c | b | c +-----+------+-----+------ + 100 | 0100 | 100 | 0100 + 125 | 0125 | 125 | 0125 + 150 | 0150 | 150 | 0150 + 175 | 0175 | 175 | 0175 + 200 | 0200 | 200 | 0200 + 225 | 0225 | 225 | 0225 + 250 | 0250 | 250 | 0250 + 275 | 0275 | 275 | 0275 +(8 rows) + +DROP TABLE prt1_adv_p3; +CREATE TABLE prt1_adv_default PARTITION OF prt1_adv DEFAULT; +NOTICE: table has parent, setting distribution columns to match parent table +ANALYZE prt1_adv; +CREATE TABLE prt2_adv_default PARTITION OF prt2_adv DEFAULT; +NOTICE: table has parent, setting distribution columns to match parent table +ANALYZE prt2_adv; +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.a >= 100 AND t1.a < 300 AND t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +-------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Join + Hash Cond: (t2_1.b = t1_1.a) + -> Seq Scan on prt2_adv_p1 t2_1 + Filter: ((b >= 100) AND (b < 300)) + -> Hash + -> Broadcast Motion 3:3 (slice2; segments: 3) + -> Seq Scan on prt1_adv_p1 t1_1 + Filter: ((a >= 100) AND (a < 300) AND (b = 0)) + -> Hash Join + Hash Cond: (t2_2.b = t1_2.a) + -> Seq Scan on prt2_adv_p2 t2_2 + Filter: ((b >= 100) AND (b < 300)) + -> Hash + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Seq Scan on prt1_adv_p2 t1_2 + Filter: ((a >= 100) AND (a < 300) AND (b = 0)) + Optimizer: Postgres query optimizer +(22 rows) + +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = t2.b) WHERE t1.a >= 100 AND t1.a < 300 AND t1.b = 0 ORDER BY t1.a, t2.b; + a | c | b | c +-----+------+-----+------ + 100 | 0100 | 100 | 0100 + 125 | 0125 | 125 | 0125 + 150 | 0150 | 150 | 0150 + 175 | 0175 | 175 | 0175 + 200 | 0200 | 200 | 0200 + 225 | 0225 | 225 | 0225 + 250 | 0250 | 250 | 0250 + 275 | 0275 | 275 | 0275 +(8 rows) + +DROP TABLE prt1_adv; +DROP TABLE prt2_adv; +-- Tests for list-partitioned tables +CREATE TABLE plt1_adv (a int, b int, c text) PARTITION BY LIST (c); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE plt1_adv_p1 PARTITION OF plt1_adv FOR VALUES IN ('0001', '0003'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt1_adv_p2 PARTITION OF plt1_adv FOR VALUES IN ('0004', '0006'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt1_adv_p3 PARTITION OF plt1_adv FOR VALUES IN ('0008', '0009'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO plt1_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (1, 3, 4, 6, 8, 9); +ANALYZE plt1_adv; +CREATE TABLE plt2_adv (a int, b int, c text) PARTITION BY LIST (c); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE plt2_adv_p1 PARTITION OF plt2_adv FOR VALUES IN ('0002', '0003'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt2_adv_p2 PARTITION OF plt2_adv FOR VALUES IN ('0004', '0006'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt2_adv_p3 PARTITION OF plt2_adv FOR VALUES IN ('0007', '0009'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9); +ANALYZE plt2_adv; +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Hash Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3 t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(24 rows) + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + a | c | a | c +---+------+---+------ + 3 | 0003 | 3 | 0003 + 4 | 0004 | 4 | 0004 + 6 | 0006 | 6 | 0006 + 9 | 0009 | 9 | 0009 +(4 rows) + +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Right Semi Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3 t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(24 rows) + +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + a | b | c +---+---+------ + 3 | 3 | 0003 + 4 | 4 | 0004 + 6 | 6 | 0006 + 9 | 9 | 0009 +(4 rows) + +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Right Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Hash Right Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Right Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3 t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(24 rows) + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + a | c | a | c +---+------+---+------ + 1 | 0001 | | + 3 | 0003 | 3 | 0003 + 4 | 0004 | 4 | 0004 + 6 | 0006 | 6 | 0006 + 8 | 0008 | | + 9 | 0009 | 9 | 0009 +(6 rows) + +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Right Anti Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Hash Right Anti Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Right Anti Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3 t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(24 rows) + +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + a | b | c +---+---+------ + 1 | 1 | 0001 + 8 | 8 | 0008 +(2 rows) + +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a; + QUERY PLAN +----------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t2.a + -> Sort + Sort Key: t1.a, t2.a + -> Append + -> Hash Full Join + Hash Cond: ((t1_1.a = t2_1.a) AND (t1_1.c = t2_1.c)) + Filter: ((COALESCE(t1_1.b, 0) < 10) AND (COALESCE(t2_1.b, 0) < 10)) + -> Seq Scan on plt1_adv_p1 t1_1 + -> Hash + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash Full Join + Hash Cond: ((t1_2.a = t2_2.a) AND (t1_2.c = t2_2.c)) + Filter: ((COALESCE(t1_2.b, 0) < 10) AND (COALESCE(t2_2.b, 0) < 10)) + -> Seq Scan on plt1_adv_p2 t1_2 + -> Hash + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash Full Join + Hash Cond: ((t1_3.a = t2_3.a) AND (t1_3.c = t2_3.c)) + Filter: ((COALESCE(t1_3.b, 0) < 10) AND (COALESCE(t2_3.b, 0) < 10)) + -> Seq Scan on plt1_adv_p3 t1_3 + -> Hash + -> Seq Scan on plt2_adv_p3 t2_3 + Optimizer: Postgres query optimizer +(24 rows) + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a; + a | c | a | c +---+------+---+------ + 1 | 0001 | | + 3 | 0003 | 3 | 0003 + 4 | 0004 | 4 | 0004 + 6 | 0006 | 6 | 0006 + 8 | 0008 | | + 9 | 0009 | 9 | 0009 + | | 2 | 0002 + | | 7 | 0007 +(8 rows) + +-- Test cases where one side has an extra partition +CREATE TABLE plt2_adv_extra PARTITION OF plt2_adv FOR VALUES IN ('0000'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO plt2_adv_extra VALUES (0, 0, '0000'); +ANALYZE plt2_adv; +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Hash Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3 t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(24 rows) + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + a | c | a | c +---+------+---+------ + 3 | 0003 | 3 | 0003 + 4 | 0004 | 4 | 0004 + 6 | 0006 | 6 | 0006 + 9 | 0009 | 9 | 0009 +(4 rows) + +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Right Semi Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3 t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(24 rows) + +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + a | b | c +---+---+------ + 3 | 3 | 0003 + 4 | 4 | 0004 + 6 | 6 | 0006 + 9 | 9 | 0009 +(4 rows) + +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Right Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Hash Right Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Right Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3 t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(24 rows) + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + a | c | a | c +---+------+---+------ + 1 | 0001 | | + 3 | 0003 | 3 | 0003 + 4 | 0004 | 4 | 0004 + 6 | 0006 | 6 | 0006 + 8 | 0008 | | + 9 | 0009 | 9 | 0009 +(6 rows) + +-- left join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt2_adv t1 LEFT JOIN plt1_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + QUERY PLAN +--------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Hash Right Join + Hash Cond: ((t2.a = t1.a) AND (t2.c = t1.c)) + -> Append + Partition Selectors: $0 + -> Seq Scan on plt1_adv_p1 t2_1 + -> Seq Scan on plt1_adv_p2 t2_2 + -> Seq Scan on plt1_adv_p3 t2_3 + -> Hash + -> Partition Selector (selector id: $0) + -> Append + -> Seq Scan on plt2_adv_extra t1_1 + Filter: (b < 10) + -> Seq Scan on plt2_adv_p1 t1_2 + Filter: (b < 10) + -> Seq Scan on plt2_adv_p2 t1_3 + Filter: (b < 10) + -> Seq Scan on plt2_adv_p3 t1_4 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(23 rows) + +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Right Anti Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Hash Right Anti Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Right Anti Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3 t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(24 rows) + +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + a | b | c +---+---+------ + 1 | 1 | 0001 + 8 | 8 | 0008 +(2 rows) + +-- anti join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt2_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt1_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + QUERY PLAN +--------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Hash Right Anti Join + Hash Cond: ((t2.a = t1.a) AND (t2.c = t1.c)) + -> Append + -> Seq Scan on plt1_adv_p1 t2_1 + -> Seq Scan on plt1_adv_p2 t2_2 + -> Seq Scan on plt1_adv_p3 t2_3 + -> Hash + -> Append + -> Seq Scan on plt2_adv_extra t1_1 + Filter: (b < 10) + -> Seq Scan on plt2_adv_p1 t1_2 + Filter: (b < 10) + -> Seq Scan on plt2_adv_p2 t1_3 + Filter: (b < 10) + -> Seq Scan on plt2_adv_p3 t1_4 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(21 rows) + +-- full join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a; + QUERY PLAN +------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t2.a + -> Sort + Sort Key: t1.a, t2.a + -> Hash Full Join + Hash Cond: ((t2.a = t1.a) AND (t2.c = t1.c)) + Filter: ((COALESCE(t1.b, 0) < 10) AND (COALESCE(t2.b, 0) < 10)) + -> Append + -> Seq Scan on plt2_adv_extra t2_1 + -> Seq Scan on plt2_adv_p1 t2_2 + -> Seq Scan on plt2_adv_p2 t2_3 + -> Seq Scan on plt2_adv_p3 t2_4 + -> Hash + -> Append + -> Seq Scan on plt1_adv_p1 t1_1 + -> Seq Scan on plt1_adv_p2 t1_2 + -> Seq Scan on plt1_adv_p3 t1_3 + Optimizer: Postgres query optimizer +(18 rows) + +DROP TABLE plt2_adv_extra; +-- Test cases where a partition on one side matches multiple partitions on +-- the other side; we currently can't do partitioned join in such cases +ALTER TABLE plt2_adv DETACH PARTITION plt2_adv_p2; +-- Split plt2_adv_p2 into two partitions so that plt1_adv_p2 matches both +CREATE TABLE plt2_adv_p2_1 PARTITION OF plt2_adv FOR VALUES IN ('0004'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt2_adv_p2_2 PARTITION OF plt2_adv FOR VALUES IN ('0006'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (4, 6); +ANALYZE plt2_adv; +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + QUERY PLAN +------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Hash Join + Hash Cond: ((t2.a = t1.a) AND (t2.c = t1.c)) + -> Append + Partition Selectors: $0 + -> Seq Scan on plt2_adv_p1 t2_1 + -> Seq Scan on plt2_adv_p2_1 t2_2 + -> Seq Scan on plt2_adv_p2_2 t2_3 + -> Seq Scan on plt2_adv_p3 t2_4 + -> Hash + -> Partition Selector (selector id: $0) + -> Append + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(22 rows) + +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + QUERY PLAN +------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Hash Right Semi Join + Hash Cond: ((t2.a = t1.a) AND (t2.c = t1.c)) + -> Append + -> Seq Scan on plt2_adv_p1 t2_1 + -> Seq Scan on plt2_adv_p2_1 t2_2 + -> Seq Scan on plt2_adv_p2_2 t2_3 + -> Seq Scan on plt2_adv_p3 t2_4 + -> Hash + -> Append + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(20 rows) + +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + QUERY PLAN +------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Hash Right Join + Hash Cond: ((t2.a = t1.a) AND (t2.c = t1.c)) + -> Append + Partition Selectors: $0 + -> Seq Scan on plt2_adv_p1 t2_1 + -> Seq Scan on plt2_adv_p2_1 t2_2 + -> Seq Scan on plt2_adv_p2_2 t2_3 + -> Seq Scan on plt2_adv_p3 t2_4 + -> Hash + -> Partition Selector (selector id: $0) + -> Append + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(22 rows) + +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + QUERY PLAN +------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Hash Right Anti Join + Hash Cond: ((t2.a = t1.a) AND (t2.c = t1.c)) + -> Append + -> Seq Scan on plt2_adv_p1 t2_1 + -> Seq Scan on plt2_adv_p2_1 t2_2 + -> Seq Scan on plt2_adv_p2_2 t2_3 + -> Seq Scan on plt2_adv_p3 t2_4 + -> Hash + -> Append + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(20 rows) + +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a; + QUERY PLAN +------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t2.a + -> Sort + Sort Key: t1.a, t2.a + -> Hash Full Join + Hash Cond: ((t2.a = t1.a) AND (t2.c = t1.c)) + Filter: ((COALESCE(t1.b, 0) < 10) AND (COALESCE(t2.b, 0) < 10)) + -> Append + -> Seq Scan on plt2_adv_p1 t2_1 + -> Seq Scan on plt2_adv_p2_1 t2_2 + -> Seq Scan on plt2_adv_p2_2 t2_3 + -> Seq Scan on plt2_adv_p3 t2_4 + -> Hash + -> Append + -> Seq Scan on plt1_adv_p1 t1_1 + -> Seq Scan on plt1_adv_p2 t1_2 + -> Seq Scan on plt1_adv_p3 t1_3 + Optimizer: Postgres query optimizer +(18 rows) + +DROP TABLE plt2_adv_p2_1; +DROP TABLE plt2_adv_p2_2; +-- Restore plt2_adv_p2 +ALTER TABLE plt2_adv ATTACH PARTITION plt2_adv_p2 FOR VALUES IN ('0004', '0006'); +-- Test NULL partitions +ALTER TABLE plt1_adv DETACH PARTITION plt1_adv_p1; +-- Change plt1_adv_p1 to the NULL partition +CREATE TABLE plt1_adv_p1_null PARTITION OF plt1_adv FOR VALUES IN (NULL, '0001', '0003'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO plt1_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (1, 3); +INSERT INTO plt1_adv VALUES (-1, -1, NULL); +ANALYZE plt1_adv; +ALTER TABLE plt2_adv DETACH PARTITION plt2_adv_p3; +-- Change plt2_adv_p3 to the NULL partition +CREATE TABLE plt2_adv_p3_null PARTITION OF plt2_adv FOR VALUES IN (NULL, '0007', '0009'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (7, 9); +INSERT INTO plt2_adv VALUES (-1, -1, NULL); +ANALYZE plt2_adv; +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1_null t1_1 + Filter: (b < 10) + -> Hash Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3_null t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(24 rows) + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + a | c | a | c +---+------+---+------ + 3 | 0003 | 3 | 0003 + 4 | 0004 | 4 | 0004 + 6 | 0006 | 6 | 0006 + 9 | 0009 | 9 | 0009 +(4 rows) + +-- semi join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Right Semi Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1_null t1_1 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3_null t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(24 rows) + +SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + a | b | c +---+---+------ + 3 | 3 | 0003 + 4 | 4 | 0004 + 6 | 6 | 0006 + 9 | 9 | 0009 +(4 rows) + +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Right Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1_null t1_1 + Filter: (b < 10) + -> Hash Right Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Right Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3_null t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(24 rows) + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + a | c | a | c +----+------+---+------ + -1 | | | + 1 | 0001 | | + 3 | 0003 | 3 | 0003 + 4 | 0004 | 4 | 0004 + 6 | 0006 | 6 | 0006 + 8 | 0008 | | + 9 | 0009 | 9 | 0009 +(7 rows) + +-- anti join +EXPLAIN (COSTS OFF) +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Right Anti Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1_null t1_1 + Filter: (b < 10) + -> Hash Right Anti Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Right Anti Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3_null t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(24 rows) + +SELECT t1.* FROM plt1_adv t1 WHERE NOT EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; + a | b | c +----+----+------ + -1 | -1 | + 1 | 1 | 0001 + 8 | 8 | 0008 +(3 rows) + +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a; + QUERY PLAN +----------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t2.a + -> Sort + Sort Key: t1.a, t2.a + -> Append + -> Hash Full Join + Hash Cond: ((t1_1.a = t2_1.a) AND (t1_1.c = t2_1.c)) + Filter: ((COALESCE(t1_1.b, 0) < 10) AND (COALESCE(t2_1.b, 0) < 10)) + -> Seq Scan on plt1_adv_p1_null t1_1 + -> Hash + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash Full Join + Hash Cond: ((t1_2.a = t2_2.a) AND (t1_2.c = t2_2.c)) + Filter: ((COALESCE(t1_2.b, 0) < 10) AND (COALESCE(t2_2.b, 0) < 10)) + -> Seq Scan on plt1_adv_p2 t1_2 + -> Hash + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash Full Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + Filter: ((COALESCE(t1_3.b, 0) < 10) AND (COALESCE(t2_3.b, 0) < 10)) + -> Seq Scan on plt2_adv_p3_null t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Optimizer: Postgres query optimizer +(24 rows) + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a; + a | c | a | c +----+------+----+------ + -1 | | | + 1 | 0001 | | + 3 | 0003 | 3 | 0003 + 4 | 0004 | 4 | 0004 + 6 | 0006 | 6 | 0006 + 8 | 0008 | | + 9 | 0009 | 9 | 0009 + | | -1 | + | | 2 | 0002 + | | 7 | 0007 +(10 rows) + +DROP TABLE plt1_adv_p1_null; +-- Restore plt1_adv_p1 +ALTER TABLE plt1_adv ATTACH PARTITION plt1_adv_p1 FOR VALUES IN ('0001', '0003'); +-- Add to plt1_adv the extra NULL partition containing only NULL values as the +-- key values +CREATE TABLE plt1_adv_extra PARTITION OF plt1_adv FOR VALUES IN (NULL); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO plt1_adv VALUES (-1, -1, NULL); +ANALYZE plt1_adv; +DROP TABLE plt2_adv_p3_null; +-- Restore plt2_adv_p3 +ALTER TABLE plt2_adv ATTACH PARTITION plt2_adv_p3 FOR VALUES IN ('0007', '0009'); +ANALYZE plt2_adv; +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Hash Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3 t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(24 rows) + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + a | c | a | c +---+------+---+------ + 3 | 0003 | 3 | 0003 + 4 | 0004 | 4 | 0004 + 6 | 0006 | 6 | 0006 + 9 | 0009 | 9 | 0009 +(4 rows) + +-- left join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + QUERY PLAN +--------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Hash Right Join + Hash Cond: ((t2.a = t1.a) AND (t2.c = t1.c)) + -> Append + Partition Selectors: $0 + -> Seq Scan on plt2_adv_p1 t2_1 + -> Seq Scan on plt2_adv_p2 t2_2 + -> Seq Scan on plt2_adv_p3 t2_3 + -> Hash + -> Partition Selector (selector id: $0) + -> Append + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + -> Seq Scan on plt1_adv_extra t1_4 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(23 rows) + +-- full join; currently we can't do partitioned join if there are no matched +-- partitions on the nullable side +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a; + QUERY PLAN +------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t2.a + -> Sort + Sort Key: t1.a, t2.a + -> Hash Full Join + Hash Cond: ((t1.a = t2.a) AND (t1.c = t2.c)) + Filter: ((COALESCE(t1.b, 0) < 10) AND (COALESCE(t2.b, 0) < 10)) + -> Append + -> Seq Scan on plt1_adv_p1 t1_1 + -> Seq Scan on plt1_adv_p2 t1_2 + -> Seq Scan on plt1_adv_p3 t1_3 + -> Seq Scan on plt1_adv_extra t1_4 + -> Hash + -> Append + -> Seq Scan on plt2_adv_p1 t2_1 + -> Seq Scan on plt2_adv_p2 t2_2 + -> Seq Scan on plt2_adv_p3 t2_3 + Optimizer: Postgres query optimizer +(18 rows) + +-- Add to plt2_adv the extra NULL partition containing only NULL values as the +-- key values +CREATE TABLE plt2_adv_extra PARTITION OF plt2_adv FOR VALUES IN (NULL); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO plt2_adv VALUES (-1, -1, NULL); +ANALYZE plt2_adv; +-- inner join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Hash Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3 t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(24 rows) + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + a | c | a | c +---+------+---+------ + 3 | 0003 | 3 | 0003 + 4 | 0004 | 4 | 0004 + 6 | 0006 | 6 | 0006 + 9 | 0009 | 9 | 0009 +(4 rows) + +-- left join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Right Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Hash Right Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Right Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3 t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + -> Hash Left Join + Hash Cond: ((t1_4.a = t2_4.a) AND (t1_4.c = t2_4.c)) + -> Seq Scan on plt1_adv_extra t1_4 + Filter: (b < 10) + -> Hash + -> Seq Scan on plt2_adv_extra t2_4 + Optimizer: Postgres query optimizer +(30 rows) + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + a | c | a | c +----+------+---+------ + -1 | | | + 1 | 0001 | | + 3 | 0003 | 3 | 0003 + 4 | 0004 | 4 | 0004 + 6 | 0006 | 6 | 0006 + 8 | 0008 | | + 9 | 0009 | 9 | 0009 +(7 rows) + +-- full join +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a; + QUERY PLAN +----------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t2.a + -> Sort + Sort Key: t1.a, t2.a + -> Append + -> Hash Full Join + Hash Cond: ((t1_1.a = t2_1.a) AND (t1_1.c = t2_1.c)) + Filter: ((COALESCE(t1_1.b, 0) < 10) AND (COALESCE(t2_1.b, 0) < 10)) + -> Seq Scan on plt1_adv_p1 t1_1 + -> Hash + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash Full Join + Hash Cond: ((t1_2.a = t2_2.a) AND (t1_2.c = t2_2.c)) + Filter: ((COALESCE(t1_2.b, 0) < 10) AND (COALESCE(t2_2.b, 0) < 10)) + -> Seq Scan on plt1_adv_p2 t1_2 + -> Hash + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash Full Join + Hash Cond: ((t1_3.a = t2_3.a) AND (t1_3.c = t2_3.c)) + Filter: ((COALESCE(t1_3.b, 0) < 10) AND (COALESCE(t2_3.b, 0) < 10)) + -> Seq Scan on plt1_adv_p3 t1_3 + -> Hash + -> Seq Scan on plt2_adv_p3 t2_3 + -> Hash Full Join + Hash Cond: ((t1_4.a = t2_4.a) AND (t1_4.c = t2_4.c)) + Filter: ((COALESCE(t1_4.b, 0) < 10) AND (COALESCE(t2_4.b, 0) < 10)) + -> Seq Scan on plt1_adv_extra t1_4 + -> Hash + -> Seq Scan on plt2_adv_extra t2_4 + Optimizer: Postgres query optimizer +(30 rows) + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 FULL JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE coalesce(t1.b, 0) < 10 AND coalesce(t2.b, 0) < 10 ORDER BY t1.a, t2.a; + a | c | a | c +----+------+----+------ + -1 | | | + 1 | 0001 | | + 3 | 0003 | 3 | 0003 + 4 | 0004 | 4 | 0004 + 6 | 0006 | 6 | 0006 + 8 | 0008 | | + 9 | 0009 | 9 | 0009 + | | -1 | + | | 2 | 0002 + | | 7 | 0007 +(10 rows) + +-- 3-way join to test the NULL partition of a join relation +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) LEFT JOIN plt1_adv t3 ON (t1.a = t3.a AND t1.c = t3.c) WHERE t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Right Join + Hash Cond: ((t3_1.a = t1_1.a) AND (t3_1.c = t1_1.c)) + -> Seq Scan on plt1_adv_p1 t3_1 + -> Hash + -> Hash Right Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Hash Right Join + Hash Cond: ((t3_2.a = t1_2.a) AND (t3_2.c = t1_2.c)) + -> Seq Scan on plt1_adv_p2 t3_2 + -> Hash + -> Hash Right Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Right Join + Hash Cond: ((t3_3.a = t1_3.a) AND (t3_3.c = t1_3.c)) + -> Seq Scan on plt1_adv_p3 t3_3 + -> Hash + -> Hash Right Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3 t2_3 + -> Hash + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) + -> Hash Left Join + Hash Cond: ((t1_4.a = t3_4.a) AND (t1_4.c = t3_4.c)) + -> Hash Left Join + Hash Cond: ((t1_4.a = t2_4.a) AND (t1_4.c = t2_4.c)) + -> Seq Scan on plt1_adv_extra t1_4 + Filter: (b < 10) + -> Hash + -> Seq Scan on plt2_adv_extra t2_4 + -> Hash + -> Seq Scan on plt1_adv_extra t3_4 + Optimizer: Postgres query optimizer +(46 rows) + +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) LEFT JOIN plt1_adv t3 ON (t1.a = t3.a AND t1.c = t3.c) WHERE t1.b < 10 ORDER BY t1.a; + a | c | a | c | a | c +----+------+---+------+---+------ + -1 | | | | | + 1 | 0001 | | | 1 | 0001 + 3 | 0003 | 3 | 0003 | 3 | 0003 + 4 | 0004 | 4 | 0004 | 4 | 0004 + 6 | 0006 | 6 | 0006 | 6 | 0006 + 8 | 0008 | | | 8 | 0008 + 9 | 0009 | 9 | 0009 | 9 | 0009 +(7 rows) + +DROP TABLE plt1_adv_extra; +DROP TABLE plt2_adv_extra; +-- Test default partitions +ALTER TABLE plt1_adv DETACH PARTITION plt1_adv_p1; +-- Change plt1_adv_p1 to the default partition +ALTER TABLE plt1_adv ATTACH PARTITION plt1_adv_p1 DEFAULT; +DROP TABLE plt1_adv_p3; +ANALYZE plt1_adv; +DROP TABLE plt2_adv_p3; +ANALYZE plt2_adv; +-- We can do partitioned join even if only one of relations has the default +-- partition +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Join + Hash Cond: ((t2_1.a = t1_2.a) AND (t2_1.c = t1_2.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1 t1_2 + Filter: (b < 10) + -> Hash Join + Hash Cond: ((t2_2.a = t1_1.a) AND (t2_2.c = t1_1.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_1 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(18 rows) + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + a | c | a | c +---+------+---+------ + 3 | 0003 | 3 | 0003 + 4 | 0004 | 4 | 0004 + 6 | 0006 | 6 | 0006 +(3 rows) + +ALTER TABLE plt2_adv DETACH PARTITION plt2_adv_p2; +-- Change plt2_adv_p2 to contain '0005' in addition to '0004' and '0006' as +-- the key values +CREATE TABLE plt2_adv_p2_ext PARTITION OF plt2_adv FOR VALUES IN ('0004', '0005', '0006'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (4, 5, 6); +ANALYZE plt2_adv; +-- Partitioned join can't be applied because the default partition of plt1_adv +-- matches plt2_adv_p1 and plt2_adv_p2_ext +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + QUERY PLAN +------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Hash Join + Hash Cond: ((t2.a = t1.a) AND (t2.c = t1.c)) + -> Append + Partition Selectors: $0 + -> Seq Scan on plt2_adv_p1 t2_1 + -> Seq Scan on plt2_adv_p2_ext t2_2 + -> Hash + -> Partition Selector (selector id: $0) + -> Append + -> Seq Scan on plt1_adv_p2 t1_1 + Filter: (b < 10) + -> Seq Scan on plt1_adv_p1 t1_2 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(18 rows) + +ALTER TABLE plt2_adv DETACH PARTITION plt2_adv_p2_ext; +-- Change plt2_adv_p2_ext to the default partition +ALTER TABLE plt2_adv ATTACH PARTITION plt2_adv_p2_ext DEFAULT; +ANALYZE plt2_adv; +-- Partitioned join can't be applied because the default partition of plt1_adv +-- matches plt2_adv_p1 and plt2_adv_p2_ext +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + QUERY PLAN +------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Hash Join + Hash Cond: ((t2.a = t1.a) AND (t2.c = t1.c)) + -> Append + Partition Selectors: $0 + -> Seq Scan on plt2_adv_p1 t2_1 + -> Seq Scan on plt2_adv_p2_ext t2_2 + -> Hash + -> Partition Selector (selector id: $0) + -> Append + -> Seq Scan on plt1_adv_p2 t1_1 + Filter: (b < 10) + -> Seq Scan on plt1_adv_p1 t1_2 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(18 rows) + +DROP TABLE plt2_adv_p2_ext; +-- Restore plt2_adv_p2 +ALTER TABLE plt2_adv ATTACH PARTITION plt2_adv_p2 FOR VALUES IN ('0004', '0006'); +ANALYZE plt2_adv; +CREATE TABLE plt3_adv (a int, b int, c text) PARTITION BY LIST (c); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE plt3_adv_p1 PARTITION OF plt3_adv FOR VALUES IN ('0004', '0006'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt3_adv_p2 PARTITION OF plt3_adv FOR VALUES IN ('0007', '0009'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO plt3_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (4, 6, 7, 9); +ANALYZE plt3_adv; +-- 3-way join to test the default partition of a join relation +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) LEFT JOIN plt3_adv t3 ON (t1.a = t3.a AND t1.c = t3.c) WHERE t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Right Join + Hash Cond: ((t3_1.a = t1_1.a) AND (t3_1.c = t1_1.c)) + -> Seq Scan on plt3_adv_p1 t3_1 + -> Hash + -> Hash Right Join + Hash Cond: ((t2_2.a = t1_1.a) AND (t2_2.c = t1_1.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_1 + Filter: (b < 10) + -> Hash Right Join + Hash Cond: ((t3_2.a = t1_2.a) AND (t3_2.c = t1_2.c)) + -> Seq Scan on plt3_adv_p2 t3_2 + -> Hash + -> Hash Right Join + Hash Cond: ((t2_1.a = t1_2.a) AND (t2_1.c = t1_2.c)) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1 t1_2 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(26 rows) + +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) LEFT JOIN plt3_adv t3 ON (t1.a = t3.a AND t1.c = t3.c) WHERE t1.b < 10 ORDER BY t1.a; + a | c | a | c | a | c +---+------+---+------+---+------ + 1 | 0001 | | | | + 3 | 0003 | 3 | 0003 | | + 4 | 0004 | 4 | 0004 | 4 | 0004 + 6 | 0006 | 6 | 0006 | 6 | 0006 +(4 rows) + +-- Test cases where one side has the default partition while the other side +-- has the NULL partition +DROP TABLE plt2_adv_p1; +-- Add the NULL partition to plt2_adv +CREATE TABLE plt2_adv_p1_null PARTITION OF plt2_adv FOR VALUES IN (NULL, '0001', '0003'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (1, 3); +INSERT INTO plt2_adv VALUES (-1, -1, NULL); +ANALYZE plt2_adv; +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Join + Hash Cond: ((t2_1.a = t1_2.a) AND (t2_1.c = t1_2.c)) + -> Seq Scan on plt2_adv_p1_null t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1 t1_2 + Filter: (b < 10) + -> Hash Join + Hash Cond: ((t2_2.a = t1_1.a) AND (t2_2.c = t1_1.c)) + -> Seq Scan on plt2_adv_p2 t2_2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1_1 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(18 rows) + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + a | c | a | c +---+------+---+------ + 1 | 0001 | 1 | 0001 + 3 | 0003 | 3 | 0003 + 4 | 0004 | 4 | 0004 + 6 | 0006 | 6 | 0006 +(4 rows) + +DROP TABLE plt2_adv_p1_null; +-- Add the NULL partition that contains only NULL values as the key values +CREATE TABLE plt2_adv_p1_null PARTITION OF plt2_adv FOR VALUES IN (NULL); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO plt2_adv VALUES (-1, -1, NULL); +ANALYZE plt2_adv; +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + QUERY PLAN +------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Hash Join + Hash Cond: ((t2.a = t1.a) AND (t2.c = t1.c)) + -> Seq Scan on plt2_adv_p2 t2 + -> Hash + -> Seq Scan on plt1_adv_p2 t1 + Filter: (b < 10) + Optimizer: Postgres query optimizer +(11 rows) + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.b < 10 ORDER BY t1.a; + a | c | a | c +---+------+---+------ + 4 | 0004 | 4 | 0004 + 6 | 0006 | 6 | 0006 +(2 rows) + +DROP TABLE plt1_adv; +DROP TABLE plt2_adv; +DROP TABLE plt3_adv; +-- Test interaction of partitioned join with partition pruning +CREATE TABLE plt1_adv (a int, b int, c text) PARTITION BY LIST (c); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE plt1_adv_p1 PARTITION OF plt1_adv FOR VALUES IN ('0001'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt1_adv_p2 PARTITION OF plt1_adv FOR VALUES IN ('0002'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt1_adv_p3 PARTITION OF plt1_adv FOR VALUES IN ('0003'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt1_adv_p4 PARTITION OF plt1_adv FOR VALUES IN (NULL, '0004', '0005'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO plt1_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (1, 2, 3, 4, 5); +INSERT INTO plt1_adv VALUES (-1, -1, NULL); +ANALYZE plt1_adv; +CREATE TABLE plt2_adv (a int, b int, c text) PARTITION BY LIST (c); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE plt2_adv_p1 PARTITION OF plt2_adv FOR VALUES IN ('0001', '0002'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt2_adv_p2 PARTITION OF plt2_adv FOR VALUES IN (NULL); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt2_adv_p3 PARTITION OF plt2_adv FOR VALUES IN ('0003'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt2_adv_p4 PARTITION OF plt2_adv FOR VALUES IN ('0004', '0005'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO plt2_adv SELECT i, i, to_char(i % 10, 'FM0000') FROM generate_series(1, 299) i WHERE i % 10 IN (1, 2, 3, 4, 5); +INSERT INTO plt2_adv VALUES (-1, -1, NULL); +ANALYZE plt2_adv; +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IN ('0003', '0004', '0005') AND t1.b < 10 ORDER BY t1.a; + QUERY PLAN +----------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p3 t2_1 + Filter: (c = ANY ('{0003,0004,0005}'::text[])) + -> Hash + -> Seq Scan on plt1_adv_p3 t1_1 + Filter: ((b < 10) AND (c = ANY ('{0003,0004,0005}'::text[]))) + -> Hash Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p4 t2_2 + Filter: (c = ANY ('{0003,0004,0005}'::text[])) + -> Hash + -> Seq Scan on plt1_adv_p4 t1_2 + Filter: ((b < 10) AND (c = ANY ('{0003,0004,0005}'::text[]))) + Optimizer: Postgres query optimizer +(20 rows) + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IN ('0003', '0004', '0005') AND t1.b < 10 ORDER BY t1.a; + a | c | a | c +---+------+---+------ + 3 | 0003 | 3 | 0003 + 4 | 0004 | 4 | 0004 + 5 | 0005 | 5 | 0005 +(3 rows) + +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IS NULL AND t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Hash Right Join + Hash Cond: ((t2.a = t1.a) AND (t2.c = t1.c)) + -> Seq Scan on plt2_adv_p4 t2 + -> Hash + -> Seq Scan on plt1_adv_p4 t1 + Filter: ((c IS NULL) AND (b < 10)) + Optimizer: Postgres query optimizer +(11 rows) + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IS NULL AND t1.b < 10 ORDER BY t1.a; + a | c | a | c +----+---+---+--- + -1 | | | +(1 row) + +CREATE TABLE plt1_adv_default PARTITION OF plt1_adv DEFAULT; +NOTICE: table has parent, setting distribution columns to match parent table +ANALYZE plt1_adv; +CREATE TABLE plt2_adv_default PARTITION OF plt2_adv DEFAULT; +NOTICE: table has parent, setting distribution columns to match parent table +ANALYZE plt2_adv; +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IN ('0003', '0004', '0005') AND t1.b < 10 ORDER BY t1.a; + QUERY PLAN +----------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Append + -> Hash Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p3 t2_1 + Filter: (c = ANY ('{0003,0004,0005}'::text[])) + -> Hash + -> Seq Scan on plt1_adv_p3 t1_1 + Filter: ((b < 10) AND (c = ANY ('{0003,0004,0005}'::text[]))) + -> Hash Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p4 t2_2 + Filter: (c = ANY ('{0003,0004,0005}'::text[])) + -> Hash + -> Seq Scan on plt1_adv_p4 t1_2 + Filter: ((b < 10) AND (c = ANY ('{0003,0004,0005}'::text[]))) + Optimizer: Postgres query optimizer +(20 rows) + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IN ('0003', '0004', '0005') AND t1.b < 10 ORDER BY t1.a; + a | c | a | c +---+------+---+------ + 3 | 0003 | 3 | 0003 + 4 | 0004 | 4 | 0004 + 5 | 0005 | 5 | 0005 +(3 rows) + +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IS NULL AND t1.b < 10 ORDER BY t1.a; + QUERY PLAN +-------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a + -> Sort + Sort Key: t1.a + -> Hash Right Join + Hash Cond: ((t2.a = t1.a) AND (t2.c = t1.c)) + -> Seq Scan on plt2_adv_p4 t2 + -> Hash + -> Seq Scan on plt1_adv_p4 t1 + Filter: ((c IS NULL) AND (b < 10)) + Optimizer: Postgres query optimizer +(11 rows) + +SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE t1.c IS NULL AND t1.b < 10 ORDER BY t1.a; + a | c | a | c +----+---+---+--- + -1 | | | +(1 row) + +DROP TABLE plt1_adv; +DROP TABLE plt2_adv; +-- Test the process_outer_partition() code path +CREATE TABLE plt1_adv (a int, b int, c text) PARTITION BY LIST (c); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE plt1_adv_p1 PARTITION OF plt1_adv FOR VALUES IN ('0000', '0001', '0002'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt1_adv_p2 PARTITION OF plt1_adv FOR VALUES IN ('0003', '0004'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO plt1_adv SELECT i, i, to_char(i % 5, 'FM0000') FROM generate_series(0, 24) i; +ANALYZE plt1_adv; +CREATE TABLE plt2_adv (a int, b int, c text) PARTITION BY LIST (c); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE plt2_adv_p1 PARTITION OF plt2_adv FOR VALUES IN ('0002'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt2_adv_p2 PARTITION OF plt2_adv FOR VALUES IN ('0003', '0004'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO plt2_adv SELECT i, i, to_char(i % 5, 'FM0000') FROM generate_series(0, 24) i WHERE i % 5 IN (2, 3, 4); +ANALYZE plt2_adv; +CREATE TABLE plt3_adv (a int, b int, c text) PARTITION BY LIST (c); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE plt3_adv_p1 PARTITION OF plt3_adv FOR VALUES IN ('0001'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE plt3_adv_p2 PARTITION OF plt3_adv FOR VALUES IN ('0003', '0004'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO plt3_adv SELECT i, i, to_char(i % 5, 'FM0000') FROM generate_series(0, 24) i WHERE i % 5 IN (1, 3, 4); +ANALYZE plt3_adv; +-- This tests that when merging partitions from plt1_adv and plt2_adv in +-- merge_list_bounds(), process_outer_partition() returns an already-assigned +-- merged partition when re-called with plt1_adv_p1 for the second list value +-- '0001' of that partition +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM (plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.c = t2.c)) FULL JOIN plt3_adv t3 ON (t1.c = t3.c) WHERE coalesce(t1.a, 0) % 5 != 3 AND coalesce(t1.a, 0) % 5 != 4 ORDER BY t1.c, t1.a, t2.a, t3.a; + QUERY PLAN +----------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.c, t1.a, t2.a, t3.a + -> Sort + Sort Key: t1.c, t1.a, t2.a, t3.a + -> Append + -> Hash Full Join + Hash Cond: (t1_1.c = t3_1.c) + Filter: (((COALESCE(t1_1.a, 0) % 5) <> 3) AND ((COALESCE(t1_1.a, 0) % 5) <> 4)) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t1_1.c + -> Hash Right Join + Hash Cond: (t2_1.c = t1_1.c) + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Hash + -> Seq Scan on plt1_adv_p1 t1_1 + -> Hash + -> Redistribute Motion 3:3 (slice4; segments: 3) + Hash Key: t3_1.c + -> Seq Scan on plt3_adv_p1 t3_1 + -> Merge Full Join + Merge Cond: (t3_2.c = t1_2.c) + Filter: (((COALESCE(t1_2.a, 0) % 5) <> 3) AND ((COALESCE(t1_2.a, 0) % 5) <> 4)) + -> Sort + Sort Key: t3_2.c + -> Redistribute Motion 3:3 (slice5; segments: 3) + Hash Key: t3_2.c + -> Seq Scan on plt3_adv_p2 t3_2 + -> Materialize + -> Merge Left Join + Merge Cond: (t1_2.c = t2_2.c) + -> Sort + Sort Key: t1_2.c + -> Redistribute Motion 3:3 (slice6; segments: 3) + Hash Key: t1_2.c + -> Seq Scan on plt1_adv_p2 t1_2 + -> Sort + Sort Key: t2_2.c + -> Redistribute Motion 3:3 (slice7; segments: 3) + Hash Key: t2_2.c + -> Seq Scan on plt2_adv_p2 t2_2 + Optimizer: Postgres query optimizer +(42 rows) + +SELECT t1.a, t1.c, t2.a, t2.c, t3.a, t3.c FROM (plt1_adv t1 LEFT JOIN plt2_adv t2 ON (t1.c = t2.c)) FULL JOIN plt3_adv t3 ON (t1.c = t3.c) WHERE coalesce(t1.a, 0) % 5 != 3 AND coalesce(t1.a, 0) % 5 != 4 ORDER BY t1.c, t1.a, t2.a, t3.a; + a | c | a | c | a | c +----+------+----+------+----+------ + 0 | 0000 | | | | + 5 | 0000 | | | | + 10 | 0000 | | | | + 15 | 0000 | | | | + 20 | 0000 | | | | + 1 | 0001 | | | 1 | 0001 + 1 | 0001 | | | 6 | 0001 + 1 | 0001 | | | 11 | 0001 + 1 | 0001 | | | 16 | 0001 + 1 | 0001 | | | 21 | 0001 + 6 | 0001 | | | 1 | 0001 + 6 | 0001 | | | 6 | 0001 + 6 | 0001 | | | 11 | 0001 + 6 | 0001 | | | 16 | 0001 + 6 | 0001 | | | 21 | 0001 + 11 | 0001 | | | 1 | 0001 + 11 | 0001 | | | 6 | 0001 + 11 | 0001 | | | 11 | 0001 + 11 | 0001 | | | 16 | 0001 + 11 | 0001 | | | 21 | 0001 + 16 | 0001 | | | 1 | 0001 + 16 | 0001 | | | 6 | 0001 + 16 | 0001 | | | 11 | 0001 + 16 | 0001 | | | 16 | 0001 + 16 | 0001 | | | 21 | 0001 + 21 | 0001 | | | 1 | 0001 + 21 | 0001 | | | 6 | 0001 + 21 | 0001 | | | 11 | 0001 + 21 | 0001 | | | 16 | 0001 + 21 | 0001 | | | 21 | 0001 + 2 | 0002 | 2 | 0002 | | + 2 | 0002 | 7 | 0002 | | + 2 | 0002 | 12 | 0002 | | + 2 | 0002 | 17 | 0002 | | + 2 | 0002 | 22 | 0002 | | + 7 | 0002 | 2 | 0002 | | + 7 | 0002 | 7 | 0002 | | + 7 | 0002 | 12 | 0002 | | + 7 | 0002 | 17 | 0002 | | + 7 | 0002 | 22 | 0002 | | + 12 | 0002 | 2 | 0002 | | + 12 | 0002 | 7 | 0002 | | + 12 | 0002 | 12 | 0002 | | + 12 | 0002 | 17 | 0002 | | + 12 | 0002 | 22 | 0002 | | + 17 | 0002 | 2 | 0002 | | + 17 | 0002 | 7 | 0002 | | + 17 | 0002 | 12 | 0002 | | + 17 | 0002 | 17 | 0002 | | + 17 | 0002 | 22 | 0002 | | + 22 | 0002 | 2 | 0002 | | + 22 | 0002 | 7 | 0002 | | + 22 | 0002 | 12 | 0002 | | + 22 | 0002 | 17 | 0002 | | + 22 | 0002 | 22 | 0002 | | +(55 rows) + +DROP TABLE plt1_adv; +DROP TABLE plt2_adv; +DROP TABLE plt3_adv; +-- Tests for multi-level partitioned tables +CREATE TABLE alpha (a double precision, b int, c text) PARTITION BY RANGE (a); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE alpha_neg PARTITION OF alpha FOR VALUES FROM ('-Infinity') TO (0) PARTITION BY RANGE (b); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE alpha_pos PARTITION OF alpha FOR VALUES FROM (0) TO (10.0) PARTITION BY LIST (c); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE alpha_neg_p1 PARTITION OF alpha_neg FOR VALUES FROM (100) TO (200); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE alpha_neg_p2 PARTITION OF alpha_neg FOR VALUES FROM (200) TO (300); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE alpha_neg_p3 PARTITION OF alpha_neg FOR VALUES FROM (300) TO (400); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE alpha_pos_p1 PARTITION OF alpha_pos FOR VALUES IN ('0001', '0003'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE alpha_pos_p2 PARTITION OF alpha_pos FOR VALUES IN ('0004', '0006'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE alpha_pos_p3 PARTITION OF alpha_pos FOR VALUES IN ('0008', '0009'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO alpha_neg SELECT -1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(100, 399) i WHERE i % 10 IN (1, 3, 4, 6, 8, 9); +INSERT INTO alpha_pos SELECT 1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(100, 399) i WHERE i % 10 IN (1, 3, 4, 6, 8, 9); +ANALYZE alpha; +CREATE TABLE beta (a double precision, b int, c text) PARTITION BY RANGE (a); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE beta_neg PARTITION OF beta FOR VALUES FROM (-10.0) TO (0) PARTITION BY RANGE (b); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE beta_pos PARTITION OF beta FOR VALUES FROM (0) TO ('Infinity') PARTITION BY LIST (c); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE beta_neg_p1 PARTITION OF beta_neg FOR VALUES FROM (100) TO (150); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE beta_neg_p2 PARTITION OF beta_neg FOR VALUES FROM (200) TO (300); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE beta_neg_p3 PARTITION OF beta_neg FOR VALUES FROM (350) TO (500); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE beta_pos_p1 PARTITION OF beta_pos FOR VALUES IN ('0002', '0003'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE beta_pos_p2 PARTITION OF beta_pos FOR VALUES IN ('0004', '0006'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE beta_pos_p3 PARTITION OF beta_pos FOR VALUES IN ('0007', '0009'); +NOTICE: table has parent, setting distribution columns to match parent table +INSERT INTO beta_neg SELECT -1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(100, 149) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9); +INSERT INTO beta_neg SELECT -1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(200, 299) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9); +INSERT INTO beta_neg SELECT -1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(350, 499) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9); +INSERT INTO beta_pos SELECT 1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(100, 149) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9); +INSERT INTO beta_pos SELECT 1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(200, 299) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9); +INSERT INTO beta_pos SELECT 1.0, i, to_char(i % 10, 'FM0000') FROM generate_series(350, 499) i WHERE i % 10 IN (2, 3, 4, 6, 7, 9); +ANALYZE beta; +EXPLAIN (COSTS OFF) +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.b = t2.b) WHERE t1.b >= 125 AND t1.b < 225 ORDER BY t1.a, t1.b; + QUERY PLAN +-------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t1.b + -> Sort + Sort Key: t1.a, t1.b + -> Append + -> Hash Join + Hash Cond: ((t1_1.a = t2_1.a) AND (t1_1.b = t2_1.b)) + -> Seq Scan on alpha_neg_p1 t1_1 + Filter: ((b >= 125) AND (b < 225)) + -> Hash + -> Seq Scan on beta_neg_p1 t2_1 + Filter: ((b >= 125) AND (b < 225)) + -> Hash Join + Hash Cond: ((t1_2.a = t2_2.a) AND (t1_2.b = t2_2.b)) + -> Seq Scan on alpha_neg_p2 t1_2 + Filter: ((b >= 125) AND (b < 225)) + -> Hash + -> Seq Scan on beta_neg_p2 t2_2 + Filter: ((b >= 125) AND (b < 225)) + -> Hash Join + Hash Cond: ((t1_4.a = t2_4.a) AND (t1_4.b = t2_4.b)) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t1_4.a, t1_4.b + -> Append + -> Seq Scan on alpha_pos_p1 t1_4 + Filter: ((b >= 125) AND (b < 225)) + -> Seq Scan on alpha_pos_p2 t1_5 + Filter: ((b >= 125) AND (b < 225)) + -> Seq Scan on alpha_pos_p3 t1_6 + Filter: ((b >= 125) AND (b < 225)) + -> Hash + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t2_4.a, t2_4.b + -> Append + -> Seq Scan on beta_pos_p1 t2_4 + Filter: ((b >= 125) AND (b < 225)) + -> Seq Scan on beta_pos_p2 t2_5 + Filter: ((b >= 125) AND (b < 225)) + -> Seq Scan on beta_pos_p3 t2_6 + Filter: ((b >= 125) AND (b < 225)) + Optimizer: Postgres query optimizer +(41 rows) + +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.b = t2.b) WHERE t1.b >= 125 AND t1.b < 225 ORDER BY t1.a, t1.b; + a | b | c | a | b | c +----+-----+------+----+-----+------ + -1 | 126 | 0006 | -1 | 126 | 0006 + -1 | 129 | 0009 | -1 | 129 | 0009 + -1 | 133 | 0003 | -1 | 133 | 0003 + -1 | 134 | 0004 | -1 | 134 | 0004 + -1 | 136 | 0006 | -1 | 136 | 0006 + -1 | 139 | 0009 | -1 | 139 | 0009 + -1 | 143 | 0003 | -1 | 143 | 0003 + -1 | 144 | 0004 | -1 | 144 | 0004 + -1 | 146 | 0006 | -1 | 146 | 0006 + -1 | 149 | 0009 | -1 | 149 | 0009 + -1 | 203 | 0003 | -1 | 203 | 0003 + -1 | 204 | 0004 | -1 | 204 | 0004 + -1 | 206 | 0006 | -1 | 206 | 0006 + -1 | 209 | 0009 | -1 | 209 | 0009 + -1 | 213 | 0003 | -1 | 213 | 0003 + -1 | 214 | 0004 | -1 | 214 | 0004 + -1 | 216 | 0006 | -1 | 216 | 0006 + -1 | 219 | 0009 | -1 | 219 | 0009 + -1 | 223 | 0003 | -1 | 223 | 0003 + -1 | 224 | 0004 | -1 | 224 | 0004 + 1 | 126 | 0006 | 1 | 126 | 0006 + 1 | 129 | 0009 | 1 | 129 | 0009 + 1 | 133 | 0003 | 1 | 133 | 0003 + 1 | 134 | 0004 | 1 | 134 | 0004 + 1 | 136 | 0006 | 1 | 136 | 0006 + 1 | 139 | 0009 | 1 | 139 | 0009 + 1 | 143 | 0003 | 1 | 143 | 0003 + 1 | 144 | 0004 | 1 | 144 | 0004 + 1 | 146 | 0006 | 1 | 146 | 0006 + 1 | 149 | 0009 | 1 | 149 | 0009 + 1 | 203 | 0003 | 1 | 203 | 0003 + 1 | 204 | 0004 | 1 | 204 | 0004 + 1 | 206 | 0006 | 1 | 206 | 0006 + 1 | 209 | 0009 | 1 | 209 | 0009 + 1 | 213 | 0003 | 1 | 213 | 0003 + 1 | 214 | 0004 | 1 | 214 | 0004 + 1 | 216 | 0006 | 1 | 216 | 0006 + 1 | 219 | 0009 | 1 | 219 | 0009 + 1 | 223 | 0003 | 1 | 223 | 0003 + 1 | 224 | 0004 | 1 | 224 | 0004 +(40 rows) + +EXPLAIN (COSTS OFF) +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE ((t1.b >= 100 AND t1.b < 110) OR (t1.b >= 200 AND t1.b < 210)) AND ((t2.b >= 100 AND t2.b < 110) OR (t2.b >= 200 AND t2.b < 210)) AND t1.c IN ('0004', '0009') ORDER BY t1.a, t1.b, t2.b; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t1.b, t2.b + -> Sort + Sort Key: t1.a, t1.b, t2.b + -> Append + -> Hash Join + Hash Cond: ((t1_2.a = t2_2.a) AND (t1_2.c = t2_2.c)) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: t1_2.a, t1_2.c + -> Append + -> Seq Scan on alpha_neg_p1 t1_2 + Filter: ((c = ANY ('{0004,0009}'::text[])) AND (((b >= 100) AND (b < 110)) OR ((b >= 200) AND (b < 210)))) + -> Seq Scan on alpha_neg_p2 t1_3 + Filter: ((c = ANY ('{0004,0009}'::text[])) AND (((b >= 100) AND (b < 110)) OR ((b >= 200) AND (b < 210)))) + -> Hash + -> Redistribute Motion 3:3 (slice3; segments: 3) + Hash Key: t2_2.a, t2_2.c + -> Append + -> Seq Scan on beta_neg_p1 t2_2 + Filter: ((c = ANY ('{0004,0009}'::text[])) AND (((b >= 100) AND (b < 110)) OR ((b >= 200) AND (b < 210)))) + -> Seq Scan on beta_neg_p2 t2_3 + Filter: ((c = ANY ('{0004,0009}'::text[])) AND (((b >= 100) AND (b < 110)) OR ((b >= 200) AND (b < 210)))) + -> Hash Join + Hash Cond: ((t1_4.a = t2_4.a) AND (t1_4.c = t2_4.c)) + -> Seq Scan on alpha_pos_p2 t1_4 + Filter: ((c = ANY ('{0004,0009}'::text[])) AND (((b >= 100) AND (b < 110)) OR ((b >= 200) AND (b < 210)))) + -> Hash + -> Seq Scan on beta_pos_p2 t2_4 + Filter: ((c = ANY ('{0004,0009}'::text[])) AND (((b >= 100) AND (b < 110)) OR ((b >= 200) AND (b < 210)))) + -> Hash Join + Hash Cond: ((t1_5.a = t2_5.a) AND (t1_5.c = t2_5.c)) + -> Seq Scan on alpha_pos_p3 t1_5 + Filter: ((c = ANY ('{0004,0009}'::text[])) AND (((b >= 100) AND (b < 110)) OR ((b >= 200) AND (b < 210)))) + -> Hash + -> Seq Scan on beta_pos_p3 t2_5 + Filter: ((c = ANY ('{0004,0009}'::text[])) AND (((b >= 100) AND (b < 110)) OR ((b >= 200) AND (b < 210)))) + Optimizer: Postgres query optimizer +(37 rows) + +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.c = t2.c) WHERE ((t1.b >= 100 AND t1.b < 110) OR (t1.b >= 200 AND t1.b < 210)) AND ((t2.b >= 100 AND t2.b < 110) OR (t2.b >= 200 AND t2.b < 210)) AND t1.c IN ('0004', '0009') ORDER BY t1.a, t1.b, t2.b; + a | b | c | a | b | c +----+-----+------+----+-----+------ + -1 | 104 | 0004 | -1 | 104 | 0004 + -1 | 104 | 0004 | -1 | 204 | 0004 + -1 | 109 | 0009 | -1 | 109 | 0009 + -1 | 109 | 0009 | -1 | 209 | 0009 + -1 | 204 | 0004 | -1 | 104 | 0004 + -1 | 204 | 0004 | -1 | 204 | 0004 + -1 | 209 | 0009 | -1 | 109 | 0009 + -1 | 209 | 0009 | -1 | 209 | 0009 + 1 | 104 | 0004 | 1 | 104 | 0004 + 1 | 104 | 0004 | 1 | 204 | 0004 + 1 | 109 | 0009 | 1 | 109 | 0009 + 1 | 109 | 0009 | 1 | 209 | 0009 + 1 | 204 | 0004 | 1 | 104 | 0004 + 1 | 204 | 0004 | 1 | 204 | 0004 + 1 | 209 | 0009 | 1 | 109 | 0009 + 1 | 209 | 0009 | 1 | 209 | 0009 +(16 rows) + +EXPLAIN (COSTS OFF) +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c) WHERE ((t1.b >= 100 AND t1.b < 110) OR (t1.b >= 200 AND t1.b < 210)) AND ((t2.b >= 100 AND t2.b < 110) OR (t2.b >= 200 AND t2.b < 210)) AND t1.c IN ('0004', '0009') ORDER BY t1.a, t1.b; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + Merge Key: t1.a, t1.b + -> Sort + Sort Key: t1.a, t1.b + -> Append + -> Hash Join + Hash Cond: ((t1_1.a = t2_1.a) AND (t1_1.b = t2_1.b) AND (t1_1.c = t2_1.c)) + -> Seq Scan on alpha_neg_p1 t1_1 + Filter: ((c = ANY ('{0004,0009}'::text[])) AND (((b >= 100) AND (b < 110)) OR ((b >= 200) AND (b < 210)))) + -> Hash + -> Seq Scan on beta_neg_p1 t2_1 + Filter: ((c = ANY ('{0004,0009}'::text[])) AND (((b >= 100) AND (b < 110)) OR ((b >= 200) AND (b < 210)))) + -> Hash Join + Hash Cond: ((t1_2.a = t2_2.a) AND (t1_2.b = t2_2.b) AND (t1_2.c = t2_2.c)) + -> Seq Scan on alpha_neg_p2 t1_2 + Filter: ((c = ANY ('{0004,0009}'::text[])) AND (((b >= 100) AND (b < 110)) OR ((b >= 200) AND (b < 210)))) + -> Hash + -> Seq Scan on beta_neg_p2 t2_2 + Filter: ((c = ANY ('{0004,0009}'::text[])) AND (((b >= 100) AND (b < 110)) OR ((b >= 200) AND (b < 210)))) + -> Hash Join + Hash Cond: ((t1_3.a = t2_3.a) AND (t1_3.b = t2_3.b) AND (t1_3.c = t2_3.c)) + -> Seq Scan on alpha_pos_p2 t1_3 + Filter: ((c = ANY ('{0004,0009}'::text[])) AND (((b >= 100) AND (b < 110)) OR ((b >= 200) AND (b < 210)))) + -> Hash + -> Seq Scan on beta_pos_p2 t2_3 + Filter: ((c = ANY ('{0004,0009}'::text[])) AND (((b >= 100) AND (b < 110)) OR ((b >= 200) AND (b < 210)))) + -> Hash Join + Hash Cond: ((t1_4.a = t2_4.a) AND (t1_4.b = t2_4.b) AND (t1_4.c = t2_4.c)) + -> Seq Scan on alpha_pos_p3 t1_4 + Filter: ((c = ANY ('{0004,0009}'::text[])) AND (((b >= 100) AND (b < 110)) OR ((b >= 200) AND (b < 210)))) + -> Hash + -> Seq Scan on beta_pos_p3 t2_4 + Filter: ((c = ANY ('{0004,0009}'::text[])) AND (((b >= 100) AND (b < 110)) OR ((b >= 200) AND (b < 210)))) + Optimizer: Postgres query optimizer +(34 rows) + +SELECT t1.*, t2.* FROM alpha t1 INNER JOIN beta t2 ON (t1.a = t2.a AND t1.b = t2.b AND t1.c = t2.c) WHERE ((t1.b >= 100 AND t1.b < 110) OR (t1.b >= 200 AND t1.b < 210)) AND ((t2.b >= 100 AND t2.b < 110) OR (t2.b >= 200 AND t2.b < 210)) AND t1.c IN ('0004', '0009') ORDER BY t1.a, t1.b; + a | b | c | a | b | c +----+-----+------+----+-----+------ + -1 | 104 | 0004 | -1 | 104 | 0004 + -1 | 109 | 0009 | -1 | 109 | 0009 + -1 | 204 | 0004 | -1 | 204 | 0004 + -1 | 209 | 0009 | -1 | 209 | 0009 + 1 | 104 | 0004 | 1 | 104 | 0004 + 1 | 109 | 0009 | 1 | 109 | 0009 + 1 | 204 | 0004 | 1 | 204 | 0004 + 1 | 209 | 0009 | 1 | 209 | 0009 +(8 rows) + +-- partitionwise join with fractional paths +CREATE TABLE fract_t (id BIGINT, PRIMARY KEY (id)) PARTITION BY RANGE (id); +CREATE TABLE fract_t0 PARTITION OF fract_t FOR VALUES FROM ('0') TO ('1000'); +NOTICE: table has parent, setting distribution columns to match parent table +CREATE TABLE fract_t1 PARTITION OF fract_t FOR VALUES FROM ('1000') TO ('2000'); +NOTICE: table has parent, setting distribution columns to match parent table +-- insert data +INSERT INTO fract_t (id) (SELECT generate_series(0, 1999)); +ANALYZE fract_t; +-- verify plan; nested index only scans +SET max_parallel_workers_per_gather = 0; +SET enable_partitionwise_join = on; +EXPLAIN (COSTS OFF) +SELECT x.id, y.id FROM fract_t x LEFT JOIN fract_t y USING (id) ORDER BY x.id ASC LIMIT 10; + QUERY PLAN +----------------------------------------------------------------------------------- + Limit + -> Gather Motion 3:1 (slice1; segments: 3) + Merge Key: x.id + -> Limit + -> Merge Append + Sort Key: x.id + -> Merge Left Join + Merge Cond: (x_1.id = y_1.id) + -> Index Only Scan using fract_t0_pkey on fract_t0 x_1 + -> Index Only Scan using fract_t0_pkey on fract_t0 y_1 + -> Merge Left Join + Merge Cond: (x_2.id = y_2.id) + -> Index Only Scan using fract_t1_pkey on fract_t1 x_2 + -> Index Only Scan using fract_t1_pkey on fract_t1 y_2 + Optimizer: Postgres query optimizer +(15 rows) + +EXPLAIN (COSTS OFF) +SELECT x.id, y.id FROM fract_t x LEFT JOIN fract_t y USING (id) ORDER BY x.id DESC LIMIT 10; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Limit + -> Gather Motion 3:1 (slice1; segments: 3) + Merge Key: x.id + -> Limit + -> Merge Append + Sort Key: x.id DESC + -> Merge Left Join + Merge Cond: (x_1.id = y_1.id) + -> Index Only Scan Backward using fract_t0_pkey on fract_t0 x_1 + -> Sort + Sort Key: y_1.id DESC + -> Seq Scan on fract_t0 y_1 + -> Merge Left Join + Merge Cond: (x_2.id = y_2.id) + -> Index Only Scan Backward using fract_t1_pkey on fract_t1 x_2 + -> Sort + Sort Key: y_2.id DESC + -> Seq Scan on fract_t1 y_2 + Optimizer: Postgres query optimizer +(19 rows) + +-- cleanup +DROP TABLE fract_t; +RESET max_parallel_workers_per_gather; +RESET enable_partitionwise_join; +-- +-- test issue https://github.com/apache/cloudberry/issues/1301 +-- +begin; +create table t_issue_1301_big( + id varchar(32), + t varchar(32) +) distributed by (id) +partition by range(t) +( +partition p1 start ('0') end ('5'), +partition p2 start ('5') end ('9999999999999999999') +); +create index idx_t_issue_1301_big_id on t_issue_1301_big(id); +insert into t_issue_1301_big select seq, seq from generate_series(1, 100000) as seq; +create table t_issue_1301_small( + id varchar(32), + t varchar(32) +) distributed by (id); +insert into t_issue_1301_small select seq*10000, seq*10000 from generate_series(1, 100) as seq; +set local optimizer = off; +set local enable_nestloop to on; +analyze t_issue_1301_big; +analyze t_issue_1301_small; +explain(costs off) select a.* from t_issue_1301_small a left join t_issue_1301_big b on a.id=b.id; + QUERY PLAN +----------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Nested Loop Left Join + -> Seq Scan on t_issue_1301_small a + -> Append + -> Index Only Scan using t_issue_1301_big_1_prt_p1_id_idx on t_issue_1301_big_1_prt_p1 b_1 + Index Cond: (id = (a.id)::text) + -> Index Only Scan using t_issue_1301_big_1_prt_p2_id_idx on t_issue_1301_big_1_prt_p2 b_2 + Index Cond: (id = (a.id)::text) + Optimizer: Postgres query optimizer +(9 rows) + +abort; +BEGIN; +CREATE TABLE t1 (id varchar(32), date date) DISTRIBUTED BY (id) +PARTITION BY RANGE (date) +(START (date '2016-01-01') INCLUSIVE END (date '2016-01-04') EXCLUSIVE EVERY (INTERVAL '1 day')); +CREATE TABLE t2 (id varchar(32)) DISTRIBUTED BY (id); +analyze t1; +analyze t2; +\d+ t1; + Partitioned table "public.t1" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+-----------------------+-----------+----------+---------+----------+--------------+------------- + id | character varying(32) | | | | extended | | + date | date | | | | plain | | +Partition key: RANGE (date) +Partitions: t1_1_prt_1 FOR VALUES FROM ('01-01-2016') TO ('01-02-2016'), + t1_1_prt_2 FOR VALUES FROM ('01-02-2016') TO ('01-03-2016'), + t1_1_prt_3 FOR VALUES FROM ('01-03-2016') TO ('01-04-2016') +Distributed by: (id) + +\d+ t2; + Table "public.t2" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+-----------------------+-----------+----------+---------+----------+--------------+------------- + id | character varying(32) | | | | extended | | +Distributed by: (id) + +EXPLAIN(COSTS OFF) SELECT COUNT(*) FROM t1_1_prt_1 JOIN t2 USING(id); + QUERY PLAN +------------------------------------------------------------------ + Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Hash Join + Hash Cond: ((t1_1_prt_1.id)::text = (t2.id)::text) + -> Seq Scan on t1_1_prt_1 + -> Hash + -> Seq Scan on t2 + Optimizer: Postgres query optimizer +(8 rows) + +EXPLAIN(COSTS OFF) SELECT COUNT(*) FROM t1 JOIN t2 USING(id); + QUERY PLAN +---------------------------------------------------------- + Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Hash Join + Hash Cond: ((t1.id)::text = (t2.id)::text) + -> Append + -> Seq Scan on t1_1_prt_1 t1_1 + -> Seq Scan on t1_1_prt_2 t1_2 + -> Seq Scan on t1_1_prt_3 t1_3 + -> Hash + -> Seq Scan on t2 + Optimizer: Postgres query optimizer +(11 rows) + +ABORT; diff --git a/src/test/regress/expected/qp_correlated_query.out b/src/test/regress/expected/qp_correlated_query.out index 59a3abc3cbf..72cddcdd5bb 100644 --- a/src/test/regress/expected/qp_correlated_query.out +++ b/src/test/regress/expected/qp_correlated_query.out @@ -76,9 +76,9 @@ commit; select a, x from qp_csq_t1, qp_csq_t2 where qp_csq_t1.a in (select x); a | x ---+--- + 5 | 5 1 | 1 3 | 3 - 5 | 5 7 | 7 (4 rows) @@ -174,11 +174,11 @@ select * from A where exists (select * from B where A.i in (select C.i from C wh Gather Motion 3:1 (slice1; segments: 3) -> Hash Semi Join Hash Cond: (a.i = b.i) - -> Hash Semi Join - Hash Cond: (a.i = c.i) - -> Seq Scan on a + -> Hash Right Semi Join + Hash Cond: (c.i = a.i) + -> Seq Scan on c -> Hash - -> Seq Scan on c + -> Seq Scan on a -> Hash -> Seq Scan on b Optimizer: Postgres query optimizer @@ -194,8 +194,8 @@ select * from A where exists (select * from B where A.i in (select C.i from C wh -- Test for ALL_SUBLINK pull-up based on both left-hand and right-hand input explain (costs off) select * from A,B where exists (select * from C where B.i not in (select C.i from C where C.i != 10)); - QUERY PLAN ---------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Semi Join -> Nested Loop @@ -218,11 +218,11 @@ select * from A,B where exists (select * from C where B.i not in (select C.i fro select * from A,B where exists (select * from C where B.i not in (select C.i from C where C.i != 10)); i | j | i | j ----+----+----+--- - 78 | -1 | 88 | 1 1 | 1 | 88 | 1 + 1 | 1 | 88 | 1 + 78 | -1 | 88 | 1 19 | 5 | 88 | 1 99 | 62 | 88 | 1 - 1 | 1 | 88 | 1 (5 rows) -- -- -- -- @@ -378,13 +378,13 @@ select A.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i i explain select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i not in (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=20000000003.86..20000000004.00 rows=10 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000003.86..20000000004.28 rows=30 width=12) + Limit (cost=20000000004.94..20000000005.08 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000004.94..20000000005.36 rows=30 width=12) Merge Key: a.i, b.i, c.j - -> Limit (cost=20000000003.86..20000000003.88 rows=10 width=12) - -> Sort (cost=20000000003.85..20000000003.90 rows=18 width=12) + -> Limit (cost=20000000004.94..20000000004.96 rows=10 width=12) + -> Sort (cost=20000000004.94..20000000004.98 rows=18 width=12) Sort Key: a.i, b.i, c.j - -> Nested Loop (cost=20000000000.00..20000000003.48 rows=18 width=12) + -> Nested Loop (cost=20000000000.00..20000000004.56 rows=18 width=12) -> Nested Loop (cost=10000000000.00..10000000002.08 rows=2 width=8) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.04 rows=1 width=4) -> Seq Scan on a (cost=0.00..1.02 rows=1 width=4) @@ -428,36 +428,36 @@ select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j explain select A.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i not in (select B.i from B where C.i = B.i and B.i !=10)) order by A.j limit 10; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=20000000100.52..20000000100.75 rows=10 width=4) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=20000000100.52..20000000100.75 rows=10 width=4) + Limit (cost=20000000005.04..20000000005.18 rows=10 width=4) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000005.04..20000000005.46 rows=30 width=4) Merge Key: a.j - -> Limit (cost=20000000100.52..20000000100.55 rows=4 width=4) - -> Sort (cost=20000000100.52..20000000100.66 rows=18 width=4) + -> Limit (cost=20000000005.04..20000000005.06 rows=10 width=4) + -> Sort (cost=20000000005.04..20000000005.08 rows=18 width=4) Sort Key: a.j - -> Nested Loop (cost=20000000000.00..20000000099.36 rows=18 width=4) - -> Nested Loop (cost=10000000000.00..10000000094.04 rows=2 width=4) - -> Seq Scan on a (cost=0.00..90.47 rows=1 width=4) + -> Nested Loop (cost=20000000000.00..20000000004.66 rows=18 width=4) + -> Nested Loop (cost=10000000000.00..10000000002.18 rows=2 width=4) + -> Seq Scan on a (cost=0.00..1.02 rows=1 width=4) Filter: (j = (SubPlan 2)) SubPlan 2 - -> Result (cost=0.00..17.68 rows=5 width=4) + -> Result (cost=0.00..1.16 rows=4 width=4) Filter: (c_1.j = a.j) - -> Materialize (cost=0.00..17.68 rows=5 width=4) - -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..17.66 rows=2 width=4) - -> Seq Scan on c c_1 (cost=0.00..17.57 rows=2 width=4) + -> Materialize (cost=0.00..1.11 rows=4 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.09 rows=4 width=4) + -> Seq Scan on c c_1 (cost=0.00..1.03 rows=2 width=4) Filter: (SubPlan 1) SubPlan 1 - -> Result (cost=0.00..3.20 rows=5 width=4) + -> Result (cost=0.00..1.17 rows=5 width=4) Filter: (c_1.i = b_1.i) - -> Materialize (cost=0.00..3.20 rows=5 width=4) - -> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..3.17 rows=2 width=4) - -> Seq Scan on b b_1 (cost=0.00..3.08 rows=2 width=4) + -> Materialize (cost=0.00..1.12 rows=5 width=4) + -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..1.09 rows=5 width=4) + -> Seq Scan on b b_1 (cost=0.00..1.02 rows=2 width=4) Filter: (i <> 10) - -> Materialize (cost=0.00..3.39 rows=6 width=0) - -> Broadcast Motion 3:3 (slice1; segments: 3) (cost=0.00..3.30 rows=6 width=0) - -> Seq Scan on b (cost=0.00..3.06 rows=2 width=0) - -> Materialize (cost=0.00..3.58 rows=9 width=0) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..3.45 rows=9 width=0) - -> Seq Scan on c (cost=0.00..3.09 rows=3 width=0) + -> Materialize (cost=0.00..1.13 rows=6 width=0) + -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..1.10 rows=6 width=0) + -> Seq Scan on b (cost=0.00..1.02 rows=2 width=0) + -> Materialize (cost=0.00..1.19 rows=9 width=0) + -> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..1.15 rows=9 width=0) + -> Seq Scan on c (cost=0.00..1.03 rows=3 width=0) Optimizer: Postgres query optimizer (31 rows) @@ -479,21 +479,21 @@ select A.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i n explain select A.i from A where A.j = (select C.j from C where C.j = A.j and C.i = any (select B.i from B where C.i = B.i and B.i !=10)); QUERY PLAN --------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..35.42 rows=1 width=4) - -> Seq Scan on a (cost=0.00..35.42 rows=1 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.04 rows=1 width=4) + -> Seq Scan on a (cost=0.00..1.02 rows=1 width=4) Filter: (j = (SubPlan 1)) SubPlan 1 - -> Hash Semi Join (cost=3.26..6.67 rows=6 width=4) + -> Hash Semi Join (cost=1.18..2.55 rows=5 width=4) Hash Cond: (c.i = b.i) - -> Result (cost=0.00..3.31 rows=9 width=8) + -> Result (cost=0.00..1.28 rows=9 width=8) Filter: (c.j = a.j) - -> Materialize (cost=0.00..3.31 rows=9 width=8) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..3.27 rows=3 width=8) - -> Seq Scan on c (cost=0.00..3.09 rows=3 width=8) - -> Hash (cost=3.20..3.20 rows=2 width=4) - -> Materialize (cost=0.00..3.20 rows=5 width=4) - -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..3.17 rows=2 width=4) - -> Seq Scan on b (cost=0.00..3.08 rows=2 width=4) + -> Materialize (cost=0.00..1.19 rows=9 width=8) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.15 rows=9 width=8) + -> Seq Scan on c (cost=0.00..1.03 rows=3 width=8) + -> Hash (cost=1.12..1.12 rows=5 width=4) + -> Materialize (cost=0.00..1.12 rows=5 width=4) + -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..1.09 rows=5 width=4) + -> Seq Scan on b (cost=0.00..1.02 rows=2 width=4) Filter: (i <> 10) Optimizer: Postgres query optimizer (17 rows) @@ -513,10 +513,10 @@ select A.i from A where A.j = (select C.j from C where C.j = A.j and C.i = any ( select a, x from qp_csq_t1, qp_csq_t2 where qp_csq_t1.a = any (select x); a | x ---+--- - 1 | 1 3 | 3 - 5 | 5 7 | 7 + 5 | 5 + 1 | 1 (4 rows) select a, x from qp_csq_t1, qp_csq_t2 where qp_csq_t1.a = any (select x) order by a, x; @@ -590,20 +590,16 @@ select * from A where A.j = any (select C.j from C,B where C.j = A.j and B.i = a -- Planner should fail due to skip-level correlation not supported. ORCA should pass select * from A,B where A.j = any (select C.j from C where C.j = A.j and B.i = any (select C.i from C where C.i != 10 and C.i = A.i)) order by 1,2,3,4; ERROR: correlated subquery with skip-level correlations is not supported --- start_ignore --- GPDB_96_MERGE_FIXME: we used to propagate the (i <> 10) qual to the Seq Scans on --- 'c'. Investigate why we lost that --- end_ignore explain select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i = any (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=20000000003.86..20000000004.00 rows=10 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000003.86..20000000004.28 rows=30 width=12) + Limit (cost=20000000004.94..20000000005.08 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000004.94..20000000005.36 rows=30 width=12) Merge Key: a.i, b.i, c.j - -> Limit (cost=20000000003.86..20000000003.88 rows=10 width=12) - -> Sort (cost=20000000003.85..20000000003.90 rows=18 width=12) + -> Limit (cost=20000000004.94..20000000004.96 rows=10 width=12) + -> Sort (cost=20000000004.94..20000000004.98 rows=18 width=12) Sort Key: a.i, b.i, c.j - -> Nested Loop (cost=20000000000.00..20000000003.48 rows=18 width=12) + -> Nested Loop (cost=20000000000.00..20000000004.56 rows=18 width=12) -> Nested Loop (cost=10000000000.00..10000000002.08 rows=2 width=8) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.04 rows=1 width=4) -> Seq Scan on a (cost=0.00..1.02 rows=1 width=4) @@ -646,36 +642,36 @@ select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j explain select A.i, B.i, C.j from A, B, C where A.j = any ( select C.j from C where not exists(select C.i from C,A where C.i = A.i and C.i =10)) order by A.i, B.i, C.j limit 10; QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=20000000007.72..20000000007.86 rows=10 width=12) + Limit (cost=20000000007.69..20000000007.83 rows=10 width=12) InitPlan 1 (returns $0) (slice6) - -> Gather Motion 1:1 (slice7; segments: 1) (cost=10000000000.00..10000000002.11 rows=3 width=0) - -> Nested Loop (cost=10000000000.00..10000000002.07 rows=1 width=0) + -> Gather Motion 1:1 (slice7; segments: 1) (cost=10000000000.00..10000000002.11 rows=3 width=4) + -> Nested Loop (cost=10000000000.00..10000000002.07 rows=1 width=4) -> Seq Scan on c c_2 (cost=0.00..1.04 rows=1 width=4) Filter: (i = 10) -> Seq Scan on a a_1 (cost=0.00..1.02 rows=1 width=4) Filter: (i = 10) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000007.72..20000000008.15 rows=30 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000007.69..20000000008.11 rows=30 width=12) Merge Key: a.i, b.i, c.j - -> Limit (cost=20000000007.72..20000000007.75 rows=10 width=12) - -> Sort (cost=20000000007.70..20000000007.92 rows=90 width=12) + -> Limit (cost=20000000007.69..20000000007.71 rows=10 width=12) + -> Sort (cost=20000000007.69..20000000007.91 rows=90 width=12) Sort Key: a.i, b.i, c.j - -> Result (cost=20000000001.13..20000000005.75 rows=90 width=12) + -> Result (cost=20000000001.07..20000000005.74 rows=90 width=12) One-Time Filter: (NOT $0) - -> Nested Loop (cost=20000000001.13..20000000005.75 rows=90 width=12) + -> Nested Loop (cost=20000000001.07..20000000005.74 rows=90 width=12) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=6 width=4) -> Seq Scan on b (cost=0.00..1.02 rows=2 width=4) - -> Materialize (cost=10000000001.13..10000000003.57 rows=15 width=8) - -> Nested Loop (cost=10000000001.13..10000000003.49 rows=15 width=8) - -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=1.13..2.27 rows=5 width=4) - -> Hash Semi Join (cost=1.13..2.20 rows=2 width=4) - Hash Cond: (a.j = c_1.j) - -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..1.05 rows=2 width=8) - Hash Key: a.j - -> Seq Scan on a (cost=0.00..1.02 rows=2 width=8) - -> Hash (cost=1.09..1.09 rows=3 width=4) - -> Redistribute Motion 3:3 (slice5; segments: 3) (cost=0.00..1.09 rows=3 width=4) - Hash Key: c_1.j - -> Seq Scan on c c_1 (cost=0.00..1.03 rows=3 width=4) + -> Materialize (cost=10000000001.07..10000000003.56 rows=15 width=8) + -> Nested Loop (cost=10000000001.07..10000000003.48 rows=15 width=8) + -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=1.07..2.26 rows=5 width=4) + -> Hash Right Semi Join (cost=1.07..2.19 rows=2 width=4) + Hash Cond: (c_1.j = a.j) + -> Redistribute Motion 3:3 (slice4; segments: 3) (cost=0.00..1.09 rows=3 width=4) + Hash Key: c_1.j + -> Seq Scan on c c_1 (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.05..1.05 rows=2 width=8) + -> Redistribute Motion 3:3 (slice5; segments: 3) (cost=0.00..1.05 rows=2 width=8) + Hash Key: a.j + -> Seq Scan on a (cost=0.00..1.02 rows=2 width=8) -> Materialize (cost=0.00..1.04 rows=3 width=4) -> Seq Scan on c (cost=0.00..1.03 rows=3 width=4) Optimizer: Postgres query optimizer @@ -699,10 +695,10 @@ select A.i, B.i, C.j from A, B, C where A.j = any ( select C.j from C where not explain select A.i, B.i, C.j from A, B, C where A.j = any (select C.j from C where C.j = A.j and not exists (select sum(B.i) from B where C.i = B.i and C.i !=10)) order by A.i, B.i, C.j limit 10; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- - Limit (cost=20000000004.85..20000000004.99 rows=10 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000004.85..20000000005.28 rows=30 width=12) + Limit (cost=20000000004.84..20000000004.98 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000004.84..20000000005.27 rows=30 width=12) Merge Key: a.i, b.i, c.j - -> Limit (cost=20000000004.85..20000000004.88 rows=10 width=12) + -> Limit (cost=20000000004.84..20000000004.87 rows=10 width=12) -> Sort (cost=20000000004.84..20000000004.95 rows=45 width=12) Sort Key: a.i, b.i, c.j -> Nested Loop (cost=20000000000.00..20000000003.87 rows=45 width=12) @@ -785,16 +781,16 @@ select * from A,B where exists (select * from C where C.j = A.j and B.i = all (s explain select A.i, B.i, C.j from A, B, C where A.j = (select sum(C.j) from C where C.j = A.j and C.i = all (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=20000000006.84..20000000006.98 rows=10 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000006.84..20000000007.26 rows=30 width=12) + Limit (cost=20000000006.82..20000000006.96 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000006.82..20000000007.24 rows=30 width=12) Merge Key: a.i, b.i, c.j - -> Limit (cost=20000000006.84..20000000006.86 rows=10 width=12) + -> Limit (cost=20000000006.82..20000000006.84 rows=10 width=12) -> Sort (cost=20000000006.82..20000000006.99 rows=67 width=12) Sort Key: a.i, b.i, c.j -> Nested Loop (cost=20000000001.11..20000000005.36 rows=67 width=12) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.15 rows=9 width=4) -> Seq Scan on c (cost=0.00..1.03 rows=3 width=4) - -> Materialize (cost=10000000001.11..10000000003.39 rows=7 width=8) + -> Materialize (cost=10000000001.11..10000000003.38 rows=7 width=8) -> Nested Loop (cost=10000000001.11..10000000003.35 rows=7 width=8) -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=1.11..2.23 rows=4 width=4) -> Hash Join (cost=1.11..2.18 rows=1 width=4) @@ -841,18 +837,18 @@ select A.i, B.i, C.j from A, B, C where A.j = (select sum(C.j) from C where C.j explain select A.i, B.i, C.j from A, B, C where A.j < all ( select C.j from C where not exists(select C.i from C,A where C.i = A.i and C.i =10)) order by A.i, B.i, C.j limit 10; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------ - Limit (cost=30000000007.49..30000000007.64 rows=10 width=12) + Limit (cost=30000000007.49..30000000007.63 rows=10 width=12) InitPlan 1 (returns $0) (slice5) - -> Gather Motion 1:1 (slice6; segments: 1) (cost=10000000000.00..10000000002.11 rows=3 width=0) - -> Nested Loop (cost=10000000000.00..10000000002.07 rows=1 width=0) + -> Gather Motion 1:1 (slice6; segments: 1) (cost=10000000000.00..10000000002.11 rows=3 width=4) + -> Nested Loop (cost=10000000000.00..10000000002.07 rows=1 width=4) -> Seq Scan on c c_2 (cost=0.00..1.04 rows=1 width=4) Filter: (i = 10) -> Seq Scan on a a_1 (cost=0.00..1.02 rows=1 width=4) Filter: (i = 10) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=30000000007.49..30000000007.92 rows=30 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=30000000007.49..30000000007.91 rows=30 width=12) Merge Key: a.i, b.i, c.j - -> Limit (cost=30000000007.49..30000000007.52 rows=10 width=12) - -> Sort (cost=30000000007.48..30000000007.63 rows=60 width=12) + -> Limit (cost=30000000007.49..30000000007.51 rows=10 width=12) + -> Sort (cost=30000000007.49..30000000007.64 rows=60 width=12) Sort Key: a.i, b.i, c.j -> Nested Loop (cost=30000000000.00..30000000006.19 rows=60 width=12) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.15 rows=9 width=4) @@ -881,10 +877,10 @@ select A.i, B.i, C.j from A, B, C where A.j < all ( select C.j from C where not explain select A.i, B.i, C.j from A, B, C where A.j = all (select C.j from C where C.j = A.j and not exists (select sum(B.i) from B where C.i = B.i and C.i !=10)) order by A.i, B.i, C.j limit 10; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- - Limit (cost=20000000004.85..20000000004.99 rows=10 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000004.85..20000000005.28 rows=30 width=12) + Limit (cost=20000000004.84..20000000004.98 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=20000000004.84..20000000005.27 rows=30 width=12) Merge Key: a.i, b.i, c.j - -> Limit (cost=20000000004.85..20000000004.88 rows=10 width=12) + -> Limit (cost=20000000004.84..20000000004.87 rows=10 width=12) -> Sort (cost=20000000004.84..20000000004.95 rows=45 width=12) Sort Key: a.i, b.i, c.j -> Nested Loop (cost=20000000000.00..20000000003.87 rows=45 width=12) @@ -1029,26 +1025,26 @@ select * from A where exists (select * from C,B where C.j = A.j and exists (sele select * from A,B where exists (select * from C where C.j = A.j and exists (select * from C where C.i = B.i)); i | j | i | j ----+----+----+---- + 1 | 1 | 1 | 43 + 1 | 1 | 1 | 1 + 1 | 1 | 1 | 43 + 1 | 1 | 1 | 1 + 78 | -1 | 1 | 43 + 78 | -1 | 1 | 1 + 99 | 62 | 1 | 43 + 99 | 62 | 1 | 1 1 | 1 | 2 | 7 1 | 1 | 2 | 7 - 99 | 62 | 2 | 7 78 | -1 | 2 | 7 - 99 | 62 | -1 | 62 - 99 | 62 | 32 | 5 - 78 | -1 | -1 | 62 - 78 | -1 | 32 | 5 + 99 | 62 | 2 | 7 1 | 1 | -1 | 62 1 | 1 | 32 | 5 1 | 1 | -1 | 62 1 | 1 | 32 | 5 - 99 | 62 | 1 | 43 - 99 | 62 | 1 | 1 - 78 | -1 | 1 | 43 - 78 | -1 | 1 | 1 - 1 | 1 | 1 | 43 - 1 | 1 | 1 | 1 - 1 | 1 | 1 | 43 - 1 | 1 | 1 | 1 + 78 | -1 | -1 | 62 + 78 | -1 | 32 | 5 + 99 | 62 | -1 | 62 + 99 | 62 | 32 | 5 (20 rows) select * from A where exists (select * from B, C where C.j = A.j and exists (select sum(C.i) from C where C.i != 10 and C.i = B.i)) order by 1, 2; @@ -1156,9 +1152,9 @@ select * from A,B,C where C.i = A.i and exists (select C.j where C.j = B.j and A select b from qp_csq_t1 where not exists(select * from qp_csq_t2 where y=a); b --- - 4 6 8 + 4 (3 rows) select b from qp_csq_t1 where not exists(select * from qp_csq_t2 where y=a) order by b; @@ -1229,8 +1225,8 @@ select * from A where not exists (select sum(C.i) from C where C.i = A.i); explain select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 0); QUERY PLAN ---------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.05 rows=5 width=8) - -> Seq Scan on a (cost=0.00..3.05 rows=2 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.08 rows=5 width=8) + -> Seq Scan on a (cost=0.00..1.02 rows=2 width=8) Optimizer: Postgres query optimizer (3 rows) @@ -1239,34 +1235,33 @@ select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 0 ----+---- 19 | 5 99 | 62 - 78 | -1 1 | 1 1 | 1 + 78 | -1 (5 rows) explain select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 5 offset 3); QUERY PLAN ---------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.05 rows=5 width=8) - -> Seq Scan on a (cost=0.00..3.05 rows=2 width=8) - Settings: optimizer=off - Optimizer status: Postgres query optimizer -(4 rows) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.08 rows=5 width=8) + -> Seq Scan on a (cost=0.00..1.02 rows=2 width=8) + Optimizer: Postgres query optimizer +(3 rows) select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 5 offset 3); i | j ----+---- 19 | 5 + 99 | 62 1 | 1 1 | 1 - 99 | 62 78 | -1 (5 rows) explain select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 1 offset 0); QUERY PLAN ------------------------------------------ - Result (cost=0.00..0.01 rows=1 width=0) + Result (cost=0.00..0.00 rows=0 width=0) One-Time Filter: false Optimizer: Postgres query optimizer (3 rows) @@ -1279,20 +1274,20 @@ select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 1 explain select C.j from C where not exists (select max(B.i) from B where C.i = B.i having max(B.i) is not null) order by C.j; QUERY PLAN --------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=31.39..31.40 rows=5 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.04..1.10 rows=4 width=4) Merge Key: c.j - -> Sort (cost=31.39..31.40 rows=2 width=4) + -> Sort (cost=1.04..1.04 rows=2 width=4) Sort Key: c.j - -> Seq Scan on c (cost=0.00..31.34 rows=2 width=4) - Filter: NOT ((SubPlan 1)) + -> Seq Scan on c (cost=0.00..1.03 rows=2 width=4) + Filter: (NOT (SubPlan 1)) SubPlan 1 - -> Aggregate (cost=3.13..3.14 rows=1 width=4) - Filter: max(b.i) IS NOT NULL - -> Result (cost=0.00..3.08 rows=1 width=4) - Filter: c.i = b.i - -> Materialize (cost=0.00..3.08 rows=1 width=4) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..3.08 rows=1 width=4) - -> Seq Scan on b (cost=0.00..3.08 rows=1 width=4) + -> Aggregate (cost=1.21..1.22 rows=1 width=4) + Filter: (max(b.i) IS NOT NULL) + -> Result (cost=0.00..1.19 rows=6 width=4) + Filter: (c.i = b.i) + -> Materialize (cost=0.00..1.13 rows=6 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=6 width=4) + -> Seq Scan on b (cost=0.00..1.02 rows=2 width=4) Optimizer: Postgres query optimizer (15 rows) @@ -1308,11 +1303,11 @@ select C.j from C where not exists (select max(B.i) from B where C.i = B.i havi explain select C.j from C where not exists (select max(B.i) from B where C.i = B.i offset 1000) order by C.j; QUERY PLAN ---------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=3.23..3.26 rows=9 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.05..1.18 rows=9 width=4) Merge Key: j - -> Sort (cost=3.23..3.26 rows=3 width=4) + -> Sort (cost=1.05..1.06 rows=3 width=4) Sort Key: j - -> Seq Scan on c (cost=0.00..3.09 rows=3 width=4) + -> Seq Scan on c (cost=0.00..1.03 rows=3 width=4) Optimizer: Postgres query optimizer (6 rows) @@ -1333,15 +1328,15 @@ select C.j from C where not exists (select max(B.i) from B where C.i = B.i offs explain select C.j from C where not exists (select rank() over (order by B.i) from B where C.i = B.i) order by C.j; QUERY PLAN ---------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=6.33..6.33 rows=4 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=2.11..2.16 rows=3 width=4) Merge Key: c.j - -> Sort (cost=6.33..6.33 rows=2 width=4) + -> Sort (cost=2.11..2.11 rows=1 width=4) Sort Key: c.j - -> Hash Anti Join (cost=3.14..6.30 rows=2 width=4) + -> Hash Anti Join (cost=1.04..2.10 rows=1 width=4) Hash Cond: (c.i = b.i) - -> Seq Scan on c (cost=0.00..3.09 rows=3 width=8) - -> Hash (cost=3.06..3.06 rows=2 width=4) - -> Seq Scan on b (cost=0.00..3.06 rows=2 width=4) + -> Seq Scan on c (cost=0.00..1.03 rows=3 width=8) + -> Hash (cost=1.02..1.02 rows=2 width=4) + -> Seq Scan on b (cost=0.00..1.02 rows=2 width=4) Optimizer: Postgres query optimizer (10 rows) @@ -1375,14 +1370,14 @@ select * from A where not exists (select sum(C.i) from C where C.i = A.i group b explain select A.i from A where not exists (select B.i from B where B.i in (select C.i from C) and B.i = A.i); QUERY PLAN ---------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.10..3.22 rows=3 width=4) - -> Hash Right Anti Join (cost=2.10..3.17 rows=1 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=2.08..3.21 rows=3 width=4) + -> Hash Right Anti Join (cost=2.08..3.16 rows=1 width=4) Hash Cond: (b.i = a.i) - -> Hash Semi Join (cost=1.07..2.12 rows=2 width=4) - Hash Cond: (b.i = c.i) - -> Seq Scan on b (cost=0.00..1.02 rows=2 width=4) - -> Hash (cost=1.03..1.03 rows=3 width=4) - -> Seq Scan on c (cost=0.00..1.03 rows=3 width=4) + -> Hash Right Semi Join (cost=1.04..2.11 rows=2 width=4) + Hash Cond: (c.i = b.i) + -> Seq Scan on c (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.02..1.02 rows=2 width=4) + -> Seq Scan on b (cost=0.00..1.02 rows=2 width=4) -> Hash (cost=1.02..1.02 rows=2 width=4) -> Seq Scan on a (cost=0.00..1.02 rows=2 width=4) Optimizer: Postgres query optimizer @@ -1391,31 +1386,27 @@ explain select A.i from A where not exists (select B.i from B where B.i in (sele select A.i from A where not exists (select B.i from B where B.i in (select C.i from C) and B.i = A.i); i ---- - 99 78 19 + 99 (3 rows) --- start_ignore --- GPDB_96_MERGE_FIXME: we used to propagate the (i <> 10) qual to the Seq Scans on --- 'c' and 'a'. Investigate why we lost that --- end_ignore explain select * from B where not exists (select * from C,A where C.i in (select C.i from C where C.i = A.i and C.i != 10) AND B.i = C.i); - QUERY PLAN -------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=3.15..4.30 rows=3 width=8) - -> Hash Right Anti Join (cost=3.15..4.25 rows=1 width=8) + QUERY PLAN +------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=3.16..4.29 rows=3 width=8) + -> Hash Right Anti Join (cost=3.16..4.24 rows=1 width=8) Hash Cond: (c.i = b.i) - -> Hash Semi Join (cost=2.11..3.19 rows=2 width=4) - Hash Cond: (a.i = c_1.i) - -> Hash Join (cost=1.04..2.10 rows=2 width=8) - Hash Cond: (c.i = a.i) - -> Seq Scan on c (cost=0.00..1.03 rows=3 width=4) - -> Hash (cost=1.02..1.02 rows=2 width=4) - -> Seq Scan on a (cost=0.00..1.02 rows=2 width=4) - -> Hash (cost=1.04..1.04 rows=3 width=4) - -> Seq Scan on c c_1 (cost=0.00..1.04 rows=3 width=4) - Filter: (i <> 10) + -> Hash Right Semi Join (cost=2.12..3.18 rows=2 width=4) + Hash Cond: (c_1.i = a.i) + -> Seq Scan on c c_1 (cost=0.00..1.04 rows=3 width=4) + Filter: (i <> 10) + -> Hash (cost=2.10..2.10 rows=2 width=8) + -> Hash Join (cost=1.04..2.10 rows=2 width=8) + Hash Cond: (c.i = a.i) + -> Seq Scan on c (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.02..1.02 rows=2 width=4) + -> Seq Scan on a (cost=0.00..1.02 rows=2 width=4) -> Hash (cost=1.02..1.02 rows=2 width=8) -> Seq Scan on b (cost=0.00..1.02 rows=2 width=8) Optimizer: Postgres query optimizer @@ -1424,31 +1415,31 @@ explain select * from B where not exists (select * from C,A where C.i in (select select * from B where not exists (select * from C,A where C.i in (select C.i from C where C.i = A.i and C.i != 10) AND B.i = C.i); i | j ----+---- + 2 | 7 88 | 1 -1 | 62 - 2 | 7 32 | 5 (4 rows) explain select * from A where A.i in (select C.j from C,B where B.i in (select i from C)); - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=10000000013.48..10000000015.62 rows=6 width=8) - -> Hash Semi Join (cost=10000000013.48..10000000015.62 rows=2 width=8) - Hash Cond: (a.i = c.j) - -> Seq Scan on a (cost=0.00..2.05 rows=2 width=8) - -> Hash (cost=10000000012.81..10000000012.81 rows=18 width=4) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=10000000003.20..10000000012.81 rows=18 width=4) - Hash Key: c.j - -> Nested Loop (cost=10000000003.20..10000000011.73 rows=18 width=4) - -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=3.20..6.59 rows=6 width=0) - -> Hash Semi Join (cost=3.20..6.35 rows=2 width=0) - Hash Cond: (b.i = c_1.i) - -> Seq Scan on b (cost=0.00..3.06 rows=2 width=4) - -> Hash (cost=3.09..3.09 rows=3 width=4) - -> Seq Scan on c c_1 (cost=0.00..3.09 rows=3 width=4) - -> Materialize (cost=0.00..3.13 rows=3 width=4) - -> Seq Scan on c (cost=0.00..3.09 rows=3 width=4) + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=10000000002.08..10000000005.01 rows=6 width=8) + -> Hash Right Semi Join (cost=10000000002.08..10000000004.93 rows=2 width=8) + Hash Cond: (c.j = a.i) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=10000000001.05..10000000003.81 rows=18 width=4) + Hash Key: c.j + -> Nested Loop (cost=10000000001.05..10000000003.45 rows=18 width=4) + -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=1.04..2.19 rows=6 width=0) + -> Hash Right Semi Join (cost=1.04..2.11 rows=2 width=0) + Hash Cond: (c_1.i = b.i) + -> Seq Scan on c c_1 (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.02..1.02 rows=2 width=4) + -> Seq Scan on b (cost=0.00..1.02 rows=2 width=4) + -> Materialize (cost=0.00..1.04 rows=3 width=4) + -> Seq Scan on c (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.02..1.02 rows=2 width=8) + -> Seq Scan on a (cost=0.00..1.02 rows=2 width=8) Optimizer: Postgres query optimizer (17 rows) @@ -1475,9 +1466,9 @@ explain select * from A where not exists (select sum(c.i) from C where C.i = A.i select * from A where not exists (select sum(c.i) from C where C.i = A.i group by C.i having c.i > 3); i | j ----+--- - 19 | 5 1 | 1 1 | 1 + 19 | 5 (3 rows) -- ---------------------------------------------------------------------- @@ -1559,9 +1550,9 @@ select * from D; -------+---- 19 | 5 99 | 62 + 11111 | -1 11111 | 1 11111 | 1 - 11111 | -1 (5 rows) update D set i = 22222 from C where C.i = D.i and not exists (select C.j from C,B where C.j = B.j and D.j < 10); @@ -1570,8 +1561,8 @@ select * from D; -------+---- 11111 | 1 11111 | 1 - 11111 | -1 19 | 5 + 11111 | -1 22222 | 62 (5 rows) @@ -2133,6 +2124,8 @@ select A.i, B.i, C.j from A, B, C where exists (select C.j from C group by C.j h begin; create table csq_emp(name text, department text, salary numeric); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'name' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into csq_emp values('a','adept',11200.00); insert into csq_emp values('b','adept',22222.00); insert into csq_emp values('c','bdept',99222.00); @@ -2182,6 +2175,8 @@ create table job ( EMPNO VARCHAR(4), jobtitle VARCHAR(20) ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'empno' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into job (EMPNO, Jobtitle) values ('01','Tester'); insert into job (EMPNO, Jobtitle) values ('02','Accountant'); insert into job (EMPNO, Jobtitle) values ('03','Developer'); @@ -3571,10 +3566,10 @@ ANALYZE qp_tab3; EXPLAIN SELECT a FROM qp_tab1 f1 LEFT JOIN qp_tab2 on a=c WHERE NOT EXISTS(SELECT 1 FROM qp_tab1 f2 WHERE f1.a = f2.a); QUERY PLAN ------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.04..3.14 rows=4 width=4) - -> Hash Anti Join (cost=2.04..3.14 rows=2 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=2.04..3.13 rows=3 width=4) + -> Hash Anti Join (cost=2.04..3.08 rows=1 width=4) Hash Cond: (f1.a = f2.a) - -> Hash Left Join (cost=1.02..2.07 rows=2 width=4) + -> Hash Left Join (cost=1.02..2.05 rows=1 width=4) Hash Cond: (f1.a = qp_tab2.c) -> Seq Scan on qp_tab1 f1 (cost=0.00..1.01 rows=1 width=4) -> Hash (cost=1.01..1.01 rows=1 width=4) @@ -3587,7 +3582,7 @@ EXPLAIN SELECT a FROM qp_tab1 f1 LEFT JOIN qp_tab2 on a=c WHERE NOT EXISTS(SELEC EXPLAIN SELECT DISTINCT a FROM qp_tab1 WHERE NOT (SELECT TRUE FROM qp_tab2 WHERE EXISTS (SELECT * FROM qp_tab3 WHERE qp_tab2.c = qp_tab3.e)); QUERY PLAN ------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=1.02..10001.04 rows=1 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.02..1.04 rows=1 width=4) Merge Key: qp_tab1.a InitPlan 1 (returns $0) (slice2) -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.02..2.09 rows=3 width=1) @@ -3596,7 +3591,7 @@ EXPLAIN SELECT DISTINCT a FROM qp_tab1 WHERE NOT (SELECT TRUE FROM qp_tab2 WHERE -> Seq Scan on qp_tab2 (cost=0.00..1.01 rows=1 width=4) -> Hash (cost=1.01..1.01 rows=1 width=4) -> Seq Scan on qp_tab3 (cost=0.00..1.01 rows=1 width=4) - -> Unique (cost=1.02..10001.03 rows=0 width=4) + -> Unique (cost=1.02..1.03 rows=0 width=4) Group Key: qp_tab1.a -> Sort (cost=1.02..1.02 rows=1 width=4) Sort Key: qp_tab1.a @@ -3644,8 +3639,8 @@ EXPLAIN SELECT * FROM qp_non_eq_a, qp_non_eq_b WHERE qp_non_eq_a.f = qp_non_eq_b SELECT * FROM qp_non_eq_a, qp_non_eq_b WHERE qp_non_eq_a.f = qp_non_eq_b.f AND qp_non_eq_a.f::text <> '-0'; i | f | i | f ---+---+---+---- - 1 | 0 | 1 | -0 1 | 0 | 3 | 0 + 1 | 0 | 1 | -0 (2 rows) EXPLAIN SELECT * FROM qp_non_eq_a INNER JOIN qp_non_eq_b ON qp_non_eq_a.f = qp_non_eq_b.f AND CASE WHEN qp_non_eq_b.f::text = '-0' THEN 1 ELSE -1::float8 END < '0'; @@ -3668,23 +3663,23 @@ EXPLAIN SELECT * FROM qp_non_eq_a INNER JOIN qp_non_eq_b ON qp_non_eq_a.f = qp_n SELECT * FROM qp_non_eq_a INNER JOIN qp_non_eq_b ON qp_non_eq_a.f = qp_non_eq_b.f AND CASE WHEN qp_non_eq_b.f::text = '-0' THEN 1 ELSE -1::float8 END < '0'; i | f | i | f ---+----+---+--- - 2 | -0 | 3 | 0 1 | 0 | 3 | 0 + 2 | -0 | 3 | 0 (2 rows) EXPLAIN SELECT * FROM qp_non_eq_a, qp_non_eq_b WHERE qp_non_eq_a.i = qp_non_eq_b.i AND qp_non_eq_a.i = ANY('{1,2,3}'::integer[]); QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 2:1 (slice1; segments: 2) (cost=1.05..3.12 rows=4 width=24) - -> Hash Join (cost=1.05..3.12 rows=2 width=24) - Hash Cond: qp_non_eq_a.i = qp_non_eq_b.i - -> Seq Scan on qp_non_eq_a (cost=0.00..2.03 rows=1 width=12) - Filter: i = ANY ('{1,2,3}'::integer[]) - -> Hash (cost=1.03..1.03 rows=1 width=12) - -> Seq Scan on qp_non_eq_b (cost=0.00..1.03 rows=1 width=12) - Filter: i = ANY ('{1,2,3}'::integer[]) + Gather Motion 2:1 (slice1; segments: 2) (cost=1.03..2.10 rows=3 width=24) + -> Hash Join (cost=1.03..2.05 rows=1 width=24) + Hash Cond: (qp_non_eq_a.i = qp_non_eq_b.i) + -> Seq Scan on qp_non_eq_a (cost=0.00..1.01 rows=1 width=12) + Filter: (i = ANY ('{1,2,3}'::integer[])) + -> Hash (cost=1.01..1.01 rows=1 width=12) + -> Seq Scan on qp_non_eq_b (cost=0.00..1.01 rows=1 width=12) + Filter: (i = ANY ('{1,2,3}'::integer[])) Optimizer: Postgres query optimizer -(10 rows) +(9 rows) SELECT * FROM qp_non_eq_a, qp_non_eq_b WHERE qp_non_eq_a.i = qp_non_eq_b.i AND qp_non_eq_a.i = ANY('{1,2,3}'::integer[]); i | f | i | f @@ -3752,37 +3747,37 @@ analyze supplier; set optimizer_enforce_subplans = 1; -- with TVF explain select x1.a, (select count(*) from generate_series(1, x1.a)) from t1 x1; - QUERY PLAN -------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..39.57 rows=3 width=4) - -> Seq Scan on t1 x1 (cost=0.00..39.57 rows=1 width=4) + QUERY PLAN +-------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..13.56 rows=3 width=12) + -> Seq Scan on t1 x1 (cost=0.00..13.52 rows=1 width=12) SubPlan 1 -> Aggregate (cost=12.50..12.51 rows=1 width=8) - -> Function Scan on generate_series (cost=0.00..10.00 rows=334 width=0) - Optimizer: legacy query optimizer + -> Function Scan on generate_series (cost=0.00..10.00 rows=1000 width=0) + Optimizer: Postgres query optimizer (6 rows) select x1.a, (select count(*) from generate_series(1, x1.a)) from t1 x1; a | count ---+------- + 1 | 1 2 | 2 3 | 3 - 1 | 1 (3 rows) -- with limit explain select t1.a, (select count(*) c from (select city from supplier limit t1.a) x) from t1; QUERY PLAN --------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..4.00 rows=3 width=12) - -> Seq Scan on t1 (cost=0.00..4.00 rows=1 width=12) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.30 rows=3 width=12) + -> Seq Scan on t1 (cost=0.00..1.26 rows=1 width=12) SubPlan 1 - -> Aggregate (cost=0.65..0.66 rows=1 width=8) - -> Limit (cost=0.00..0.64 rows=1 width=32) - -> Result (cost=0.00..3.17 rows=5 width=32) - -> Materialize (cost=0.00..3.17 rows=5 width=0) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..3.15 rows=2 width=0) - -> Seq Scan on supplier (cost=0.00..3.05 rows=2 width=0) + -> Aggregate (cost=0.24..0.25 rows=1 width=8) + -> Limit (cost=0.00..0.23 rows=1 width=32) + -> Result (cost=0.00..1.16 rows=5 width=32) + -> Materialize (cost=0.00..1.11 rows=5 width=0) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.08 rows=5 width=0) + -> Seq Scan on supplier (cost=0.00..1.02 rows=2 width=0) Optimizer: Postgres query optimizer (10 rows) @@ -3798,48 +3793,48 @@ select t1.a, (select count(*) c from (select city from supplier limit t1.a) x) f explain select t1.*, (select count(*) as ct from generate_series(1, a), t1) from t1; QUERY PLAN --------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..30000000173.36 rows=3 width=8) - -> Seq Scan on t1 (cost=0.00..30000000173.36 rows=1 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..10000000057.12 rows=3 width=16) + -> Seq Scan on t1 (cost=0.00..10000000057.08 rows=1 width=16) SubPlan 1 - -> Aggregate (cost=10000000057.10..10000000057.11 rows=1 width=8) - -> Nested Loop (cost=10000000000.00..10000000049.60 rows=3000 width=0) + -> Aggregate (cost=10000000056.06..10000000056.07 rows=1 width=8) + -> Nested Loop (cost=10000000000.00..10000000048.56 rows=3000 width=0) -> Function Scan on generate_series (cost=0.00..10.00 rows=1000 width=0) - -> Materialize (cost=0.00..2.10 rows=3 width=0) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..2.09 rows=1 width=0) - -> Seq Scan on t1 t1_1 (cost=0.00..2.03 rows=1 width=0) + -> Materialize (cost=0.00..1.06 rows=3 width=0) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.05 rows=3 width=0) + -> Seq Scan on t1 t1_1 (cost=0.00..1.01 rows=1 width=0) Optimizer: Postgres query optimizer (10 rows) select t1.*, (select count(*) as ct from generate_series(1, a), t1) from t1; a | b | ct ---+---+---- - 1 | 1 | 3 2 | 2 | 6 3 | 3 | 9 + 1 | 1 | 3 (3 rows) explain select * from t1 where 0 < (select count(*) from generate_series(1, a), t1); QUERY PLAN --------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..30000000173.37 rows=1 width=8) - -> Seq Scan on t1 (cost=0.00..30000000173.37 rows=1 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=8) + -> Seq Scan on t1 (cost=0.00..1.01 rows=1 width=8) Filter: (0 < (SubPlan 1)) SubPlan 1 - -> Aggregate (cost=10000000057.10..10000000057.11 rows=1 width=8) - -> Nested Loop (cost=10000000000.00..10000000049.60 rows=3000 width=0) + -> Aggregate (cost=10000000056.06..10000000056.07 rows=1 width=8) + -> Nested Loop (cost=10000000000.00..10000000048.56 rows=3000 width=0) -> Function Scan on generate_series (cost=0.00..10.00 rows=1000 width=0) - -> Materialize (cost=0.00..2.10 rows=3 width=0) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..2.09 rows=1 width=0) - -> Seq Scan on t1 t1_1 (cost=0.00..2.03 rows=1 width=0) + -> Materialize (cost=0.00..1.06 rows=3 width=0) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.05 rows=3 width=0) + -> Seq Scan on t1 t1_1 (cost=0.00..1.01 rows=1 width=0) Optimizer: Postgres query optimizer (11 rows) select * from t1 where 0 < (select count(*) from generate_series(1, a), t1); a | b ---+--- - 1 | 1 2 | 2 3 | 3 + 1 | 1 (3 rows) reset optimizer_enforce_subplans; diff --git a/src/test/regress/expected/qp_correlated_query_optimizer.out b/src/test/regress/expected/qp_correlated_query_optimizer.out index 4144761b34f..b99c6e8cbac 100644 --- a/src/test/regress/expected/qp_correlated_query_optimizer.out +++ b/src/test/regress/expected/qp_correlated_query_optimizer.out @@ -76,9 +76,9 @@ commit; select a, x from qp_csq_t1, qp_csq_t2 where qp_csq_t1.a in (select x); a | x ---+--- + 5 | 5 1 | 1 3 | 3 - 5 | 5 7 | 7 (4 rows) @@ -169,8 +169,8 @@ select A.i, B.i, C.j from A, B, C where A.j in (select C.j from C where C.j = A. -- Test for sublink pull-up based on both left-hand and right-hand input explain (costs off) select * from A where exists (select * from B where A.i in (select C.i from C where C.i = B.i)); - QUERY PLAN ---------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Join Hash Cond: (a.i = c.i) @@ -186,7 +186,7 @@ select * from A where exists (select * from B where A.i in (select C.i from C wh -> Hash -> Seq Scan on b Filter: (NOT (i IS NULL)) - Optimizer: Pivotal Optimizer (GPORCA) version 2.70.0 + Optimizer: GPORCA (16 rows) select * from A where exists (select * from B where A.i in (select C.i from C where C.i = B.i)); @@ -199,8 +199,8 @@ select * from A where exists (select * from B where A.i in (select C.i from C wh -- Test for ALL_SUBLINK pull-up based on both left-hand and right-hand input explain (costs off) select * from A,B where exists (select * from C where B.i not in (select C.i from C where C.i != 10)); - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -225,17 +225,17 @@ select * from A,B where exists (select * from C where B.i not in (select C.i fro -> Materialize -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on c - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (25 rows) select * from A,B where exists (select * from C where B.i not in (select C.i from C where C.i != 10)); i | j | i | j ----+----+----+--- - 78 | -1 | 88 | 1 - 1 | 1 | 88 | 1 19 | 5 | 88 | 1 99 | 62 | 88 | 1 1 | 1 | 88 | 1 + 1 | 1 | 88 | 1 + 78 | -1 | 88 | 1 (5 rows) -- -- -- -- @@ -391,29 +391,29 @@ select A.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i i explain select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i not in (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=0.00..1390613111661.99 rows=10 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1390613111661.99 rows=10 width=12) + Limit (cost=0.00..1390613123493.04 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1390613123493.04 rows=10 width=12) Merge Key: a.i, b_1.i, c_1.j - -> Limit (cost=0.00..1390613111661.99 rows=4 width=12) - -> Sort (cost=0.00..1390613111661.99 rows=90 width=12) + -> Limit (cost=0.00..1390613123493.04 rows=4 width=12) + -> Sort (cost=0.00..1390613123493.04 rows=90 width=12) Sort Key: a.i, b_1.i, c_1.j - -> Nested Loop (cost=0.00..1390613111661.95 rows=90 width=12) + -> Nested Loop (cost=0.00..1390613123493.00 rows=90 width=12) Join Filter: true - -> Nested Loop (cost=0.00..1324033.29 rows=18 width=8) + -> Nested Loop (cost=0.00..1324033.31 rows=18 width=8) Join Filter: true -> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..431.00 rows=6 width=4) -> Seq Scan on b b_1 (cost=0.00..431.00 rows=2 width=4) -> Seq Scan on c c_1 (cost=0.00..431.00 rows=3 width=4) - -> Materialize (cost=0.00..1356696152.56 rows=5 width=4) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1356696152.56 rows=5 width=4) - -> Seq Scan on a (cost=0.00..1356696152.56 rows=2 width=4) + -> Materialize (cost=0.00..1356696164.10 rows=5 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1356696164.10 rows=5 width=4) + -> Seq Scan on a (cost=0.00..1356696164.10 rows=2 width=4) Filter: (j = (SubPlan 2)) SubPlan 2 - -> Result (cost=0.00..1324036.59 rows=1 width=4) + -> Result (cost=0.00..1324036.60 rows=1 width=4) Filter: (c.j = a.j) - -> Materialize (cost=0.00..1324036.58 rows=9 width=4) - -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..1324036.58 rows=9 width=4) - -> Seq Scan on c (cost=0.00..1324036.58 rows=3 width=4) + -> Materialize (cost=0.00..1324036.59 rows=9 width=4) + -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..1324036.59 rows=9 width=4) + -> Seq Scan on c (cost=0.00..1324036.59 rows=3 width=4) Filter: (SubPlan 1) SubPlan 1 -> Result (cost=0.00..431.00 rows=1 width=1) @@ -425,7 +425,7 @@ explain select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..431.00 rows=6 width=4) -> Seq Scan on b (cost=0.00..431.00 rows=2 width=4) Filter: (i <> 10) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (35 rows) select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i not in (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; @@ -446,23 +446,23 @@ select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j explain select A.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i not in (select B.i from B where C.i = B.i and B.i !=10)) order by A.j limit 10; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=0.00..1390613110663.90 rows=10 width=4) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1390613110663.90 rows=10 width=4) + Limit (cost=0.00..1390613122494.94 rows=10 width=4) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1390613122494.94 rows=10 width=4) Merge Key: a.j - -> Limit (cost=0.00..1390613110663.90 rows=4 width=4) - -> Sort (cost=0.00..1390613110663.90 rows=90 width=4) + -> Limit (cost=0.00..1390613122494.94 rows=4 width=4) + -> Sort (cost=0.00..1390613122494.94 rows=90 width=4) Sort Key: a.j - -> Nested Loop (cost=0.00..1390613110663.88 rows=90 width=4) + -> Nested Loop (cost=0.00..1390613122494.93 rows=90 width=4) Join Filter: true - -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..1356696152.54 rows=5 width=4) - -> Seq Scan on a (cost=0.00..1356696152.54 rows=2 width=4) + -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..1356696164.08 rows=5 width=4) + -> Seq Scan on a (cost=0.00..1356696164.08 rows=2 width=4) Filter: (j = (SubPlan 2)) SubPlan 2 - -> Result (cost=0.00..1324036.59 rows=1 width=4) + -> Result (cost=0.00..1324036.60 rows=1 width=4) Filter: (c_1.j = a.j) - -> Materialize (cost=0.00..1324036.58 rows=9 width=4) - -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..1324036.58 rows=9 width=4) - -> Seq Scan on c c_1 (cost=0.00..1324036.58 rows=3 width=4) + -> Materialize (cost=0.00..1324036.59 rows=9 width=4) + -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..1324036.59 rows=9 width=4) + -> Seq Scan on c c_1 (cost=0.00..1324036.59 rows=3 width=4) Filter: (SubPlan 1) SubPlan 1 -> Result (cost=0.00..431.00 rows=1 width=1) @@ -474,13 +474,13 @@ explain select A.j from A, B, C where A.j = (select C.j from C where C.j = A.j a -> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..431.00 rows=6 width=4) -> Seq Scan on b b_1 (cost=0.00..431.00 rows=2 width=4) Filter: (i <> 10) - -> Materialize (cost=0.00..1324032.34 rows=18 width=1) - -> Nested Loop (cost=0.00..1324032.34 rows=18 width=1) + -> Materialize (cost=0.00..1324032.35 rows=18 width=1) + -> Nested Loop (cost=0.00..1324032.35 rows=18 width=1) Join Filter: true -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=6 width=1) -> Seq Scan on b (cost=0.00..431.00 rows=2 width=1) -> Seq Scan on c (cost=0.00..431.00 rows=3 width=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (35 rows) select A.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i not in (select B.i from B where C.i = B.i and B.i !=10)) order by A.j limit 10; @@ -501,8 +501,8 @@ select A.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i n explain select A.i from A where A.j = (select C.j from C where C.j = A.j and C.i = any (select B.i from B where C.i = B.i and B.i !=10)); QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1765379.74 rows=5 width=4) - -> Seq Scan on a (cost=0.00..1765379.74 rows=2 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1765380.02 rows=5 width=4) + -> Seq Scan on a (cost=0.00..1765380.02 rows=2 width=4) Filter: (j = (SubPlan 1)) SubPlan 1 -> Result (cost=0.00..862.00 rows=1 width=4) @@ -512,11 +512,12 @@ explain select A.i from A where A.j = (select C.j from C where C.j = A.j and C.i -> Hash Semi Join (cost=0.00..862.00 rows=2 width=4) Hash Cond: ((c.i = b.i) AND (c.i = b.i)) -> Seq Scan on c (cost=0.00..431.00 rows=3 width=8) + Filter: (i <> 10) -> Hash (cost=431.00..431.00 rows=2 width=4) -> Seq Scan on b (cost=0.00..431.00 rows=2 width=4) Filter: (i <> 10) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 -(15 rows) + Optimizer: GPORCA +(16 rows) select A.i from A where A.j = (select C.j from C where C.j = A.j and C.i = any (select B.i from B where C.i = B.i and B.i !=10)); i @@ -533,10 +534,10 @@ select A.i from A where A.j = (select C.j from C where C.j = A.j and C.i = any ( select a, x from qp_csq_t1, qp_csq_t2 where qp_csq_t1.a = any (select x); a | x ---+--- - 1 | 1 3 | 3 - 5 | 5 7 | 7 + 5 | 5 + 1 | 1 (4 rows) select a, x from qp_csq_t1, qp_csq_t2 where qp_csq_t1.a = any (select x) order by a, x; @@ -620,22 +621,22 @@ select * from A,B where A.j = any (select C.j from C where C.j = A.j and B.i = a explain select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i = any (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=0.00..3164000462.21 rows=10 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3164000462.21 rows=10 width=12) + Limit (cost=0.00..3164000591.57 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3164000591.57 rows=10 width=12) Merge Key: a.i, b_1.i, c_1.j - -> Limit (cost=0.00..3164000462.21 rows=4 width=12) - -> Sort (cost=0.00..3164000462.21 rows=90 width=12) + -> Limit (cost=0.00..3164000591.57 rows=4 width=12) + -> Sort (cost=0.00..3164000591.57 rows=90 width=12) Sort Key: a.i, b_1.i, c_1.j - -> Nested Loop (cost=0.00..3164000462.17 rows=90 width=12) + -> Nested Loop (cost=0.00..3164000591.53 rows=90 width=12) Join Filter: true - -> Nested Loop (cost=0.00..1324033.29 rows=18 width=8) + -> Nested Loop (cost=0.00..1324033.31 rows=18 width=8) Join Filter: true -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..431.00 rows=6 width=4) -> Seq Scan on b b_1 (cost=0.00..431.00 rows=2 width=4) -> Seq Scan on c c_1 (cost=0.00..431.00 rows=3 width=4) - -> Materialize (cost=0.00..1765379.90 rows=5 width=4) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1765379.90 rows=5 width=4) - -> Seq Scan on a (cost=0.00..1765379.90 rows=2 width=4) + -> Materialize (cost=0.00..1765380.02 rows=5 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1765380.02 rows=5 width=4) + -> Seq Scan on a (cost=0.00..1765380.02 rows=2 width=4) Filter: (j = (SubPlan 1)) SubPlan 1 -> Result (cost=0.00..862.00 rows=1 width=4) @@ -645,11 +646,12 @@ explain select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C -> Hash Semi Join (cost=0.00..862.00 rows=2 width=4) Hash Cond: ((c.i = b.i) AND (c.i = b.i)) -> Seq Scan on c (cost=0.00..431.00 rows=3 width=8) + Filter: (i <> 10) -> Hash (cost=431.00..431.00 rows=2 width=4) -> Seq Scan on b (cost=0.00..431.00 rows=2 width=4) Filter: (i <> 10) - Optimizer: Pivotal Optimizer (GPORCA) -(29 rows) + Optimizer: GPORCA +(30 rows) select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j and C.i = any (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; i | i | j @@ -669,17 +671,17 @@ select A.i, B.i, C.j from A, B, C where A.j = (select C.j from C where C.j = A.j explain select A.i, B.i, C.j from A, B, C where A.j = any ( select C.j from C where not exists(select C.i from C,A where C.i = A.i and C.i =10)) order by A.i, B.i, C.j limit 10; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=0.00..1358457987.42 rows=4 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1358457987.42 rows=10 width=12) + Limit (cost=0.00..1358457995.86 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1358457995.86 rows=10 width=12) Merge Key: a.i, b.i, c.j - -> Limit (cost=0.00..1358457987.42 rows=4 width=12) - -> Sort (cost=0.00..1358457987.42 rows=90 width=12) + -> Limit (cost=0.00..1358457995.86 rows=4 width=12) + -> Sort (cost=0.00..1358457995.86 rows=90 width=12) Sort Key: a.i, b.i, c.j - -> Hash Semi Join (cost=0.00..1358457987.38 rows=90 width=12) - Hash Cond: a.j = c_2.j - -> Nested Loop (cost=0.00..1356692610.50 rows=90 width=16) + -> Hash Semi Join (cost=0.00..1358457995.82 rows=90 width=12) + Hash Cond: (a.j = c_2.j) + -> Nested Loop (cost=0.00..1356692618.97 rows=90 width=16) Join Filter: true - -> Nested Loop (cost=0.00..1324033.12 rows=10 width=12) + -> Nested Loop (cost=0.00..1324033.13 rows=10 width=12) Join Filter: true -> Seq Scan on a (cost=0.00..431.00 rows=2 width=8) -> Materialize (cost=0.00..431.00 rows=6 width=4) @@ -688,21 +690,21 @@ explain select A.i, B.i, C.j from A, B, C where A.j = any ( select C.j from C wh -> Materialize (cost=0.00..431.00 rows=9 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=9 width=4) -> Seq Scan on c (cost=0.00..431.00 rows=3 width=4) - -> Hash (cost=1765376.85..1765376.85 rows=9 width=4) - -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..1765376.85 rows=9 width=4) - -> Nested Loop Anti Join (cost=0.00..1765376.85 rows=3 width=4) + -> Hash (cost=1765376.83..1765376.83 rows=9 width=4) + -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..1765376.83 rows=9 width=4) + -> Nested Loop Anti Join (cost=0.00..1765376.83 rows=3 width=4) Join Filter: true -> Seq Scan on c c_2 (cost=0.00..431.00 rows=3 width=4) - -> Materialize (cost=0.00..862.00 rows=2 width=1) - -> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..862.00 rows=2 width=1) + -> Materialize (cost=0.00..862.00 rows=1 width=1) + -> Broadcast Motion 3:3 (slice5; segments: 3) (cost=0.00..862.00 rows=1 width=1) -> Hash Join (cost=0.00..862.00 rows=1 width=1) - Hash Cond: c_1.i = a_1.i + Hash Cond: (c_1.i = a_1.i) -> Seq Scan on c c_1 (cost=0.00..431.00 rows=1 width=4) - Filter: i = 10 AND i = 10 + Filter: ((i = 10) AND (i = 10)) -> Hash (cost=431.00..431.00 rows=1 width=4) -> Seq Scan on a a_1 (cost=0.00..431.00 rows=1 width=4) - Filter: i = 10 AND i = 10 - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 + Filter: ((i = 10) AND (i = 10)) + Optimizer: GPORCA (34 rows) select A.i, B.i, C.j from A, B, C where A.j = any ( select C.j from C where not exists(select C.i from C,A where C.i = A.i and C.i =10)) order by A.i, B.i, C.j limit 10; @@ -723,15 +725,15 @@ select A.i, B.i, C.j from A, B, C where A.j = any ( select C.j from C where not explain select A.i, B.i, C.j from A, B, C where A.j = any (select C.j from C where C.j = A.j and not exists (select sum(B.i) from B where C.i = B.i and C.i !=10)) order by A.i, B.i, C.j limit 10; QUERY PLAN --------------------------------------------------------------------------------------------------------------------- - Limit (cost=0.00..1356692053.43 rows=10 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1356692053.43 rows=10 width=12) + Limit (cost=0.00..1356692061.89 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1356692061.89 rows=10 width=12) Merge Key: a.i, b.i, c.j - -> Limit (cost=0.00..1356692053.43 rows=4 width=12) - -> Sort (cost=0.00..1356692053.43 rows=18 width=12) + -> Limit (cost=0.00..1356692061.89 rows=4 width=12) + -> Sort (cost=0.00..1356692061.89 rows=18 width=12) Sort Key: a.i, b.i, c.j - -> Nested Loop (cost=0.00..1356692053.42 rows=18 width=12) + -> Nested Loop (cost=0.00..1356692061.89 rows=18 width=12) Join Filter: true - -> Nested Loop (cost=0.00..1324032.58 rows=2 width=8) + -> Nested Loop (cost=0.00..1324032.59 rows=2 width=8) Join Filter: true -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=4) -> Hash Semi Join (cost=0.00..431.00 rows=1 width=4) @@ -744,7 +746,7 @@ explain select A.i, B.i, C.j from A, B, C where A.j = any (select C.j from C whe -> Materialize (cost=0.00..431.00 rows=9 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=9 width=4) -> Seq Scan on c (cost=0.00..431.00 rows=3 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (22 rows) select A.i, B.i, C.j from A, B, C where A.j = any (select C.j from C where C.j = A.j and not exists (select sum(B.i) from B where C.i = B.i and C.i !=10)) order by A.i, B.i, C.j limit 10; @@ -811,30 +813,30 @@ select * from A,B where exists (select * from C where C.j = A.j and B.i = all (s explain select A.i, B.i, C.j from A, B, C where A.j = (select sum(C.j) from C where C.j = A.j and C.i = all (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=0.00..2712506248.09 rows=10 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2712506248.09 rows=10 width=12) + Limit (cost=0.00..2712506271.17 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2712506271.17 rows=10 width=12) Merge Key: a.i, b_1.i, c_1.j - -> Limit (cost=0.00..2712506248.09 rows=4 width=12) - -> Sort (cost=0.00..2712506248.09 rows=90 width=12) + -> Limit (cost=0.00..2712506271.17 rows=4 width=12) + -> Sort (cost=0.00..2712506271.17 rows=90 width=12) Sort Key: a.i, b_1.i, c_1.j - -> Nested Loop (cost=0.00..2712506248.05 rows=90 width=12) + -> Nested Loop (cost=0.00..2712506271.13 rows=90 width=12) Join Filter: true - -> Nested Loop (cost=0.00..1324033.29 rows=18 width=8) + -> Nested Loop (cost=0.00..1324033.31 rows=18 width=8) Join Filter: true -> Broadcast Motion 3:3 (slice6; segments: 3) (cost=0.00..431.00 rows=6 width=4) -> Seq Scan on b b_1 (cost=0.00..431.00 rows=2 width=4) -> Seq Scan on c c_1 (cost=0.00..431.00 rows=3 width=4) - -> Materialize (cost=0.00..1324467.58 rows=5 width=4) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1324467.58 rows=5 width=4) - -> Hash Join (cost=0.00..1324467.58 rows=2 width=4) + -> Materialize (cost=0.00..1324467.60 rows=5 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1324467.60 rows=5 width=4) + -> Hash Join (cost=0.00..1324467.60 rows=2 width=4) Hash Cond: (((sum(c.j)) = (a.j)::bigint) AND (c.j = a.j)) - -> GroupAggregate (cost=0.00..1324036.58 rows=3 width=12) + -> GroupAggregate (cost=0.00..1324036.59 rows=3 width=12) Group Key: c.j - -> Sort (cost=0.00..1324036.58 rows=3 width=4) + -> Sort (cost=0.00..1324036.59 rows=3 width=4) Sort Key: c.j - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1324036.58 rows=3 width=4) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1324036.59 rows=3 width=4) Hash Key: c.j - -> Seq Scan on c (cost=0.00..1324036.58 rows=3 width=4) + -> Seq Scan on c (cost=0.00..1324036.59 rows=3 width=4) Filter: (SubPlan 1) SubPlan 1 -> Result (cost=0.00..431.00 rows=1 width=1) @@ -850,7 +852,7 @@ explain select A.i, B.i, C.j from A, B, C where A.j = (select sum(C.j) from C wh -> Redistribute Motion 3:3 (slice5; segments: 3) (cost=0.00..431.00 rows=2 width=8) Hash Key: a.j -> Seq Scan on a (cost=0.00..431.00 rows=2 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (40 rows) select A.i, B.i, C.j from A, B, C where A.j = (select sum(C.j) from C where C.j = A.j and C.i = all (select B.i from B where C.i = B.i and B.i !=10)) order by A.i, B.i, C.j limit 10; @@ -871,17 +873,17 @@ select A.i, B.i, C.j from A, B, C where A.j = (select sum(C.j) from C where C.j explain select A.i, B.i, C.j from A, B, C where A.j < all ( select C.j from C where not exists(select C.i from C,A where C.i = A.i and C.i =10)) order by A.i, B.i, C.j limit 10; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=0.00..1391061420469.59 rows=4 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1391061420469.59 rows=10 width=12) + Limit (cost=0.00..1391061429119.82 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1391061429119.82 rows=10 width=12) Merge Key: a_1.i, b.i, c_2.j - -> Limit (cost=0.00..1391061420469.59 rows=4 width=12) - -> Sort (cost=0.00..1391061420469.59 rows=36 width=12) + -> Limit (cost=0.00..1391061429119.82 rows=4 width=12) + -> Sort (cost=0.00..1391061429119.82 rows=36 width=12) Sort Key: a_1.i, b.i, c_2.j - -> Nested Loop Left Anti Semi (Not-In) Join (cost=0.00..1391061420469.58 rows=36 width=12) - Join Filter: a_1.j >= c_1.j - -> Nested Loop (cost=0.00..1356692610.50 rows=90 width=16) + -> Nested Loop Left Anti Semi (Not-In) Join (cost=0.00..1391061429119.81 rows=36 width=12) + Join Filter: (a_1.j >= c_1.j) + -> Nested Loop (cost=0.00..1356692618.97 rows=90 width=16) Join Filter: true - -> Nested Loop (cost=0.00..1324033.12 rows=10 width=12) + -> Nested Loop (cost=0.00..1324033.13 rows=10 width=12) Join Filter: true -> Seq Scan on a a_1 (cost=0.00..431.00 rows=2 width=8) -> Materialize (cost=0.00..431.00 rows=6 width=4) @@ -890,21 +892,21 @@ explain select A.i, B.i, C.j from A, B, C where A.j < all ( select C.j from C wh -> Materialize (cost=0.00..431.00 rows=9 width=4) -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..431.00 rows=9 width=4) -> Seq Scan on c c_2 (cost=0.00..431.00 rows=3 width=4) - -> Materialize (cost=0.00..1765376.85 rows=9 width=4) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1765376.85 rows=9 width=4) - -> Nested Loop Anti Join (cost=0.00..1765376.85 rows=3 width=4) + -> Materialize (cost=0.00..1765376.83 rows=9 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1765376.83 rows=9 width=4) + -> Nested Loop Anti Join (cost=0.00..1765376.83 rows=3 width=4) Join Filter: true -> Seq Scan on c c_1 (cost=0.00..431.00 rows=3 width=4) - -> Materialize (cost=0.00..862.00 rows=2 width=1) - -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..862.00 rows=2 width=1) + -> Materialize (cost=0.00..862.00 rows=1 width=1) + -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..862.00 rows=1 width=1) -> Hash Join (cost=0.00..862.00 rows=1 width=1) - Hash Cond: c.i = a.i + Hash Cond: (c.i = a.i) -> Seq Scan on c (cost=0.00..431.00 rows=1 width=4) - Filter: i = 10 AND i = 10 + Filter: ((i = 10) AND (i = 10)) -> Hash (cost=431.00..431.00 rows=1 width=4) -> Seq Scan on a (cost=0.00..431.00 rows=1 width=4) - Filter: i = 10 AND i = 10 - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 + Filter: ((i = 10) AND (i = 10)) + Optimizer: GPORCA (34 rows) select A.i, B.i, C.j from A, B, C where A.j < all ( select C.j from C where not exists(select C.i from C,A where C.i = A.i and C.i =10)) order by A.i, B.i, C.j limit 10; @@ -915,15 +917,15 @@ select A.i, B.i, C.j from A, B, C where A.j < all ( select C.j from C where not explain select A.i, B.i, C.j from A, B, C where A.j = all (select C.j from C where C.j = A.j and not exists (select sum(B.i) from B where C.i = B.i and C.i !=10)) order by A.i, B.i, C.j limit 10; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit (cost=0.00..2260124027.48 rows=10 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2260124027.48 rows=10 width=12) + Limit (cost=0.00..2260124042.86 rows=10 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2260124042.86 rows=10 width=12) Merge Key: a.i, b.i, c.j - -> Limit (cost=0.00..2260124027.48 rows=4 width=12) - -> Sort (cost=0.00..2260124027.48 rows=18 width=12) + -> Limit (cost=0.00..2260124042.86 rows=4 width=12) + -> Sort (cost=0.00..2260124042.86 rows=18 width=12) Sort Key: a.i, b.i, c.j - -> Nested Loop (cost=0.00..2260124027.48 rows=18 width=12) + -> Nested Loop (cost=0.00..2260124042.86 rows=18 width=12) Join Filter: true - -> Nested Loop (cost=0.00..1324033.29 rows=18 width=8) + -> Nested Loop (cost=0.00..1324033.31 rows=18 width=8) Join Filter: true -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..431.00 rows=6 width=4) -> Seq Scan on b (cost=0.00..431.00 rows=2 width=4) @@ -938,7 +940,7 @@ explain select A.i, B.i, C.j from A, B, C where A.j = all (select C.j from C whe -> Aggregate (cost=0.00..0.00 rows=0 width=16) -> Result (cost=0.00..0.00 rows=0 width=4) One-Time Filter: false - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (24 rows) select A.i, B.i, C.j from A, B, C where A.j = all (select C.j from C where C.j = A.j and not exists (select sum(B.i) from B where C.i = B.i and C.i !=10)) order by A.i, B.i, C.j limit 10; @@ -1066,26 +1068,26 @@ select * from A where exists (select * from C,B where C.j = A.j and exists (sele select * from A,B where exists (select * from C where C.j = A.j and exists (select * from C where C.i = B.i)); i | j | i | j ----+----+----+---- - 1 | 1 | 32 | 5 - 1 | 1 | 32 | 5 - 99 | 62 | 32 | 5 - 78 | -1 | 32 | 5 - 1 | 1 | 1 | 43 - 1 | 1 | -1 | 62 - 1 | 1 | 1 | 1 + 99 | 62 | 2 | 7 1 | 1 | 2 | 7 - 1 | 1 | 1 | 43 - 1 | 1 | -1 | 62 - 1 | 1 | 1 | 1 1 | 1 | 2 | 7 + 78 | -1 | 2 | 7 99 | 62 | 1 | 43 - 99 | 62 | -1 | 62 99 | 62 | 1 | 1 - 99 | 62 | 2 | 7 + 1 | 1 | 1 | 43 + 1 | 1 | 1 | 1 + 1 | 1 | 1 | 43 + 1 | 1 | 1 | 1 78 | -1 | 1 | 43 - 78 | -1 | -1 | 62 78 | -1 | 1 | 1 - 78 | -1 | 2 | 7 + 99 | 62 | -1 | 62 + 99 | 62 | 32 | 5 + 1 | 1 | -1 | 62 + 1 | 1 | 32 | 5 + 1 | 1 | -1 | 62 + 1 | 1 | 32 | 5 + 78 | -1 | -1 | 62 + 78 | -1 | 32 | 5 (20 rows) select * from A where exists (select * from B, C where C.j = A.j and exists (select sum(C.i) from C where C.i != 10 and C.i = B.i)) order by 1, 2; @@ -1194,8 +1196,8 @@ select b from qp_csq_t1 where not exists(select * from qp_csq_t2 where y=a); b --- 4 - 6 8 + 6 (3 rows) select b from qp_csq_t1 where not exists(select * from qp_csq_t2 where y=a) order by b; @@ -1272,67 +1274,64 @@ explain select * from A where not exists (select sum(C.i) from C where C.i = A.i -> Seq Scan on a (cost=0.00..431.00 rows=2 width=8) -> Result (cost=0.00..0.00 rows=0 width=1) One-Time Filter: false - Settings: optimizer=on - Optimizer status: Pivotal Optimizer (GPORCA) version 2.42.0 -(8 rows) + Optimizer: GPORCA +(7 rows) select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 0); i | j ----+---- 19 | 5 99 | 62 - 78 | -1 1 | 1 1 | 1 + 78 | -1 (5 rows) explain select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 5 offset 3); QUERY PLAN -------------------------------------------------------------------------------------------------------------- - Result (cost=0.00..1324035.78 rows=2 width=8) - Filter: (subplan) + Result (cost=0.00..1324035.79 rows=5 width=8) + Filter: (SubPlan 1) -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=5 width=8) -> Seq Scan on a (cost=0.00..431.00 rows=2 width=8) SubPlan 1 -> Limit (cost=0.00..431.00 rows=1 width=8) -> Aggregate (cost=0.00..431.00 rows=1 width=8) -> Result (cost=0.00..431.00 rows=1 width=4) - Filter: c.i = $0 - -> Materialize (cost=0.00..431.00 rows=3 width=4) + Filter: (c.i = a.i) + -> Materialize (cost=0.00..431.00 rows=9 width=4) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=9 width=4) -> Seq Scan on c (cost=0.00..431.00 rows=3 width=4) - Settings: optimizer=on - Optimizer status: Pivotal Optimizer (GPORCA) version 2.42.0 -(14 rows) + Optimizer: GPORCA +(13 rows) select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 5 offset 3); i | j ----+---- 19 | 5 + 99 | 62 1 | 1 1 | 1 - 99 | 62 78 | -1 (5 rows) explain select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 1 offset 0); QUERY PLAN -------------------------------------------------------------------------------------------------------------- - Result (cost=0.00..1324035.78 rows=2 width=8) - Filter: (subplan) + Result (cost=0.00..1324035.79 rows=5 width=8) + Filter: (SubPlan 1) -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=5 width=8) -> Seq Scan on a (cost=0.00..431.00 rows=2 width=8) SubPlan 1 -> Limit (cost=0.00..431.00 rows=1 width=8) -> Aggregate (cost=0.00..431.00 rows=1 width=8) -> Result (cost=0.00..431.00 rows=1 width=4) - Filter: c.i = $0 - -> Materialize (cost=0.00..431.00 rows=3 width=4) + Filter: (c.i = a.i) + -> Materialize (cost=0.00..431.00 rows=9 width=4) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=9 width=4) -> Seq Scan on c (cost=0.00..431.00 rows=3 width=4) - Settings: optimizer=on - Optimizer status: Pivotal Optimizer (GPORCA) version 2.42.0 -(14 rows) + Optimizer: GPORCA +(13 rows) select * from A where not exists (select sum(C.i) from C where C.i = A.i limit 1 offset 0); i | j @@ -1347,19 +1346,18 @@ explain select C.j from C where not exists (select max(B.i) from B where C.i = -> Sort (cost=0.00..862.00 rows=2 width=4) Sort Key: c.j -> Hash Anti Join (cost=0.00..862.00 rows=2 width=4) - Hash Cond: c.i = b.i + Hash Cond: (c.i = b.i) -> Seq Scan on c (cost=0.00..431.00 rows=3 width=8) -> Hash (cost=431.00..431.00 rows=1 width=4) -> Result (cost=0.00..431.00 rows=1 width=4) - Filter: NOT (max(b.i)) IS NULL + Filter: (NOT ((max(b.i)) IS NULL)) -> GroupAggregate (cost=0.00..431.00 rows=2 width=8) - Group By: b.i + Group Key: b.i -> Sort (cost=0.00..431.00 rows=2 width=4) Sort Key: b.i -> Seq Scan on b (cost=0.00..431.00 rows=2 width=4) - Settings: optimizer=on - Optimizer status: Pivotal Optimizer (GPORCA) version 2.34.0 -(17 rows) + Optimizer: GPORCA +(16 rows) select C.j from C where not exists (select max(B.i) from B where C.i = B.i having max(B.i) is not null) order by C.j; j @@ -1373,24 +1371,23 @@ select C.j from C where not exists (select max(B.i) from B where C.i = B.i havi explain select C.j from C where not exists (select max(B.i) from B where C.i = B.i offset 1000) order by C.j; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324036.36 rows=9 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324036.37 rows=9 width=4) Merge Key: c.j - -> Result (cost=0.00..1324036.36 rows=3 width=4) - -> Sort (cost=0.00..1324036.36 rows=3 width=4) + -> Result (cost=0.00..1324036.37 rows=3 width=4) + -> Sort (cost=0.00..1324036.37 rows=3 width=4) Sort Key: c.j - -> Seq Scan on c (cost=0.00..1324036.36 rows=3 width=4) - Filter: (subplan) + -> Seq Scan on c (cost=0.00..1324036.37 rows=3 width=4) + Filter: (SubPlan 1) SubPlan 1 -> Limit (cost=0.00..431.00 rows=1 width=4) -> Aggregate (cost=0.00..431.00 rows=1 width=4) -> Result (cost=0.00..431.00 rows=1 width=4) - Filter: $0 = b.i + Filter: (c.i = b.i) -> Materialize (cost=0.00..431.00 rows=6 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=6 width=4) -> Seq Scan on b (cost=0.00..431.00 rows=2 width=4) - Settings: optimizer=on - Optimizer status: Pivotal Optimizer (GPORCA) version 2.34.0 -(17 rows) + Optimizer: GPORCA +(16 rows) select C.j from C where not exists (select max(B.i) from B where C.i = B.i offset 1000) order by C.j; j @@ -1409,12 +1406,12 @@ select C.j from C where not exists (select max(B.i) from B where C.i = B.i offs explain select C.j from C where not exists (select rank() over (order by B.i) from B where C.i = B.i) order by C.j; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324036.36 rows=9 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324036.79 rows=9 width=4) Merge Key: c.j - -> Result (cost=0.00..1324036.36 rows=3 width=4) - -> Sort (cost=0.00..1324036.36 rows=3 width=4) + -> Result (cost=0.00..1324036.79 rows=3 width=4) + -> Sort (cost=0.00..1324036.79 rows=3 width=4) Sort Key: c.j - -> Seq Scan on c (cost=0.00..1324036.36 rows=3 width=4) + -> Seq Scan on c (cost=0.00..1324036.79 rows=3 width=4) Filter: (SubPlan 1) SubPlan 1 -> WindowAgg (cost=0.00..431.00 rows=1 width=4) @@ -1426,7 +1423,7 @@ explain select C.j from C where not exists (select rank() over (order by B.i) fr -> Materialize (cost=0.00..431.00 rows=6 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=6 width=4) -> Seq Scan on b (cost=0.00..431.00 rows=2 width=4) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (18 rows) select C.j from C where not exists (select rank() over (order by B.i) from B where C.i = B.i) order by C.j; @@ -1439,19 +1436,19 @@ select C.j from C where not exists (select rank() over (order by B.i) from B wh (4 rows) explain select * from A where not exists (select sum(C.i) from C where C.i = A.i group by a.i); - QUERY PLAN ------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=2 width=8) -> Hash Anti Join (cost=0.00..862.00 rows=1 width=8) - Hash Cond: a.i = c.i + Hash Cond: (a.i = c.i) -> Seq Scan on a (cost=0.00..431.00 rows=2 width=8) -> Hash (cost=431.00..431.00 rows=3 width=4) -> GroupAggregate (cost=0.00..431.00 rows=3 width=4) - Group By: c.i + Group Key: c.i -> Sort (cost=0.00..431.00 rows=3 width=4) Sort Key: c.i -> Seq Scan on c (cost=0.00..431.00 rows=3 width=4) - Optimizer status: Pivotal Optimizer (GPORCA) version 2.46.1 + Optimizer: GPORCA (11 rows) select * from A where not exists (select sum(C.i) from C where C.i = A.i group by a.i); @@ -1461,94 +1458,93 @@ select * from A where not exists (select sum(C.i) from C where C.i = A.i group b (1 row) explain select A.i from A where not exists (select B.i from B where B.i in (select C.i from C) and B.i = A.i); - QUERY PLAN ---------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1293.00 rows=2 width=4) - -> Hash Anti Join (cost=0.00..1293.00 rows=1 width=4) - Hash Cond: a.i = b.i - -> Seq Scan on a (cost=0.00..431.00 rows=2 width=4) - -> Hash (cost=862.00..862.00 rows=2 width=4) - -> Hash Semi Join (cost=0.00..862.00 rows=2 width=4) - Hash Cond: b.i = c.i + -> Hash Right Anti Join (cost=0.00..1293.00 rows=1 width=4) + Hash Cond: (a.i = b.i) + -> Hash Right Semi Join (cost=0.00..862.00 rows=2 width=4) + Hash Cond: (b.i = c.i) + -> Seq Scan on c (cost=0.00..431.00 rows=3 width=4) + -> Hash (cost=431.00..431.00 rows=2 width=4) -> Seq Scan on b (cost=0.00..431.00 rows=2 width=4) - -> Hash (cost=431.00..431.00 rows=3 width=4) - -> Seq Scan on c (cost=0.00..431.00 rows=3 width=4) - Settings: optimizer=on - Optimizer status: Pivotal Optimizer (GPORCA) version 2.40.3 -(12 rows) + -> Hash (cost=431.00..431.00 rows=2 width=4) + -> Seq Scan on a (cost=0.00..431.00 rows=2 width=4) + Optimizer: GPORCA +(11 rows) select A.i from A where not exists (select B.i from B where B.i in (select C.i from C) and B.i = A.i); i ---- + 19 99 78 - 19 (3 rows) explain select * from B where not exists (select * from C,A where C.i in (select C.i from C where C.i = A.i and C.i != 10) AND B.i = C.i); QUERY PLAN --------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324895.10 rows=1 width=8) - -> Hash Anti Join (cost=0.00..1324895.10 rows=1 width=8) - Hash Cond: b.i = c.i + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324895.11 rows=1 width=8) + -> Hash Anti Join (cost=0.00..1324895.11 rows=1 width=8) + Hash Cond: (b.i = c.i) -> Seq Scan on b (cost=0.00..431.00 rows=2 width=8) - -> Hash (cost=1324464.10..1324464.10 rows=13 width=4) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1324464.10 rows=13 width=4) + -> Hash (cost=1324464.11..1324464.11 rows=3 width=4) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1324464.11 rows=3 width=4) Hash Key: c.i - -> Hash Semi Join (cost=0.00..1324464.10 rows=13 width=4) - Hash Cond: a.i = c_1.i AND c.i = c_1.i - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1324033.09 rows=15 width=8) + -> Hash Semi Join (cost=0.00..1324464.11 rows=3 width=4) + Hash Cond: ((a.i = c_1.i) AND (c.i = c_1.i)) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1324033.10 rows=15 width=8) Hash Key: a.i - -> Nested Loop (cost=0.00..1324033.09 rows=15 width=8) + -> Nested Loop (cost=0.00..1324033.10 rows=15 width=8) Join Filter: true -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..431.00 rows=5 width=4) -> Seq Scan on a (cost=0.00..431.00 rows=2 width=4) -> Seq Scan on c (cost=0.00..431.00 rows=3 width=4) -> Hash (cost=431.00..431.00 rows=3 width=4) -> Seq Scan on c c_1 (cost=0.00..431.00 rows=3 width=4) - Filter: i <> 10 - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 + Filter: (i <> 10) + Optimizer: GPORCA (20 rows) select * from B where not exists (select * from C,A where C.i in (select C.i from C where C.i = A.i and C.i != 10) AND B.i = C.i); i | j ----+---- - 88 | 1 - -1 | 62 2 | 7 + -1 | 62 32 | 5 + 88 | 1 (4 rows) explain select * from A where A.i in (select C.j from C,B where B.i in (select i from C)); QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324895.30 rows=5 width=8) - -> Hash Join (cost=0.00..1324895.30 rows=2 width=8) - Hash Cond: a.i = c.j + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324895.31 rows=5 width=8) + -> Hash Join (cost=0.00..1324895.31 rows=2 width=8) + Hash Cond: (a.i = c.j) -> Seq Scan on a (cost=0.00..431.00 rows=2 width=8) - -> Hash (cost=1324464.30..1324464.30 rows=3 width=4) - -> GroupAggregate (cost=0.00..1324464.30 rows=3 width=4) + -> Hash (cost=1324464.31..1324464.31 rows=3 width=4) + -> GroupAggregate (cost=0.00..1324464.31 rows=3 width=4) Group Key: c.j - -> Sort (cost=0.00..1324464.30 rows=3 width=4) + -> Sort (cost=0.00..1324464.31 rows=3 width=4) Sort Key: c.j - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1324464.30 rows=3 width=4) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1324464.31 rows=3 width=4) Hash Key: c.j - -> GroupAggregate (cost=0.00..1324464.30 rows=3 width=4) + -> GroupAggregate (cost=0.00..1324464.31 rows=3 width=4) Group Key: c.j - -> Sort (cost=0.00..1324464.30 rows=18 width=4) + -> Sort (cost=0.00..1324464.31 rows=18 width=4) Sort Key: c.j - -> Hash Semi Join (cost=0.00..1324464.30 rows=18 width=4) - Hash Cond: b.i = c_1.i - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1324033.29 rows=18 width=8) + -> Hash Semi Join (cost=0.00..1324464.31 rows=18 width=4) + Hash Cond: (b.i = c_1.i) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1324033.31 rows=18 width=8) Hash Key: b.i - -> Nested Loop (cost=0.00..1324033.29 rows=18 width=8) + -> Nested Loop (cost=0.00..1324033.31 rows=18 width=8) Join Filter: true -> Broadcast Motion 3:3 (slice4; segments: 3) (cost=0.00..431.00 rows=6 width=4) -> Seq Scan on b (cost=0.00..431.00 rows=2 width=4) -> Seq Scan on c (cost=0.00..431.00 rows=3 width=4) -> Hash (cost=431.00..431.00 rows=3 width=4) -> Seq Scan on c c_1 (cost=0.00..431.00 rows=3 width=4) - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 + Optimizer: GPORCA (27 rows) select * from A where A.i in (select C.j from C,B where B.i in (select i from C)); @@ -1563,7 +1559,7 @@ explain select * from A where not exists (select sum(c.i) from C where C.i = A.i --------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=2 width=8) -> Hash Anti Join (cost=0.00..862.00 rows=1 width=8) - Hash Cond: a.i = c.i + Hash Cond: (a.i = c.i) -> Seq Scan on a (cost=0.00..431.00 rows=2 width=8) -> Hash (cost=431.00..431.00 rows=2 width=4) -> GroupAggregate (cost=0.00..431.00 rows=2 width=4) @@ -1571,16 +1567,16 @@ explain select * from A where not exists (select sum(c.i) from C where C.i = A.i -> Sort (cost=0.00..431.00 rows=2 width=4) Sort Key: c.i -> Seq Scan on c (cost=0.00..431.00 rows=2 width=4) - Filter: i > 3 - Optimizer: Pivotal Optimizer (GPORCA) version 2.55.13 + Filter: (i > 3) + Optimizer: GPORCA (12 rows) select * from A where not exists (select sum(c.i) from C where C.i = A.i group by C.i having c.i > 3); i | j ----+--- - 19 | 5 1 | 1 1 | 1 + 19 | 5 (3 rows) -- ---------------------------------------------------------------------- @@ -1660,10 +1656,10 @@ update D set i = 11111 from C where C.i = D.i and exists (select C.j from C,B wh select * from D; i | j -------+---- - 19 | 5 - 99 | 62 11111 | 1 11111 | 1 + 19 | 5 + 99 | 62 11111 | -1 (5 rows) @@ -1671,11 +1667,11 @@ update D set i = 22222 from C where C.i = D.i and not exists (select C.j from C, select * from D; i | j -------+---- - 11111 | 1 - 11111 | 1 - 11111 | -1 19 | 5 + 11111 | -1 22222 | 62 + 11111 | 1 + 11111 | 1 (5 rows) -- -- -- -- @@ -2261,6 +2257,8 @@ select A.i, B.i, C.j from A, B, C where exists (select C.j from C group by C.j h begin; create table csq_emp(name text, department text, salary numeric); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'name' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into csq_emp values('a','adept',11200.00); insert into csq_emp values('b','adept',22222.00); insert into csq_emp values('c','bdept',99222.00); @@ -2310,6 +2308,8 @@ create table job ( EMPNO VARCHAR(4), jobtitle VARCHAR(20) ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'empno' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into job (EMPNO, Jobtitle) values ('01','Tester'); insert into job (EMPNO, Jobtitle) values ('02','Accountant'); insert into job (EMPNO, Jobtitle) values ('03','Developer'); @@ -3699,32 +3699,32 @@ ANALYZE qp_tab1; ANALYZE qp_tab2; ANALYZE qp_tab3; EXPLAIN SELECT a FROM qp_tab1 f1 LEFT JOIN qp_tab2 on a=c WHERE NOT EXISTS(SELECT 1 FROM qp_tab1 f2 WHERE f1.a = f2.a); - QUERY PLAN -------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1293.00 rows=2 width=4) -> Hash Left Join (cost=0.00..1293.00 rows=1 width=4) - Hash Cond: (qp_tab1.a = qp_tab2.c) + Hash Cond: (f1.a = qp_tab2.c) -> Hash Anti Join (cost=0.00..862.00 rows=1 width=4) - Hash Cond: (qp_tab1.a = qp_tab1_1.a) + Hash Cond: (f1.a = f2.a) -> Seq Scan on qp_tab1 f1 (cost=0.00..431.00 rows=1 width=4) -> Hash (cost=431.00..431.00 rows=1 width=4) -> Seq Scan on qp_tab1 f2 (cost=0.00..431.00 rows=1 width=4) -> Hash (cost=431.00..431.00 rows=1 width=4) -> Seq Scan on qp_tab2 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (11 rows) EXPLAIN SELECT DISTINCT a FROM qp_tab1 WHERE NOT (SELECT TRUE FROM qp_tab2 WHERE EXISTS (SELECT * FROM qp_tab3 WHERE qp_tab2.c = qp_tab3.e)); QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1765377.02 rows=1 width=4) - -> GroupAggregate (cost=0.00..1765377.02 rows=1 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1765377.06 rows=1 width=4) + -> GroupAggregate (cost=0.00..1765377.06 rows=1 width=4) Group Key: qp_tab1.a - -> Sort (cost=0.00..1765377.02 rows=1 width=4) + -> Sort (cost=0.00..1765377.06 rows=1 width=4) Sort Key: qp_tab1.a - -> Result (cost=0.00..1765377.02 rows=1 width=4) + -> Result (cost=0.00..1765377.06 rows=1 width=4) Filter: (NOT (true)) - -> Nested Loop Left Join (cost=0.00..1765377.02 rows=1 width=5) + -> Nested Loop Left Join (cost=0.00..1765377.06 rows=1 width=5) Join Filter: true -> Seq Scan on qp_tab1 (cost=0.00..431.00 rows=1 width=4) -> Assert (cost=0.00..862.00 rows=1 width=1) @@ -3736,10 +3736,11 @@ EXPLAIN SELECT DISTINCT a FROM qp_tab1 WHERE NOT (SELECT TRUE FROM qp_tab2 WHERE -> Hash Semi Join (cost=0.00..862.00 rows=1 width=1) Hash Cond: (qp_tab2.c = qp_tab3.e) -> Seq Scan on qp_tab2 (cost=0.00..431.00 rows=1 width=4) + Filter: (NOT (c IS NULL)) -> Hash (cost=431.00..431.00 rows=1 width=4) -> Seq Scan on qp_tab3 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) -(22 rows) + Optimizer: GPORCA +(23 rows) SELECT DISTINCT a FROM qp_tab1 WHERE NOT (SELECT TRUE FROM qp_tab2 WHERE EXISTS (SELECT * FROM qp_tab3 WHERE qp_tab2.c = qp_tab3.e)); a @@ -3764,13 +3765,13 @@ EXPLAIN SELECT * FROM qp_non_eq_a, qp_non_eq_b WHERE qp_non_eq_a.f = qp_non_eq_b ---------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=2 width=24) -> Hash Join (cost=0.00..862.00 rows=1 width=24) - Hash Cond: qp_non_eq_b.f = qp_non_eq_a.f + Hash Cond: (qp_non_eq_b.f = qp_non_eq_a.f) -> Seq Scan on qp_non_eq_b (cost=0.00..431.00 rows=1 width=12) -> Hash (cost=431.00..431.00 rows=1 width=12) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=12) -> Seq Scan on qp_non_eq_a (cost=0.00..431.00 rows=1 width=12) - Filter: f::text <> '-0'::text - Optimizer: Pivotal Optimizer (GPORCA) version 2.72.0 + Filter: ((f)::text <> '-0'::text) + Optimizer: GPORCA (9 rows) SELECT * FROM qp_non_eq_a, qp_non_eq_b WHERE qp_non_eq_a.f = qp_non_eq_b.f AND qp_non_eq_a.f::text <> '-0'; @@ -3781,38 +3782,38 @@ SELECT * FROM qp_non_eq_a, qp_non_eq_b WHERE qp_non_eq_a.f = qp_non_eq_b.f AND q (2 rows) EXPLAIN SELECT * FROM qp_non_eq_a INNER JOIN qp_non_eq_b ON qp_non_eq_a.f = qp_non_eq_b.f AND CASE WHEN qp_non_eq_b.f::text = '-0' THEN 1 ELSE -1::float8 END < '0'; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=2 width=24) -> Hash Join (cost=0.00..862.00 rows=1 width=24) - Hash Cond: qp_non_eq_a.f = qp_non_eq_b.f + Hash Cond: (qp_non_eq_a.f = qp_non_eq_b.f) -> Seq Scan on qp_non_eq_a (cost=0.00..431.00 rows=1 width=12) -> Hash (cost=431.00..431.00 rows=1 width=12) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=12) -> Seq Scan on qp_non_eq_b (cost=0.00..431.00 rows=1 width=12) - Filter: CASE WHEN f::text = '-0'::text THEN 1::double precision ELSE (-1)::double precision END < 0::double precision - Optimizer: Pivotal Optimizer (GPORCA) version 2.72.0 + Filter: (CASE WHEN ((f)::text = '-0'::text) THEN '1'::double precision ELSE '-1'::double precision END < '0'::double precision) + Optimizer: GPORCA (9 rows) SELECT * FROM qp_non_eq_a INNER JOIN qp_non_eq_b ON qp_non_eq_a.f = qp_non_eq_b.f AND CASE WHEN qp_non_eq_b.f::text = '-0' THEN 1 ELSE -1::float8 END < '0'; i | f | i | f ---+----+---+--- - 2 | -0 | 3 | 0 1 | 0 | 3 | 0 + 2 | -0 | 3 | 0 (2 rows) EXPLAIN SELECT * FROM qp_non_eq_a, qp_non_eq_b WHERE qp_non_eq_a.i = qp_non_eq_b.i AND qp_non_eq_a.i = ANY('{1,2,3}'::integer[]); - QUERY PLAN --------------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=2 width=24) -> Hash Join (cost=0.00..862.00 rows=1 width=24) - Hash Cond: qp_non_eq_a.i = qp_non_eq_b.i + Hash Cond: (qp_non_eq_a.i = qp_non_eq_b.i) -> Seq Scan on qp_non_eq_a (cost=0.00..431.00 rows=1 width=12) - Filter: (i = ANY ('{1,2,3}'::integer[])) AND (i = 1 OR i = 2 OR i = 3) + Filter: ((i = ANY ('{1,2,3}'::integer[])) AND (i = ANY ('{1,2,3}'::integer[]))) -> Hash (cost=431.00..431.00 rows=1 width=12) -> Seq Scan on qp_non_eq_b (cost=0.00..431.00 rows=1 width=12) - Filter: i = 1 OR i = 2 OR i = 3 - Optimizer: Pivotal Optimizer (GPORCA) version 2.72.0 + Filter: (i = ANY ('{1,2,3}'::integer[])) + Optimizer: GPORCA (9 rows) SELECT * FROM qp_non_eq_a, qp_non_eq_b WHERE qp_non_eq_a.i = qp_non_eq_b.i AND qp_non_eq_a.i = ANY('{1,2,3}'::integer[]); @@ -3826,12 +3827,12 @@ EXPLAIN SELECT * FROM qp_non_eq_a, qp_non_eq_b WHERE qp_non_eq_a.i = qp_non_eq_b -------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=1 width=24) -> Hash Join (cost=0.00..862.00 rows=1 width=24) - Hash Cond: qp_non_eq_a.i = qp_non_eq_b.i + Hash Cond: (qp_non_eq_a.i = qp_non_eq_b.i) -> Seq Scan on qp_non_eq_a (cost=0.00..431.00 rows=1 width=12) - Filter: i::numeric = ANY ('{1,2,3}'::numeric[]) + Filter: ((i)::numeric = ANY ('{1,2,3}'::numeric[])) -> Hash (cost=431.00..431.00 rows=1 width=12) -> Seq Scan on qp_non_eq_b (cost=0.00..431.00 rows=1 width=12) - Optimizer: Pivotal Optimizer (GPORCA) version 2.72.0 + Optimizer: GPORCA (8 rows) SELECT * FROM qp_non_eq_a, qp_non_eq_b WHERE qp_non_eq_a.i = qp_non_eq_b.i AND qp_non_eq_a.i = ANY('{1,2,3}'::numeric[]); @@ -3888,15 +3889,15 @@ explain select x1.a, (select count(*) from generate_series(1, x1.a)) from t1 x1; SubPlan 1 -> Aggregate (cost=0.00..0.00 rows=1 width=8) -> Function Scan on generate_series (cost=0.00..0.00 rows=334 width=1) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (6 rows) select x1.a, (select count(*) from generate_series(1, x1.a)) from t1 x1; a | count ---+------- - 1 | 1 2 | 2 3 | 3 + 1 | 1 (3 rows) -- with limit @@ -3911,7 +3912,7 @@ explain select t1.a, (select count(*) c from (select city from supplier limit t1 -> Materialize (cost=0.00..431.00 rows=5 width=1) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=5 width=1) -> Seq Scan on supplier (cost=0.00..431.00 rows=2 width=1) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (9 rows) select t1.a, (select count(*) c from (select city from supplier limit t1.a) x) from t1; @@ -3926,17 +3927,17 @@ select t1.a, (select count(*) c from (select city from supplier limit t1.a) x) f explain select t1.*, (select count(*) as ct from generate_series(1, a), t1) from t1; QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1808684647.64 rows=3 width=16) - -> Seq Scan on t1 (cost=0.00..1808684647.64 rows=334 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1808684649.95 rows=3 width=16) + -> Seq Scan on t1 (cost=0.00..1808684649.95 rows=334 width=16) SubPlan 1 -> Aggregate (cost=0.00..1765431.58 rows=1 width=8) - -> Nested Loop (cost=0.00..1765431.58 rows=1000 width=1) + -> Nested Loop (cost=0.00..1765431.58 rows=3000 width=1) Join Filter: true -> Materialize (cost=0.00..431.00 rows=3 width=1) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=3 width=1) -> Seq Scan on t1 t1_1 (cost=0.00..431.00 rows=1 width=1) -> Function Scan on generate_series (cost=0.00..0.00 rows=334 width=1) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (11 rows) select t1.*, (select count(*) as ct from generate_series(1, a), t1) from t1; @@ -3950,19 +3951,19 @@ select t1.*, (select count(*) as ct from generate_series(1, a), t1) from t1; explain select * from t1 where 0 < (select count(*) from generate_series(1, a), t1); QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1808684647.65 rows=3 width=8) - -> Result (cost=0.00..1808684647.65 rows=1 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1808684649.96 rows=3 width=8) + -> Result (cost=0.00..1808684649.96 rows=1 width=8) Filter: (0 < (SubPlan 1)) - -> Seq Scan on t1 (cost=0.00..1808684647.64 rows=334 width=16) + -> Seq Scan on t1 (cost=0.00..1808684649.95 rows=334 width=16) SubPlan 1 -> Aggregate (cost=0.00..1765431.58 rows=1 width=8) - -> Nested Loop (cost=0.00..1765431.58 rows=1000 width=1) + -> Nested Loop (cost=0.00..1765431.58 rows=3000 width=1) Join Filter: true -> Materialize (cost=0.00..431.00 rows=3 width=1) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=3 width=1) -> Seq Scan on t1 t1_1 (cost=0.00..431.00 rows=1 width=1) -> Function Scan on generate_series (cost=0.00..0.00 rows=334 width=1) - Optimizer: PQO version 3.27.0 + Optimizer: GPORCA (13 rows) select * from t1 where 0 < (select count(*) from generate_series(1, a), t1); diff --git a/src/test/regress/expected/qp_join_universal_optimizer.out b/src/test/regress/expected/qp_join_universal_optimizer.out index 3bec51ee4f3..986307b4f6a 100644 --- a/src/test/regress/expected/qp_join_universal_optimizer.out +++ b/src/test/regress/expected/qp_join_universal_optimizer.out @@ -40,7 +40,7 @@ create table part (c1 int, c2 int) partition by list(c2) ( partition part1 values (1, 2, 3, 4), partition part2 values (5, 6, 7), partition part3 values (8, 9, 0)); -NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c1' as the Greenplum Database data distribution key for this table. +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c1' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into part select i, i%10 from generate_series(1, 999) i; -- const tvf (universal) @@ -81,7 +81,7 @@ explain (analyze, costs off, timing off, summary off) select * from dist join co -> Result (actual rows=1 loops=1) Filter: ((1) = 1) -> Result (actual rows=1 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) explain (analyze, costs off, timing off, summary off) select * from dist join unnest_arr on dist.c1 = unnest_arr.c1; @@ -97,7 +97,7 @@ explain (analyze, costs off, timing off, summary off) select * from dist join un -> Result (actual rows=7 loops=1) -> ProjectSet (actual rows=7 loops=1) -> Result (actual rows=1 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) explain (analyze, costs off, timing off, summary off) select * from dist join gen_series on dist.c1 = gen_series.c1; @@ -112,7 +112,7 @@ explain (analyze, costs off, timing off, summary off) select * from dist join ge Buckets: 524288 Batches: 1 Memory Usage: 4097kB -> ProjectSet (actual rows=21 loops=1) -> Result (actual rows=1 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) -- randomly distributed ⋈ universal @@ -128,47 +128,47 @@ explain (analyze, timing off, summary off) select * from rand join const_tvf(1) Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.02 rows=1 width=8) (actual rows=1 loops=1) -> Hash Join (cost=0.00..431.02 rows=1 width=8) (actual rows=1 loops=1) Hash Cond: (c1 = (1)) - Extra Text: (seg2) Hash chain length 1.0 avg, 1 max, using 1 of 524288 buckets. + Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 1 of 524288 buckets. -> Seq Scan on rand (cost=0.00..431.02 rows=1 width=4) (actual rows=1 loops=1) Filter: (c1 = 1) - Rows Removed by Filter: 322 + Rows Removed by Filter: 336 -> Hash (cost=0.00..0.00 rows=1 width=4) (actual rows=1 loops=1) Buckets: 524288 Batches: 1 Memory Usage: 4097kB -> Result (cost=0.00..0.00 rows=1 width=4) (actual rows=1 loops=1) Filter: ((1) = 1) -> Result (cost=0.00..0.00 rows=1 width=1) (actual rows=1 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) explain (analyze, timing off, summary off) select * from rand join unnest_arr on rand.c1 = unnest_arr.c1; QUERY PLAN -------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.11 rows=999 width=8) (actual rows=3 loops=1) - -> Hash Join (cost=0.00..431.08 rows=333 width=8) (actual rows=2 loops=1) + -> Hash Join (cost=0.00..431.08 rows=333 width=8) (actual rows=1 loops=1) Hash Cond: (c1 = (((unnest('{-3,-2,-1,0,1,2,3}'::text[])))::integer)) Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 7 of 524288 buckets. - -> Seq Scan on rand (cost=0.00..431.01 rows=333 width=4) (actual rows=338 loops=1) + -> Seq Scan on rand (cost=0.00..431.01 rows=333 width=4) (actual rows=343 loops=1) -> Hash (cost=0.00..0.00 rows=1 width=4) (actual rows=7 loops=1) Buckets: 524288 Batches: 1 Memory Usage: 4097kB -> Result (cost=0.00..0.00 rows=1 width=4) (actual rows=7 loops=1) -> ProjectSet (cost=0.00..0.00 rows=1 width=4) (actual rows=7 loops=1) -> Result (cost=0.00..0.00 rows=1 width=1) (actual rows=1 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) explain (analyze, timing off, summary off) select * from rand join gen_series on rand.c1 = gen_series.c1; QUERY PLAN --------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.11 rows=999 width=8) (actual rows=10 loops=1) - -> Hash Join (cost=0.00..431.08 rows=333 width=8) (actual rows=7 loops=1) + -> Hash Join (cost=0.00..431.08 rows=333 width=8) (actual rows=5 loops=1) Hash Cond: (c1 = (generate_series('-10'::integer, 10))) - Extra Text: (seg2) Hash chain length 1.0 avg, 1 max, using 21 of 524288 buckets. - -> Seq Scan on rand (cost=0.00..431.01 rows=333 width=4) (actual rows=338 loops=1) + Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 21 of 524288 buckets. + -> Seq Scan on rand (cost=0.00..431.01 rows=333 width=4) (actual rows=343 loops=1) -> Hash (cost=0.00..0.00 rows=1 width=4) (actual rows=21 loops=1) Buckets: 524288 Batches: 1 Memory Usage: 4097kB -> ProjectSet (cost=0.00..0.00 rows=1 width=4) (actual rows=21 loops=1) -> Result (cost=0.00..0.00 rows=1 width=1) (actual rows=1 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) -- replicated ⋈ universal @@ -181,9 +181,9 @@ explain (analyze, costs off, timing off, summary off) select * from rep join con Gather Motion 3:1 (slice1; segments: 3) (actual rows=1 loops=1) -> Hash Join (actual rows=1 loops=1) Hash Cond: ((1) = c1) - Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 1 of 524288 buckets. + Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 1 of 524288 buckets. -> Result (actual rows=1 loops=1) - One-Time Filter: (gp_execution_segment() = 1) + One-Time Filter: (gp_execution_segment() = 0) -> Result (actual rows=1 loops=1) Filter: ((1) = 1) -> Result (actual rows=1 loops=1) @@ -192,7 +192,7 @@ explain (analyze, costs off, timing off, summary off) select * from rep join con -> Seq Scan on rep (actual rows=1 loops=1) Filter: (c1 = 1) Rows Removed by Filter: 998 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (15 rows) explain (analyze, costs off, timing off, summary off) select * from rep join unnest_arr on rep.c1 = unnest_arr.c1; @@ -201,16 +201,16 @@ explain (analyze, costs off, timing off, summary off) select * from rep join unn Gather Motion 3:1 (slice1; segments: 3) (actual rows=3 loops=1) -> Hash Join (actual rows=3 loops=1) Hash Cond: ((((unnest('{-3,-2,-1,0,1,2,3}'::text[])))::integer) = c1) - Extra Text: (seg2) Hash chain length 1.0 avg, 1 max, using 999 of 524288 buckets. + Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 999 of 524288 buckets. -> Result (actual rows=7 loops=1) - One-Time Filter: (gp_execution_segment() = 2) + One-Time Filter: (gp_execution_segment() = 0) -> Result (actual rows=7 loops=1) -> ProjectSet (actual rows=7 loops=1) -> Result (actual rows=1 loops=1) -> Hash (actual rows=999 loops=1) Buckets: 524288 Batches: 1 Memory Usage: 4132kB -> Seq Scan on rep (actual rows=999 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) explain (analyze, costs off, timing off, summary off) select * from rep join gen_series on rep.c1 = gen_series.c1; @@ -219,15 +219,15 @@ explain (analyze, costs off, timing off, summary off) select * from rep join gen Gather Motion 3:1 (slice1; segments: 3) (actual rows=10 loops=1) -> Hash Join (actual rows=10 loops=1) Hash Cond: ((generate_series('-10'::integer, 10)) = c1) - Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 999 of 524288 buckets. + Extra Text: (seg2) Hash chain length 1.0 avg, 1 max, using 999 of 524288 buckets. -> Result (actual rows=21 loops=1) - One-Time Filter: (gp_execution_segment() = 1) + One-Time Filter: (gp_execution_segment() = 2) -> ProjectSet (actual rows=21 loops=1) -> Result (actual rows=1 loops=1) -> Hash (actual rows=999 loops=1) Buckets: 524288 Batches: 1 Memory Usage: 4132kB -> Seq Scan on rep (actual rows=999 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) -- partitioned ⋈ universal @@ -251,7 +251,7 @@ explain (analyze, costs off, timing off, summary off) select * from part join co -> Result (actual rows=1 loops=1) Filter: ((1) = 1) -> Result (actual rows=1 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (15 rows) explain (analyze, costs off, timing off, summary off) select * from part join unnest_arr on part.c2 = unnest_arr.c1; @@ -270,7 +270,7 @@ explain (analyze, costs off, timing off, summary off) select * from part join un -> Result (actual rows=7 loops=1) -> ProjectSet (actual rows=7 loops=1) -> Result (actual rows=1 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (14 rows) explain (analyze, costs off, timing off, summary off) select * from part join gen_series on part.c2 = gen_series.c1; @@ -288,7 +288,7 @@ explain (analyze, costs off, timing off, summary off) select * from part join ge -> Partition Selector (selector id: $0) (actual rows=21 loops=1) -> ProjectSet (actual rows=21 loops=1) -> Result (actual rows=1 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) -- distributed ⟕ universal @@ -305,7 +305,7 @@ explain (analyze, costs off, timing off, summary off) select * from dist left jo -> Hash (actual rows=1 loops=1) Buckets: 524288 Batches: 1 Memory Usage: 4097kB -> Result (actual rows=1 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) explain (analyze, costs off, timing off, summary off) select * from dist left join unnest_arr on dist.c1 = unnest_arr.c1; @@ -321,7 +321,7 @@ explain (analyze, costs off, timing off, summary off) select * from dist left jo -> Result (actual rows=7 loops=1) -> ProjectSet (actual rows=7 loops=1) -> Result (actual rows=1 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) explain (analyze, costs off, timing off, summary off) select * from dist left join gen_series on dist.c1 = gen_series.c1; @@ -336,7 +336,7 @@ explain (analyze, costs off, timing off, summary off) select * from dist left jo Buckets: 524288 Batches: 1 Memory Usage: 4097kB -> ProjectSet (actual rows=21 loops=1) -> Result (actual rows=1 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) -- universal ⟕ distributed @@ -360,7 +360,7 @@ explain (analyze, costs off, timing off, summary off) select * from unnest_arr l -> Hash (actual rows=340 loops=1) Buckets: 524288 Batches: 1 Memory Usage: 4108kB -> Seq Scan on dist (actual rows=340 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) explain (analyze, costs off, timing off, summary off) select * from gen_series left join dist on dist.c1 = gen_series.c1; @@ -376,7 +376,7 @@ explain (analyze, costs off, timing off, summary off) select * from gen_series l -> Hash (actual rows=340 loops=1) Buckets: 524288 Batches: 1 Memory Usage: 4108kB -> Seq Scan on dist (actual rows=340 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) -- universal ▷ distributed @@ -385,53 +385,52 @@ explain (analyze, costs off, timing off, summary off) select * from gen_series l -- it needs to be deduplicated. This is achieved by a hash -- filter (duplicate-sensitive hash motion). explain (analyze, costs off, timing off, summary off) select * from const_tvf(1) ct(c1) where not exists (select 1 from dist where dist.c1 = ct.c1); - QUERY PLAN ------------------------------------------------------------------------------------- - Hash Anti Join (actual rows=0 loops=1) - Hash Cond: ((1) = c1) - Extra Text: Hash chain length 1.0 avg, 1 max, using 1 of 524288 buckets. - -> Result (actual rows=1 loops=1) - -> Hash (actual rows=1 loops=1) - Buckets: 524288 Batches: 1 Memory Usage: 4097kB - -> Result (actual rows=1 loops=1) - -> Gather Motion 3:1 (slice1; segments: 3) (actual rows=1 loops=1) - -> Seq Scan on dist (actual rows=1 loops=1) - Filter: (c1 = 1) - Rows Removed by Filter: 321 - Optimizer: Pivotal Optimizer (GPORCA) -(12 rows) + QUERY PLAN +------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (actual rows=0 loops=1) + -> Hash Right Anti Join (actual rows=0 loops=1) + Hash Cond: ((1) = c1) + -> Seq Scan on dist (actual rows=1 loops=1) + Filter: (c1 = 1) + Rows Removed by Filter: 321 + -> Hash (actual rows=1 loops=1) + Buckets: 524288 Batches: 1 Memory Usage: 4097kB + -> Result (actual rows=1 loops=1) + -> Result (actual rows=1 loops=1) + Optimizer: GPORCA +(11 rows) explain (analyze, costs off, timing off, summary off) select * from unnest_arr where not exists (select 1 from dist where dist.c1 = unnest_arr.c1); - QUERY PLAN ---------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=4 loops=1) - -> Hash Anti Join (actual rows=3 loops=1) + -> Hash Right Anti Join (actual rows=3 loops=1) Hash Cond: ((((unnest('{-3,-2,-1,0,1,2,3}'::text[])))::integer) = c1) - Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 322 of 524288 buckets. - -> Result (actual rows=4 loops=1) - -> Result (actual rows=7 loops=1) - -> ProjectSet (actual rows=7 loops=1) - -> Result (actual rows=1 loops=1) - -> Hash (actual rows=340 loops=1) - Buckets: 524288 Batches: 1 Memory Usage: 4110kB - -> Seq Scan on dist (actual rows=340 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 4 of 524288 buckets. + -> Seq Scan on dist (actual rows=340 loops=1) + -> Hash (actual rows=4 loops=1) + Buckets: 524288 Batches: 1 Memory Usage: 4097kB + -> Result (actual rows=4 loops=1) + -> Result (actual rows=7 loops=1) + -> ProjectSet (actual rows=7 loops=1) + -> Result (actual rows=1 loops=1) + Optimizer: GPORCA (12 rows) explain (analyze, costs off, timing off, summary off) select * from gen_series where not exists (select 1 from dist where dist.c1 = gen_series.c1); - QUERY PLAN ---------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (actual rows=11 loops=1) - -> Hash Anti Join (actual rows=6 loops=1) + -> Hash Right Anti Join (actual rows=6 loops=1) Hash Cond: ((generate_series('-10'::integer, 10)) = c1) - Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 322 of 524288 buckets. - -> Result (actual rows=8 loops=1) - -> ProjectSet (actual rows=21 loops=1) - -> Result (actual rows=1 loops=1) - -> Hash (actual rows=340 loops=1) - Buckets: 524288 Batches: 1 Memory Usage: 4110kB - -> Seq Scan on dist (actual rows=340 loops=1) - Optimizer: Pivotal Optimizer (GPORCA) + Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 7 of 524288 buckets. + -> Seq Scan on dist (actual rows=340 loops=1) + -> Hash (actual rows=8 loops=1) + Buckets: 524288 Batches: 1 Memory Usage: 4097kB + -> Result (actual rows=8 loops=1) + -> ProjectSet (actual rows=21 loops=1) + -> Result (actual rows=1 loops=1) + Optimizer: GPORCA (11 rows) -- Testing inner nested loop join @@ -448,7 +447,7 @@ explain (analyze, costs off, timing off, summary off) select * from dist join co Rows Removed by Join Filter: 337 -> Result (actual rows=1 loops=1) -> Seq Scan on dist (actual rows=170 loops=2) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) explain (analyze, costs off, timing off, summary off) select * from dist join unnest_arr on dist.c1 < unnest_arr.c1; @@ -462,7 +461,7 @@ explain (analyze, costs off, timing off, summary off) select * from dist join un -> ProjectSet (actual rows=7 loops=1) -> Result (actual rows=1 loops=1) -> Seq Scan on dist (actual rows=298 loops=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) explain (analyze, costs off, timing off, summary off) select * from dist join gen_series on dist.c1 < gen_series.c1; @@ -475,6 +474,6 @@ explain (analyze, costs off, timing off, summary off) select * from dist join ge -> ProjectSet (actual rows=21 loops=1) -> Result (actual rows=1 loops=1) -> Seq Scan on dist (actual rows=325 loops=22) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) diff --git a/src/test/regress/expected/qp_subquery_optimizer.out b/src/test/regress/expected/qp_subquery_optimizer.out index 84b381dcc8d..b4f8593a3de 100644 --- a/src/test/regress/expected/qp_subquery_optimizer.out +++ b/src/test/regress/expected/qp_subquery_optimizer.out @@ -106,10 +106,10 @@ SELECT '' AS six, f1 AS "Correlated Field", f2 AS "Second Field" six | Correlated Field | Second Field -----+------------------+-------------- | 1 | 2 - | 2 | 3 | 1 | 1 - | 2 | 2 + | 2 | 3 | 3 | 4 + | 2 | 2 | 3 | 3 (6 rows) @@ -119,10 +119,10 @@ SELECT '' AS six, f1 AS "Correlated Field", f3 AS "Second Field" (SELECT f2 FROM SUBSELECT_TBL1 WHERE CAST(upper.f2 AS float) = f3); six | Correlated Field | Second Field -----+------------------+-------------- - | 2 | 4 | 1 | 1 - | 2 | 2 + | 2 | 4 | 3 | 5 + | 2 | 2 | 3 | 3 (5 rows) @@ -132,10 +132,10 @@ SELECT '' AS six, f1 AS "Correlated Field", f3 AS "Second Field" WHERE f2 = CAST(f3 AS integer)); six | Correlated Field | Second Field -----+------------------+-------------- - | 1 | 3 + | 6 | 8 | 2 | 4 | 3 | 5 - | 6 | 8 + | 1 | 3 (4 rows) SELECT '' AS five, f1 AS "Correlated Field" @@ -146,11 +146,11 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery five | Correlated Field ------+------------------ - | 3 + | 2 | 3 | 2 + | 3 | 1 - | 2 (5 rows) begin; @@ -187,31 +187,31 @@ select * from ( SELECT '' AS "col", * FROM join_tab1 AS tx)A; col | i | j | t -----+---+---+------- | 1 | 4 | one - | 2 | 3 | two | 0 | | zero - | 3 | 2 | three - | 4 | 1 | four | 5 | 0 | five | 6 | 6 | six + | 2 | 3 | two + | 3 | 2 | three + | 4 | 1 | four | 7 | 7 | seven + | 8 | 8 | eight | | | null | | 0 | zero - | 8 | 8 | eight (11 rows) select * from ( SELECT '' AS "col", * FROM join_tab1 AS tx) AS A; col | i | j | t -----+---+---+------- - | 8 | 8 | eight | 1 | 4 | one - | 2 | 3 | two | 0 | | zero - | 3 | 2 | three - | 4 | 1 | four | 5 | 0 | five | 6 | 6 | six + | 2 | 3 | two + | 3 | 2 | three + | 4 | 1 | four | 7 | 7 | seven + | 8 | 8 | eight | | | null | | 0 | zero (11 rows) @@ -220,17 +220,17 @@ select * from ( SELECT '' AS "col", * FROM join_tab1 AS tx) AS A; select * from(SELECT '' AS "col", * FROM join_tab1 AS tx) as A(a,b,c); a | b | c | t ---+---+---+------- + | 2 | 3 | two | 3 | 2 | three | 4 | 1 | four - | 5 | 0 | five - | 6 | 6 | six | 7 | 7 | seven + | 8 | 8 | eight | | | null | | 0 | zero - | 8 | 8 | eight | 1 | 4 | one - | 2 | 3 | two | 0 | | zero + | 5 | 0 | five + | 6 | 6 | six (11 rows) @@ -238,23 +238,23 @@ select * from(SELECT '' AS "col", t1.a, t2.e FROM join_tab1 t1 (a, b, c), join_t WHERE t1.a = t2.d)as A; col | a | e -----+---+---- - | 3 | -3 | 5 | -5 | 5 | -5 | 1 | -1 + | 0 | | 2 | 2 + | 3 | -3 | 2 | 4 - | 0 | (7 rows) select * from join_tab1 where exists(select * from join_tab2 where join_tab1.i=join_tab2.i); i | j | t ---+---+------- + 2 | 3 | two 3 | 2 | three 5 | 0 | five 1 | 4 | one - 2 | 3 | two 0 | | zero (5 rows) @@ -418,8 +418,8 @@ select name from emp_list where sal>(select avg(sal) from emp_list); select name from emp_list where sal<(select avg(sal) from emp_list); name ---------------------- - empone emptwo + empone (2 rows) @@ -469,24 +469,24 @@ select i,j,t from (select * from (select i,j,t from join_tab1)as dtab1 UNION select * from(select i,j,t from join_tab4) as dtab2 )as mtab; i | j | t ---+---+-------- - 1 | 7 | sunday - 3 | 5 | tueday - 4 | 1 | four - 6 | 2 | friday - | | null + 0 | | zero 1 | 4 | one - 2 | 6 | monday + 1 | 7 | sunday 5 | 0 | five 5 | 3 | thuday + 6 | 2 | friday 6 | 6 | six - 7 | 7 | seven - 8 | 8 | eight - | 0 | zero - 0 | | zero 2 | 3 | two + 2 | 6 | monday 3 | 2 | three + 3 | 5 | tueday + 4 | 1 | four 4 | 4 | wedday 7 | 1 | satday + 7 | 7 | seven + 8 | 8 | eight + | 0 | zero + | | null (18 rows) @@ -525,7 +525,7 @@ FROM subselect_tbl1 out; -> Seq Scan on join_tab1 -> Hash -> Seq Scan on join_tab2 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (15 rows) SELECT (SELECT join_tab1.i - join_tab2.i @@ -550,8 +550,8 @@ SELECT (SELECT join_tab1.i - join_tab2.i FROM join_tab1, join_tab2 WHERE join_tab1.i = join_tab2.i and out1.i = out2.i LIMIT 1) as x FROM join_tab1 out1, join_tab2 out2; - QUERY PLAN -------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -570,7 +570,7 @@ FROM join_tab1 out1, join_tab2 out2; -> Seq Scan on join_tab1 -> Hash -> Seq Scan on join_tab2 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (19 rows) SELECT (SELECT join_tab1.i - join_tab2.i @@ -579,13 +579,13 @@ SELECT (SELECT join_tab1.i - join_tab2.i FROM join_tab1 out1, join_tab2 out2; x --- - - 0 + 0 + 0 @@ -602,7 +602,6 @@ FROM join_tab1 out1, join_tab2 out2; - 0 @@ -612,16 +611,13 @@ FROM join_tab1 out1, join_tab2 out2; - 0 - 0 - 0 @@ -629,7 +625,6 @@ FROM join_tab1 out1, join_tab2 out2; - 0 @@ -653,6 +648,9 @@ FROM join_tab1 out1, join_tab2 out2; + 0 + 0 + @@ -676,8 +674,10 @@ FROM join_tab1 out1, join_tab2 out2; + 0 + 0 (99 rows) -- Same, in an outer join @@ -691,8 +691,8 @@ SELECT (SELECT coalesce(join_tab1.i + join_tab2.i, 0) >= 0 FROM join_tab1 LEFT JOIN join_tab2 ON join_tab1.i = join_tab2.i and out.f1 > 0 LIMIT 1) as x FROM subselect_tbl1 out; - QUERY PLAN ----------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------- Result -> Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on subselect_tbl1 "out" @@ -707,7 +707,7 @@ FROM subselect_tbl1 out; -> Materialize -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on join_tab2 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (15 rows) SELECT (SELECT coalesce(join_tab1.i + join_tab2.i, 0) >= 0 @@ -731,8 +731,8 @@ SELECT (SELECT coalesce(join_tab1.i + join_tab2.i, 0) >= 0 FROM join_tab1 LEFT JOIN join_tab2 ON join_tab1.i = join_tab2.i and out1.i = out2.i LIMIT 1) as x FROM join_tab1 out1, join_tab2 out2; - QUERY PLAN ------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------- Result -> Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop @@ -751,7 +751,7 @@ FROM join_tab1 out1, join_tab2 out2; -> Materialize -> Gather Motion 3:1 (slice3; segments: 3) -> Seq Scan on join_tab2 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (19 rows) SELECT (SELECT coalesce(join_tab1.i + join_tab2.i, 0) >= 0 @@ -990,8 +990,8 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery a | b ---+--- - 3 | 4 5 | + 3 | 4 (2 rows) select t1.a, t2.b from t1 left join t2 on (t1.a=t2.a and ((t1.a,t2.b) not in (select i1.a,i1.b from i1))); @@ -999,9 +999,9 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery a | b ---+--- - 1 | - 3 | 4 5 | + 3 | 4 + 1 | (3 rows) -- @@ -1012,8 +1012,8 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery a | b ---+--- - 3 | 4 5 | + 3 | 4 | 8 (3 rows) @@ -1023,11 +1023,11 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery a | b ---+--- - 3 | 4 - 5 | - | 8 1 | | 2 + 3 | 4 + | 8 + 5 | (5 rows) -- @@ -1062,10 +1062,10 @@ commit; select Tbl01.*,foo(Tbl01.a) as foo from Tbl01; -- showing foo values a | b | c | foo ---+----+----+----- - 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | | 11 | 12 | 13 + 1 | 2 | 3 | (4 rows) select Tbl01.* from Tbl01 where foo(Tbl01.a) not in (select a from Tbl03); @@ -1075,8 +1075,7 @@ select Tbl01.* from Tbl01 where foo(Tbl01.a) not in (select a from Tbl03); (1 row) create table Tbl02 as select Tbl01.*,foo(Tbl01.a) as foo from Tbl01; -NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'a' as the Apache Cloudberry data distribution key for this table. -HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause. Creating a NULL policy entry. select Tbl02.* from Tbl02 where foo not in (select a from Tbl03); a | b | c | foo ---+----+----+----- @@ -1085,18 +1084,32 @@ select Tbl02.* from Tbl02 where foo not in (select a from Tbl03); begin; create table Tbl04(a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into Tbl04 values(1,2),(3,4),(5,6); create table Tbl05(a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into Tbl05 values(1,2); create table Tbl06(a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into Tbl06 values(1,2),(3,4); create table i3(a int not null, b int not null); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into i3 values(1,2); create table Tbl07(a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into Tbl07 values(1,2),(3,4),(null,null); create table Tbl08(a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into Tbl08 values(1,2),(3,4),(null,null); create table Tbl09(a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into Tbl09 values(1,2),(5,null),(null,8); analyze Tbl04; analyze Tbl05; @@ -1134,8 +1147,8 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery a | b ---+--- - 3 | 4 5 | 6 + 3 | 4 (2 rows) select Tbl04.* from Tbl04 where (Tbl04.a,Tbl04.b) not in (select Tbl07.a,Tbl07.b from Tbl07 left join Tbl08 on (Tbl07.a=Tbl08.a) where Tbl07.a = 1 and Tbl07.b = 2); -- expected: (3,4),(5,6) @@ -1189,8 +1202,8 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery a | b ---+--- - 3 | 4 5 | 6 + 3 | 4 (2 rows) select Tbl04.* from Tbl04 where (Tbl04.a,Tbl04.b) not in (select Tbl05.a,Tbl05.b from Tbl05,i3 where Tbl05.a < i3.a and Tbl05.b > i3.b); @@ -1209,8 +1222,8 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery a | b ---+--- - 3 | 4 5 | 6 + 3 | 4 (2 rows) select Tbl04.* from Tbl04 where (Tbl04.a,Tbl04.b) not in ((1,2)); @@ -1262,8 +1275,8 @@ DETAIL: Falling back to Postgres-based planner because GPORCA does not support select Tbl04.* from Tbl04 where Tbl04.a NOT IN (select Tbl09.a from Tbl09 where Tbl09.b is null); -- (1,2) (3,4) a | b ---+--- - 3 | 4 1 | 2 + 3 | 4 (2 rows) select Tbl04.* from Tbl04 where Tbl04.a NOT IN (select i3.a from i3); @@ -1347,9 +1360,9 @@ DETAIL: Falling back to Postgres-based planner because GPORCA does not support select Tbl09.a, Tbl09.b from Tbl09; a | b ---+--- + | 8 1 | 2 5 | - | 8 (3 rows) select Tbl04.* from Tbl04 where (Tbl04.a,Tbl04.b) not in (select Tbl09.a,Tbl09.b from Tbl09); -- expected: (3,4) @@ -1363,8 +1376,8 @@ DETAIL: Falling back to Postgres-based planner because GPORCA does not support select Tbl09.a, Tbl09.b from Tbl09 group by Tbl09.a, Tbl09.b; a | b ---+--- - 5 | | 8 + 5 | 1 | 2 (3 rows) @@ -1437,8 +1450,8 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery a | b ---+--- - 3 | 4 5 | 6 + 3 | 4 (2 rows) -- Cases where the planner "should have" determined not-nullabitlity @@ -1463,9 +1476,13 @@ DETAIL: Falling back to Postgres-based planner because GPORCA does not support -- additional queries drop table if exists Tbl04; create table Tbl04(x int, y int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'x' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into Tbl04 values(1,2); insert into Tbl04 values(3,4); create table Tbl10(x int, y int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'x' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into Tbl10 values(1,null); select * from Tbl04 where (x,y) not in (select x,y from Tbl10); INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner @@ -1521,8 +1538,8 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery a | b --------+---------- - tushar | pednekar rob | klopp + tushar | pednekar (2 rows) SELECT TblText1.a, TblText2.b FROM TblText1 JOIN TblText2 ON TblText1.a = TblText2.a WHERE (( (TblText1.a, TblText2.b) IN (SELECT TblText3.a, TblText3.b FROM TblText3))); @@ -1530,8 +1547,8 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Non-Scalar Subquery a | b ---------+--------- - florian | waas oak | barrett + florian | waas (2 rows) -- @@ -1539,37 +1556,44 @@ DETAIL: Falling back to Postgres-based planner because GPORCA does not support -- begin; create table TabDel1(a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into TabDel1 values(1,2),(3,4),(5,6); create table TabDel2 as select * from TabDel1; +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause. Creating a NULL policy entry. create table TabDel3(a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into TabDel3 values(1,2); create table TabDel4(a int not null, b int not null); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into TabDel4 values(1,2); commit; explain delete from TabDel1 where TabDel1.a not in (select a from TabDel3); -- do not support this because we produce NLASJ QUERY PLAN --------------------------------------------------------------------------------------------------- - Delete on tabdel1 (cost=0.00..862.04 rows=1 width=1) - -> Hash Left Anti Semi (Not-In) Join (cost=0.00..862.00 rows=1 width=18) + Delete on tabdel1 (cost=0.00..862.02 rows=1 width=1) + -> Hash Left Anti Semi (Not-In) Join (cost=0.00..862.00 rows=1 width=14) Hash Cond: (tabdel1.a = tabdel3.a) - -> Seq Scan on tabdel1 (cost=0.00..431.00 rows=1 width=18) - -> Hash (cost=431.00..431.00 rows=1 width=4) - -> Broadcast Motion 3:3 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=4) + -> Seq Scan on tabdel1 (cost=0.00..431.00 rows=1 width=14) + -> Hash (cost=431.00..431.00 rows=3 width=4) + -> Broadcast Motion 3:3 (slice1; segments: 3) (cost=0.00..431.00 rows=3 width=4) -> Seq Scan on tabdel3 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) explain delete from TabDel2 where TabDel2.a not in (select a from TabDel4); -- support this QUERY PLAN --------------------------------------------------------------------------------------------------- - Delete on tabdel2 (cost=0.00..862.03 rows=1 width=1) - -> Hash Left Anti Semi (Not-In) Join (cost=0.00..862.00 rows=1 width=18) + Delete on tabdel2 (cost=0.00..862.02 rows=1 width=1) + -> Hash Left Anti Semi (Not-In) Join (cost=0.00..862.00 rows=1 width=10) Hash Cond: (tabdel2.a = tabdel4.a) - -> Seq Scan on tabdel2 (cost=0.00..431.00 rows=1 width=18) + -> Seq Scan on tabdel2 (cost=0.00..431.00 rows=1 width=14) -> Hash (cost=431.00..431.00 rows=3 width=4) -> Broadcast Motion 3:3 (slice1; segments: 3) (cost=0.00..431.00 rows=3 width=4) -> Seq Scan on tabdel4 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) delete from TabDel2 where TabDel2.a not in (select a from TabDel4); @@ -1612,9 +1636,9 @@ update TblUp2 set a=100 where a not in (select a from TblUp4); select * from TblUp2; a | b -----+--- - 100 | 4 - 1 | 2 100 | 6 + 1 | 2 + 100 | 4 (3 rows) -- @@ -1645,8 +1669,8 @@ select * from subselect_tab1 where (select b from subselect_tab2) is null; select * from subselect_tab1 where b::bool = ( c = any(select c from subselect_tab2)); a | b | c -----+-------+--- - 200 | true | 2 100 | false | 1 + 200 | true | 2 (2 rows) -- ALL subquery deeply nested in a scalar expression @@ -1708,15 +1732,15 @@ INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Inherited tables QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2296.15..4165.55 rows=51935 width=4) - -> Hash Join (cost=2296.15..3473.08 rows=17312 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=2123.03..3992.43 rows=51935 width=4) + -> Hash Join (cost=2123.03..3299.97 rows=17312 width=4) Hash Cond: (append_rel.att1 = test.att1) -> Append (cost=0.00..848.02 rows=51934 width=8) -> Seq Scan on append_rel append_rel_1 (cost=0.00..1.01 rows=1 width=8) -> Seq Scan on append_rel1 append_rel_2 (cost=0.00..293.67 rows=25967 width=8) -> Seq Scan on append_rel2 append_rel_3 (cost=0.00..293.67 rows=25967 width=8) - -> Hash (cost=2283.65..2283.65 rows=1000 width=4) - -> HashAggregate (cost=2280.31..2283.65 rows=1000 width=4) + -> Hash (cost=2110.53..2110.53 rows=1000 width=4) + -> HashAggregate (cost=2107.20..2110.53 rows=1000 width=4) Group Key: test.att1 -> Subquery Scan on test (cost=1021.14..2063.92 rows=17312 width=4) -> Hash Semi Join (cost=1021.14..2063.92 rows=17312 width=8) @@ -1795,8 +1819,8 @@ from ( select unnest(t1.an_array_column) unnested_array_column from table_with_array_column t1, table_with_array_column t2) zz where unnested_array_column is not null; - QUERY PLAN ---------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Result Filter: (NOT ((unnest(t1.an_array_column)) IS NULL)) @@ -1807,7 +1831,7 @@ where unnested_array_column is not null; -> Materialize -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on table_with_array_column t2 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) select * @@ -1834,8 +1858,8 @@ from( select (subquery_nonpush_through_1.a in (select a from subquery_nonpush_through_2))::text as xx, subquery_nonpush_through_1.b from subquery_nonpush_through_1,subquery_nonpush_through_2) t where xx='dd'; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Result Filter: ((((hashed SubPlan 1))::text) = 'dd'::text) @@ -1851,8 +1875,8 @@ where xx='dd'; -> Materialize -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on subquery_nonpush_through_2 subquery_nonpush_through_2_1 - Optimizer: Pivotal Optimizer (GPORCA) -(19 rows) + Optimizer: GPORCA +(16 rows) select * from( @@ -1895,8 +1919,9 @@ from ( -> Seq Scan on qp_subquery.a1 Output: a1.a1 Filter: (NOT (a1.a1 IS NULL)) + Settings: optimizer = 'on' Optimizer: GPORCA -(13 rows) +(14 rows) select a1,case when a2 in (select a1::text from a1 where a1 is not null) then 'true' else 'false' end as checkcol from ( @@ -1924,9 +1949,9 @@ create materialized view v as select a, b from t distributed randomly; select * from v where exists (select a from v); a | b ---+--- + 1 | 1 2 | | 3 - 1 | 1 (3 rows) select * from v where exists (select a from v limit 0); @@ -1937,17 +1962,17 @@ select * from v where exists (select a from v limit 0); select * from v where exists (select a from v where a=2); a | b ---+--- + 1 | 1 2 | | 3 - 1 | 1 (3 rows) select * from v where exists (select a from v where a<>2); a | b ---+--- + 1 | 1 2 | | 3 - 1 | 1 (3 rows) select * from v where not exists (select a from v); @@ -1976,9 +2001,9 @@ select * from v where not exists (select a from v where a<>2); select * from v where exists (select b from v); a | b ---+--- + 1 | 1 2 | | 3 - 1 | 1 (3 rows) select * from v where exists (select b from v limit 0); @@ -1994,9 +2019,9 @@ select * from v where exists (select b from v where b=2); select * from v where exists (select b from v where b<>2); a | b ---+--- + 1 | 1 2 | | 3 - 1 | 1 (3 rows) select * from v where not exists (select b from v); @@ -2007,17 +2032,17 @@ select * from v where not exists (select b from v); select * from v where not exists (select b from v limit 0); a | b ---+--- + 1 | 1 2 | | 3 - 1 | 1 (3 rows) select * from v where not exists (select b from v where b=2); a | b ---+--- + 1 | 1 2 | | 3 - 1 | 1 (3 rows) select * from v where not exists (select b from v where b<>2); @@ -2036,9 +2061,9 @@ WHERE EXISTS WHERE t2.param = t1.param); param ------- + 2 3 1 - 2 (3 rows) EXPLAIN (COSTS OFF) SELECT * FROM (SELECT BTRIM(p1.b) AS param FROM tab1 p1 JOIN tab1 p2 USING(a)) t1 @@ -2046,26 +2071,26 @@ WHERE EXISTS (SELECT 1 FROM (SELECT BTRIM(p1.b) AS param FROM tab1 p1 JOIN tab1 p2 USING(a)) t2 WHERE t2.param = t1.param); - QUERY PLAN ---------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join - Hash Cond: (btrim(p1.b) = btrim(p1_1.b)) - -> Hash Join - Hash Cond: (p1.a = p2.a) - -> Seq Scan on tab1 p1 - Filter: (NOT (btrim(b) IS NULL)) - -> Hash - -> Broadcast Motion 3:3 (slice2; segments: 3) - -> Seq Scan on tab1 p2 + -> Hash Right Semi Join + Hash Cond: (btrim(p1_1.b) = btrim(p1.b)) + -> Broadcast Motion 3:3 (slice2; segments: 3) + -> Hash Join + Hash Cond: (p1.a = p2.a) + -> Seq Scan on tab1 p1 + -> Hash + -> Broadcast Motion 3:3 (slice3; segments: 3) + -> Seq Scan on tab1 p2 -> Hash - -> Broadcast Motion 3:3 (slice3; segments: 3) - -> Hash Join - Hash Cond: (p1_1.a = p2_1.a) - -> Seq Scan on tab1 p1_1 - -> Hash - -> Broadcast Motion 3:3 (slice4; segments: 3) - -> Seq Scan on tab1 p2_1 + -> Hash Join + Hash Cond: (p1_1.a = p2_1.a) + -> Seq Scan on tab1 p1_1 + Filter: (NOT (btrim(b) IS NULL)) + -> Hash + -> Broadcast Motion 3:3 (slice4; segments: 3) + -> Seq Scan on tab1 p2_1 Optimizer: GPORCA (19 rows) @@ -2080,8 +2105,8 @@ WHERE EXISTS param ------- 2 - 1 3 + 1 (3 rows) EXPLAIN (COSTS OFF) SELECT * FROM (SELECT BTRIM(p1.b) AS param FROM tab1 p1 JOIN tab1 p2 USING(a)) t1 diff --git a/src/test/regress/expected/rightsemijoin.out b/src/test/regress/expected/rightsemijoin.out new file mode 100644 index 00000000000..c784385d2a7 --- /dev/null +++ b/src/test/regress/expected/rightsemijoin.out @@ -0,0 +1,129 @@ +-- +-- Right Semi / Right Anti Join (GPORCA) +-- +-- GPORCA can build the hash table on the (smaller) left-hand side of a semi or +-- anti join and probe it with the larger right-hand side, which avoids having +-- to de-duplicate the large right side. The behaviour is controlled by the +-- developer GUC optimizer_enable_right_semi_join (ON by default). +-- +-- These cases force GPORCA (set optimizer=on) so the new +-- CPhysicalRightSemiHashJoin / CPhysicalRightAntiSemiHashJoin xforms are +-- exercised; the matching answer file rightsemijoin_optimizer.out captures the +-- right-semi/right-anti plan shapes, while rightsemijoin.out captures the +-- Postgres planner plans. +-- +create schema rsj; +set search_path = rsj, public; +-- stabilize the join method across planners +set enable_nestloop = off; +set enable_mergejoin = off; +create table rsj_small(a int, b int) distributed by (a); +create table rsj_big(a int, b int) distributed by (a); +-- small LHS: 1..50, plus two values absent from rsj_big +insert into rsj_small select i, i from generate_series(1,50) i; +insert into rsj_small values (600001, 1), (600002, 2); +-- large, high-NDV RHS: de-duplicating it would be expensive, so the right-semi +-- plan (build on the small LHS) wins. +insert into rsj_big select i, i from generate_series(1,500000) i; +analyze rsj_small; +analyze rsj_big; +-- +-- Semi join (IN): GUC on -> Hash Right Semi Join (build on small LHS) +-- +set optimizer_enable_right_semi_join = on; +explain (costs off) +select * from rsj_small s where s.a in (select a from rsj_big b); + QUERY PLAN +------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Right Semi Join + Hash Cond: (b.a = s.a) + -> Seq Scan on rsj_big b + -> Hash + -> Seq Scan on rsj_small s + Optimizer: Postgres query optimizer +(7 rows) + +-- GUC off -> regular Hash Semi Join (build on RHS) +set optimizer_enable_right_semi_join = off; +explain (costs off) +select * from rsj_small s where s.a in (select a from rsj_big b); + QUERY PLAN +------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Right Semi Join + Hash Cond: (b.a = s.a) + -> Seq Scan on rsj_big b + -> Hash + -> Seq Scan on rsj_small s + Optimizer: Postgres query optimizer +(7 rows) + +-- +-- Anti join (NOT EXISTS): GUC on -> Hash Right Anti Join (build on small LHS) +-- +set optimizer_enable_right_semi_join = on; +explain (costs off) +select * from rsj_small s where not exists (select 1 from rsj_big b where b.a = s.a); + QUERY PLAN +------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Right Anti Join + Hash Cond: (b.a = s.a) + -> Seq Scan on rsj_big b + -> Hash + -> Seq Scan on rsj_small s + Optimizer: Postgres query optimizer +(7 rows) + +-- GUC off -> regular Hash Anti Join +set optimizer_enable_right_semi_join = off; +explain (costs off) +select * from rsj_small s where not exists (select 1 from rsj_big b where b.a = s.a); + QUERY PLAN +------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Right Anti Join + Hash Cond: (b.a = s.a) + -> Seq Scan on rsj_big b + -> Hash + -> Seq Scan on rsj_small s + Optimizer: Postgres query optimizer +(7 rows) + +-- +-- Correctness: results are identical regardless of the GUC / plan shape. +-- +set optimizer_enable_right_semi_join = on; +select count(*) as semi_on from rsj_small s where s.a in (select a from rsj_big b); + semi_on +--------- + 50 +(1 row) + +select count(*) as anti_on from rsj_small s where not exists (select 1 from rsj_big b where b.a = s.a); + anti_on +--------- + 2 +(1 row) + +set optimizer_enable_right_semi_join = off; +select count(*) as semi_off from rsj_small s where s.a in (select a from rsj_big b); + semi_off +---------- + 50 +(1 row) + +select count(*) as anti_off from rsj_small s where not exists (select 1 from rsj_big b where b.a = s.a); + anti_off +---------- + 2 +(1 row) + +reset optimizer_enable_right_semi_join; +reset enable_nestloop; +reset enable_mergejoin; +reset search_path; +set client_min_messages = warning; +drop schema rsj cascade; +reset client_min_messages; diff --git a/src/test/regress/expected/rightsemijoin_optimizer.out b/src/test/regress/expected/rightsemijoin_optimizer.out new file mode 100644 index 00000000000..00276103d54 --- /dev/null +++ b/src/test/regress/expected/rightsemijoin_optimizer.out @@ -0,0 +1,129 @@ +-- +-- Right Semi / Right Anti Join (GPORCA) +-- +-- GPORCA can build the hash table on the (smaller) left-hand side of a semi or +-- anti join and probe it with the larger right-hand side, which avoids having +-- to de-duplicate the large right side. The behaviour is controlled by the +-- developer GUC optimizer_enable_right_semi_join (ON by default). +-- +-- These cases force GPORCA (set optimizer=on) so the new +-- CPhysicalRightSemiHashJoin / CPhysicalRightAntiSemiHashJoin xforms are +-- exercised; the matching answer file rightsemijoin_optimizer.out captures the +-- right-semi/right-anti plan shapes, while rightsemijoin.out captures the +-- Postgres planner plans. +-- +create schema rsj; +set search_path = rsj, public; +-- stabilize the join method across planners +set enable_nestloop = off; +set enable_mergejoin = off; +create table rsj_small(a int, b int) distributed by (a); +create table rsj_big(a int, b int) distributed by (a); +-- small LHS: 1..50, plus two values absent from rsj_big +insert into rsj_small select i, i from generate_series(1,50) i; +insert into rsj_small values (600001, 1), (600002, 2); +-- large, high-NDV RHS: de-duplicating it would be expensive, so the right-semi +-- plan (build on the small LHS) wins. +insert into rsj_big select i, i from generate_series(1,500000) i; +analyze rsj_small; +analyze rsj_big; +-- +-- Semi join (IN): GUC on -> Hash Right Semi Join (build on small LHS) +-- +set optimizer_enable_right_semi_join = on; +explain (costs off) +select * from rsj_small s where s.a in (select a from rsj_big b); + QUERY PLAN +------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Right Semi Join + Hash Cond: (s.a = b.a) + -> Seq Scan on rsj_big b + -> Hash + -> Seq Scan on rsj_small s + Optimizer: GPORCA +(7 rows) + +-- GUC off -> regular Hash Semi Join (build on RHS) +set optimizer_enable_right_semi_join = off; +explain (costs off) +select * from rsj_small s where s.a in (select a from rsj_big b); + QUERY PLAN +------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Semi Join + Hash Cond: (s.a = b.a) + -> Seq Scan on rsj_small s + -> Hash + -> Seq Scan on rsj_big b + Optimizer: GPORCA +(7 rows) + +-- +-- Anti join (NOT EXISTS): GUC on -> Hash Right Anti Join (build on small LHS) +-- +set optimizer_enable_right_semi_join = on; +explain (costs off) +select * from rsj_small s where not exists (select 1 from rsj_big b where b.a = s.a); + QUERY PLAN +------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Right Anti Join + Hash Cond: (s.a = b.a) + -> Seq Scan on rsj_big b + -> Hash + -> Seq Scan on rsj_small s + Optimizer: GPORCA +(7 rows) + +-- GUC off -> regular Hash Anti Join +set optimizer_enable_right_semi_join = off; +explain (costs off) +select * from rsj_small s where not exists (select 1 from rsj_big b where b.a = s.a); + QUERY PLAN +------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Anti Join + Hash Cond: (s.a = b.a) + -> Seq Scan on rsj_small s + -> Hash + -> Seq Scan on rsj_big b + Optimizer: GPORCA +(7 rows) + +-- +-- Correctness: results are identical regardless of the GUC / plan shape. +-- +set optimizer_enable_right_semi_join = on; +select count(*) as semi_on from rsj_small s where s.a in (select a from rsj_big b); + semi_on +--------- + 50 +(1 row) + +select count(*) as anti_on from rsj_small s where not exists (select 1 from rsj_big b where b.a = s.a); + anti_on +--------- + 2 +(1 row) + +set optimizer_enable_right_semi_join = off; +select count(*) as semi_off from rsj_small s where s.a in (select a from rsj_big b); + semi_off +---------- + 50 +(1 row) + +select count(*) as anti_off from rsj_small s where not exists (select 1 from rsj_big b where b.a = s.a); + anti_off +---------- + 2 +(1 row) + +reset optimizer_enable_right_semi_join; +reset enable_nestloop; +reset enable_mergejoin; +reset search_path; +set client_min_messages = warning; +drop schema rsj cascade; +reset client_min_messages; diff --git a/src/test/regress/expected/rowhints.out b/src/test/regress/expected/rowhints.out index eca9a9bb6a9..aac6e5999c5 100644 --- a/src/test/regress/expected/rowhints.out +++ b/src/test/regress/expected/rowhints.out @@ -4,17 +4,21 @@ -- Row hints have not implments in Postgres-based planner LOAD 'pg_hint_plan'; DROP SCHEMA IF EXISTS rowhints CASCADE; +NOTICE: schema "rowhints" does not exist, skipping CREATE SCHEMA rowhints; SET search_path=rowhints; SET optimizer_trace_fallback=on; -- Setup tables CREATE TABLE my_table(a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE INDEX my_awesome_index ON my_table(a); CREATE TABLE your_table(a int, b int) WITH (appendonly=true); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE INDEX your_awesome_index ON your_table(a); CREATE TABLE our_table(a int, b int) PARTITION BY RANGE (a) (PARTITION p1 START(0) END(100) INCLUSIVE EVERY(20)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE INDEX our_awesome_index ON our_table(a); INSERT INTO my_table SELECT i, i FROM generate_series(1, 100)i; @@ -31,7 +35,7 @@ ANALYZE my_table, your_table, our_table; -------------------------------------------------------------------- -- Baseline no hints EXPLAIN SELECT t1.a, t2.a FROM my_table AS t1, your_table AS t2, our_table AS t3; - QUERY PLAN + QUERY PLAN ------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=20000000000.00..20000017562.79 rows=1000000 width=8) -> Nested Loop (cost=20000000000.00..20000004229.45 rows=333333 width=8) @@ -108,8 +112,8 @@ LOG: statement: /*+ EXPLAIN SELECT t1.a, t2.a FROM my_table AS t1, your_table AS t2, our_table AS t3; LOG: pg_hint_plan: used hint: -Rows(t1 t2 t3 +123) not used hint: +Rows(t1 t2 t3 +123) duplication hint: error hint: \o @@ -145,8 +149,8 @@ LOG: statement: /*+ EXPLAIN SELECT t1.a, t2.a FROM my_table AS t1, your_table AS t2, our_table AS t3; LOG: pg_hint_plan: used hint: -Rows(t1 t2 t3 -123) not used hint: +Rows(t1 t2 t3 -123) duplication hint: error hint: \o @@ -182,8 +186,8 @@ LOG: statement: /*+ EXPLAIN SELECT t1.a, t2.a FROM my_table AS t1, your_table AS t2, our_table AS t3; LOG: pg_hint_plan: used hint: -Rows(t1 t2 t3 *123) not used hint: +Rows(t1 t2 t3 *123) duplication hint: error hint: \o @@ -224,8 +228,8 @@ LOG: statement: /*+ EXPLAIN SELECT * FROM my_table, (SELECT * FROM your_table) AS q; LOG: pg_hint_plan: used hint: -Rows(my_table your_table #123) not used hint: +Rows(my_table your_table #123) duplication hint: error hint: \o @@ -256,8 +260,8 @@ LOG: statement: /*+ EXPLAIN WITH cte AS (SELECT * FROM my_table, (SELECT * FROM your_table) as q) SELECT * FROM cte; LOG: pg_hint_plan: used hint: -Rows(my_table your_table #123) not used hint: +Rows(my_table your_table #123) duplication hint: error hint: \o @@ -326,8 +330,8 @@ LOG: statement: /*+ EXPLAIN SELECT t1.a, t2.a FROM my_table AS t1, your_table AS t2, our_table AS t3; LOG: pg_hint_plan: used hint: -Rows(t1 t2 *123) not used hint: +Rows(t1 t2 *123) duplication hint: error hint: \o @@ -375,17 +379,17 @@ error hint: QUERY PLAN ---------------- Gather Motion 3:1 (slice1; segments: 3) (cost=xxx..xxx rows=100 width=xxx) - -> Hash Semi Join (cost=xxx..xxx rows=33 width=xxx) - Hash Cond: (t1.a = t2.a) - -> Seq Scan on my_table t1 (cost=xxx..xxx rows=33 width=xxx) - -> Hash (cost=xxx..xxx rows=34 width=xxx) - -> Append (cost=xxx..xxx rows=34 width=xxx) - -> Seq Scan on our_table_1_prt_p1_1 t2_1 (cost=xxx..xxx rows=6 width=xxx) - -> Seq Scan on our_table_1_prt_p1_2 t2_2 (cost=xxx..xxx rows=7 width=xxx) - -> Seq Scan on our_table_1_prt_p1_3 t2_3 (cost=xxx..xxx rows=7 width=xxx) - -> Seq Scan on our_table_1_prt_p1_4 t2_4 (cost=xxx..xxx rows=7 width=xxx) - -> Seq Scan on our_table_1_prt_p1_5 t2_5 (cost=xxx..xxx rows=7 width=xxx) - -> Seq Scan on our_table_1_prt_p1_6 t2_6 (cost=xxx..xxx rows=1 width=xxx) + -> Hash Right Semi Join (cost=xxx..xxx rows=33 width=xxx) + Hash Cond: (t2.a = t1.a) + -> Append (cost=xxx..xxx rows=34 width=xxx) + -> Seq Scan on our_table_1_prt_p1_1 t2_1 (cost=xxx..xxx rows=6 width=xxx) + -> Seq Scan on our_table_1_prt_p1_2 t2_2 (cost=xxx..xxx rows=7 width=xxx) + -> Seq Scan on our_table_1_prt_p1_3 t2_3 (cost=xxx..xxx rows=7 width=xxx) + -> Seq Scan on our_table_1_prt_p1_4 t2_4 (cost=xxx..xxx rows=7 width=xxx) + -> Seq Scan on our_table_1_prt_p1_5 t2_5 (cost=xxx..xxx rows=7 width=xxx) + -> Seq Scan on our_table_1_prt_p1_6 t2_6 (cost=xxx..xxx rows=1 width=xxx) + -> Hash (cost=xxx..xxx rows=33 width=xxx) + -> Seq Scan on my_table t1 (cost=xxx..xxx rows=33 width=xxx) Optimizer: Postgres query optimizer \o results/pg_hint_plan.tmpout @@ -428,7 +432,7 @@ error hint: --------------------------------------------------------------------------------------------- SELECT disable_xform('CXformLeftSemiJoin2InnerJoin'); LOG: statement: SELECT disable_xform('CXformLeftSemiJoin2InnerJoin'); - disable_xform + disable_xform ------------------------------------------ CXformLeftSemiJoin2InnerJoin is disabled (1 row) diff --git a/src/test/regress/expected/rpt_joins.out b/src/test/regress/expected/rpt_joins.out index fe4f0e0dcbe..2a162d65ce6 100644 --- a/src/test/regress/expected/rpt_joins.out +++ b/src/test/regress/expected/rpt_joins.out @@ -1,6 +1,10 @@ -- -- Tests for joins between replicated tables -- +-- start_ignore +create extension if not exists gp_debug_numsegments; +NOTICE: extension "gp_debug_numsegments" already exists, skipping +-- end_ignore create schema rpt_joins; set search_path to rpt_joins, public; -- @@ -46,105 +50,105 @@ SELECT '' AS "xxx", * FROM J1_TBL CROSS JOIN J2_TBL; xxx | i | j | t | i | k -----+---+---+-------+---+---- + | 2 | 3 | two | 1 | -1 + | 3 | 2 | three | 1 | -1 + | 4 | 1 | four | 1 | -1 + | 7 | 7 | seven | 1 | -1 | 8 | 8 | eight | 1 | -1 + | | | null | 1 | -1 + | | 0 | zero | 1 | -1 + | 2 | 3 | two | 2 | 2 + | 3 | 2 | three | 2 | 2 + | 4 | 1 | four | 2 | 2 + | 7 | 7 | seven | 2 | 2 | 8 | 8 | eight | 2 | 2 + | | | null | 2 | 2 + | | 0 | zero | 2 | 2 + | 2 | 3 | two | 3 | -3 + | 3 | 2 | three | 3 | -3 + | 4 | 1 | four | 3 | -3 + | 7 | 7 | seven | 3 | -3 | 8 | 8 | eight | 3 | -3 + | | | null | 3 | -3 + | | 0 | zero | 3 | -3 + | 2 | 3 | two | 2 | 4 + | 3 | 2 | three | 2 | 4 + | 4 | 1 | four | 2 | 4 + | 7 | 7 | seven | 2 | 4 | 8 | 8 | eight | 2 | 4 + | | | null | 2 | 4 + | | 0 | zero | 2 | 4 + | 2 | 3 | two | 5 | -5 + | 3 | 2 | three | 5 | -5 + | 4 | 1 | four | 5 | -5 + | 7 | 7 | seven | 5 | -5 | 8 | 8 | eight | 5 | -5 + | | | null | 5 | -5 + | | 0 | zero | 5 | -5 + | 2 | 3 | two | 5 | -5 + | 3 | 2 | three | 5 | -5 + | 4 | 1 | four | 5 | -5 + | 7 | 7 | seven | 5 | -5 | 8 | 8 | eight | 5 | -5 + | | | null | 5 | -5 + | | 0 | zero | 5 | -5 + | 2 | 3 | two | 0 | + | 3 | 2 | three | 0 | + | 4 | 1 | four | 0 | + | 7 | 7 | seven | 0 | | 8 | 8 | eight | 0 | + | | | null | 0 | + | | 0 | zero | 0 | + | 2 | 3 | two | | + | 3 | 2 | three | | + | 4 | 1 | four | | + | 7 | 7 | seven | | | 8 | 8 | eight | | + | | | null | | + | | 0 | zero | | + | 2 | 3 | two | | 0 + | 3 | 2 | three | | 0 + | 4 | 1 | four | | 0 + | 7 | 7 | seven | | 0 | 8 | 8 | eight | | 0 + | | | null | | 0 + | | 0 | zero | | 0 | 1 | 4 | one | 1 | -1 - | 1 | 4 | one | 2 | 2 - | 1 | 4 | one | 3 | -3 - | 1 | 4 | one | 2 | 4 - | 1 | 4 | one | 5 | -5 - | 1 | 4 | one | 5 | -5 - | 1 | 4 | one | 0 | - | 1 | 4 | one | | - | 1 | 4 | one | | 0 - | 2 | 3 | two | 1 | -1 - | 2 | 3 | two | 2 | 2 - | 2 | 3 | two | 3 | -3 - | 2 | 3 | two | 2 | 4 - | 2 | 3 | two | 5 | -5 - | 2 | 3 | two | 5 | -5 - | 2 | 3 | two | 0 | - | 2 | 3 | two | | - | 2 | 3 | two | | 0 | 0 | | zero | 1 | -1 + | 1 | 4 | one | 2 | 2 | 0 | | zero | 2 | 2 + | 1 | 4 | one | 3 | -3 | 0 | | zero | 3 | -3 + | 1 | 4 | one | 2 | 4 | 0 | | zero | 2 | 4 + | 1 | 4 | one | 5 | -5 | 0 | | zero | 5 | -5 + | 1 | 4 | one | 5 | -5 | 0 | | zero | 5 | -5 + | 1 | 4 | one | 0 | | 0 | | zero | 0 | + | 1 | 4 | one | | | 0 | | zero | | + | 1 | 4 | one | | 0 | 0 | | zero | | 0 - | 3 | 2 | three | 1 | -1 - | 3 | 2 | three | 2 | 2 - | 3 | 2 | three | 3 | -3 - | 3 | 2 | three | 2 | 4 - | 3 | 2 | three | 5 | -5 - | 3 | 2 | three | 5 | -5 - | 3 | 2 | three | 0 | - | 3 | 2 | three | | - | 3 | 2 | three | | 0 - | 4 | 1 | four | 1 | -1 - | 4 | 1 | four | 2 | 2 - | 4 | 1 | four | 3 | -3 - | 4 | 1 | four | 2 | 4 - | 4 | 1 | four | 5 | -5 - | 4 | 1 | four | 5 | -5 - | 4 | 1 | four | 0 | - | 4 | 1 | four | | - | 4 | 1 | four | | 0 | 5 | 0 | five | 1 | -1 - | 5 | 0 | five | 2 | 2 - | 5 | 0 | five | 3 | -3 - | 5 | 0 | five | 2 | 4 - | 5 | 0 | five | 5 | -5 - | 5 | 0 | five | 5 | -5 - | 5 | 0 | five | 0 | - | 5 | 0 | five | | - | 5 | 0 | five | | 0 | 6 | 6 | six | 1 | -1 + | 5 | 0 | five | 2 | 2 | 6 | 6 | six | 2 | 2 + | 5 | 0 | five | 3 | -3 | 6 | 6 | six | 3 | -3 + | 5 | 0 | five | 2 | 4 | 6 | 6 | six | 2 | 4 + | 5 | 0 | five | 5 | -5 | 6 | 6 | six | 5 | -5 + | 5 | 0 | five | 5 | -5 | 6 | 6 | six | 5 | -5 + | 5 | 0 | five | 0 | | 6 | 6 | six | 0 | + | 5 | 0 | five | | | 6 | 6 | six | | + | 5 | 0 | five | | 0 | 6 | 6 | six | | 0 - | 7 | 7 | seven | 1 | -1 - | 7 | 7 | seven | 2 | 2 - | 7 | 7 | seven | 3 | -3 - | 7 | 7 | seven | 2 | 4 - | 7 | 7 | seven | 5 | -5 - | 7 | 7 | seven | 5 | -5 - | 7 | 7 | seven | 0 | - | 7 | 7 | seven | | - | 7 | 7 | seven | | 0 - | | | null | 1 | -1 - | | | null | 2 | 2 - | | | null | 3 | -3 - | | | null | 2 | 4 - | | | null | 5 | -5 - | | | null | 5 | -5 - | | | null | 0 | - | | | null | | - | | | null | | 0 - | | 0 | zero | 1 | -1 - | | 0 | zero | 2 | 2 - | | 0 | zero | 3 | -3 - | | 0 | zero | 2 | 4 - | | 0 | zero | 5 | -5 - | | 0 | zero | 5 | -5 - | | 0 | zero | 0 | - | | 0 | zero | | - | | 0 | zero | | 0 (99 rows) -- ambiguous column @@ -158,105 +162,105 @@ SELECT '' AS "xxx", t1.i, k, t FROM J1_TBL t1 CROSS JOIN J2_TBL t2; xxx | i | k | t -----+---+----+------- - | 1 | -1 | one - | 1 | 2 | one - | 1 | -3 | one - | 1 | 4 | one - | 1 | -5 | one - | 1 | -5 | one - | 1 | | one - | 1 | | one - | 1 | 0 | one | 2 | -1 | two - | 2 | 2 | two - | 2 | -3 | two - | 2 | 4 | two - | 2 | -5 | two - | 2 | -5 | two - | 2 | | two - | 2 | | two - | 2 | 0 | two - | 0 | -1 | zero - | 0 | 2 | zero - | 0 | -3 | zero - | 0 | 4 | zero - | 0 | -5 | zero - | 0 | -5 | zero - | 0 | | zero - | 0 | | zero - | 0 | 0 | zero | 3 | -1 | three - | 3 | 2 | three - | 3 | -3 | three - | 3 | 4 | three - | 3 | -5 | three - | 3 | -5 | three - | 3 | | three - | 3 | | three - | 3 | 0 | three | 4 | -1 | four + | 7 | -1 | seven + | 8 | -1 | eight + | | -1 | null + | | -1 | zero + | 2 | 2 | two + | 3 | 2 | three | 4 | 2 | four + | 7 | 2 | seven + | 8 | 2 | eight + | | 2 | null + | | 2 | zero + | 2 | -3 | two + | 3 | -3 | three | 4 | -3 | four + | 7 | -3 | seven + | 8 | -3 | eight + | | -3 | null + | | -3 | zero + | 2 | 4 | two + | 3 | 4 | three | 4 | 4 | four + | 7 | 4 | seven + | 8 | 4 | eight + | | 4 | null + | | 4 | zero + | 2 | -5 | two + | 3 | -5 | three | 4 | -5 | four + | 7 | -5 | seven + | 8 | -5 | eight + | | -5 | null + | | -5 | zero + | 2 | -5 | two + | 3 | -5 | three | 4 | -5 | four + | 7 | -5 | seven + | 8 | -5 | eight + | | -5 | null + | | -5 | zero + | 2 | | two + | 3 | | three | 4 | | four + | 7 | | seven + | 8 | | eight + | | | null + | | | zero + | 2 | | two + | 3 | | three | 4 | | four + | 7 | | seven + | 8 | | eight + | | | null + | | | zero + | 2 | 0 | two + | 3 | 0 | three | 4 | 0 | four + | 7 | 0 | seven + | 8 | 0 | eight + | | 0 | null + | | 0 | zero | 5 | -1 | five - | 5 | 2 | five - | 5 | -3 | five - | 5 | 4 | five - | 5 | -5 | five - | 5 | -5 | five - | 5 | | five - | 5 | | five - | 5 | 0 | five | 6 | -1 | six + | 5 | 2 | five | 6 | 2 | six + | 5 | -3 | five | 6 | -3 | six + | 5 | 4 | five | 6 | 4 | six + | 5 | -5 | five | 6 | -5 | six + | 5 | -5 | five | 6 | -5 | six + | 5 | | five | 6 | | six + | 5 | | five | 6 | | six + | 5 | 0 | five | 6 | 0 | six - | 7 | -1 | seven - | 7 | 2 | seven - | 7 | -3 | seven - | 7 | 4 | seven - | 7 | -5 | seven - | 7 | -5 | seven - | 7 | | seven - | 7 | | seven - | 7 | 0 | seven - | | -1 | null - | | 2 | null - | | -3 | null - | | 4 | null - | | -5 | null - | | -5 | null - | | | null - | | | null - | | 0 | null - | | -1 | zero - | | 2 | zero - | | -3 | zero - | | 4 | zero - | | -5 | zero - | | -5 | zero - | | | zero - | | | zero - | | 0 | zero - | 8 | -1 | eight - | 8 | 2 | eight - | 8 | -3 | eight - | 8 | 4 | eight - | 8 | -5 | eight - | 8 | -5 | eight - | 8 | | eight - | 8 | | eight - | 8 | 0 | eight + | 1 | -1 | one + | 0 | -1 | zero + | 1 | 2 | one + | 0 | 2 | zero + | 1 | -3 | one + | 0 | -3 | zero + | 1 | 4 | one + | 0 | 4 | zero + | 1 | -5 | one + | 0 | -5 | zero + | 1 | -5 | one + | 0 | -5 | zero + | 1 | | one + | 0 | | zero + | 1 | | one + | 0 | | zero + | 1 | 0 | one + | 0 | 0 | zero (99 rows) SELECT '' AS "xxx", ii, tt, kk @@ -265,104 +269,104 @@ SELECT '' AS "xxx", ii, tt, kk xxx | ii | tt | kk -----+----+-------+---- | 1 | one | -1 - | 1 | one | 2 - | 1 | one | -3 - | 1 | one | 4 - | 1 | one | -5 - | 1 | one | -5 - | 1 | one | - | 1 | one | - | 1 | one | 0 - | 2 | two | -1 - | 2 | two | 2 - | 2 | two | -3 - | 2 | two | 4 - | 2 | two | -5 - | 2 | two | -5 - | 2 | two | - | 2 | two | - | 2 | two | 0 | 0 | zero | -1 + | 1 | one | 2 | 0 | zero | 2 + | 1 | one | -3 | 0 | zero | -3 + | 1 | one | 4 | 0 | zero | 4 + | 1 | one | -5 | 0 | zero | -5 + | 1 | one | -5 | 0 | zero | -5 + | 1 | one | | 0 | zero | + | 1 | one | | 0 | zero | + | 1 | one | 0 | 0 | zero | 0 - | 8 | eight | -1 - | 8 | eight | 2 - | 8 | eight | -3 - | 8 | eight | 4 - | 8 | eight | -5 - | 8 | eight | -5 - | 8 | eight | - | 8 | eight | - | 8 | eight | 0 + | 2 | two | -1 | 3 | three | -1 - | 3 | three | 2 - | 3 | three | -3 - | 3 | three | 4 - | 3 | three | -5 - | 3 | three | -5 - | 3 | three | - | 3 | three | - | 3 | three | 0 | 4 | four | -1 + | 7 | seven | -1 + | 8 | eight | -1 + | | null | -1 + | | zero | -1 + | 2 | two | 2 + | 3 | three | 2 | 4 | four | 2 + | 7 | seven | 2 + | 8 | eight | 2 + | | null | 2 + | | zero | 2 + | 2 | two | -3 + | 3 | three | -3 | 4 | four | -3 + | 7 | seven | -3 + | 8 | eight | -3 + | | null | -3 + | | zero | -3 + | 2 | two | 4 + | 3 | three | 4 | 4 | four | 4 + | 7 | seven | 4 + | 8 | eight | 4 + | | null | 4 + | | zero | 4 + | 2 | two | -5 + | 3 | three | -5 | 4 | four | -5 + | 7 | seven | -5 + | 8 | eight | -5 + | | null | -5 + | | zero | -5 + | 2 | two | -5 + | 3 | three | -5 | 4 | four | -5 + | 7 | seven | -5 + | 8 | eight | -5 + | | null | -5 + | | zero | -5 + | 2 | two | + | 3 | three | | 4 | four | + | 7 | seven | + | 8 | eight | + | | null | + | | zero | + | 2 | two | + | 3 | three | | 4 | four | + | 7 | seven | + | 8 | eight | + | | null | + | | zero | + | 2 | two | 0 + | 3 | three | 0 | 4 | four | 0 + | 7 | seven | 0 + | 8 | eight | 0 + | | null | 0 + | | zero | 0 | 5 | five | -1 - | 5 | five | 2 - | 5 | five | -3 - | 5 | five | 4 - | 5 | five | -5 - | 5 | five | -5 - | 5 | five | - | 5 | five | - | 5 | five | 0 | 6 | six | -1 + | 5 | five | 2 | 6 | six | 2 + | 5 | five | -3 | 6 | six | -3 + | 5 | five | 4 | 6 | six | 4 + | 5 | five | -5 | 6 | six | -5 + | 5 | five | -5 | 6 | six | -5 + | 5 | five | | 6 | six | + | 5 | five | | 6 | six | + | 5 | five | 0 | 6 | six | 0 - | 7 | seven | -1 - | 7 | seven | 2 - | 7 | seven | -3 - | 7 | seven | 4 - | 7 | seven | -5 - | 7 | seven | -5 - | 7 | seven | - | 7 | seven | - | 7 | seven | 0 - | | null | -1 - | | null | 2 - | | null | -3 - | | null | 4 - | | null | -5 - | | null | -5 - | | null | - | | null | - | | null | 0 - | | zero | -1 - | | zero | 2 - | | zero | -3 - | | zero | 4 - | | zero | -5 - | | zero | -5 - | | zero | - | | zero | - | | zero | 0 (99 rows) SELECT '' AS "xxx", tx.ii, tx.jj, tx.kk @@ -370,192 +374,111 @@ SELECT '' AS "xxx", tx.ii, tx.jj, tx.kk AS tx (ii, jj, tt, ii2, kk); xxx | ii | jj | kk -----+----+----+---- + | 5 | 0 | -1 + | 6 | 6 | -1 + | 5 | 0 | 2 + | 6 | 6 | 2 + | 5 | 0 | -3 + | 6 | 6 | -3 + | 5 | 0 | 4 + | 6 | 6 | 4 + | 5 | 0 | -5 + | 6 | 6 | -5 + | 5 | 0 | -5 + | 6 | 6 | -5 + | 5 | 0 | + | 6 | 6 | + | 5 | 0 | + | 6 | 6 | + | 5 | 0 | 0 + | 6 | 6 | 0 | 1 | 4 | -1 - | 1 | 4 | 2 - | 1 | 4 | -3 - | 1 | 4 | 4 - | 1 | 4 | -5 - | 1 | 4 | -5 - | 1 | 4 | - | 1 | 4 | - | 1 | 4 | 0 - | 2 | 3 | -1 - | 2 | 3 | 2 - | 2 | 3 | -3 - | 2 | 3 | 4 - | 2 | 3 | -5 - | 2 | 3 | -5 - | 2 | 3 | - | 2 | 3 | - | 2 | 3 | 0 | 0 | | -1 + | 1 | 4 | 2 | 0 | | 2 + | 1 | 4 | -3 | 0 | | -3 + | 1 | 4 | 4 | 0 | | 4 + | 1 | 4 | -5 | 0 | | -5 + | 1 | 4 | -5 | 0 | | -5 + | 1 | 4 | | 0 | | + | 1 | 4 | | 0 | | + | 1 | 4 | 0 | 0 | | 0 + | 2 | 3 | -1 | 3 | 2 | -1 - | 3 | 2 | 2 - | 3 | 2 | -3 - | 3 | 2 | 4 - | 3 | 2 | -5 - | 3 | 2 | -5 - | 3 | 2 | - | 3 | 2 | - | 3 | 2 | 0 | 4 | 1 | -1 - | 4 | 1 | 2 - | 4 | 1 | -3 - | 4 | 1 | 4 - | 4 | 1 | -5 - | 4 | 1 | -5 - | 4 | 1 | - | 4 | 1 | - | 4 | 1 | 0 - | 5 | 0 | -1 - | 5 | 0 | 2 - | 5 | 0 | -3 - | 5 | 0 | 4 - | 5 | 0 | -5 - | 5 | 0 | -5 - | 5 | 0 | - | 5 | 0 | - | 5 | 0 | 0 - | 6 | 6 | -1 - | 6 | 6 | 2 - | 6 | 6 | -3 - | 6 | 6 | 4 - | 6 | 6 | -5 - | 6 | 6 | -5 - | 6 | 6 | - | 6 | 6 | - | 6 | 6 | 0 | 7 | 7 | -1 - | 7 | 7 | 2 - | 7 | 7 | -3 - | 7 | 7 | 4 - | 7 | 7 | -5 - | 7 | 7 | -5 - | 7 | 7 | - | 7 | 7 | - | 7 | 7 | 0 + | 8 | 8 | -1 | | | -1 - | | | 2 - | | | -3 - | | | 4 - | | | -5 - | | | -5 - | | | - | | | - | | | 0 | | 0 | -1 - | | 0 | 2 - | | 0 | -3 - | | 0 | 4 - | | 0 | -5 - | | 0 | -5 - | | 0 | - | | 0 | - | | 0 | 0 - | 8 | 8 | -1 + | 2 | 3 | 2 + | 3 | 2 | 2 + | 4 | 1 | 2 + | 7 | 7 | 2 | 8 | 8 | 2 + | | | 2 + | | 0 | 2 + | 2 | 3 | -3 + | 3 | 2 | -3 + | 4 | 1 | -3 + | 7 | 7 | -3 | 8 | 8 | -3 + | | | -3 + | | 0 | -3 + | 2 | 3 | 4 + | 3 | 2 | 4 + | 4 | 1 | 4 + | 7 | 7 | 4 | 8 | 8 | 4 + | | | 4 + | | 0 | 4 + | 2 | 3 | -5 + | 3 | 2 | -5 + | 4 | 1 | -5 + | 7 | 7 | -5 | 8 | 8 | -5 + | | | -5 + | | 0 | -5 + | 2 | 3 | -5 + | 3 | 2 | -5 + | 4 | 1 | -5 + | 7 | 7 | -5 | 8 | 8 | -5 - | 8 | 8 | - | 8 | 8 | - | 8 | 8 | 0 -(99 rows) - -SELECT '' AS "xxx", * - FROM J1_TBL CROSS JOIN J2_TBL a CROSS JOIN J2_TBL b; - xxx | i | j | t | i | k | i | k ------+---+---+-------+---+----+---+---- - | 8 | 8 | eight | 1 | -1 | 1 | -1 - | 8 | 8 | eight | 1 | -1 | 2 | 2 - | 8 | 8 | eight | 1 | -1 | 3 | -3 - | 8 | 8 | eight | 1 | -1 | 2 | 4 - | 8 | 8 | eight | 1 | -1 | 5 | -5 - | 8 | 8 | eight | 1 | -1 | 5 | -5 - | 8 | 8 | eight | 1 | -1 | 0 | - | 8 | 8 | eight | 1 | -1 | | - | 8 | 8 | eight | 1 | -1 | | 0 - | 8 | 8 | eight | 2 | 2 | 1 | -1 - | 8 | 8 | eight | 2 | 2 | 2 | 2 - | 8 | 8 | eight | 2 | 2 | 3 | -3 - | 8 | 8 | eight | 2 | 2 | 2 | 4 - | 8 | 8 | eight | 2 | 2 | 5 | -5 - | 8 | 8 | eight | 2 | 2 | 5 | -5 - | 8 | 8 | eight | 2 | 2 | 0 | - | 8 | 8 | eight | 2 | 2 | | - | 8 | 8 | eight | 2 | 2 | | 0 - | 8 | 8 | eight | 3 | -3 | 1 | -1 - | 8 | 8 | eight | 3 | -3 | 2 | 2 - | 8 | 8 | eight | 3 | -3 | 3 | -3 - | 8 | 8 | eight | 3 | -3 | 2 | 4 - | 8 | 8 | eight | 3 | -3 | 5 | -5 - | 8 | 8 | eight | 3 | -3 | 5 | -5 - | 8 | 8 | eight | 3 | -3 | 0 | - | 8 | 8 | eight | 3 | -3 | | - | 8 | 8 | eight | 3 | -3 | | 0 - | 8 | 8 | eight | 2 | 4 | 1 | -1 - | 8 | 8 | eight | 2 | 4 | 2 | 2 - | 8 | 8 | eight | 2 | 4 | 3 | -3 - | 8 | 8 | eight | 2 | 4 | 2 | 4 - | 8 | 8 | eight | 2 | 4 | 5 | -5 - | 8 | 8 | eight | 2 | 4 | 5 | -5 - | 8 | 8 | eight | 2 | 4 | 0 | - | 8 | 8 | eight | 2 | 4 | | - | 8 | 8 | eight | 2 | 4 | | 0 - | 8 | 8 | eight | 5 | -5 | 1 | -1 - | 8 | 8 | eight | 5 | -5 | 2 | 2 - | 8 | 8 | eight | 5 | -5 | 3 | -3 - | 8 | 8 | eight | 5 | -5 | 2 | 4 - | 8 | 8 | eight | 5 | -5 | 5 | -5 - | 8 | 8 | eight | 5 | -5 | 5 | -5 - | 8 | 8 | eight | 5 | -5 | 0 | - | 8 | 8 | eight | 5 | -5 | | - | 8 | 8 | eight | 5 | -5 | | 0 - | 8 | 8 | eight | 5 | -5 | 1 | -1 - | 8 | 8 | eight | 5 | -5 | 2 | 2 - | 8 | 8 | eight | 5 | -5 | 3 | -3 - | 8 | 8 | eight | 5 | -5 | 2 | 4 - | 8 | 8 | eight | 5 | -5 | 5 | -5 - | 8 | 8 | eight | 5 | -5 | 5 | -5 - | 8 | 8 | eight | 5 | -5 | 0 | - | 8 | 8 | eight | 5 | -5 | | - | 8 | 8 | eight | 5 | -5 | | 0 - | 8 | 8 | eight | 0 | | 1 | -1 - | 8 | 8 | eight | 0 | | 2 | 2 - | 8 | 8 | eight | 0 | | 3 | -3 - | 8 | 8 | eight | 0 | | 2 | 4 - | 8 | 8 | eight | 0 | | 5 | -5 - | 8 | 8 | eight | 0 | | 5 | -5 - | 8 | 8 | eight | 0 | | 0 | - | 8 | 8 | eight | 0 | | | - | 8 | 8 | eight | 0 | | | 0 - | 8 | 8 | eight | | | 1 | -1 - | 8 | 8 | eight | | | 2 | 2 - | 8 | 8 | eight | | | 3 | -3 - | 8 | 8 | eight | | | 2 | 4 - | 8 | 8 | eight | | | 5 | -5 - | 8 | 8 | eight | | | 5 | -5 - | 8 | 8 | eight | | | 0 | - | 8 | 8 | eight | | | | - | 8 | 8 | eight | | | | 0 - | 8 | 8 | eight | | 0 | 1 | -1 - | 8 | 8 | eight | | 0 | 2 | 2 - | 8 | 8 | eight | | 0 | 3 | -3 - | 8 | 8 | eight | | 0 | 2 | 4 - | 8 | 8 | eight | | 0 | 5 | -5 - | 8 | 8 | eight | | 0 | 5 | -5 - | 8 | 8 | eight | | 0 | 0 | - | 8 | 8 | eight | | 0 | | - | 8 | 8 | eight | | 0 | | 0 + | | | -5 + | | 0 | -5 + | 2 | 3 | + | 3 | 2 | + | 4 | 1 | + | 7 | 7 | + | 8 | 8 | + | | | + | | 0 | + | 2 | 3 | + | 3 | 2 | + | 4 | 1 | + | 7 | 7 | + | 8 | 8 | + | | | + | | 0 | + | 2 | 3 | 0 + | 3 | 2 | 0 + | 4 | 1 | 0 + | 7 | 7 | 0 + | 8 | 8 | 0 + | | | 0 + | | 0 | 0 +(99 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL CROSS JOIN J2_TBL a CROSS JOIN J2_TBL b; + xxx | i | j | t | i | k | i | k +-----+---+---+-------+---+----+---+---- | 1 | 4 | one | 1 | -1 | 1 | -1 | 1 | 4 | one | 1 | -1 | 2 | 2 | 1 | 4 | one | 1 | -1 | 3 | -3 @@ -565,15 +488,6 @@ SELECT '' AS "xxx", * | 1 | 4 | one | 1 | -1 | 0 | | 1 | 4 | one | 1 | -1 | | | 1 | 4 | one | 1 | -1 | | 0 - | 2 | 3 | two | 1 | -1 | 1 | -1 - | 2 | 3 | two | 1 | -1 | 2 | 2 - | 2 | 3 | two | 1 | -1 | 3 | -3 - | 2 | 3 | two | 1 | -1 | 2 | 4 - | 2 | 3 | two | 1 | -1 | 5 | -5 - | 2 | 3 | two | 1 | -1 | 5 | -5 - | 2 | 3 | two | 1 | -1 | 0 | - | 2 | 3 | two | 1 | -1 | | - | 2 | 3 | two | 1 | -1 | | 0 | 0 | | zero | 1 | -1 | 1 | -1 | 0 | | zero | 1 | -1 | 2 | 2 | 0 | | zero | 1 | -1 | 3 | -3 @@ -592,15 +506,6 @@ SELECT '' AS "xxx", * | 1 | 4 | one | 2 | 2 | 0 | | 1 | 4 | one | 2 | 2 | | | 1 | 4 | one | 2 | 2 | | 0 - | 2 | 3 | two | 2 | 2 | 1 | -1 - | 2 | 3 | two | 2 | 2 | 2 | 2 - | 2 | 3 | two | 2 | 2 | 3 | -3 - | 2 | 3 | two | 2 | 2 | 2 | 4 - | 2 | 3 | two | 2 | 2 | 5 | -5 - | 2 | 3 | two | 2 | 2 | 5 | -5 - | 2 | 3 | two | 2 | 2 | 0 | - | 2 | 3 | two | 2 | 2 | | - | 2 | 3 | two | 2 | 2 | | 0 | 0 | | zero | 2 | 2 | 1 | -1 | 0 | | zero | 2 | 2 | 2 | 2 | 0 | | zero | 2 | 2 | 3 | -3 @@ -619,15 +524,6 @@ SELECT '' AS "xxx", * | 1 | 4 | one | 3 | -3 | 0 | | 1 | 4 | one | 3 | -3 | | | 1 | 4 | one | 3 | -3 | | 0 - | 2 | 3 | two | 3 | -3 | 1 | -1 - | 2 | 3 | two | 3 | -3 | 2 | 2 - | 2 | 3 | two | 3 | -3 | 3 | -3 - | 2 | 3 | two | 3 | -3 | 2 | 4 - | 2 | 3 | two | 3 | -3 | 5 | -5 - | 2 | 3 | two | 3 | -3 | 5 | -5 - | 2 | 3 | two | 3 | -3 | 0 | - | 2 | 3 | two | 3 | -3 | | - | 2 | 3 | two | 3 | -3 | | 0 | 0 | | zero | 3 | -3 | 1 | -1 | 0 | | zero | 3 | -3 | 2 | 2 | 0 | | zero | 3 | -3 | 3 | -3 @@ -646,15 +542,6 @@ SELECT '' AS "xxx", * | 1 | 4 | one | 2 | 4 | 0 | | 1 | 4 | one | 2 | 4 | | | 1 | 4 | one | 2 | 4 | | 0 - | 2 | 3 | two | 2 | 4 | 1 | -1 - | 2 | 3 | two | 2 | 4 | 2 | 2 - | 2 | 3 | two | 2 | 4 | 3 | -3 - | 2 | 3 | two | 2 | 4 | 2 | 4 - | 2 | 3 | two | 2 | 4 | 5 | -5 - | 2 | 3 | two | 2 | 4 | 5 | -5 - | 2 | 3 | two | 2 | 4 | 0 | - | 2 | 3 | two | 2 | 4 | | - | 2 | 3 | two | 2 | 4 | | 0 | 0 | | zero | 2 | 4 | 1 | -1 | 0 | | zero | 2 | 4 | 2 | 2 | 0 | | zero | 2 | 4 | 3 | -3 @@ -673,15 +560,6 @@ SELECT '' AS "xxx", * | 1 | 4 | one | 5 | -5 | 0 | | 1 | 4 | one | 5 | -5 | | | 1 | 4 | one | 5 | -5 | | 0 - | 2 | 3 | two | 5 | -5 | 1 | -1 - | 2 | 3 | two | 5 | -5 | 2 | 2 - | 2 | 3 | two | 5 | -5 | 3 | -3 - | 2 | 3 | two | 5 | -5 | 2 | 4 - | 2 | 3 | two | 5 | -5 | 5 | -5 - | 2 | 3 | two | 5 | -5 | 5 | -5 - | 2 | 3 | two | 5 | -5 | 0 | - | 2 | 3 | two | 5 | -5 | | - | 2 | 3 | two | 5 | -5 | | 0 | 0 | | zero | 5 | -5 | 1 | -1 | 0 | | zero | 5 | -5 | 2 | 2 | 0 | | zero | 5 | -5 | 3 | -3 @@ -700,15 +578,6 @@ SELECT '' AS "xxx", * | 1 | 4 | one | 5 | -5 | 0 | | 1 | 4 | one | 5 | -5 | | | 1 | 4 | one | 5 | -5 | | 0 - | 2 | 3 | two | 5 | -5 | 1 | -1 - | 2 | 3 | two | 5 | -5 | 2 | 2 - | 2 | 3 | two | 5 | -5 | 3 | -3 - | 2 | 3 | two | 5 | -5 | 2 | 4 - | 2 | 3 | two | 5 | -5 | 5 | -5 - | 2 | 3 | two | 5 | -5 | 5 | -5 - | 2 | 3 | two | 5 | -5 | 0 | - | 2 | 3 | two | 5 | -5 | | - | 2 | 3 | two | 5 | -5 | | 0 | 0 | | zero | 5 | -5 | 1 | -1 | 0 | | zero | 5 | -5 | 2 | 2 | 0 | | zero | 5 | -5 | 3 | -3 @@ -727,21 +596,222 @@ SELECT '' AS "xxx", * | 1 | 4 | one | 0 | | 0 | | 1 | 4 | one | 0 | | | | 1 | 4 | one | 0 | | | 0 - | 2 | 3 | two | 0 | | 1 | -1 - | 2 | 3 | two | 0 | | 2 | 2 - | 2 | 3 | two | 0 | | 3 | -3 - | 2 | 3 | two | 0 | | 2 | 4 - | 2 | 3 | two | 0 | | 5 | -5 - | 2 | 3 | two | 0 | | 5 | -5 - | 2 | 3 | two | 0 | | 0 | - | 2 | 3 | two | 0 | | | - | 2 | 3 | two | 0 | | | 0 | 0 | | zero | 0 | | 1 | -1 | 0 | | zero | 0 | | 2 | 2 | 0 | | zero | 0 | | 3 | -3 | 0 | | zero | 0 | | 2 | 4 | 0 | | zero | 0 | | 5 | -5 | 0 | | zero | 0 | | 5 | -5 + | 0 | | zero | 0 | | 0 | + | 0 | | zero | 0 | | | + | 0 | | zero | 0 | | | 0 + | 1 | 4 | one | | | 1 | -1 + | 1 | 4 | one | | | 2 | 2 + | 1 | 4 | one | | | 3 | -3 + | 1 | 4 | one | | | 2 | 4 + | 1 | 4 | one | | | 5 | -5 + | 1 | 4 | one | | | 5 | -5 + | 1 | 4 | one | | | 0 | + | 1 | 4 | one | | | | + | 1 | 4 | one | | | | 0 + | 0 | | zero | | | 1 | -1 + | 0 | | zero | | | 2 | 2 + | 0 | | zero | | | 3 | -3 + | 0 | | zero | | | 2 | 4 + | 0 | | zero | | | 5 | -5 + | 0 | | zero | | | 5 | -5 + | 0 | | zero | | | 0 | + | 0 | | zero | | | | + | 0 | | zero | | | | 0 + | 1 | 4 | one | | 0 | 1 | -1 + | 1 | 4 | one | | 0 | 2 | 2 + | 1 | 4 | one | | 0 | 3 | -3 + | 1 | 4 | one | | 0 | 2 | 4 + | 1 | 4 | one | | 0 | 5 | -5 + | 1 | 4 | one | | 0 | 5 | -5 + | 1 | 4 | one | | 0 | 0 | + | 1 | 4 | one | | 0 | | + | 1 | 4 | one | | 0 | | 0 + | 0 | | zero | | 0 | 1 | -1 + | 0 | | zero | | 0 | 2 | 2 + | 0 | | zero | | 0 | 3 | -3 + | 0 | | zero | | 0 | 2 | 4 + | 0 | | zero | | 0 | 5 | -5 + | 0 | | zero | | 0 | 5 | -5 + | 0 | | zero | | 0 | 0 | + | 0 | | zero | | 0 | | + | 0 | | zero | | 0 | | 0 + | 5 | 0 | five | 1 | -1 | 1 | -1 + | 5 | 0 | five | 1 | -1 | 2 | 2 + | 5 | 0 | five | 1 | -1 | 3 | -3 + | 5 | 0 | five | 1 | -1 | 2 | 4 + | 5 | 0 | five | 1 | -1 | 5 | -5 + | 5 | 0 | five | 1 | -1 | 5 | -5 + | 5 | 0 | five | 1 | -1 | 0 | + | 5 | 0 | five | 1 | -1 | | + | 5 | 0 | five | 1 | -1 | | 0 + | 6 | 6 | six | 1 | -1 | 1 | -1 + | 6 | 6 | six | 1 | -1 | 2 | 2 + | 6 | 6 | six | 1 | -1 | 3 | -3 + | 6 | 6 | six | 1 | -1 | 2 | 4 + | 6 | 6 | six | 1 | -1 | 5 | -5 + | 6 | 6 | six | 1 | -1 | 5 | -5 + | 6 | 6 | six | 1 | -1 | 0 | + | 6 | 6 | six | 1 | -1 | | + | 6 | 6 | six | 1 | -1 | | 0 + | 5 | 0 | five | 2 | 2 | 1 | -1 + | 5 | 0 | five | 2 | 2 | 2 | 2 + | 5 | 0 | five | 2 | 2 | 3 | -3 + | 5 | 0 | five | 2 | 2 | 2 | 4 + | 5 | 0 | five | 2 | 2 | 5 | -5 + | 5 | 0 | five | 2 | 2 | 5 | -5 + | 5 | 0 | five | 2 | 2 | 0 | + | 5 | 0 | five | 2 | 2 | | + | 5 | 0 | five | 2 | 2 | | 0 + | 6 | 6 | six | 2 | 2 | 1 | -1 + | 6 | 6 | six | 2 | 2 | 2 | 2 + | 6 | 6 | six | 2 | 2 | 3 | -3 + | 6 | 6 | six | 2 | 2 | 2 | 4 + | 6 | 6 | six | 2 | 2 | 5 | -5 + | 6 | 6 | six | 2 | 2 | 5 | -5 + | 6 | 6 | six | 2 | 2 | 0 | + | 6 | 6 | six | 2 | 2 | | + | 6 | 6 | six | 2 | 2 | | 0 + | 5 | 0 | five | 3 | -3 | 1 | -1 + | 5 | 0 | five | 3 | -3 | 2 | 2 + | 5 | 0 | five | 3 | -3 | 3 | -3 + | 5 | 0 | five | 3 | -3 | 2 | 4 + | 5 | 0 | five | 3 | -3 | 5 | -5 + | 5 | 0 | five | 3 | -3 | 5 | -5 + | 5 | 0 | five | 3 | -3 | 0 | + | 5 | 0 | five | 3 | -3 | | + | 5 | 0 | five | 3 | -3 | | 0 + | 6 | 6 | six | 3 | -3 | 1 | -1 + | 6 | 6 | six | 3 | -3 | 2 | 2 + | 6 | 6 | six | 3 | -3 | 3 | -3 + | 6 | 6 | six | 3 | -3 | 2 | 4 + | 6 | 6 | six | 3 | -3 | 5 | -5 + | 6 | 6 | six | 3 | -3 | 5 | -5 + | 6 | 6 | six | 3 | -3 | 0 | + | 6 | 6 | six | 3 | -3 | | + | 6 | 6 | six | 3 | -3 | | 0 + | 5 | 0 | five | 2 | 4 | 1 | -1 + | 5 | 0 | five | 2 | 4 | 2 | 2 + | 5 | 0 | five | 2 | 4 | 3 | -3 + | 5 | 0 | five | 2 | 4 | 2 | 4 + | 5 | 0 | five | 2 | 4 | 5 | -5 + | 5 | 0 | five | 2 | 4 | 5 | -5 + | 5 | 0 | five | 2 | 4 | 0 | + | 5 | 0 | five | 2 | 4 | | + | 5 | 0 | five | 2 | 4 | | 0 + | 6 | 6 | six | 2 | 4 | 1 | -1 + | 6 | 6 | six | 2 | 4 | 2 | 2 + | 6 | 6 | six | 2 | 4 | 3 | -3 + | 6 | 6 | six | 2 | 4 | 2 | 4 + | 6 | 6 | six | 2 | 4 | 5 | -5 + | 6 | 6 | six | 2 | 4 | 5 | -5 + | 6 | 6 | six | 2 | 4 | 0 | + | 6 | 6 | six | 2 | 4 | | + | 6 | 6 | six | 2 | 4 | | 0 + | 5 | 0 | five | 5 | -5 | 1 | -1 + | 5 | 0 | five | 5 | -5 | 2 | 2 + | 5 | 0 | five | 5 | -5 | 3 | -3 + | 5 | 0 | five | 5 | -5 | 2 | 4 + | 5 | 0 | five | 5 | -5 | 5 | -5 + | 5 | 0 | five | 5 | -5 | 5 | -5 + | 5 | 0 | five | 5 | -5 | 0 | + | 5 | 0 | five | 5 | -5 | | + | 5 | 0 | five | 5 | -5 | | 0 + | 6 | 6 | six | 5 | -5 | 1 | -1 + | 6 | 6 | six | 5 | -5 | 2 | 2 + | 6 | 6 | six | 5 | -5 | 3 | -3 + | 6 | 6 | six | 5 | -5 | 2 | 4 + | 6 | 6 | six | 5 | -5 | 5 | -5 + | 6 | 6 | six | 5 | -5 | 5 | -5 + | 6 | 6 | six | 5 | -5 | 0 | + | 6 | 6 | six | 5 | -5 | | + | 6 | 6 | six | 5 | -5 | | 0 + | 5 | 0 | five | 5 | -5 | 1 | -1 + | 5 | 0 | five | 5 | -5 | 2 | 2 + | 5 | 0 | five | 5 | -5 | 3 | -3 + | 5 | 0 | five | 5 | -5 | 2 | 4 + | 5 | 0 | five | 5 | -5 | 5 | -5 + | 5 | 0 | five | 5 | -5 | 5 | -5 + | 5 | 0 | five | 5 | -5 | 0 | + | 5 | 0 | five | 5 | -5 | | + | 5 | 0 | five | 5 | -5 | | 0 + | 6 | 6 | six | 5 | -5 | 1 | -1 + | 6 | 6 | six | 5 | -5 | 2 | 2 + | 6 | 6 | six | 5 | -5 | 3 | -3 + | 6 | 6 | six | 5 | -5 | 2 | 4 + | 6 | 6 | six | 5 | -5 | 5 | -5 + | 6 | 6 | six | 5 | -5 | 5 | -5 + | 6 | 6 | six | 5 | -5 | 0 | + | 6 | 6 | six | 5 | -5 | | + | 6 | 6 | six | 5 | -5 | | 0 + | 5 | 0 | five | 0 | | 1 | -1 + | 5 | 0 | five | 0 | | 2 | 2 + | 5 | 0 | five | 0 | | 3 | -3 + | 5 | 0 | five | 0 | | 2 | 4 + | 5 | 0 | five | 0 | | 5 | -5 + | 5 | 0 | five | 0 | | 5 | -5 + | 5 | 0 | five | 0 | | 0 | + | 5 | 0 | five | 0 | | | + | 5 | 0 | five | 0 | | | 0 + | 6 | 6 | six | 0 | | 1 | -1 + | 6 | 6 | six | 0 | | 2 | 2 + | 6 | 6 | six | 0 | | 3 | -3 + | 6 | 6 | six | 0 | | 2 | 4 + | 6 | 6 | six | 0 | | 5 | -5 + | 6 | 6 | six | 0 | | 5 | -5 + | 6 | 6 | six | 0 | | 0 | + | 6 | 6 | six | 0 | | | + | 6 | 6 | six | 0 | | | 0 + | 5 | 0 | five | | | 1 | -1 + | 5 | 0 | five | | | 2 | 2 + | 5 | 0 | five | | | 3 | -3 + | 5 | 0 | five | | | 2 | 4 + | 5 | 0 | five | | | 5 | -5 + | 5 | 0 | five | | | 5 | -5 + | 5 | 0 | five | | | 0 | + | 5 | 0 | five | | | | + | 5 | 0 | five | | | | 0 + | 6 | 6 | six | | | 1 | -1 + | 6 | 6 | six | | | 2 | 2 + | 6 | 6 | six | | | 3 | -3 + | 6 | 6 | six | | | 2 | 4 + | 6 | 6 | six | | | 5 | -5 + | 6 | 6 | six | | | 5 | -5 + | 6 | 6 | six | | | 0 | + | 6 | 6 | six | | | | + | 6 | 6 | six | | | | 0 + | 5 | 0 | five | | 0 | 1 | -1 + | 5 | 0 | five | | 0 | 2 | 2 + | 5 | 0 | five | | 0 | 3 | -3 + | 5 | 0 | five | | 0 | 2 | 4 + | 5 | 0 | five | | 0 | 5 | -5 + | 5 | 0 | five | | 0 | 5 | -5 + | 5 | 0 | five | | 0 | 0 | + | 5 | 0 | five | | 0 | | + | 5 | 0 | five | | 0 | | 0 + | 6 | 6 | six | | 0 | 1 | -1 + | 6 | 6 | six | | 0 | 2 | 2 + | 6 | 6 | six | | 0 | 3 | -3 + | 6 | 6 | six | | 0 | 2 | 4 + | 6 | 6 | six | | 0 | 5 | -5 + | 6 | 6 | six | | 0 | 5 | -5 + | 6 | 6 | six | | 0 | 0 | + | 6 | 6 | six | | 0 | | + | 6 | 6 | six | | 0 | | 0 + | 2 | 3 | two | 1 | -1 | 1 | -1 + | 2 | 3 | two | 1 | -1 | 2 | 2 + | 2 | 3 | two | 1 | -1 | 3 | -3 + | 2 | 3 | two | 1 | -1 | 2 | 4 + | 2 | 3 | two | 1 | -1 | 5 | -5 + | 2 | 3 | two | 1 | -1 | 5 | -5 + | 2 | 3 | two | 1 | -1 | 0 | + | 2 | 3 | two | 1 | -1 | | + | 2 | 3 | two | 1 | -1 | | 0 | 3 | 2 | three | 1 | -1 | 1 | -1 | 3 | 2 | three | 1 | -1 | 2 | 2 | 3 | 2 | three | 1 | -1 | 3 | -3 @@ -760,24 +830,6 @@ SELECT '' AS "xxx", * | 4 | 1 | four | 1 | -1 | 0 | | 4 | 1 | four | 1 | -1 | | | 4 | 1 | four | 1 | -1 | | 0 - | 5 | 0 | five | 1 | -1 | 1 | -1 - | 5 | 0 | five | 1 | -1 | 2 | 2 - | 5 | 0 | five | 1 | -1 | 3 | -3 - | 5 | 0 | five | 1 | -1 | 2 | 4 - | 5 | 0 | five | 1 | -1 | 5 | -5 - | 5 | 0 | five | 1 | -1 | 5 | -5 - | 5 | 0 | five | 1 | -1 | 0 | - | 5 | 0 | five | 1 | -1 | | - | 5 | 0 | five | 1 | -1 | | 0 - | 6 | 6 | six | 1 | -1 | 1 | -1 - | 6 | 6 | six | 1 | -1 | 2 | 2 - | 6 | 6 | six | 1 | -1 | 3 | -3 - | 6 | 6 | six | 1 | -1 | 2 | 4 - | 6 | 6 | six | 1 | -1 | 5 | -5 - | 6 | 6 | six | 1 | -1 | 5 | -5 - | 6 | 6 | six | 1 | -1 | 0 | - | 6 | 6 | six | 1 | -1 | | - | 6 | 6 | six | 1 | -1 | | 0 | 7 | 7 | seven | 1 | -1 | 1 | -1 | 7 | 7 | seven | 1 | -1 | 2 | 2 | 7 | 7 | seven | 1 | -1 | 3 | -3 @@ -787,6 +839,15 @@ SELECT '' AS "xxx", * | 7 | 7 | seven | 1 | -1 | 0 | | 7 | 7 | seven | 1 | -1 | | | 7 | 7 | seven | 1 | -1 | | 0 + | 8 | 8 | eight | 1 | -1 | 1 | -1 + | 8 | 8 | eight | 1 | -1 | 2 | 2 + | 8 | 8 | eight | 1 | -1 | 3 | -3 + | 8 | 8 | eight | 1 | -1 | 2 | 4 + | 8 | 8 | eight | 1 | -1 | 5 | -5 + | 8 | 8 | eight | 1 | -1 | 5 | -5 + | 8 | 8 | eight | 1 | -1 | 0 | + | 8 | 8 | eight | 1 | -1 | | + | 8 | 8 | eight | 1 | -1 | | 0 | | | null | 1 | -1 | 1 | -1 | | | null | 1 | -1 | 2 | 2 | | | null | 1 | -1 | 3 | -3 @@ -805,6 +866,15 @@ SELECT '' AS "xxx", * | | 0 | zero | 1 | -1 | 0 | | | 0 | zero | 1 | -1 | | | | 0 | zero | 1 | -1 | | 0 + | 2 | 3 | two | 2 | 2 | 1 | -1 + | 2 | 3 | two | 2 | 2 | 2 | 2 + | 2 | 3 | two | 2 | 2 | 3 | -3 + | 2 | 3 | two | 2 | 2 | 2 | 4 + | 2 | 3 | two | 2 | 2 | 5 | -5 + | 2 | 3 | two | 2 | 2 | 5 | -5 + | 2 | 3 | two | 2 | 2 | 0 | + | 2 | 3 | two | 2 | 2 | | + | 2 | 3 | two | 2 | 2 | | 0 | 3 | 2 | three | 2 | 2 | 1 | -1 | 3 | 2 | three | 2 | 2 | 2 | 2 | 3 | 2 | three | 2 | 2 | 3 | -3 @@ -823,24 +893,6 @@ SELECT '' AS "xxx", * | 4 | 1 | four | 2 | 2 | 0 | | 4 | 1 | four | 2 | 2 | | | 4 | 1 | four | 2 | 2 | | 0 - | 5 | 0 | five | 2 | 2 | 1 | -1 - | 5 | 0 | five | 2 | 2 | 2 | 2 - | 5 | 0 | five | 2 | 2 | 3 | -3 - | 5 | 0 | five | 2 | 2 | 2 | 4 - | 5 | 0 | five | 2 | 2 | 5 | -5 - | 5 | 0 | five | 2 | 2 | 5 | -5 - | 5 | 0 | five | 2 | 2 | 0 | - | 5 | 0 | five | 2 | 2 | | - | 5 | 0 | five | 2 | 2 | | 0 - | 6 | 6 | six | 2 | 2 | 1 | -1 - | 6 | 6 | six | 2 | 2 | 2 | 2 - | 6 | 6 | six | 2 | 2 | 3 | -3 - | 6 | 6 | six | 2 | 2 | 2 | 4 - | 6 | 6 | six | 2 | 2 | 5 | -5 - | 6 | 6 | six | 2 | 2 | 5 | -5 - | 6 | 6 | six | 2 | 2 | 0 | - | 6 | 6 | six | 2 | 2 | | - | 6 | 6 | six | 2 | 2 | | 0 | 7 | 7 | seven | 2 | 2 | 1 | -1 | 7 | 7 | seven | 2 | 2 | 2 | 2 | 7 | 7 | seven | 2 | 2 | 3 | -3 @@ -850,6 +902,15 @@ SELECT '' AS "xxx", * | 7 | 7 | seven | 2 | 2 | 0 | | 7 | 7 | seven | 2 | 2 | | | 7 | 7 | seven | 2 | 2 | | 0 + | 8 | 8 | eight | 2 | 2 | 1 | -1 + | 8 | 8 | eight | 2 | 2 | 2 | 2 + | 8 | 8 | eight | 2 | 2 | 3 | -3 + | 8 | 8 | eight | 2 | 2 | 2 | 4 + | 8 | 8 | eight | 2 | 2 | 5 | -5 + | 8 | 8 | eight | 2 | 2 | 5 | -5 + | 8 | 8 | eight | 2 | 2 | 0 | + | 8 | 8 | eight | 2 | 2 | | + | 8 | 8 | eight | 2 | 2 | | 0 | | | null | 2 | 2 | 1 | -1 | | | null | 2 | 2 | 2 | 2 | | | null | 2 | 2 | 3 | -3 @@ -868,6 +929,15 @@ SELECT '' AS "xxx", * | | 0 | zero | 2 | 2 | 0 | | | 0 | zero | 2 | 2 | | | | 0 | zero | 2 | 2 | | 0 + | 2 | 3 | two | 3 | -3 | 1 | -1 + | 2 | 3 | two | 3 | -3 | 2 | 2 + | 2 | 3 | two | 3 | -3 | 3 | -3 + | 2 | 3 | two | 3 | -3 | 2 | 4 + | 2 | 3 | two | 3 | -3 | 5 | -5 + | 2 | 3 | two | 3 | -3 | 5 | -5 + | 2 | 3 | two | 3 | -3 | 0 | + | 2 | 3 | two | 3 | -3 | | + | 2 | 3 | two | 3 | -3 | | 0 | 3 | 2 | three | 3 | -3 | 1 | -1 | 3 | 2 | three | 3 | -3 | 2 | 2 | 3 | 2 | three | 3 | -3 | 3 | -3 @@ -886,24 +956,6 @@ SELECT '' AS "xxx", * | 4 | 1 | four | 3 | -3 | 0 | | 4 | 1 | four | 3 | -3 | | | 4 | 1 | four | 3 | -3 | | 0 - | 5 | 0 | five | 3 | -3 | 1 | -1 - | 5 | 0 | five | 3 | -3 | 2 | 2 - | 5 | 0 | five | 3 | -3 | 3 | -3 - | 5 | 0 | five | 3 | -3 | 2 | 4 - | 5 | 0 | five | 3 | -3 | 5 | -5 - | 5 | 0 | five | 3 | -3 | 5 | -5 - | 5 | 0 | five | 3 | -3 | 0 | - | 5 | 0 | five | 3 | -3 | | - | 5 | 0 | five | 3 | -3 | | 0 - | 6 | 6 | six | 3 | -3 | 1 | -1 - | 6 | 6 | six | 3 | -3 | 2 | 2 - | 6 | 6 | six | 3 | -3 | 3 | -3 - | 6 | 6 | six | 3 | -3 | 2 | 4 - | 6 | 6 | six | 3 | -3 | 5 | -5 - | 6 | 6 | six | 3 | -3 | 5 | -5 - | 6 | 6 | six | 3 | -3 | 0 | - | 6 | 6 | six | 3 | -3 | | - | 6 | 6 | six | 3 | -3 | | 0 | 7 | 7 | seven | 3 | -3 | 1 | -1 | 7 | 7 | seven | 3 | -3 | 2 | 2 | 7 | 7 | seven | 3 | -3 | 3 | -3 @@ -913,6 +965,15 @@ SELECT '' AS "xxx", * | 7 | 7 | seven | 3 | -3 | 0 | | 7 | 7 | seven | 3 | -3 | | | 7 | 7 | seven | 3 | -3 | | 0 + | 8 | 8 | eight | 3 | -3 | 1 | -1 + | 8 | 8 | eight | 3 | -3 | 2 | 2 + | 8 | 8 | eight | 3 | -3 | 3 | -3 + | 8 | 8 | eight | 3 | -3 | 2 | 4 + | 8 | 8 | eight | 3 | -3 | 5 | -5 + | 8 | 8 | eight | 3 | -3 | 5 | -5 + | 8 | 8 | eight | 3 | -3 | 0 | + | 8 | 8 | eight | 3 | -3 | | + | 8 | 8 | eight | 3 | -3 | | 0 | | | null | 3 | -3 | 1 | -1 | | | null | 3 | -3 | 2 | 2 | | | null | 3 | -3 | 3 | -3 @@ -931,6 +992,15 @@ SELECT '' AS "xxx", * | | 0 | zero | 3 | -3 | 0 | | | 0 | zero | 3 | -3 | | | | 0 | zero | 3 | -3 | | 0 + | 2 | 3 | two | 2 | 4 | 1 | -1 + | 2 | 3 | two | 2 | 4 | 2 | 2 + | 2 | 3 | two | 2 | 4 | 3 | -3 + | 2 | 3 | two | 2 | 4 | 2 | 4 + | 2 | 3 | two | 2 | 4 | 5 | -5 + | 2 | 3 | two | 2 | 4 | 5 | -5 + | 2 | 3 | two | 2 | 4 | 0 | + | 2 | 3 | two | 2 | 4 | | + | 2 | 3 | two | 2 | 4 | | 0 | 3 | 2 | three | 2 | 4 | 1 | -1 | 3 | 2 | three | 2 | 4 | 2 | 2 | 3 | 2 | three | 2 | 4 | 3 | -3 @@ -949,24 +1019,6 @@ SELECT '' AS "xxx", * | 4 | 1 | four | 2 | 4 | 0 | | 4 | 1 | four | 2 | 4 | | | 4 | 1 | four | 2 | 4 | | 0 - | 5 | 0 | five | 2 | 4 | 1 | -1 - | 5 | 0 | five | 2 | 4 | 2 | 2 - | 5 | 0 | five | 2 | 4 | 3 | -3 - | 5 | 0 | five | 2 | 4 | 2 | 4 - | 5 | 0 | five | 2 | 4 | 5 | -5 - | 5 | 0 | five | 2 | 4 | 5 | -5 - | 5 | 0 | five | 2 | 4 | 0 | - | 5 | 0 | five | 2 | 4 | | - | 5 | 0 | five | 2 | 4 | | 0 - | 6 | 6 | six | 2 | 4 | 1 | -1 - | 6 | 6 | six | 2 | 4 | 2 | 2 - | 6 | 6 | six | 2 | 4 | 3 | -3 - | 6 | 6 | six | 2 | 4 | 2 | 4 - | 6 | 6 | six | 2 | 4 | 5 | -5 - | 6 | 6 | six | 2 | 4 | 5 | -5 - | 6 | 6 | six | 2 | 4 | 0 | - | 6 | 6 | six | 2 | 4 | | - | 6 | 6 | six | 2 | 4 | | 0 | 7 | 7 | seven | 2 | 4 | 1 | -1 | 7 | 7 | seven | 2 | 4 | 2 | 2 | 7 | 7 | seven | 2 | 4 | 3 | -3 @@ -976,6 +1028,15 @@ SELECT '' AS "xxx", * | 7 | 7 | seven | 2 | 4 | 0 | | 7 | 7 | seven | 2 | 4 | | | 7 | 7 | seven | 2 | 4 | | 0 + | 8 | 8 | eight | 2 | 4 | 1 | -1 + | 8 | 8 | eight | 2 | 4 | 2 | 2 + | 8 | 8 | eight | 2 | 4 | 3 | -3 + | 8 | 8 | eight | 2 | 4 | 2 | 4 + | 8 | 8 | eight | 2 | 4 | 5 | -5 + | 8 | 8 | eight | 2 | 4 | 5 | -5 + | 8 | 8 | eight | 2 | 4 | 0 | + | 8 | 8 | eight | 2 | 4 | | + | 8 | 8 | eight | 2 | 4 | | 0 | | | null | 2 | 4 | 1 | -1 | | | null | 2 | 4 | 2 | 2 | | | null | 2 | 4 | 3 | -3 @@ -994,6 +1055,15 @@ SELECT '' AS "xxx", * | | 0 | zero | 2 | 4 | 0 | | | 0 | zero | 2 | 4 | | | | 0 | zero | 2 | 4 | | 0 + | 2 | 3 | two | 5 | -5 | 1 | -1 + | 2 | 3 | two | 5 | -5 | 2 | 2 + | 2 | 3 | two | 5 | -5 | 3 | -3 + | 2 | 3 | two | 5 | -5 | 2 | 4 + | 2 | 3 | two | 5 | -5 | 5 | -5 + | 2 | 3 | two | 5 | -5 | 5 | -5 + | 2 | 3 | two | 5 | -5 | 0 | + | 2 | 3 | two | 5 | -5 | | + | 2 | 3 | two | 5 | -5 | | 0 | 3 | 2 | three | 5 | -5 | 1 | -1 | 3 | 2 | three | 5 | -5 | 2 | 2 | 3 | 2 | three | 5 | -5 | 3 | -3 @@ -1012,24 +1082,6 @@ SELECT '' AS "xxx", * | 4 | 1 | four | 5 | -5 | 0 | | 4 | 1 | four | 5 | -5 | | | 4 | 1 | four | 5 | -5 | | 0 - | 5 | 0 | five | 5 | -5 | 1 | -1 - | 5 | 0 | five | 5 | -5 | 2 | 2 - | 5 | 0 | five | 5 | -5 | 3 | -3 - | 5 | 0 | five | 5 | -5 | 2 | 4 - | 5 | 0 | five | 5 | -5 | 5 | -5 - | 5 | 0 | five | 5 | -5 | 5 | -5 - | 5 | 0 | five | 5 | -5 | 0 | - | 5 | 0 | five | 5 | -5 | | - | 5 | 0 | five | 5 | -5 | | 0 - | 6 | 6 | six | 5 | -5 | 1 | -1 - | 6 | 6 | six | 5 | -5 | 2 | 2 - | 6 | 6 | six | 5 | -5 | 3 | -3 - | 6 | 6 | six | 5 | -5 | 2 | 4 - | 6 | 6 | six | 5 | -5 | 5 | -5 - | 6 | 6 | six | 5 | -5 | 5 | -5 - | 6 | 6 | six | 5 | -5 | 0 | - | 6 | 6 | six | 5 | -5 | | - | 6 | 6 | six | 5 | -5 | | 0 | 7 | 7 | seven | 5 | -5 | 1 | -1 | 7 | 7 | seven | 5 | -5 | 2 | 2 | 7 | 7 | seven | 5 | -5 | 3 | -3 @@ -1039,6 +1091,15 @@ SELECT '' AS "xxx", * | 7 | 7 | seven | 5 | -5 | 0 | | 7 | 7 | seven | 5 | -5 | | | 7 | 7 | seven | 5 | -5 | | 0 + | 8 | 8 | eight | 5 | -5 | 1 | -1 + | 8 | 8 | eight | 5 | -5 | 2 | 2 + | 8 | 8 | eight | 5 | -5 | 3 | -3 + | 8 | 8 | eight | 5 | -5 | 2 | 4 + | 8 | 8 | eight | 5 | -5 | 5 | -5 + | 8 | 8 | eight | 5 | -5 | 5 | -5 + | 8 | 8 | eight | 5 | -5 | 0 | + | 8 | 8 | eight | 5 | -5 | | + | 8 | 8 | eight | 5 | -5 | | 0 | | | null | 5 | -5 | 1 | -1 | | | null | 5 | -5 | 2 | 2 | | | null | 5 | -5 | 3 | -3 @@ -1057,6 +1118,15 @@ SELECT '' AS "xxx", * | | 0 | zero | 5 | -5 | 0 | | | 0 | zero | 5 | -5 | | | | 0 | zero | 5 | -5 | | 0 + | 2 | 3 | two | 5 | -5 | 1 | -1 + | 2 | 3 | two | 5 | -5 | 2 | 2 + | 2 | 3 | two | 5 | -5 | 3 | -3 + | 2 | 3 | two | 5 | -5 | 2 | 4 + | 2 | 3 | two | 5 | -5 | 5 | -5 + | 2 | 3 | two | 5 | -5 | 5 | -5 + | 2 | 3 | two | 5 | -5 | 0 | + | 2 | 3 | two | 5 | -5 | | + | 2 | 3 | two | 5 | -5 | | 0 | 3 | 2 | three | 5 | -5 | 1 | -1 | 3 | 2 | three | 5 | -5 | 2 | 2 | 3 | 2 | three | 5 | -5 | 3 | -3 @@ -1075,24 +1145,6 @@ SELECT '' AS "xxx", * | 4 | 1 | four | 5 | -5 | 0 | | 4 | 1 | four | 5 | -5 | | | 4 | 1 | four | 5 | -5 | | 0 - | 5 | 0 | five | 5 | -5 | 1 | -1 - | 5 | 0 | five | 5 | -5 | 2 | 2 - | 5 | 0 | five | 5 | -5 | 3 | -3 - | 5 | 0 | five | 5 | -5 | 2 | 4 - | 5 | 0 | five | 5 | -5 | 5 | -5 - | 5 | 0 | five | 5 | -5 | 5 | -5 - | 5 | 0 | five | 5 | -5 | 0 | - | 5 | 0 | five | 5 | -5 | | - | 5 | 0 | five | 5 | -5 | | 0 - | 6 | 6 | six | 5 | -5 | 1 | -1 - | 6 | 6 | six | 5 | -5 | 2 | 2 - | 6 | 6 | six | 5 | -5 | 3 | -3 - | 6 | 6 | six | 5 | -5 | 2 | 4 - | 6 | 6 | six | 5 | -5 | 5 | -5 - | 6 | 6 | six | 5 | -5 | 5 | -5 - | 6 | 6 | six | 5 | -5 | 0 | - | 6 | 6 | six | 5 | -5 | | - | 6 | 6 | six | 5 | -5 | | 0 | 7 | 7 | seven | 5 | -5 | 1 | -1 | 7 | 7 | seven | 5 | -5 | 2 | 2 | 7 | 7 | seven | 5 | -5 | 3 | -3 @@ -1102,6 +1154,15 @@ SELECT '' AS "xxx", * | 7 | 7 | seven | 5 | -5 | 0 | | 7 | 7 | seven | 5 | -5 | | | 7 | 7 | seven | 5 | -5 | | 0 + | 8 | 8 | eight | 5 | -5 | 1 | -1 + | 8 | 8 | eight | 5 | -5 | 2 | 2 + | 8 | 8 | eight | 5 | -5 | 3 | -3 + | 8 | 8 | eight | 5 | -5 | 2 | 4 + | 8 | 8 | eight | 5 | -5 | 5 | -5 + | 8 | 8 | eight | 5 | -5 | 5 | -5 + | 8 | 8 | eight | 5 | -5 | 0 | + | 8 | 8 | eight | 5 | -5 | | + | 8 | 8 | eight | 5 | -5 | | 0 | | | null | 5 | -5 | 1 | -1 | | | null | 5 | -5 | 2 | 2 | | | null | 5 | -5 | 3 | -3 @@ -1120,6 +1181,15 @@ SELECT '' AS "xxx", * | | 0 | zero | 5 | -5 | 0 | | | 0 | zero | 5 | -5 | | | | 0 | zero | 5 | -5 | | 0 + | 2 | 3 | two | 0 | | 1 | -1 + | 2 | 3 | two | 0 | | 2 | 2 + | 2 | 3 | two | 0 | | 3 | -3 + | 2 | 3 | two | 0 | | 2 | 4 + | 2 | 3 | two | 0 | | 5 | -5 + | 2 | 3 | two | 0 | | 5 | -5 + | 2 | 3 | two | 0 | | 0 | + | 2 | 3 | two | 0 | | | + | 2 | 3 | two | 0 | | | 0 | 3 | 2 | three | 0 | | 1 | -1 | 3 | 2 | three | 0 | | 2 | 2 | 3 | 2 | three | 0 | | 3 | -3 @@ -1138,24 +1208,6 @@ SELECT '' AS "xxx", * | 4 | 1 | four | 0 | | 0 | | 4 | 1 | four | 0 | | | | 4 | 1 | four | 0 | | | 0 - | 5 | 0 | five | 0 | | 1 | -1 - | 5 | 0 | five | 0 | | 2 | 2 - | 5 | 0 | five | 0 | | 3 | -3 - | 5 | 0 | five | 0 | | 2 | 4 - | 5 | 0 | five | 0 | | 5 | -5 - | 5 | 0 | five | 0 | | 5 | -5 - | 5 | 0 | five | 0 | | 0 | - | 5 | 0 | five | 0 | | | - | 5 | 0 | five | 0 | | | 0 - | 6 | 6 | six | 0 | | 1 | -1 - | 6 | 6 | six | 0 | | 2 | 2 - | 6 | 6 | six | 0 | | 3 | -3 - | 6 | 6 | six | 0 | | 2 | 4 - | 6 | 6 | six | 0 | | 5 | -5 - | 6 | 6 | six | 0 | | 5 | -5 - | 6 | 6 | six | 0 | | 0 | - | 6 | 6 | six | 0 | | | - | 6 | 6 | six | 0 | | | 0 | 7 | 7 | seven | 0 | | 1 | -1 | 7 | 7 | seven | 0 | | 2 | 2 | 7 | 7 | seven | 0 | | 3 | -3 @@ -1165,6 +1217,15 @@ SELECT '' AS "xxx", * | 7 | 7 | seven | 0 | | 0 | | 7 | 7 | seven | 0 | | | | 7 | 7 | seven | 0 | | | 0 + | 8 | 8 | eight | 0 | | 1 | -1 + | 8 | 8 | eight | 0 | | 2 | 2 + | 8 | 8 | eight | 0 | | 3 | -3 + | 8 | 8 | eight | 0 | | 2 | 4 + | 8 | 8 | eight | 0 | | 5 | -5 + | 8 | 8 | eight | 0 | | 5 | -5 + | 8 | 8 | eight | 0 | | 0 | + | 8 | 8 | eight | 0 | | | + | 8 | 8 | eight | 0 | | | 0 | | | null | 0 | | 1 | -1 | | | null | 0 | | 2 | 2 | | | null | 0 | | 3 | -3 @@ -1183,6 +1244,15 @@ SELECT '' AS "xxx", * | | 0 | zero | 0 | | 0 | | | 0 | zero | 0 | | | | | 0 | zero | 0 | | | 0 + | 2 | 3 | two | | | 1 | -1 + | 2 | 3 | two | | | 2 | 2 + | 2 | 3 | two | | | 3 | -3 + | 2 | 3 | two | | | 2 | 4 + | 2 | 3 | two | | | 5 | -5 + | 2 | 3 | two | | | 5 | -5 + | 2 | 3 | two | | | 0 | + | 2 | 3 | two | | | | + | 2 | 3 | two | | | | 0 | 3 | 2 | three | | | 1 | -1 | 3 | 2 | three | | | 2 | 2 | 3 | 2 | three | | | 3 | -3 @@ -1201,24 +1271,6 @@ SELECT '' AS "xxx", * | 4 | 1 | four | | | 0 | | 4 | 1 | four | | | | | 4 | 1 | four | | | | 0 - | 5 | 0 | five | | | 1 | -1 - | 5 | 0 | five | | | 2 | 2 - | 5 | 0 | five | | | 3 | -3 - | 5 | 0 | five | | | 2 | 4 - | 5 | 0 | five | | | 5 | -5 - | 5 | 0 | five | | | 5 | -5 - | 5 | 0 | five | | | 0 | - | 5 | 0 | five | | | | - | 5 | 0 | five | | | | 0 - | 6 | 6 | six | | | 1 | -1 - | 6 | 6 | six | | | 2 | 2 - | 6 | 6 | six | | | 3 | -3 - | 6 | 6 | six | | | 2 | 4 - | 6 | 6 | six | | | 5 | -5 - | 6 | 6 | six | | | 5 | -5 - | 6 | 6 | six | | | 0 | - | 6 | 6 | six | | | | - | 6 | 6 | six | | | | 0 | 7 | 7 | seven | | | 1 | -1 | 7 | 7 | seven | | | 2 | 2 | 7 | 7 | seven | | | 3 | -3 @@ -1228,6 +1280,15 @@ SELECT '' AS "xxx", * | 7 | 7 | seven | | | 0 | | 7 | 7 | seven | | | | | 7 | 7 | seven | | | | 0 + | 8 | 8 | eight | | | 1 | -1 + | 8 | 8 | eight | | | 2 | 2 + | 8 | 8 | eight | | | 3 | -3 + | 8 | 8 | eight | | | 2 | 4 + | 8 | 8 | eight | | | 5 | -5 + | 8 | 8 | eight | | | 5 | -5 + | 8 | 8 | eight | | | 0 | + | 8 | 8 | eight | | | | + | 8 | 8 | eight | | | | 0 | | | null | | | 1 | -1 | | | null | | | 2 | 2 | | | null | | | 3 | -3 @@ -1246,6 +1307,15 @@ SELECT '' AS "xxx", * | | 0 | zero | | | 0 | | | 0 | zero | | | | | | 0 | zero | | | | 0 + | 2 | 3 | two | | 0 | 1 | -1 + | 2 | 3 | two | | 0 | 2 | 2 + | 2 | 3 | two | | 0 | 3 | -3 + | 2 | 3 | two | | 0 | 2 | 4 + | 2 | 3 | two | | 0 | 5 | -5 + | 2 | 3 | two | | 0 | 5 | -5 + | 2 | 3 | two | | 0 | 0 | + | 2 | 3 | two | | 0 | | + | 2 | 3 | two | | 0 | | 0 | 3 | 2 | three | | 0 | 1 | -1 | 3 | 2 | three | | 0 | 2 | 2 | 3 | 2 | three | | 0 | 3 | -3 @@ -1264,24 +1334,6 @@ SELECT '' AS "xxx", * | 4 | 1 | four | | 0 | 0 | | 4 | 1 | four | | 0 | | | 4 | 1 | four | | 0 | | 0 - | 5 | 0 | five | | 0 | 1 | -1 - | 5 | 0 | five | | 0 | 2 | 2 - | 5 | 0 | five | | 0 | 3 | -3 - | 5 | 0 | five | | 0 | 2 | 4 - | 5 | 0 | five | | 0 | 5 | -5 - | 5 | 0 | five | | 0 | 5 | -5 - | 5 | 0 | five | | 0 | 0 | - | 5 | 0 | five | | 0 | | - | 5 | 0 | five | | 0 | | 0 - | 6 | 6 | six | | 0 | 1 | -1 - | 6 | 6 | six | | 0 | 2 | 2 - | 6 | 6 | six | | 0 | 3 | -3 - | 6 | 6 | six | | 0 | 2 | 4 - | 6 | 6 | six | | 0 | 5 | -5 - | 6 | 6 | six | | 0 | 5 | -5 - | 6 | 6 | six | | 0 | 0 | - | 6 | 6 | six | | 0 | | - | 6 | 6 | six | | 0 | | 0 | 7 | 7 | seven | | 0 | 1 | -1 | 7 | 7 | seven | | 0 | 2 | 2 | 7 | 7 | seven | | 0 | 3 | -3 @@ -1291,6 +1343,15 @@ SELECT '' AS "xxx", * | 7 | 7 | seven | | 0 | 0 | | 7 | 7 | seven | | 0 | | | 7 | 7 | seven | | 0 | | 0 + | 8 | 8 | eight | | 0 | 1 | -1 + | 8 | 8 | eight | | 0 | 2 | 2 + | 8 | 8 | eight | | 0 | 3 | -3 + | 8 | 8 | eight | | 0 | 2 | 4 + | 8 | 8 | eight | | 0 | 5 | -5 + | 8 | 8 | eight | | 0 | 5 | -5 + | 8 | 8 | eight | | 0 | 0 | + | 8 | 8 | eight | | 0 | | + | 8 | 8 | eight | | 0 | | 0 | | | null | | 0 | 1 | -1 | | | null | | 0 | 2 | 2 | | | null | | 0 | 3 | -3 @@ -1309,63 +1370,6 @@ SELECT '' AS "xxx", * | | 0 | zero | | 0 | 0 | | | 0 | zero | | 0 | | | | 0 | zero | | 0 | | 0 - | 0 | | zero | 0 | | 0 | - | 0 | | zero | 0 | | | - | 0 | | zero | 0 | | | 0 - | 1 | 4 | one | | | 1 | -1 - | 1 | 4 | one | | | 2 | 2 - | 1 | 4 | one | | | 3 | -3 - | 1 | 4 | one | | | 2 | 4 - | 1 | 4 | one | | | 5 | -5 - | 1 | 4 | one | | | 5 | -5 - | 1 | 4 | one | | | 0 | - | 1 | 4 | one | | | | - | 1 | 4 | one | | | | 0 - | 2 | 3 | two | | | 1 | -1 - | 2 | 3 | two | | | 2 | 2 - | 2 | 3 | two | | | 3 | -3 - | 2 | 3 | two | | | 2 | 4 - | 2 | 3 | two | | | 5 | -5 - | 2 | 3 | two | | | 5 | -5 - | 2 | 3 | two | | | 0 | - | 2 | 3 | two | | | | - | 2 | 3 | two | | | | 0 - | 0 | | zero | | | 1 | -1 - | 0 | | zero | | | 2 | 2 - | 0 | | zero | | | 3 | -3 - | 0 | | zero | | | 2 | 4 - | 0 | | zero | | | 5 | -5 - | 0 | | zero | | | 5 | -5 - | 0 | | zero | | | 0 | - | 0 | | zero | | | | - | 0 | | zero | | | | 0 - | 1 | 4 | one | | 0 | 1 | -1 - | 1 | 4 | one | | 0 | 2 | 2 - | 1 | 4 | one | | 0 | 3 | -3 - | 1 | 4 | one | | 0 | 2 | 4 - | 1 | 4 | one | | 0 | 5 | -5 - | 1 | 4 | one | | 0 | 5 | -5 - | 1 | 4 | one | | 0 | 0 | - | 1 | 4 | one | | 0 | | - | 1 | 4 | one | | 0 | | 0 - | 2 | 3 | two | | 0 | 1 | -1 - | 2 | 3 | two | | 0 | 2 | 2 - | 2 | 3 | two | | 0 | 3 | -3 - | 2 | 3 | two | | 0 | 2 | 4 - | 2 | 3 | two | | 0 | 5 | -5 - | 2 | 3 | two | | 0 | 5 | -5 - | 2 | 3 | two | | 0 | 0 | - | 2 | 3 | two | | 0 | | - | 2 | 3 | two | | 0 | | 0 - | 0 | | zero | | 0 | 1 | -1 - | 0 | | zero | | 0 | 2 | 2 - | 0 | | zero | | 0 | 3 | -3 - | 0 | | zero | | 0 | 2 | 4 - | 0 | | zero | | 0 | 5 | -5 - | 0 | | zero | | 0 | 5 | -5 - | 0 | | zero | | 0 | 0 | - | 0 | | zero | | 0 | | - | 0 | | zero | | 0 | | 0 (891 rows) -- @@ -1383,13 +1387,13 @@ SELECT '' AS "xxx", * FROM J1_TBL INNER JOIN J2_TBL USING (i); xxx | i | j | t | k -----+---+---+-------+---- - | 3 | 2 | three | -3 | 5 | 0 | five | -5 | 5 | 0 | five | -5 | 1 | 4 | one | -1 - | 2 | 3 | two | 4 - | 2 | 3 | two | 2 | 0 | | zero | + | 2 | 3 | two | 2 + | 3 | 2 | three | -3 + | 2 | 3 | two | 4 (7 rows) -- Same as above, slightly different syntax @@ -1397,11 +1401,11 @@ SELECT '' AS "xxx", * FROM J1_TBL JOIN J2_TBL USING (i); xxx | i | j | t | k -----+---+---+-------+---- - | 1 | 4 | one | -1 - | 2 | 3 | two | 4 | 2 | 3 | two | 2 - | 0 | | zero | | 3 | 2 | three | -3 + | 2 | 3 | two | 4 + | 1 | 4 | one | -1 + | 0 | | zero | | 5 | 0 | five | -5 | 5 | 0 | five | -5 (7 rows) @@ -1439,24 +1443,24 @@ SELECT '' AS "xxx", * FROM J1_TBL NATURAL JOIN J2_TBL; xxx | i | j | t | k -----+---+---+-------+---- - | 1 | 4 | one | -1 - | 2 | 3 | two | 4 | 2 | 3 | two | 2 - | 0 | | zero | | 3 | 2 | three | -3 + | 2 | 3 | two | 4 | 5 | 0 | five | -5 | 5 | 0 | five | -5 + | 1 | 4 | one | -1 + | 0 | | zero | (7 rows) SELECT '' AS "xxx", * FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (a, d); xxx | a | b | c | d -----+---+---+-------+---- - | 1 | 4 | one | -1 - | 2 | 3 | two | 4 | 2 | 3 | two | 2 - | 0 | | zero | | 3 | 2 | three | -3 + | 2 | 3 | two | 4 + | 1 | 4 | one | -1 + | 0 | | zero | | 5 | 0 | five | -5 | 5 | 0 | five | -5 (7 rows) @@ -1466,8 +1470,8 @@ SELECT '' AS "xxx", * xxx | a | b | c | d -----+---+---+------+--- | 2 | 3 | two | 2 - | 0 | | zero | | 4 | 1 | four | 2 + | 0 | | zero | (3 rows) -- mismatch number of columns @@ -1476,11 +1480,11 @@ SELECT '' AS "xxx", * FROM J1_TBL t1 (a, b) NATURAL JOIN J2_TBL t2 (a); xxx | a | b | t | k -----+---+---+-------+---- - | 1 | 4 | one | -1 - | 2 | 3 | two | 4 | 2 | 3 | two | 2 - | 0 | | zero | | 3 | 2 | three | -3 + | 2 | 3 | two | 4 + | 1 | 4 | one | -1 + | 0 | | zero | | 5 | 0 | five | -5 | 5 | 0 | five | -5 (7 rows) @@ -1493,10 +1497,10 @@ SELECT '' AS "xxx", * xxx | i | j | t | i | k -----+---+---+-------+---+---- | 1 | 4 | one | 1 | -1 - | 2 | 3 | two | 2 | 4 - | 2 | 3 | two | 2 | 2 | 0 | | zero | 0 | + | 2 | 3 | two | 2 | 2 | 3 | 2 | three | 3 | -3 + | 2 | 3 | two | 2 | 4 | 5 | 0 | five | 5 | -5 | 5 | 0 | five | 5 | -5 (7 rows) @@ -1505,8 +1509,8 @@ SELECT '' AS "xxx", * FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.k); xxx | i | j | t | i | k -----+---+---+------+---+--- - | 2 | 3 | two | 2 | 2 | 0 | | zero | | 0 + | 2 | 3 | two | 2 | 2 | 4 | 1 | four | 2 | 4 (3 rows) @@ -1518,12 +1522,12 @@ SELECT '' AS "xxx", * xxx | i | j | t | i | k -----+---+---+-------+---+--- | 1 | 4 | one | 2 | 2 - | 1 | 4 | one | 2 | 4 - | 2 | 3 | two | 2 | 2 - | 2 | 3 | two | 2 | 4 | 0 | | zero | 2 | 2 + | 1 | 4 | one | 2 | 4 | 0 | | zero | 2 | 4 | 0 | | zero | | 0 + | 2 | 3 | two | 2 | 2 + | 2 | 3 | two | 2 | 4 | 3 | 2 | three | 2 | 4 | 4 | 1 | four | 2 | 4 (9 rows) @@ -1576,15 +1580,15 @@ SELECT '' AS "xxx", * FROM J1_TBL RIGHT OUTER JOIN J2_TBL USING (i); xxx | i | j | t | k -----+---+---+-------+---- - | 1 | 4 | one | -1 | 2 | 3 | two | 2 | 3 | 2 | three | -3 | 2 | 3 | two | 4 - | 5 | 0 | five | -5 - | 5 | 0 | five | -5 - | 0 | | zero | | | | | | | | | 0 + | 1 | 4 | one | -1 + | 0 | | zero | + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 (9 rows) SELECT '' AS "xxx", * @@ -1592,14 +1596,14 @@ SELECT '' AS "xxx", * xxx | i | j | t | k -----+---+---+-------+---- | 1 | 4 | one | -1 + | 0 | | zero | | 2 | 3 | two | 2 | 3 | 2 | three | -3 | 2 | 3 | two | 4 - | 5 | 0 | five | -5 - | 5 | 0 | five | -5 - | 0 | | zero | | | | | | | | | 0 + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 (9 rows) SELECT '' AS "xxx", * @@ -1681,8 +1685,8 @@ SELECT * FROM t1 FULL JOIN t2 USING (name) FULL JOIN t3 USING (name); ------+----+----+---- bb | 11 | 12 | 13 dd | | | 33 - cc | | 22 | 23 ee | | 42 | + cc | | 22 | 23 (4 rows) -- @@ -1696,8 +1700,8 @@ INNER JOIN USING (name); name | n | n ------+----+---- - bb | 12 | 13 cc | 22 | 23 + bb | 12 | 13 (2 rows) SELECT * FROM @@ -1708,8 +1712,8 @@ USING (name); name | n | n ------+----+---- bb | 12 | 13 - cc | 22 | 23 ee | 42 | + cc | 22 | 23 (3 rows) SELECT * FROM @@ -1719,10 +1723,10 @@ FULL JOIN USING (name); name | n | n ------+----+---- - bb | 12 | 13 cc | 22 | 23 - dd | | 33 ee | 42 | + bb | 12 | 13 + dd | | 33 (4 rows) -- Cases with non-nullable expressions in subquery results; @@ -1744,8 +1748,8 @@ NATURAL LEFT JOIN name | s2_n | s2_2 | s3_n | s3_2 ------+------+------+------+------ bb | 12 | 2 | 13 | 3 - cc | 22 | 2 | 23 | 3 ee | 42 | 2 | | + cc | 22 | 2 | 23 | 3 (3 rows) SELECT * FROM @@ -1755,8 +1759,8 @@ NATURAL FULL JOIN name | s2_n | s2_2 | s3_n | s3_2 ------+------+------+------+------ bb | 12 | 2 | 13 | 3 - cc | 22 | 2 | 23 | 3 dd | | | 33 | 3 + cc | 22 | 2 | 23 | 3 ee | 42 | 2 | | (4 rows) @@ -1781,8 +1785,8 @@ NATURAL FULL JOIN ------+------+------+------+------+------+------ bb | 11 | 1 | 12 | 2 | 13 | 3 dd | | | | | 33 | 3 - cc | | | 22 | 2 | 23 | 3 ee | | | 42 | 2 | | + cc | | | 22 | 2 | 23 | 3 (4 rows) SELECT * FROM @@ -1795,10 +1799,10 @@ NATURAL FULL JOIN ) ss2; name | s1_n | s2_n | s3_n ------+------+------+------ - cc | | 22 | 23 - ee | | 42 | bb | 11 | 12 | 13 dd | | | 33 + ee | | 42 | + cc | | 22 | 23 (4 rows) SELECT * FROM @@ -1813,8 +1817,8 @@ NATURAL FULL JOIN ------+------+------+------+------ bb | 11 | 12 | 2 | 13 dd | | | | 33 - cc | | 22 | 2 | 23 ee | | 42 | 2 | + cc | | 22 | 2 | 23 (4 rows) -- Test for propagation of nullability constraints into sub-joins @@ -1844,19 +1848,19 @@ select * from x; select * from y; y1 | y2 ----+----- + 2 | 222 3 | 333 4 | 1 | 111 - 2 | 222 (4 rows) select * from x left join y on (x1 = y1 and x2 is not null); x1 | x2 | y1 | y2 ----+----+----+----- - 1 | 11 | 1 | 111 2 | 22 | 2 | 222 3 | | | 4 | 44 | 4 | + 1 | 11 | 1 | 111 5 | | | (5 rows) @@ -1864,20 +1868,20 @@ select * from x left join y on (x1 = y1 and y2 is not null); x1 | x2 | y1 | y2 ----+----+----+----- 1 | 11 | 1 | 111 + 5 | | | 2 | 22 | 2 | 222 3 | | 3 | 333 4 | 44 | | - 5 | | | (5 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | 3 | 4 | 44 | 4 | | 4 | 44 + 1 | 11 | 1 | 111 | 1 | 11 5 | | | | 5 | (5 rows) @@ -1919,27 +1923,27 @@ select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1) where (x2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 4 | 44 | 4 | | 4 | 44 + 1 | 11 | 1 | 111 | 1 | 11 (3 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1) where (y2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 3 | | 3 | 333 | 3 | + 1 | 11 | 1 | 111 | 1 | 11 (3 rows) select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1) where (xx2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 ----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 2 | 22 | 2 | 222 | 2 | 22 4 | 44 | 4 | | 4 | 44 + 1 | 11 | 1 | 111 | 1 | 11 (3 rows) -- @@ -2018,8 +2022,8 @@ set enable_nestloop to off; select tt1.*, tt2.* from tt1 left join tt2 on tt1.joincol = tt2.joincol; tt1_id | joincol | tt2_id | joincol --------+---------+--------+--------- - 1 | 11 | 21 | 11 1 | 11 | 22 | 11 + 1 | 11 | 21 | 11 2 | | | (3 rows) @@ -2055,9 +2059,9 @@ LEFT JOIN ( WHERE d.f1 IS NULL; f1 ------ + 9999 0 1 - 9999 (3 rows) -- @@ -2509,7 +2513,7 @@ explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) retur -- CBDB_FIXME: How to derive a plan? -- Replicates join OuterQuery explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select ( select foo.c1 from (select * from strewn_issue_15860) foo join cte1 using(c2) where foo.c1 = hash_issue_15860.c1) from hash_issue_15860; -ERROR: could not devise a query plan for the given query (pathnode.c:281) +ERROR: could not devise a query plan for the given query (pathnode.c:285) -- Test case for Github Issue 17460 create table t_17460 (a int ) distributed replicated; create table foo_17460 (a int); @@ -2522,15 +2526,15 @@ analyze foo_17460; -- update|delete on replicated table should not use unique rowid skill -- to plan semi join. explain (costs off) delete from t_17460 where a in (select a from foo_17460); - QUERY PLAN ---------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------- Delete on t_17460 - -> Hash Semi Join - Hash Cond: (t_17460.a = foo_17460.a) - -> Seq Scan on t_17460 + -> Hash Right Semi Join + Hash Cond: (foo_17460.a = t_17460.a) + -> Broadcast Motion 3:3 (slice1; segments: 3) + -> Seq Scan on foo_17460 -> Hash - -> Broadcast Motion 3:3 (slice1; segments: 3) - -> Seq Scan on foo_17460 + -> Seq Scan on t_17460 Optimizer: Postgres query optimizer (8 rows) diff --git a/src/test/regress/expected/rpt_joins_optimizer.out b/src/test/regress/expected/rpt_joins_optimizer.out new file mode 100644 index 00000000000..25ff4770dd6 --- /dev/null +++ b/src/test/regress/expected/rpt_joins_optimizer.out @@ -0,0 +1,2556 @@ +-- +-- Tests for joins between replicated tables +-- +-- start_ignore +create extension if not exists gp_debug_numsegments; +NOTICE: extension "gp_debug_numsegments" already exists, skipping +-- end_ignore +create schema rpt_joins; +set search_path to rpt_joins, public; +-- +-- Test JOIN clauses, bellow tests are copy from tests for partitioned table +-- +CREATE TABLE J1_TBL ( + i integer, + j integer, + t text +); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'i' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE J2_TBL ( + i integer, + k integer +) distributed replicated; +INSERT INTO J1_TBL VALUES (1, 4, 'one'); +INSERT INTO J1_TBL VALUES (2, 3, 'two'); +INSERT INTO J1_TBL VALUES (3, 2, 'three'); +INSERT INTO J1_TBL VALUES (4, 1, 'four'); +INSERT INTO J1_TBL VALUES (5, 0, 'five'); +INSERT INTO J1_TBL VALUES (6, 6, 'six'); +INSERT INTO J1_TBL VALUES (7, 7, 'seven'); +INSERT INTO J1_TBL VALUES (8, 8, 'eight'); +INSERT INTO J1_TBL VALUES (0, NULL, 'zero'); +INSERT INTO J1_TBL VALUES (NULL, NULL, 'null'); +INSERT INTO J1_TBL VALUES (NULL, 0, 'zero'); +INSERT INTO J2_TBL VALUES (1, -1); +INSERT INTO J2_TBL VALUES (2, 2); +INSERT INTO J2_TBL VALUES (3, -3); +INSERT INTO J2_TBL VALUES (2, 4); +INSERT INTO J2_TBL VALUES (5, -5); +INSERT INTO J2_TBL VALUES (5, -5); +INSERT INTO J2_TBL VALUES (0, NULL); +INSERT INTO J2_TBL VALUES (NULL, NULL); +INSERT INTO J2_TBL VALUES (NULL, 0); +-- +-- CROSS JOIN +-- Qualifications are not allowed on cross joins, +-- which degenerate into a standard unqualified inner join. +-- +SELECT '' AS "xxx", * + FROM J1_TBL CROSS JOIN J2_TBL; + xxx | i | j | t | i | k +-----+---+---+-------+---+---- + | 2 | 3 | two | 1 | -1 + | 2 | 3 | two | 2 | 2 + | 2 | 3 | two | 3 | -3 + | 2 | 3 | two | 2 | 4 + | 2 | 3 | two | 5 | -5 + | 2 | 3 | two | 5 | -5 + | 2 | 3 | two | 0 | + | 2 | 3 | two | | + | 2 | 3 | two | | 0 + | 3 | 2 | three | 1 | -1 + | 3 | 2 | three | 2 | 2 + | 3 | 2 | three | 3 | -3 + | 3 | 2 | three | 2 | 4 + | 3 | 2 | three | 5 | -5 + | 3 | 2 | three | 5 | -5 + | 3 | 2 | three | 0 | + | 3 | 2 | three | | + | 3 | 2 | three | | 0 + | 4 | 1 | four | 1 | -1 + | 4 | 1 | four | 2 | 2 + | 4 | 1 | four | 3 | -3 + | 4 | 1 | four | 2 | 4 + | 4 | 1 | four | 5 | -5 + | 4 | 1 | four | 5 | -5 + | 4 | 1 | four | 0 | + | 4 | 1 | four | | + | 4 | 1 | four | | 0 + | 7 | 7 | seven | 1 | -1 + | 7 | 7 | seven | 2 | 2 + | 7 | 7 | seven | 3 | -3 + | 7 | 7 | seven | 2 | 4 + | 7 | 7 | seven | 5 | -5 + | 7 | 7 | seven | 5 | -5 + | 7 | 7 | seven | 0 | + | 7 | 7 | seven | | + | 7 | 7 | seven | | 0 + | 8 | 8 | eight | 1 | -1 + | 8 | 8 | eight | 2 | 2 + | 8 | 8 | eight | 3 | -3 + | 8 | 8 | eight | 2 | 4 + | 8 | 8 | eight | 5 | -5 + | 8 | 8 | eight | 5 | -5 + | 8 | 8 | eight | 0 | + | 8 | 8 | eight | | + | 8 | 8 | eight | | 0 + | | | null | 1 | -1 + | | | null | 2 | 2 + | | | null | 3 | -3 + | | | null | 2 | 4 + | | | null | 5 | -5 + | | | null | 5 | -5 + | | | null | 0 | + | | | null | | + | | | null | | 0 + | | 0 | zero | 1 | -1 + | | 0 | zero | 2 | 2 + | | 0 | zero | 3 | -3 + | | 0 | zero | 2 | 4 + | | 0 | zero | 5 | -5 + | | 0 | zero | 5 | -5 + | | 0 | zero | 0 | + | | 0 | zero | | + | | 0 | zero | | 0 + | 1 | 4 | one | 1 | -1 + | 1 | 4 | one | 2 | 2 + | 1 | 4 | one | 3 | -3 + | 1 | 4 | one | 2 | 4 + | 1 | 4 | one | 5 | -5 + | 1 | 4 | one | 5 | -5 + | 1 | 4 | one | 0 | + | 1 | 4 | one | | + | 1 | 4 | one | | 0 + | 0 | | zero | 1 | -1 + | 0 | | zero | 2 | 2 + | 0 | | zero | 3 | -3 + | 0 | | zero | 2 | 4 + | 0 | | zero | 5 | -5 + | 0 | | zero | 5 | -5 + | 0 | | zero | 0 | + | 0 | | zero | | + | 0 | | zero | | 0 + | 5 | 0 | five | 1 | -1 + | 5 | 0 | five | 2 | 2 + | 5 | 0 | five | 3 | -3 + | 5 | 0 | five | 2 | 4 + | 5 | 0 | five | 5 | -5 + | 5 | 0 | five | 5 | -5 + | 5 | 0 | five | 0 | + | 5 | 0 | five | | + | 5 | 0 | five | | 0 + | 6 | 6 | six | 1 | -1 + | 6 | 6 | six | 2 | 2 + | 6 | 6 | six | 3 | -3 + | 6 | 6 | six | 2 | 4 + | 6 | 6 | six | 5 | -5 + | 6 | 6 | six | 5 | -5 + | 6 | 6 | six | 0 | + | 6 | 6 | six | | + | 6 | 6 | six | | 0 +(99 rows) + +-- ambiguous column +SELECT '' AS "xxx", i, k, t + FROM J1_TBL CROSS JOIN J2_TBL; +ERROR: column reference "i" is ambiguous +LINE 1: SELECT '' AS "xxx", i, k, t + ^ +-- resolve previous ambiguity by specifying the table name +SELECT '' AS "xxx", t1.i, k, t + FROM J1_TBL t1 CROSS JOIN J2_TBL t2; + xxx | i | k | t +-----+---+----+------- + | 2 | -1 | two + | 2 | 2 | two + | 2 | -3 | two + | 2 | 4 | two + | 2 | -5 | two + | 2 | -5 | two + | 2 | | two + | 2 | | two + | 2 | 0 | two + | 3 | -1 | three + | 3 | 2 | three + | 3 | -3 | three + | 3 | 4 | three + | 3 | -5 | three + | 3 | -5 | three + | 3 | | three + | 3 | | three + | 3 | 0 | three + | 4 | -1 | four + | 4 | 2 | four + | 4 | -3 | four + | 4 | 4 | four + | 4 | -5 | four + | 4 | -5 | four + | 4 | | four + | 4 | | four + | 4 | 0 | four + | 7 | -1 | seven + | 7 | 2 | seven + | 7 | -3 | seven + | 7 | 4 | seven + | 7 | -5 | seven + | 7 | -5 | seven + | 7 | | seven + | 7 | | seven + | 7 | 0 | seven + | 8 | -1 | eight + | 8 | 2 | eight + | 8 | -3 | eight + | 8 | 4 | eight + | 8 | -5 | eight + | 8 | -5 | eight + | 8 | | eight + | 8 | | eight + | 8 | 0 | eight + | | -1 | null + | | 2 | null + | | -3 | null + | | 4 | null + | | -5 | null + | | -5 | null + | | | null + | | | null + | | 0 | null + | | -1 | zero + | | 2 | zero + | | -3 | zero + | | 4 | zero + | | -5 | zero + | | -5 | zero + | | | zero + | | | zero + | | 0 | zero + | 1 | -1 | one + | 1 | 2 | one + | 1 | -3 | one + | 1 | 4 | one + | 1 | -5 | one + | 1 | -5 | one + | 1 | | one + | 1 | | one + | 1 | 0 | one + | 0 | -1 | zero + | 0 | 2 | zero + | 0 | -3 | zero + | 0 | 4 | zero + | 0 | -5 | zero + | 0 | -5 | zero + | 0 | | zero + | 0 | | zero + | 0 | 0 | zero + | 5 | -1 | five + | 5 | 2 | five + | 5 | -3 | five + | 5 | 4 | five + | 5 | -5 | five + | 5 | -5 | five + | 5 | | five + | 5 | | five + | 5 | 0 | five + | 6 | -1 | six + | 6 | 2 | six + | 6 | -3 | six + | 6 | 4 | six + | 6 | -5 | six + | 6 | -5 | six + | 6 | | six + | 6 | | six + | 6 | 0 | six +(99 rows) + +SELECT '' AS "xxx", ii, tt, kk + FROM (J1_TBL CROSS JOIN J2_TBL) + AS tx (ii, jj, tt, ii2, kk); + xxx | ii | tt | kk +-----+----+-------+---- + | 2 | two | -1 + | 2 | two | 2 + | 2 | two | -3 + | 2 | two | 4 + | 2 | two | -5 + | 2 | two | -5 + | 2 | two | + | 2 | two | + | 2 | two | 0 + | 3 | three | -1 + | 3 | three | 2 + | 3 | three | -3 + | 3 | three | 4 + | 3 | three | -5 + | 3 | three | -5 + | 3 | three | + | 3 | three | + | 3 | three | 0 + | 4 | four | -1 + | 4 | four | 2 + | 4 | four | -3 + | 4 | four | 4 + | 4 | four | -5 + | 4 | four | -5 + | 4 | four | + | 4 | four | + | 4 | four | 0 + | 7 | seven | -1 + | 7 | seven | 2 + | 7 | seven | -3 + | 7 | seven | 4 + | 7 | seven | -5 + | 7 | seven | -5 + | 7 | seven | + | 7 | seven | + | 7 | seven | 0 + | 8 | eight | -1 + | 8 | eight | 2 + | 8 | eight | -3 + | 8 | eight | 4 + | 8 | eight | -5 + | 8 | eight | -5 + | 8 | eight | + | 8 | eight | + | 8 | eight | 0 + | | null | -1 + | | null | 2 + | | null | -3 + | | null | 4 + | | null | -5 + | | null | -5 + | | null | + | | null | + | | null | 0 + | | zero | -1 + | | zero | 2 + | | zero | -3 + | | zero | 4 + | | zero | -5 + | | zero | -5 + | | zero | + | | zero | + | | zero | 0 + | 1 | one | -1 + | 1 | one | 2 + | 1 | one | -3 + | 1 | one | 4 + | 1 | one | -5 + | 1 | one | -5 + | 1 | one | + | 1 | one | + | 1 | one | 0 + | 0 | zero | -1 + | 0 | zero | 2 + | 0 | zero | -3 + | 0 | zero | 4 + | 0 | zero | -5 + | 0 | zero | -5 + | 0 | zero | + | 0 | zero | + | 0 | zero | 0 + | 5 | five | -1 + | 5 | five | 2 + | 5 | five | -3 + | 5 | five | 4 + | 5 | five | -5 + | 5 | five | -5 + | 5 | five | + | 5 | five | + | 5 | five | 0 + | 6 | six | -1 + | 6 | six | 2 + | 6 | six | -3 + | 6 | six | 4 + | 6 | six | -5 + | 6 | six | -5 + | 6 | six | + | 6 | six | + | 6 | six | 0 +(99 rows) + +SELECT '' AS "xxx", tx.ii, tx.jj, tx.kk + FROM (J1_TBL t1 (a, b, c) CROSS JOIN J2_TBL t2 (d, e)) + AS tx (ii, jj, tt, ii2, kk); + xxx | ii | jj | kk +-----+----+----+---- + | 5 | 0 | -1 + | 5 | 0 | 2 + | 5 | 0 | -3 + | 5 | 0 | 4 + | 5 | 0 | -5 + | 5 | 0 | -5 + | 5 | 0 | + | 5 | 0 | + | 5 | 0 | 0 + | 6 | 6 | -1 + | 6 | 6 | 2 + | 6 | 6 | -3 + | 6 | 6 | 4 + | 6 | 6 | -5 + | 6 | 6 | -5 + | 6 | 6 | + | 6 | 6 | + | 6 | 6 | 0 + | 2 | 3 | -1 + | 2 | 3 | 2 + | 2 | 3 | -3 + | 2 | 3 | 4 + | 2 | 3 | -5 + | 2 | 3 | -5 + | 2 | 3 | + | 2 | 3 | + | 2 | 3 | 0 + | 3 | 2 | -1 + | 3 | 2 | 2 + | 3 | 2 | -3 + | 3 | 2 | 4 + | 3 | 2 | -5 + | 3 | 2 | -5 + | 3 | 2 | + | 3 | 2 | + | 3 | 2 | 0 + | 4 | 1 | -1 + | 4 | 1 | 2 + | 4 | 1 | -3 + | 4 | 1 | 4 + | 4 | 1 | -5 + | 4 | 1 | -5 + | 4 | 1 | + | 4 | 1 | + | 4 | 1 | 0 + | 7 | 7 | -1 + | 7 | 7 | 2 + | 7 | 7 | -3 + | 7 | 7 | 4 + | 7 | 7 | -5 + | 7 | 7 | -5 + | 7 | 7 | + | 7 | 7 | + | 7 | 7 | 0 + | 8 | 8 | -1 + | 8 | 8 | 2 + | 8 | 8 | -3 + | 8 | 8 | 4 + | 8 | 8 | -5 + | 8 | 8 | -5 + | 8 | 8 | + | 8 | 8 | + | 8 | 8 | 0 + | | | -1 + | | | 2 + | | | -3 + | | | 4 + | | | -5 + | | | -5 + | | | + | | | + | | | 0 + | | 0 | -1 + | | 0 | 2 + | | 0 | -3 + | | 0 | 4 + | | 0 | -5 + | | 0 | -5 + | | 0 | + | | 0 | + | | 0 | 0 + | 1 | 4 | -1 + | 1 | 4 | 2 + | 1 | 4 | -3 + | 1 | 4 | 4 + | 1 | 4 | -5 + | 1 | 4 | -5 + | 1 | 4 | + | 1 | 4 | + | 1 | 4 | 0 + | 0 | | -1 + | 0 | | 2 + | 0 | | -3 + | 0 | | 4 + | 0 | | -5 + | 0 | | -5 + | 0 | | + | 0 | | + | 0 | | 0 +(99 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL CROSS JOIN J2_TBL a CROSS JOIN J2_TBL b; + xxx | i | j | t | i | k | i | k +-----+---+---+-------+---+----+---+---- + | 2 | 3 | two | 1 | -1 | 1 | -1 + | 2 | 3 | two | 2 | 2 | 1 | -1 + | 2 | 3 | two | 3 | -3 | 1 | -1 + | 2 | 3 | two | 2 | 4 | 1 | -1 + | 2 | 3 | two | 5 | -5 | 1 | -1 + | 2 | 3 | two | 5 | -5 | 1 | -1 + | 2 | 3 | two | 0 | | 1 | -1 + | 2 | 3 | two | | | 1 | -1 + | 2 | 3 | two | | 0 | 1 | -1 + | 2 | 3 | two | 1 | -1 | 2 | 2 + | 2 | 3 | two | 2 | 2 | 2 | 2 + | 2 | 3 | two | 3 | -3 | 2 | 2 + | 2 | 3 | two | 2 | 4 | 2 | 2 + | 2 | 3 | two | 5 | -5 | 2 | 2 + | 2 | 3 | two | 5 | -5 | 2 | 2 + | 2 | 3 | two | 0 | | 2 | 2 + | 2 | 3 | two | | | 2 | 2 + | 2 | 3 | two | | 0 | 2 | 2 + | 2 | 3 | two | 1 | -1 | 3 | -3 + | 2 | 3 | two | 2 | 2 | 3 | -3 + | 2 | 3 | two | 3 | -3 | 3 | -3 + | 2 | 3 | two | 2 | 4 | 3 | -3 + | 2 | 3 | two | 5 | -5 | 3 | -3 + | 2 | 3 | two | 5 | -5 | 3 | -3 + | 2 | 3 | two | 0 | | 3 | -3 + | 2 | 3 | two | | | 3 | -3 + | 2 | 3 | two | | 0 | 3 | -3 + | 2 | 3 | two | 1 | -1 | 2 | 4 + | 2 | 3 | two | 2 | 2 | 2 | 4 + | 2 | 3 | two | 3 | -3 | 2 | 4 + | 2 | 3 | two | 2 | 4 | 2 | 4 + | 2 | 3 | two | 5 | -5 | 2 | 4 + | 2 | 3 | two | 5 | -5 | 2 | 4 + | 2 | 3 | two | 0 | | 2 | 4 + | 2 | 3 | two | | | 2 | 4 + | 2 | 3 | two | | 0 | 2 | 4 + | 2 | 3 | two | 1 | -1 | 5 | -5 + | 2 | 3 | two | 2 | 2 | 5 | -5 + | 2 | 3 | two | 3 | -3 | 5 | -5 + | 2 | 3 | two | 2 | 4 | 5 | -5 + | 2 | 3 | two | 5 | -5 | 5 | -5 + | 2 | 3 | two | 5 | -5 | 5 | -5 + | 2 | 3 | two | 0 | | 5 | -5 + | 2 | 3 | two | | | 5 | -5 + | 2 | 3 | two | | 0 | 5 | -5 + | 2 | 3 | two | 1 | -1 | 5 | -5 + | 2 | 3 | two | 2 | 2 | 5 | -5 + | 2 | 3 | two | 3 | -3 | 5 | -5 + | 2 | 3 | two | 2 | 4 | 5 | -5 + | 2 | 3 | two | 5 | -5 | 5 | -5 + | 2 | 3 | two | 5 | -5 | 5 | -5 + | 2 | 3 | two | 0 | | 5 | -5 + | 2 | 3 | two | | | 5 | -5 + | 2 | 3 | two | | 0 | 5 | -5 + | 2 | 3 | two | 1 | -1 | 0 | + | 2 | 3 | two | 2 | 2 | 0 | + | 2 | 3 | two | 3 | -3 | 0 | + | 2 | 3 | two | 2 | 4 | 0 | + | 2 | 3 | two | 5 | -5 | 0 | + | 2 | 3 | two | 5 | -5 | 0 | + | 2 | 3 | two | 0 | | 0 | + | 2 | 3 | two | | | 0 | + | 2 | 3 | two | | 0 | 0 | + | 2 | 3 | two | 1 | -1 | | + | 2 | 3 | two | 2 | 2 | | + | 2 | 3 | two | 3 | -3 | | + | 2 | 3 | two | 2 | 4 | | + | 2 | 3 | two | 5 | -5 | | + | 2 | 3 | two | 5 | -5 | | + | 2 | 3 | two | 0 | | | + | 2 | 3 | two | | | | + | 2 | 3 | two | | 0 | | + | 2 | 3 | two | 1 | -1 | | 0 + | 2 | 3 | two | 2 | 2 | | 0 + | 2 | 3 | two | 3 | -3 | | 0 + | 2 | 3 | two | 2 | 4 | | 0 + | 2 | 3 | two | 5 | -5 | | 0 + | 2 | 3 | two | 5 | -5 | | 0 + | 2 | 3 | two | 0 | | | 0 + | 2 | 3 | two | | | | 0 + | 2 | 3 | two | | 0 | | 0 + | 3 | 2 | three | 1 | -1 | 1 | -1 + | 3 | 2 | three | 2 | 2 | 1 | -1 + | 3 | 2 | three | 3 | -3 | 1 | -1 + | 3 | 2 | three | 2 | 4 | 1 | -1 + | 3 | 2 | three | 5 | -5 | 1 | -1 + | 3 | 2 | three | 5 | -5 | 1 | -1 + | 3 | 2 | three | 0 | | 1 | -1 + | 3 | 2 | three | | | 1 | -1 + | 3 | 2 | three | | 0 | 1 | -1 + | 3 | 2 | three | 1 | -1 | 2 | 2 + | 3 | 2 | three | 2 | 2 | 2 | 2 + | 3 | 2 | three | 3 | -3 | 2 | 2 + | 3 | 2 | three | 2 | 4 | 2 | 2 + | 3 | 2 | three | 5 | -5 | 2 | 2 + | 3 | 2 | three | 5 | -5 | 2 | 2 + | 3 | 2 | three | 0 | | 2 | 2 + | 3 | 2 | three | | | 2 | 2 + | 3 | 2 | three | | 0 | 2 | 2 + | 3 | 2 | three | 1 | -1 | 3 | -3 + | 3 | 2 | three | 2 | 2 | 3 | -3 + | 3 | 2 | three | 3 | -3 | 3 | -3 + | 3 | 2 | three | 2 | 4 | 3 | -3 + | 3 | 2 | three | 5 | -5 | 3 | -3 + | 3 | 2 | three | 5 | -5 | 3 | -3 + | 3 | 2 | three | 0 | | 3 | -3 + | 3 | 2 | three | | | 3 | -3 + | 3 | 2 | three | | 0 | 3 | -3 + | 3 | 2 | three | 1 | -1 | 2 | 4 + | 3 | 2 | three | 2 | 2 | 2 | 4 + | 3 | 2 | three | 3 | -3 | 2 | 4 + | 3 | 2 | three | 2 | 4 | 2 | 4 + | 3 | 2 | three | 5 | -5 | 2 | 4 + | 3 | 2 | three | 5 | -5 | 2 | 4 + | 3 | 2 | three | 0 | | 2 | 4 + | 3 | 2 | three | | | 2 | 4 + | 3 | 2 | three | | 0 | 2 | 4 + | 3 | 2 | three | 1 | -1 | 5 | -5 + | 3 | 2 | three | 2 | 2 | 5 | -5 + | 3 | 2 | three | 3 | -3 | 5 | -5 + | 3 | 2 | three | 2 | 4 | 5 | -5 + | 3 | 2 | three | 5 | -5 | 5 | -5 + | 3 | 2 | three | 5 | -5 | 5 | -5 + | 3 | 2 | three | 0 | | 5 | -5 + | 3 | 2 | three | | | 5 | -5 + | 3 | 2 | three | | 0 | 5 | -5 + | 3 | 2 | three | 1 | -1 | 5 | -5 + | 3 | 2 | three | 2 | 2 | 5 | -5 + | 3 | 2 | three | 3 | -3 | 5 | -5 + | 3 | 2 | three | 2 | 4 | 5 | -5 + | 3 | 2 | three | 5 | -5 | 5 | -5 + | 3 | 2 | three | 5 | -5 | 5 | -5 + | 3 | 2 | three | 0 | | 5 | -5 + | 3 | 2 | three | | | 5 | -5 + | 3 | 2 | three | | 0 | 5 | -5 + | 3 | 2 | three | 1 | -1 | 0 | + | 3 | 2 | three | 2 | 2 | 0 | + | 3 | 2 | three | 3 | -3 | 0 | + | 3 | 2 | three | 2 | 4 | 0 | + | 3 | 2 | three | 5 | -5 | 0 | + | 3 | 2 | three | 5 | -5 | 0 | + | 3 | 2 | three | 0 | | 0 | + | 3 | 2 | three | | | 0 | + | 3 | 2 | three | | 0 | 0 | + | 3 | 2 | three | 1 | -1 | | + | 3 | 2 | three | 2 | 2 | | + | 3 | 2 | three | 3 | -3 | | + | 3 | 2 | three | 2 | 4 | | + | 3 | 2 | three | 5 | -5 | | + | 3 | 2 | three | 5 | -5 | | + | 3 | 2 | three | 0 | | | + | 3 | 2 | three | | | | + | 3 | 2 | three | | 0 | | + | 3 | 2 | three | 1 | -1 | | 0 + | 3 | 2 | three | 2 | 2 | | 0 + | 3 | 2 | three | 3 | -3 | | 0 + | 3 | 2 | three | 2 | 4 | | 0 + | 3 | 2 | three | 5 | -5 | | 0 + | 3 | 2 | three | 5 | -5 | | 0 + | 3 | 2 | three | 0 | | | 0 + | 3 | 2 | three | | | | 0 + | 3 | 2 | three | | 0 | | 0 + | 4 | 1 | four | 1 | -1 | 1 | -1 + | 4 | 1 | four | 2 | 2 | 1 | -1 + | 4 | 1 | four | 3 | -3 | 1 | -1 + | 4 | 1 | four | 2 | 4 | 1 | -1 + | 4 | 1 | four | 5 | -5 | 1 | -1 + | 4 | 1 | four | 5 | -5 | 1 | -1 + | 4 | 1 | four | 0 | | 1 | -1 + | 4 | 1 | four | | | 1 | -1 + | 4 | 1 | four | | 0 | 1 | -1 + | 4 | 1 | four | 1 | -1 | 2 | 2 + | 4 | 1 | four | 2 | 2 | 2 | 2 + | 4 | 1 | four | 3 | -3 | 2 | 2 + | 4 | 1 | four | 2 | 4 | 2 | 2 + | 4 | 1 | four | 5 | -5 | 2 | 2 + | 4 | 1 | four | 5 | -5 | 2 | 2 + | 4 | 1 | four | 0 | | 2 | 2 + | 4 | 1 | four | | | 2 | 2 + | 4 | 1 | four | | 0 | 2 | 2 + | 4 | 1 | four | 1 | -1 | 3 | -3 + | 4 | 1 | four | 2 | 2 | 3 | -3 + | 4 | 1 | four | 3 | -3 | 3 | -3 + | 4 | 1 | four | 2 | 4 | 3 | -3 + | 4 | 1 | four | 5 | -5 | 3 | -3 + | 4 | 1 | four | 5 | -5 | 3 | -3 + | 4 | 1 | four | 0 | | 3 | -3 + | 4 | 1 | four | | | 3 | -3 + | 4 | 1 | four | | 0 | 3 | -3 + | 4 | 1 | four | 1 | -1 | 2 | 4 + | 4 | 1 | four | 2 | 2 | 2 | 4 + | 4 | 1 | four | 3 | -3 | 2 | 4 + | 4 | 1 | four | 2 | 4 | 2 | 4 + | 4 | 1 | four | 5 | -5 | 2 | 4 + | 4 | 1 | four | 5 | -5 | 2 | 4 + | 4 | 1 | four | 0 | | 2 | 4 + | 4 | 1 | four | | | 2 | 4 + | 5 | 0 | five | 1 | -1 | 1 | -1 + | 5 | 0 | five | 2 | 2 | 1 | -1 + | 5 | 0 | five | 3 | -3 | 1 | -1 + | 5 | 0 | five | 2 | 4 | 1 | -1 + | 5 | 0 | five | 5 | -5 | 1 | -1 + | 5 | 0 | five | 5 | -5 | 1 | -1 + | 5 | 0 | five | 0 | | 1 | -1 + | 5 | 0 | five | | | 1 | -1 + | 5 | 0 | five | | 0 | 1 | -1 + | 5 | 0 | five | 1 | -1 | 2 | 2 + | 5 | 0 | five | 2 | 2 | 2 | 2 + | 5 | 0 | five | 3 | -3 | 2 | 2 + | 5 | 0 | five | 2 | 4 | 2 | 2 + | 5 | 0 | five | 5 | -5 | 2 | 2 + | 5 | 0 | five | 5 | -5 | 2 | 2 + | 5 | 0 | five | 0 | | 2 | 2 + | 5 | 0 | five | | | 2 | 2 + | 5 | 0 | five | | 0 | 2 | 2 + | 5 | 0 | five | 1 | -1 | 3 | -3 + | 5 | 0 | five | 2 | 2 | 3 | -3 + | 5 | 0 | five | 3 | -3 | 3 | -3 + | 5 | 0 | five | 2 | 4 | 3 | -3 + | 5 | 0 | five | 5 | -5 | 3 | -3 + | 5 | 0 | five | 5 | -5 | 3 | -3 + | 5 | 0 | five | 0 | | 3 | -3 + | 5 | 0 | five | | | 3 | -3 + | 5 | 0 | five | | 0 | 3 | -3 + | 5 | 0 | five | 1 | -1 | 2 | 4 + | 5 | 0 | five | 2 | 2 | 2 | 4 + | 5 | 0 | five | 3 | -3 | 2 | 4 + | 5 | 0 | five | 2 | 4 | 2 | 4 + | 5 | 0 | five | 5 | -5 | 2 | 4 + | 5 | 0 | five | 5 | -5 | 2 | 4 + | 5 | 0 | five | 0 | | 2 | 4 + | 5 | 0 | five | | | 2 | 4 + | 5 | 0 | five | | 0 | 2 | 4 + | 5 | 0 | five | 1 | -1 | 5 | -5 + | 5 | 0 | five | 2 | 2 | 5 | -5 + | 5 | 0 | five | 3 | -3 | 5 | -5 + | 5 | 0 | five | 2 | 4 | 5 | -5 + | 5 | 0 | five | 5 | -5 | 5 | -5 + | 5 | 0 | five | 5 | -5 | 5 | -5 + | 5 | 0 | five | 0 | | 5 | -5 + | 5 | 0 | five | | | 5 | -5 + | 5 | 0 | five | | 0 | 5 | -5 + | 5 | 0 | five | 1 | -1 | 5 | -5 + | 5 | 0 | five | 2 | 2 | 5 | -5 + | 5 | 0 | five | 3 | -3 | 5 | -5 + | 5 | 0 | five | 2 | 4 | 5 | -5 + | 5 | 0 | five | 5 | -5 | 5 | -5 + | 5 | 0 | five | 5 | -5 | 5 | -5 + | 5 | 0 | five | 0 | | 5 | -5 + | 5 | 0 | five | | | 5 | -5 + | 5 | 0 | five | | 0 | 5 | -5 + | 5 | 0 | five | 1 | -1 | 0 | + | 5 | 0 | five | 2 | 2 | 0 | + | 5 | 0 | five | 3 | -3 | 0 | + | 5 | 0 | five | 2 | 4 | 0 | + | 5 | 0 | five | 5 | -5 | 0 | + | 5 | 0 | five | 5 | -5 | 0 | + | 5 | 0 | five | 0 | | 0 | + | 5 | 0 | five | | | 0 | + | 5 | 0 | five | | 0 | 0 | + | 5 | 0 | five | 1 | -1 | | + | 5 | 0 | five | 2 | 2 | | + | 5 | 0 | five | 3 | -3 | | + | 5 | 0 | five | 2 | 4 | | + | 5 | 0 | five | 5 | -5 | | + | 5 | 0 | five | 5 | -5 | | + | 5 | 0 | five | 0 | | | + | 5 | 0 | five | | | | + | 5 | 0 | five | | 0 | | + | 5 | 0 | five | 1 | -1 | | 0 + | 5 | 0 | five | 2 | 2 | | 0 + | 5 | 0 | five | 3 | -3 | | 0 + | 5 | 0 | five | 2 | 4 | | 0 + | 5 | 0 | five | 5 | -5 | | 0 + | 5 | 0 | five | 5 | -5 | | 0 + | 5 | 0 | five | 0 | | | 0 + | 5 | 0 | five | | | | 0 + | 5 | 0 | five | | 0 | | 0 + | 6 | 6 | six | 1 | -1 | 1 | -1 + | 6 | 6 | six | 2 | 2 | 1 | -1 + | 6 | 6 | six | 3 | -3 | 1 | -1 + | 6 | 6 | six | 2 | 4 | 1 | -1 + | 6 | 6 | six | 5 | -5 | 1 | -1 + | 6 | 6 | six | 5 | -5 | 1 | -1 + | 6 | 6 | six | 0 | | 1 | -1 + | 6 | 6 | six | | | 1 | -1 + | 6 | 6 | six | | 0 | 1 | -1 + | 6 | 6 | six | 1 | -1 | 2 | 2 + | 6 | 6 | six | 2 | 2 | 2 | 2 + | 6 | 6 | six | 3 | -3 | 2 | 2 + | 6 | 6 | six | 2 | 4 | 2 | 2 + | 6 | 6 | six | 5 | -5 | 2 | 2 + | 6 | 6 | six | 5 | -5 | 2 | 2 + | 6 | 6 | six | 0 | | 2 | 2 + | 6 | 6 | six | | | 2 | 2 + | 6 | 6 | six | | 0 | 2 | 2 + | 6 | 6 | six | 1 | -1 | 3 | -3 + | 6 | 6 | six | 2 | 2 | 3 | -3 + | 6 | 6 | six | 3 | -3 | 3 | -3 + | 6 | 6 | six | 2 | 4 | 3 | -3 + | 6 | 6 | six | 5 | -5 | 3 | -3 + | 6 | 6 | six | 5 | -5 | 3 | -3 + | 6 | 6 | six | 0 | | 3 | -3 + | 6 | 6 | six | | | 3 | -3 + | 6 | 6 | six | | 0 | 3 | -3 + | 6 | 6 | six | 1 | -1 | 2 | 4 + | 6 | 6 | six | 2 | 2 | 2 | 4 + | 6 | 6 | six | 3 | -3 | 2 | 4 + | 6 | 6 | six | 2 | 4 | 2 | 4 + | 6 | 6 | six | 5 | -5 | 2 | 4 + | 6 | 6 | six | 5 | -5 | 2 | 4 + | 6 | 6 | six | 0 | | 2 | 4 + | 6 | 6 | six | | | 2 | 4 + | 6 | 6 | six | | 0 | 2 | 4 + | 6 | 6 | six | 1 | -1 | 5 | -5 + | 6 | 6 | six | 2 | 2 | 5 | -5 + | 6 | 6 | six | 3 | -3 | 5 | -5 + | 6 | 6 | six | 2 | 4 | 5 | -5 + | 6 | 6 | six | 5 | -5 | 5 | -5 + | 6 | 6 | six | 5 | -5 | 5 | -5 + | 6 | 6 | six | 0 | | 5 | -5 + | 6 | 6 | six | | | 5 | -5 + | 6 | 6 | six | | 0 | 5 | -5 + | 6 | 6 | six | 1 | -1 | 5 | -5 + | 6 | 6 | six | 2 | 2 | 5 | -5 + | 6 | 6 | six | 3 | -3 | 5 | -5 + | 6 | 6 | six | 2 | 4 | 5 | -5 + | 6 | 6 | six | 5 | -5 | 5 | -5 + | 6 | 6 | six | 5 | -5 | 5 | -5 + | 6 | 6 | six | 0 | | 5 | -5 + | 6 | 6 | six | | | 5 | -5 + | 6 | 6 | six | | 0 | 5 | -5 + | 6 | 6 | six | 1 | -1 | 0 | + | 6 | 6 | six | 2 | 2 | 0 | + | 6 | 6 | six | 3 | -3 | 0 | + | 6 | 6 | six | 2 | 4 | 0 | + | 6 | 6 | six | 5 | -5 | 0 | + | 6 | 6 | six | 5 | -5 | 0 | + | 6 | 6 | six | 0 | | 0 | + | 6 | 6 | six | | | 0 | + | 6 | 6 | six | | 0 | 0 | + | 6 | 6 | six | 1 | -1 | | + | 6 | 6 | six | 2 | 2 | | + | 6 | 6 | six | 3 | -3 | | + | 6 | 6 | six | 2 | 4 | | + | 6 | 6 | six | 5 | -5 | | + | 6 | 6 | six | 5 | -5 | | + | 6 | 6 | six | 0 | | | + | 6 | 6 | six | | | | + | 6 | 6 | six | | 0 | | + | 6 | 6 | six | 1 | -1 | | 0 + | 6 | 6 | six | 2 | 2 | | 0 + | 6 | 6 | six | 3 | -3 | | 0 + | 6 | 6 | six | 2 | 4 | | 0 + | 6 | 6 | six | 5 | -5 | | 0 + | 6 | 6 | six | 5 | -5 | | 0 + | 6 | 6 | six | 0 | | | 0 + | 6 | 6 | six | | | | 0 + | 6 | 6 | six | | 0 | | 0 + | 1 | 4 | one | 1 | -1 | 1 | -1 + | 1 | 4 | one | 2 | 2 | 1 | -1 + | 1 | 4 | one | 3 | -3 | 1 | -1 + | 1 | 4 | one | 2 | 4 | 1 | -1 + | 1 | 4 | one | 5 | -5 | 1 | -1 + | 1 | 4 | one | 5 | -5 | 1 | -1 + | 1 | 4 | one | 0 | | 1 | -1 + | 1 | 4 | one | | | 1 | -1 + | 1 | 4 | one | | 0 | 1 | -1 + | 1 | 4 | one | 1 | -1 | 2 | 2 + | 1 | 4 | one | 2 | 2 | 2 | 2 + | 1 | 4 | one | 3 | -3 | 2 | 2 + | 1 | 4 | one | 2 | 4 | 2 | 2 + | 1 | 4 | one | 5 | -5 | 2 | 2 + | 1 | 4 | one | 5 | -5 | 2 | 2 + | 1 | 4 | one | 0 | | 2 | 2 + | 1 | 4 | one | | | 2 | 2 + | 1 | 4 | one | | 0 | 2 | 2 + | 1 | 4 | one | 1 | -1 | 3 | -3 + | 1 | 4 | one | 2 | 2 | 3 | -3 + | 1 | 4 | one | 3 | -3 | 3 | -3 + | 1 | 4 | one | 2 | 4 | 3 | -3 + | 1 | 4 | one | 5 | -5 | 3 | -3 + | 1 | 4 | one | 5 | -5 | 3 | -3 + | 1 | 4 | one | 0 | | 3 | -3 + | 1 | 4 | one | | | 3 | -3 + | 1 | 4 | one | | 0 | 3 | -3 + | 1 | 4 | one | 1 | -1 | 2 | 4 + | 1 | 4 | one | 2 | 2 | 2 | 4 + | 1 | 4 | one | 3 | -3 | 2 | 4 + | 1 | 4 | one | 2 | 4 | 2 | 4 + | 1 | 4 | one | 5 | -5 | 2 | 4 + | 1 | 4 | one | 5 | -5 | 2 | 4 + | 1 | 4 | one | 0 | | 2 | 4 + | 1 | 4 | one | | | 2 | 4 + | 1 | 4 | one | | 0 | 2 | 4 + | 1 | 4 | one | 1 | -1 | 5 | -5 + | 1 | 4 | one | 2 | 2 | 5 | -5 + | 1 | 4 | one | 3 | -3 | 5 | -5 + | 1 | 4 | one | 2 | 4 | 5 | -5 + | 1 | 4 | one | 5 | -5 | 5 | -5 + | 1 | 4 | one | 5 | -5 | 5 | -5 + | 1 | 4 | one | 0 | | 5 | -5 + | 1 | 4 | one | | | 5 | -5 + | 1 | 4 | one | | 0 | 5 | -5 + | 1 | 4 | one | 1 | -1 | 5 | -5 + | 1 | 4 | one | 2 | 2 | 5 | -5 + | 1 | 4 | one | 3 | -3 | 5 | -5 + | 1 | 4 | one | 2 | 4 | 5 | -5 + | 1 | 4 | one | 5 | -5 | 5 | -5 + | 1 | 4 | one | 5 | -5 | 5 | -5 + | 1 | 4 | one | 0 | | 5 | -5 + | 1 | 4 | one | | | 5 | -5 + | 1 | 4 | one | | 0 | 5 | -5 + | 1 | 4 | one | 1 | -1 | 0 | + | 1 | 4 | one | 2 | 2 | 0 | + | 1 | 4 | one | 3 | -3 | 0 | + | 1 | 4 | one | 2 | 4 | 0 | + | 1 | 4 | one | 5 | -5 | 0 | + | 1 | 4 | one | 5 | -5 | 0 | + | 1 | 4 | one | 0 | | 0 | + | 1 | 4 | one | | | 0 | + | 1 | 4 | one | | 0 | 0 | + | 1 | 4 | one | 1 | -1 | | + | 1 | 4 | one | 2 | 2 | | + | 1 | 4 | one | 3 | -3 | | + | 1 | 4 | one | 2 | 4 | | + | 1 | 4 | one | 5 | -5 | | + | 1 | 4 | one | 5 | -5 | | + | 1 | 4 | one | 0 | | | + | 1 | 4 | one | | | | + | 1 | 4 | one | | 0 | | + | 1 | 4 | one | 1 | -1 | | 0 + | 1 | 4 | one | 2 | 2 | | 0 + | 1 | 4 | one | 3 | -3 | | 0 + | 1 | 4 | one | 2 | 4 | | 0 + | 1 | 4 | one | 5 | -5 | | 0 + | 1 | 4 | one | 5 | -5 | | 0 + | 1 | 4 | one | 0 | | | 0 + | 1 | 4 | one | | | | 0 + | 1 | 4 | one | | 0 | | 0 + | 0 | | zero | 1 | -1 | 1 | -1 + | 0 | | zero | 2 | 2 | 1 | -1 + | 0 | | zero | 3 | -3 | 1 | -1 + | 0 | | zero | 2 | 4 | 1 | -1 + | 0 | | zero | 5 | -5 | 1 | -1 + | 0 | | zero | 5 | -5 | 1 | -1 + | 0 | | zero | 0 | | 1 | -1 + | 0 | | zero | | | 1 | -1 + | 0 | | zero | | 0 | 1 | -1 + | 0 | | zero | 1 | -1 | 2 | 2 + | 0 | | zero | 2 | 2 | 2 | 2 + | 0 | | zero | 3 | -3 | 2 | 2 + | 0 | | zero | 2 | 4 | 2 | 2 + | 0 | | zero | 5 | -5 | 2 | 2 + | 0 | | zero | 5 | -5 | 2 | 2 + | 0 | | zero | 0 | | 2 | 2 + | 0 | | zero | | | 2 | 2 + | 0 | | zero | | 0 | 2 | 2 + | 0 | | zero | 1 | -1 | 3 | -3 + | 0 | | zero | 2 | 2 | 3 | -3 + | 0 | | zero | 3 | -3 | 3 | -3 + | 0 | | zero | 2 | 4 | 3 | -3 + | 0 | | zero | 5 | -5 | 3 | -3 + | 0 | | zero | 5 | -5 | 3 | -3 + | 0 | | zero | 0 | | 3 | -3 + | 0 | | zero | | | 3 | -3 + | 0 | | zero | | 0 | 3 | -3 + | 0 | | zero | 1 | -1 | 2 | 4 + | 0 | | zero | 2 | 2 | 2 | 4 + | 0 | | zero | 3 | -3 | 2 | 4 + | 0 | | zero | 2 | 4 | 2 | 4 + | 0 | | zero | 5 | -5 | 2 | 4 + | 0 | | zero | 5 | -5 | 2 | 4 + | 0 | | zero | 0 | | 2 | 4 + | 0 | | zero | | | 2 | 4 + | 0 | | zero | | 0 | 2 | 4 + | 0 | | zero | 1 | -1 | 5 | -5 + | 0 | | zero | 2 | 2 | 5 | -5 + | 0 | | zero | 3 | -3 | 5 | -5 + | 0 | | zero | 2 | 4 | 5 | -5 + | 0 | | zero | 5 | -5 | 5 | -5 + | 0 | | zero | 5 | -5 | 5 | -5 + | 0 | | zero | 0 | | 5 | -5 + | 0 | | zero | | | 5 | -5 + | 0 | | zero | | 0 | 5 | -5 + | 0 | | zero | 1 | -1 | 5 | -5 + | 0 | | zero | 2 | 2 | 5 | -5 + | 0 | | zero | 3 | -3 | 5 | -5 + | 0 | | zero | 2 | 4 | 5 | -5 + | 0 | | zero | 5 | -5 | 5 | -5 + | 0 | | zero | 5 | -5 | 5 | -5 + | 0 | | zero | 0 | | 5 | -5 + | 0 | | zero | | | 5 | -5 + | 0 | | zero | | 0 | 5 | -5 + | 0 | | zero | 1 | -1 | 0 | + | 0 | | zero | 2 | 2 | 0 | + | 0 | | zero | 3 | -3 | 0 | + | 0 | | zero | 2 | 4 | 0 | + | 0 | | zero | 5 | -5 | 0 | + | 0 | | zero | 5 | -5 | 0 | + | 0 | | zero | 0 | | 0 | + | 0 | | zero | | | 0 | + | 0 | | zero | | 0 | 0 | + | 0 | | zero | 1 | -1 | | + | 0 | | zero | 2 | 2 | | + | 0 | | zero | 3 | -3 | | + | 0 | | zero | 2 | 4 | | + | 0 | | zero | 5 | -5 | | + | 0 | | zero | 5 | -5 | | + | 0 | | zero | 0 | | | + | 0 | | zero | | | | + | 0 | | zero | | 0 | | + | 0 | | zero | 1 | -1 | | 0 + | 0 | | zero | 2 | 2 | | 0 + | 0 | | zero | 3 | -3 | | 0 + | 0 | | zero | 2 | 4 | | 0 + | 0 | | zero | 5 | -5 | | 0 + | 0 | | zero | 5 | -5 | | 0 + | 0 | | zero | 0 | | | 0 + | 0 | | zero | | | | 0 + | 0 | | zero | | 0 | | 0 + | 4 | 1 | four | | 0 | 2 | 4 + | 4 | 1 | four | 1 | -1 | 5 | -5 + | 4 | 1 | four | 2 | 2 | 5 | -5 + | 4 | 1 | four | 3 | -3 | 5 | -5 + | 4 | 1 | four | 2 | 4 | 5 | -5 + | 4 | 1 | four | 5 | -5 | 5 | -5 + | 4 | 1 | four | 5 | -5 | 5 | -5 + | 4 | 1 | four | 0 | | 5 | -5 + | 4 | 1 | four | | | 5 | -5 + | 4 | 1 | four | | 0 | 5 | -5 + | 4 | 1 | four | 1 | -1 | 5 | -5 + | 4 | 1 | four | 2 | 2 | 5 | -5 + | 4 | 1 | four | 3 | -3 | 5 | -5 + | 4 | 1 | four | 2 | 4 | 5 | -5 + | 4 | 1 | four | 5 | -5 | 5 | -5 + | 4 | 1 | four | 5 | -5 | 5 | -5 + | 4 | 1 | four | 0 | | 5 | -5 + | 4 | 1 | four | | | 5 | -5 + | 4 | 1 | four | | 0 | 5 | -5 + | 4 | 1 | four | 1 | -1 | 0 | + | 4 | 1 | four | 2 | 2 | 0 | + | 4 | 1 | four | 3 | -3 | 0 | + | 4 | 1 | four | 2 | 4 | 0 | + | 4 | 1 | four | 5 | -5 | 0 | + | 4 | 1 | four | 5 | -5 | 0 | + | 4 | 1 | four | 0 | | 0 | + | 4 | 1 | four | | | 0 | + | 4 | 1 | four | | 0 | 0 | + | 4 | 1 | four | 1 | -1 | | + | 4 | 1 | four | 2 | 2 | | + | 4 | 1 | four | 3 | -3 | | + | 4 | 1 | four | 2 | 4 | | + | 4 | 1 | four | 5 | -5 | | + | 4 | 1 | four | 5 | -5 | | + | 4 | 1 | four | 0 | | | + | 4 | 1 | four | | | | + | 4 | 1 | four | | 0 | | + | 4 | 1 | four | 1 | -1 | | 0 + | 4 | 1 | four | 2 | 2 | | 0 + | 4 | 1 | four | 3 | -3 | | 0 + | 4 | 1 | four | 2 | 4 | | 0 + | 4 | 1 | four | 5 | -5 | | 0 + | 4 | 1 | four | 5 | -5 | | 0 + | 4 | 1 | four | 0 | | | 0 + | 4 | 1 | four | | | | 0 + | 4 | 1 | four | | 0 | | 0 + | 7 | 7 | seven | 1 | -1 | 1 | -1 + | 7 | 7 | seven | 2 | 2 | 1 | -1 + | 7 | 7 | seven | 3 | -3 | 1 | -1 + | 7 | 7 | seven | 2 | 4 | 1 | -1 + | 7 | 7 | seven | 5 | -5 | 1 | -1 + | 7 | 7 | seven | 5 | -5 | 1 | -1 + | 7 | 7 | seven | 0 | | 1 | -1 + | 7 | 7 | seven | | | 1 | -1 + | 7 | 7 | seven | | 0 | 1 | -1 + | 7 | 7 | seven | 1 | -1 | 2 | 2 + | 7 | 7 | seven | 2 | 2 | 2 | 2 + | 7 | 7 | seven | 3 | -3 | 2 | 2 + | 7 | 7 | seven | 2 | 4 | 2 | 2 + | 7 | 7 | seven | 5 | -5 | 2 | 2 + | 7 | 7 | seven | 5 | -5 | 2 | 2 + | 7 | 7 | seven | 0 | | 2 | 2 + | 7 | 7 | seven | | | 2 | 2 + | 7 | 7 | seven | | 0 | 2 | 2 + | 7 | 7 | seven | 1 | -1 | 3 | -3 + | 7 | 7 | seven | 2 | 2 | 3 | -3 + | 7 | 7 | seven | 3 | -3 | 3 | -3 + | 7 | 7 | seven | 2 | 4 | 3 | -3 + | 7 | 7 | seven | 5 | -5 | 3 | -3 + | 7 | 7 | seven | 5 | -5 | 3 | -3 + | 7 | 7 | seven | 0 | | 3 | -3 + | 7 | 7 | seven | | | 3 | -3 + | 7 | 7 | seven | | 0 | 3 | -3 + | 7 | 7 | seven | 1 | -1 | 2 | 4 + | 7 | 7 | seven | 2 | 2 | 2 | 4 + | 7 | 7 | seven | 3 | -3 | 2 | 4 + | 7 | 7 | seven | 2 | 4 | 2 | 4 + | 7 | 7 | seven | 5 | -5 | 2 | 4 + | 7 | 7 | seven | 5 | -5 | 2 | 4 + | 7 | 7 | seven | 0 | | 2 | 4 + | 7 | 7 | seven | | | 2 | 4 + | 7 | 7 | seven | | 0 | 2 | 4 + | 7 | 7 | seven | 1 | -1 | 5 | -5 + | 7 | 7 | seven | 2 | 2 | 5 | -5 + | 7 | 7 | seven | 3 | -3 | 5 | -5 + | 7 | 7 | seven | 2 | 4 | 5 | -5 + | 7 | 7 | seven | 5 | -5 | 5 | -5 + | 7 | 7 | seven | 5 | -5 | 5 | -5 + | 7 | 7 | seven | 0 | | 5 | -5 + | 7 | 7 | seven | | | 5 | -5 + | 7 | 7 | seven | | 0 | 5 | -5 + | 7 | 7 | seven | 1 | -1 | 5 | -5 + | 7 | 7 | seven | 2 | 2 | 5 | -5 + | 7 | 7 | seven | 3 | -3 | 5 | -5 + | 7 | 7 | seven | 2 | 4 | 5 | -5 + | 7 | 7 | seven | 5 | -5 | 5 | -5 + | 7 | 7 | seven | 5 | -5 | 5 | -5 + | 7 | 7 | seven | 0 | | 5 | -5 + | 7 | 7 | seven | | | 5 | -5 + | 7 | 7 | seven | | 0 | 5 | -5 + | 7 | 7 | seven | 1 | -1 | 0 | + | 7 | 7 | seven | 2 | 2 | 0 | + | 7 | 7 | seven | 3 | -3 | 0 | + | 7 | 7 | seven | 2 | 4 | 0 | + | 7 | 7 | seven | 5 | -5 | 0 | + | 7 | 7 | seven | 5 | -5 | 0 | + | 7 | 7 | seven | 0 | | 0 | + | 7 | 7 | seven | | | 0 | + | 7 | 7 | seven | | 0 | 0 | + | 7 | 7 | seven | 1 | -1 | | + | 7 | 7 | seven | 2 | 2 | | + | 7 | 7 | seven | 3 | -3 | | + | 7 | 7 | seven | 2 | 4 | | + | 7 | 7 | seven | 5 | -5 | | + | 7 | 7 | seven | 5 | -5 | | + | 7 | 7 | seven | 0 | | | + | 7 | 7 | seven | | | | + | 7 | 7 | seven | | 0 | | + | 7 | 7 | seven | 1 | -1 | | 0 + | 7 | 7 | seven | 2 | 2 | | 0 + | 7 | 7 | seven | 3 | -3 | | 0 + | 7 | 7 | seven | 2 | 4 | | 0 + | 7 | 7 | seven | 5 | -5 | | 0 + | 7 | 7 | seven | 5 | -5 | | 0 + | 7 | 7 | seven | 0 | | | 0 + | 7 | 7 | seven | | | | 0 + | 7 | 7 | seven | | 0 | | 0 + | 8 | 8 | eight | 1 | -1 | 1 | -1 + | 8 | 8 | eight | 2 | 2 | 1 | -1 + | 8 | 8 | eight | 3 | -3 | 1 | -1 + | 8 | 8 | eight | 2 | 4 | 1 | -1 + | 8 | 8 | eight | 5 | -5 | 1 | -1 + | 8 | 8 | eight | 5 | -5 | 1 | -1 + | 8 | 8 | eight | 0 | | 1 | -1 + | 8 | 8 | eight | | | 1 | -1 + | 8 | 8 | eight | | 0 | 1 | -1 + | 8 | 8 | eight | 1 | -1 | 2 | 2 + | 8 | 8 | eight | 2 | 2 | 2 | 2 + | 8 | 8 | eight | 3 | -3 | 2 | 2 + | 8 | 8 | eight | 2 | 4 | 2 | 2 + | 8 | 8 | eight | 5 | -5 | 2 | 2 + | 8 | 8 | eight | 5 | -5 | 2 | 2 + | 8 | 8 | eight | 0 | | 2 | 2 + | 8 | 8 | eight | | | 2 | 2 + | 8 | 8 | eight | | 0 | 2 | 2 + | 8 | 8 | eight | 1 | -1 | 3 | -3 + | 8 | 8 | eight | 2 | 2 | 3 | -3 + | 8 | 8 | eight | 3 | -3 | 3 | -3 + | 8 | 8 | eight | 2 | 4 | 3 | -3 + | 8 | 8 | eight | 5 | -5 | 3 | -3 + | 8 | 8 | eight | 5 | -5 | 3 | -3 + | 8 | 8 | eight | 0 | | 3 | -3 + | 8 | 8 | eight | | | 3 | -3 + | 8 | 8 | eight | | 0 | 3 | -3 + | 8 | 8 | eight | 1 | -1 | 2 | 4 + | 8 | 8 | eight | 2 | 2 | 2 | 4 + | 8 | 8 | eight | 3 | -3 | 2 | 4 + | 8 | 8 | eight | 2 | 4 | 2 | 4 + | 8 | 8 | eight | 5 | -5 | 2 | 4 + | 8 | 8 | eight | 5 | -5 | 2 | 4 + | 8 | 8 | eight | 0 | | 2 | 4 + | 8 | 8 | eight | | | 2 | 4 + | 8 | 8 | eight | | 0 | 2 | 4 + | 8 | 8 | eight | 1 | -1 | 5 | -5 + | 8 | 8 | eight | 2 | 2 | 5 | -5 + | 8 | 8 | eight | 3 | -3 | 5 | -5 + | 8 | 8 | eight | 2 | 4 | 5 | -5 + | 8 | 8 | eight | 5 | -5 | 5 | -5 + | 8 | 8 | eight | 5 | -5 | 5 | -5 + | 8 | 8 | eight | 0 | | 5 | -5 + | 8 | 8 | eight | | | 5 | -5 + | 8 | 8 | eight | | 0 | 5 | -5 + | 8 | 8 | eight | 1 | -1 | 5 | -5 + | 8 | 8 | eight | 2 | 2 | 5 | -5 + | 8 | 8 | eight | 3 | -3 | 5 | -5 + | 8 | 8 | eight | 2 | 4 | 5 | -5 + | 8 | 8 | eight | 5 | -5 | 5 | -5 + | 8 | 8 | eight | 5 | -5 | 5 | -5 + | 8 | 8 | eight | 0 | | 5 | -5 + | 8 | 8 | eight | | | 5 | -5 + | 8 | 8 | eight | | 0 | 5 | -5 + | 8 | 8 | eight | 1 | -1 | 0 | + | 8 | 8 | eight | 2 | 2 | 0 | + | 8 | 8 | eight | 3 | -3 | 0 | + | 8 | 8 | eight | 2 | 4 | 0 | + | 8 | 8 | eight | 5 | -5 | 0 | + | 8 | 8 | eight | 5 | -5 | 0 | + | 8 | 8 | eight | 0 | | 0 | + | 8 | 8 | eight | | | 0 | + | 8 | 8 | eight | | 0 | 0 | + | 8 | 8 | eight | 1 | -1 | | + | 8 | 8 | eight | 2 | 2 | | + | 8 | 8 | eight | 3 | -3 | | + | 8 | 8 | eight | 2 | 4 | | + | 8 | 8 | eight | 5 | -5 | | + | 8 | 8 | eight | 5 | -5 | | + | 8 | 8 | eight | 0 | | | + | 8 | 8 | eight | | | | + | 8 | 8 | eight | | 0 | | + | 8 | 8 | eight | 1 | -1 | | 0 + | 8 | 8 | eight | 2 | 2 | | 0 + | 8 | 8 | eight | 3 | -3 | | 0 + | 8 | 8 | eight | 2 | 4 | | 0 + | 8 | 8 | eight | 5 | -5 | | 0 + | 8 | 8 | eight | 5 | -5 | | 0 + | 8 | 8 | eight | 0 | | | 0 + | 8 | 8 | eight | | | | 0 + | 8 | 8 | eight | | 0 | | 0 + | | | null | 1 | -1 | 1 | -1 + | | | null | 2 | 2 | 1 | -1 + | | | null | 3 | -3 | 1 | -1 + | | | null | 2 | 4 | 1 | -1 + | | | null | 5 | -5 | 1 | -1 + | | | null | 5 | -5 | 1 | -1 + | | | null | 0 | | 1 | -1 + | | | null | | | 1 | -1 + | | | null | | 0 | 1 | -1 + | | | null | 1 | -1 | 2 | 2 + | | | null | 2 | 2 | 2 | 2 + | | | null | 3 | -3 | 2 | 2 + | | | null | 2 | 4 | 2 | 2 + | | | null | 5 | -5 | 2 | 2 + | | | null | 5 | -5 | 2 | 2 + | | | null | 0 | | 2 | 2 + | | | null | | | 2 | 2 + | | | null | | 0 | 2 | 2 + | | | null | 1 | -1 | 3 | -3 + | | | null | 2 | 2 | 3 | -3 + | | | null | 3 | -3 | 3 | -3 + | | | null | 2 | 4 | 3 | -3 + | | | null | 5 | -5 | 3 | -3 + | | | null | 5 | -5 | 3 | -3 + | | | null | 0 | | 3 | -3 + | | | null | | | 3 | -3 + | | | null | | 0 | 3 | -3 + | | | null | 1 | -1 | 2 | 4 + | | | null | 2 | 2 | 2 | 4 + | | | null | 3 | -3 | 2 | 4 + | | | null | 2 | 4 | 2 | 4 + | | | null | 5 | -5 | 2 | 4 + | | | null | 5 | -5 | 2 | 4 + | | | null | 0 | | 2 | 4 + | | | null | | | 2 | 4 + | | | null | | 0 | 2 | 4 + | | | null | 1 | -1 | 5 | -5 + | | | null | 2 | 2 | 5 | -5 + | | | null | 3 | -3 | 5 | -5 + | | | null | 2 | 4 | 5 | -5 + | | | null | 5 | -5 | 5 | -5 + | | | null | 5 | -5 | 5 | -5 + | | | null | 0 | | 5 | -5 + | | | null | | | 5 | -5 + | | | null | | 0 | 5 | -5 + | | | null | 1 | -1 | 5 | -5 + | | | null | 2 | 2 | 5 | -5 + | | | null | 3 | -3 | 5 | -5 + | | | null | 2 | 4 | 5 | -5 + | | | null | 5 | -5 | 5 | -5 + | | | null | 5 | -5 | 5 | -5 + | | | null | 0 | | 5 | -5 + | | | null | | | 5 | -5 + | | | null | | 0 | 5 | -5 + | | | null | 1 | -1 | 0 | + | | | null | 2 | 2 | 0 | + | | | null | 3 | -3 | 0 | + | | | null | 2 | 4 | 0 | + | | | null | 5 | -5 | 0 | + | | | null | 5 | -5 | 0 | + | | | null | 0 | | 0 | + | | | null | | | 0 | + | | | null | | 0 | 0 | + | | | null | 1 | -1 | | + | | | null | 2 | 2 | | + | | | null | 3 | -3 | | + | | | null | 2 | 4 | | + | | | null | 5 | -5 | | + | | | null | 5 | -5 | | + | | | null | 0 | | | + | | | null | | | | + | | | null | | 0 | | + | | | null | 1 | -1 | | 0 + | | | null | 2 | 2 | | 0 + | | | null | 3 | -3 | | 0 + | | | null | 2 | 4 | | 0 + | | | null | 5 | -5 | | 0 + | | | null | 5 | -5 | | 0 + | | | null | 0 | | | 0 + | | | null | | | | 0 + | | | null | | 0 | | 0 + | | 0 | zero | 1 | -1 | 1 | -1 + | | 0 | zero | 2 | 2 | 1 | -1 + | | 0 | zero | 3 | -3 | 1 | -1 + | | 0 | zero | 2 | 4 | 1 | -1 + | | 0 | zero | 5 | -5 | 1 | -1 + | | 0 | zero | 5 | -5 | 1 | -1 + | | 0 | zero | 0 | | 1 | -1 + | | 0 | zero | | | 1 | -1 + | | 0 | zero | | 0 | 1 | -1 + | | 0 | zero | 1 | -1 | 2 | 2 + | | 0 | zero | 2 | 2 | 2 | 2 + | | 0 | zero | 3 | -3 | 2 | 2 + | | 0 | zero | 2 | 4 | 2 | 2 + | | 0 | zero | 5 | -5 | 2 | 2 + | | 0 | zero | 5 | -5 | 2 | 2 + | | 0 | zero | 0 | | 2 | 2 + | | 0 | zero | | | 2 | 2 + | | 0 | zero | | 0 | 2 | 2 + | | 0 | zero | 1 | -1 | 3 | -3 + | | 0 | zero | 2 | 2 | 3 | -3 + | | 0 | zero | 3 | -3 | 3 | -3 + | | 0 | zero | 2 | 4 | 3 | -3 + | | 0 | zero | 5 | -5 | 3 | -3 + | | 0 | zero | 5 | -5 | 3 | -3 + | | 0 | zero | 0 | | 3 | -3 + | | 0 | zero | | | 3 | -3 + | | 0 | zero | | 0 | 3 | -3 + | | 0 | zero | 1 | -1 | 2 | 4 + | | 0 | zero | 2 | 2 | 2 | 4 + | | 0 | zero | 3 | -3 | 2 | 4 + | | 0 | zero | 2 | 4 | 2 | 4 + | | 0 | zero | 5 | -5 | 2 | 4 + | | 0 | zero | 5 | -5 | 2 | 4 + | | 0 | zero | 0 | | 2 | 4 + | | 0 | zero | | | 2 | 4 + | | 0 | zero | | 0 | 2 | 4 + | | 0 | zero | 1 | -1 | 5 | -5 + | | 0 | zero | 2 | 2 | 5 | -5 + | | 0 | zero | 3 | -3 | 5 | -5 + | | 0 | zero | 2 | 4 | 5 | -5 + | | 0 | zero | 5 | -5 | 5 | -5 + | | 0 | zero | 5 | -5 | 5 | -5 + | | 0 | zero | 0 | | 5 | -5 + | | 0 | zero | | | 5 | -5 + | | 0 | zero | | 0 | 5 | -5 + | | 0 | zero | 1 | -1 | 5 | -5 + | | 0 | zero | 2 | 2 | 5 | -5 + | | 0 | zero | 3 | -3 | 5 | -5 + | | 0 | zero | 2 | 4 | 5 | -5 + | | 0 | zero | 5 | -5 | 5 | -5 + | | 0 | zero | 5 | -5 | 5 | -5 + | | 0 | zero | 0 | | 5 | -5 + | | 0 | zero | | | 5 | -5 + | | 0 | zero | | 0 | 5 | -5 + | | 0 | zero | 1 | -1 | 0 | + | | 0 | zero | 2 | 2 | 0 | + | | 0 | zero | 3 | -3 | 0 | + | | 0 | zero | 2 | 4 | 0 | + | | 0 | zero | 5 | -5 | 0 | + | | 0 | zero | 5 | -5 | 0 | + | | 0 | zero | 0 | | 0 | + | | 0 | zero | | | 0 | + | | 0 | zero | | 0 | 0 | + | | 0 | zero | 1 | -1 | | + | | 0 | zero | 2 | 2 | | + | | 0 | zero | 3 | -3 | | + | | 0 | zero | 2 | 4 | | + | | 0 | zero | 5 | -5 | | + | | 0 | zero | 5 | -5 | | + | | 0 | zero | 0 | | | + | | 0 | zero | | | | + | | 0 | zero | | 0 | | + | | 0 | zero | 1 | -1 | | 0 + | | 0 | zero | 2 | 2 | | 0 + | | 0 | zero | 3 | -3 | | 0 + | | 0 | zero | 2 | 4 | | 0 + | | 0 | zero | 5 | -5 | | 0 + | | 0 | zero | 5 | -5 | | 0 + | | 0 | zero | 0 | | | 0 + | | 0 | zero | | | | 0 + | | 0 | zero | | 0 | | 0 +(891 rows) + +-- +-- +-- Inner joins (equi-joins) +-- +-- +-- +-- Inner joins (equi-joins) with USING clause +-- The USING syntax changes the shape of the resulting table +-- by including a column in the USING clause only once in the result. +-- +-- Inner equi-join on specified column +SELECT '' AS "xxx", * + FROM J1_TBL INNER JOIN J2_TBL USING (i); + xxx | i | j | t | k +-----+---+---+-------+---- + | 1 | 4 | one | -1 + | 0 | | zero | + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 + | 2 | 3 | two | 4 + | 2 | 3 | two | 2 + | 3 | 2 | three | -3 +(7 rows) + +-- Same as above, slightly different syntax +SELECT '' AS "xxx", * + FROM J1_TBL JOIN J2_TBL USING (i); + xxx | i | j | t | k +-----+---+---+-------+---- + | 1 | 4 | one | -1 + | 0 | | zero | + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 + | 2 | 3 | two | 4 + | 2 | 3 | two | 2 + | 3 | 2 | three | -3 +(7 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL t1 (a, b, c) JOIN J2_TBL t2 (a, d) USING (a) + ORDER BY a, d; + xxx | a | b | c | d +-----+---+---+-------+---- + | 0 | | zero | + | 1 | 4 | one | -1 + | 2 | 3 | two | 2 + | 2 | 3 | two | 4 + | 3 | 2 | three | -3 + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 +(7 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL t1 (a, b, c) JOIN J2_TBL t2 (a, b) USING (b) + ORDER BY b, t1.a; + xxx | b | a | c | a +-----+---+---+-------+--- + | 0 | 5 | five | + | 0 | | zero | + | 2 | 3 | three | 2 + | 4 | 1 | one | 2 +(4 rows) + +-- +-- NATURAL JOIN +-- Inner equi-join on all columns with the same name +-- +SELECT '' AS "xxx", * + FROM J1_TBL NATURAL JOIN J2_TBL; + xxx | i | j | t | k +-----+---+---+-------+---- + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 + | 1 | 4 | one | -1 + | 0 | | zero | + | 2 | 3 | two | 4 + | 2 | 3 | two | 2 + | 3 | 2 | three | -3 +(7 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (a, d); + xxx | a | b | c | d +-----+---+---+-------+---- + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 + | 2 | 3 | two | 4 + | 2 | 3 | two | 2 + | 3 | 2 | three | -3 + | 1 | 4 | one | -1 + | 0 | | zero | +(7 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a); + xxx | a | b | c | d +-----+---+---+------+--- + | 2 | 3 | two | 2 + | 4 | 1 | four | 2 + | 0 | | zero | +(3 rows) + +-- mismatch number of columns +-- currently, Postgres will fill in with underlying names +SELECT '' AS "xxx", * + FROM J1_TBL t1 (a, b) NATURAL JOIN J2_TBL t2 (a); + xxx | a | b | t | k +-----+---+---+-------+---- + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 + | 2 | 3 | two | 4 + | 2 | 3 | two | 2 + | 3 | 2 | three | -3 + | 1 | 4 | one | -1 + | 0 | | zero | +(7 rows) + +-- +-- Inner joins (equi-joins) +-- +SELECT '' AS "xxx", * + FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.i); + xxx | i | j | t | i | k +-----+---+---+-------+---+---- + | 2 | 3 | two | 2 | 4 + | 2 | 3 | two | 2 | 2 + | 3 | 2 | three | 3 | -3 + | 5 | 0 | five | 5 | -5 + | 5 | 0 | five | 5 | -5 + | 1 | 4 | one | 1 | -1 + | 0 | | zero | 0 | +(7 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.k); + xxx | i | j | t | i | k +-----+---+---+------+---+--- + | 2 | 3 | two | 2 | 2 + | 4 | 1 | four | 2 | 4 + | 0 | | zero | | 0 +(3 rows) + +-- +-- Non-equi-joins +-- +SELECT '' AS "xxx", * + FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i <= J2_TBL.k); + xxx | i | j | t | i | k +-----+---+---+-------+---+--- + | 2 | 3 | two | 2 | 2 + | 2 | 3 | two | 2 | 4 + | 3 | 2 | three | 2 | 4 + | 4 | 1 | four | 2 | 4 + | 1 | 4 | one | 2 | 2 + | 1 | 4 | one | 2 | 4 + | 0 | | zero | 2 | 2 + | 0 | | zero | 2 | 4 + | 0 | | zero | | 0 +(9 rows) + +-- +-- Outer joins +-- Note that OUTER is a noise word +-- +SELECT '' AS "xxx", * + FROM J1_TBL LEFT OUTER JOIN J2_TBL USING (i) + ORDER BY i, k, t; + xxx | i | j | t | k +-----+---+---+-------+---- + | 0 | | zero | + | 1 | 4 | one | -1 + | 2 | 3 | two | 2 + | 2 | 3 | two | 4 + | 3 | 2 | three | -3 + | 4 | 1 | four | + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 + | 6 | 6 | six | + | 7 | 7 | seven | + | 8 | 8 | eight | + | | | null | + | | 0 | zero | +(13 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL LEFT JOIN J2_TBL USING (i) + ORDER BY i, k, t; + xxx | i | j | t | k +-----+---+---+-------+---- + | 0 | | zero | + | 1 | 4 | one | -1 + | 2 | 3 | two | 2 + | 2 | 3 | two | 4 + | 3 | 2 | three | -3 + | 4 | 1 | four | + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 + | 6 | 6 | six | + | 7 | 7 | seven | + | 8 | 8 | eight | + | | | null | + | | 0 | zero | +(13 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL RIGHT OUTER JOIN J2_TBL USING (i); + xxx | i | j | t | k +-----+---+---+-------+---- + | 2 | 3 | two | 2 + | 3 | 2 | three | -3 + | 2 | 3 | two | 4 + | | | | + | | | | 0 + | 1 | 4 | one | -1 + | 0 | | zero | + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 +(9 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL RIGHT JOIN J2_TBL USING (i); + xxx | i | j | t | k +-----+---+---+-------+---- + | 1 | 4 | one | -1 + | 0 | | zero | + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 + | 2 | 3 | two | 2 + | 3 | 2 | three | -3 + | 2 | 3 | two | 4 + | | | | + | | | | 0 +(9 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL FULL OUTER JOIN J2_TBL USING (i) + ORDER BY i, k, t; + xxx | i | j | t | k +-----+---+---+-------+---- + | 0 | | zero | + | 1 | 4 | one | -1 + | 2 | 3 | two | 2 + | 2 | 3 | two | 4 + | 3 | 2 | three | -3 + | 4 | 1 | four | + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 + | 6 | 6 | six | + | 7 | 7 | seven | + | 8 | 8 | eight | + | | | | 0 + | | | null | + | | 0 | zero | + | | | | +(15 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL FULL JOIN J2_TBL USING (i) + ORDER BY i, k, t; + xxx | i | j | t | k +-----+---+---+-------+---- + | 0 | | zero | + | 1 | 4 | one | -1 + | 2 | 3 | two | 2 + | 2 | 3 | two | 4 + | 3 | 2 | three | -3 + | 4 | 1 | four | + | 5 | 0 | five | -5 + | 5 | 0 | five | -5 + | 6 | 6 | six | + | 7 | 7 | seven | + | 8 | 8 | eight | + | | | | 0 + | | | null | + | | 0 | zero | + | | | | +(15 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL LEFT JOIN J2_TBL USING (i) WHERE (k = 1); + xxx | i | j | t | k +-----+---+---+---+--- +(0 rows) + +SELECT '' AS "xxx", * + FROM J1_TBL LEFT JOIN J2_TBL USING (i) WHERE (i = 1); + xxx | i | j | t | k +-----+---+---+-----+---- + | 1 | 4 | one | -1 +(1 row) + +-- +-- Multiway full join +-- +CREATE TABLE t1 (name TEXT, n INTEGER); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'name' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TABLE t2 (name TEXT, n INTEGER) distributed replicated; +CREATE TABLE t3 (name TEXT, n INTEGER); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'name' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +INSERT INTO t1 VALUES ( 'bb', 11 ); +INSERT INTO t2 VALUES ( 'bb', 12 ); +INSERT INTO t2 VALUES ( 'cc', 22 ); +INSERT INTO t2 VALUES ( 'ee', 42 ); +INSERT INTO t3 VALUES ( 'bb', 13 ); +INSERT INTO t3 VALUES ( 'cc', 23 ); +INSERT INTO t3 VALUES ( 'dd', 33 ); +SELECT * FROM t1 FULL JOIN t2 USING (name) FULL JOIN t3 USING (name); + name | n | n | n +------+----+----+---- + bb | 11 | 12 | 13 + cc | | 22 | 23 + ee | | 42 | + dd | | | 33 +(4 rows) + +-- +-- Test interactions of join syntax and subqueries +-- +-- Basic cases (we expect planner to pull up the subquery here) +SELECT * FROM +(SELECT * FROM t2) as s2 +INNER JOIN +(SELECT * FROM t3) s3 +USING (name); + name | n | n +------+----+---- + bb | 12 | 13 + cc | 22 | 23 +(2 rows) + +SELECT * FROM +(SELECT * FROM t2) as s2 +LEFT JOIN +(SELECT * FROM t3) s3 +USING (name); + name | n | n +------+----+---- + bb | 12 | 13 + ee | 42 | + cc | 22 | 23 +(3 rows) + +SELECT * FROM +(SELECT * FROM t2) as s2 +FULL JOIN +(SELECT * FROM t3) s3 +USING (name); + name | n | n +------+----+---- + ee | 42 | + bb | 12 | 13 + dd | | 33 + cc | 22 | 23 +(4 rows) + +-- Cases with non-nullable expressions in subquery results; +-- make sure these go to null as expected +SELECT * FROM +(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 +NATURAL INNER JOIN +(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; + name | s2_n | s2_2 | s3_n | s3_2 +------+------+------+------+------ + bb | 12 | 2 | 13 | 3 + cc | 22 | 2 | 23 | 3 +(2 rows) + +SELECT * FROM +(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 +NATURAL LEFT JOIN +(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; + name | s2_n | s2_2 | s3_n | s3_2 +------+------+------+------+------ + bb | 12 | 2 | 13 | 3 + ee | 42 | 2 | | + cc | 22 | 2 | 23 | 3 +(3 rows) + +SELECT * FROM +(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 +NATURAL FULL JOIN +(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; + name | s2_n | s2_2 | s3_n | s3_2 +------+------+------+------+------ + bb | 12 | 2 | 13 | 3 + cc | 22 | 2 | 23 | 3 + ee | 42 | 2 | | + dd | | | 33 | 3 +(4 rows) + +SELECT * FROM +(SELECT name, n as s1_n, 1 as s1_1 FROM t1) as s1 +NATURAL INNER JOIN +(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 +NATURAL INNER JOIN +(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; + name | s1_n | s1_1 | s2_n | s2_2 | s3_n | s3_2 +------+------+------+------+------+------+------ + bb | 11 | 1 | 12 | 2 | 13 | 3 +(1 row) + +SELECT * FROM +(SELECT name, n as s1_n, 1 as s1_1 FROM t1) as s1 +NATURAL FULL JOIN +(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 +NATURAL FULL JOIN +(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; + name | s1_n | s1_1 | s2_n | s2_2 | s3_n | s3_2 +------+------+------+------+------+------+------ + bb | 11 | 1 | 12 | 2 | 13 | 3 + cc | | | 22 | 2 | 23 | 3 + ee | | | 42 | 2 | | + dd | | | | | 33 | 3 +(4 rows) + +SELECT * FROM +(SELECT name, n as s1_n FROM t1) as s1 +NATURAL FULL JOIN + (SELECT * FROM + (SELECT name, n as s2_n FROM t2) as s2 + NATURAL FULL JOIN + (SELECT name, n as s3_n FROM t3) as s3 + ) ss2; + name | s1_n | s2_n | s3_n +------+------+------+------ + cc | | 22 | 23 + ee | | 42 | + bb | 11 | 12 | 13 + dd | | | 33 +(4 rows) + +SELECT * FROM +(SELECT name, n as s1_n FROM t1) as s1 +NATURAL FULL JOIN + (SELECT * FROM + (SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 + NATURAL FULL JOIN + (SELECT name, n as s3_n FROM t3) as s3 + ) ss2; + name | s1_n | s2_n | s2_2 | s3_n +------+------+------+------+------ + bb | 11 | 12 | 2 | 13 + dd | | | | 33 + cc | | 22 | 2 | 23 + ee | | 42 | 2 | +(4 rows) + +-- Test for propagation of nullability constraints into sub-joins +create temp table x (x1 int, x2 int) distributed replicated; +insert into x values (1,11); +insert into x values (2,22); +insert into x values (3,null); +insert into x values (4,44); +insert into x values (5,null); +create temp table y (y1 int, y2 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'y1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into y values (1,111); +insert into y values (2,222); +insert into y values (3,333); +insert into y values (4,null); +select * from x; + x1 | x2 +----+---- + 1 | 11 + 2 | 22 + 3 | + 4 | 44 + 5 | +(5 rows) + +select * from y; + y1 | y2 +----+----- + 1 | 111 + 2 | 222 + 3 | 333 + 4 | +(4 rows) + +select * from x left join y on (x1 = y1 and x2 is not null); + x1 | x2 | y1 | y2 +----+----+----+----- + 2 | 22 | 2 | 222 + 3 | | | + 4 | 44 | 4 | + 1 | 11 | 1 | 111 + 5 | | | +(5 rows) + +select * from x left join y on (x1 = y1 and y2 is not null); + x1 | x2 | y1 | y2 +----+----+----+----- + 1 | 11 | 1 | 111 + 5 | | | + 2 | 22 | 2 | 222 + 3 | | 3 | 333 + 4 | 44 | | +(5 rows) + +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1); + x1 | x2 | y1 | y2 | xx1 | xx2 +----+----+----+-----+-----+----- + 2 | 22 | 2 | 222 | 2 | 22 + 3 | | 3 | 333 | 3 | + 4 | 44 | 4 | | 4 | 44 + 5 | | | | 5 | + 1 | 11 | 1 | 111 | 1 | 11 +(5 rows) + +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1 and x2 is not null); + x1 | x2 | y1 | y2 | xx1 | xx2 +----+----+----+-----+-----+----- + 5 | | | | | + 2 | 22 | 2 | 222 | 2 | 22 + 3 | | 3 | 333 | | + 4 | 44 | 4 | | 4 | 44 + 1 | 11 | 1 | 111 | 1 | 11 +(5 rows) + +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1 and y2 is not null); + x1 | x2 | y1 | y2 | xx1 | xx2 +----+----+----+-----+-----+----- + 1 | 11 | 1 | 111 | 1 | 11 + 5 | | | | | + 2 | 22 | 2 | 222 | 2 | 22 + 3 | | 3 | 333 | 3 | + 4 | 44 | 4 | | | +(5 rows) + +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1 and xx2 is not null); + x1 | x2 | y1 | y2 | xx1 | xx2 +----+----+----+-----+-----+----- + 5 | | | | | + 2 | 22 | 2 | 222 | 2 | 22 + 3 | | 3 | 333 | | + 4 | 44 | 4 | | 4 | 44 + 1 | 11 | 1 | 111 | 1 | 11 +(5 rows) + +-- these should NOT give the same answers as above +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1) where (x2 is not null); + x1 | x2 | y1 | y2 | xx1 | xx2 +----+----+----+-----+-----+----- + 2 | 22 | 2 | 222 | 2 | 22 + 4 | 44 | 4 | | 4 | 44 + 1 | 11 | 1 | 111 | 1 | 11 +(3 rows) + +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1) where (y2 is not null); + x1 | x2 | y1 | y2 | xx1 | xx2 +----+----+----+-----+-----+----- + 2 | 22 | 2 | 222 | 2 | 22 + 3 | | 3 | 333 | 3 | + 1 | 11 | 1 | 111 | 1 | 11 +(3 rows) + +select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) +on (x1 = xx1) where (xx2 is not null); + x1 | x2 | y1 | y2 | xx1 | xx2 +----+----+----+-----+-----+----- + 2 | 22 | 2 | 222 | 2 | 22 + 4 | 44 | 4 | | 4 | 44 + 1 | 11 | 1 | 111 | 1 | 11 +(3 rows) + +-- +-- regression test: check for bug with propagation of implied equality +-- to outside an IN +-- +create table foo (unique1 int, unique2 int) distributed replicated; +insert into foo values (1, 2), (2, 42); +select count(*) from foo a where unique1 in + (select unique1 from foo b join foo c using (unique1) + where b.unique2 = 42); + count +------- + 1 +(1 row) + +drop table if exists foo; +-- Both DELETE and UPDATE allow the specification of additional tables +-- to "join" against to determine which rows should be modified. +CREATE TEMP TABLE t1 (a int, b int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +CREATE TEMP TABLE t2 (a int, b int) distributed replicated; +CREATE TEMP TABLE t3 (x int, y int) distributed replicated; +CREATE TEMP TABLE t4 (x int, y int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'x' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +INSERT INTO t1 VALUES (5, 10); +INSERT INTO t1 VALUES (15, 20); +INSERT INTO t1 VALUES (100, 100); +INSERT INTO t1 VALUES (200, 1000); +INSERT INTO t2 VALUES (200, 2000); +INSERT INTO t3 VALUES (5, 20); +INSERT INTO t3 VALUES (6, 7); +INSERT INTO t3 VALUES (7, 8); +INSERT INTO t3 VALUES (500, 100); +INSERT INTO t4 SELECT * FROM t3; +DELETE FROM t3 USING t1 table1 WHERE t3.x = table1.a; +SELECT * FROM t3; + x | y +-----+----- + 6 | 7 + 7 | 8 + 500 | 100 +(3 rows) + +DELETE FROM t4 USING t1 JOIN t2 USING (a) WHERE t4.x > t1.a; +SELECT * FROM t4; + x | y +---+---- + 5 | 20 + 6 | 7 + 7 | 8 +(3 rows) + +DELETE FROM t3 USING t3 t3_other WHERE t3.x = t3_other.x AND t3.y = t3_other.y; +SELECT * FROM t3; + x | y +---+--- +(0 rows) + +-- +-- regression test for 8.1 merge right join bug +-- +CREATE TEMP TABLE tt1 ( tt1_id int4, joincol int4 ) distributed replicated; +INSERT INTO tt1 VALUES (1, 11); +INSERT INTO tt1 VALUES (2, NULL); +CREATE TEMP TABLE tt2 ( tt2_id int4, joincol int4 ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'tt2_id' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +INSERT INTO tt2 VALUES (21, 11); +INSERT INTO tt2 VALUES (22, 11); +set enable_hashjoin to off; +set enable_nestloop to off; +-- these should give the same results +select tt1.*, tt2.* from tt1 left join tt2 on tt1.joincol = tt2.joincol; + tt1_id | joincol | tt2_id | joincol +--------+---------+--------+--------- + 2 | | | + 1 | 11 | 21 | 11 + 1 | 11 | 22 | 11 +(3 rows) + +select tt1.*, tt2.* from tt2 right join tt1 on tt1.joincol = tt2.joincol; + tt1_id | joincol | tt2_id | joincol +--------+---------+--------+--------- + 2 | | | + 1 | 11 | 21 | 11 + 1 | 11 | 22 | 11 +(3 rows) + +reset enable_hashjoin; +reset enable_nestloop; +-- +-- regression test for 8.2 bug with improper re-ordering of left joins +-- +create temp table tt3(f1 int, f2 text) distributed replicated; +insert into tt3 select x, repeat('xyzzy', 100) from generate_series(1,10000) x; +create index tt3i on tt3(f1); +analyze tt3; +create temp table tt4(f1 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into tt4 values (0),(1),(9999); +analyze tt4; +SELECT a.f1 +FROM tt4 a +LEFT JOIN ( + SELECT b.f1 + FROM tt3 b LEFT JOIN tt3 c ON (b.f1 = c.f1) + WHERE c.f1 IS NULL +) AS d ON (a.f1 = d.f1) +WHERE d.f1 IS NULL; + f1 +------ + 0 + 1 + 9999 +(3 rows) + +-- +-- regression test for problems of the sort depicted in bug #3494 +-- +create temp table tt5(f1 int, f2 int) distributed replicated; +create temp table tt6(f1 int, f2 int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into tt5 values(1, 10); +insert into tt5 values(1, 11); +insert into tt6 values(1, 9); +insert into tt6 values(1, 2); +insert into tt6 values(2, 9); +select * from tt5,tt6 where tt5.f1 = tt6.f1 and tt5.f1 = tt5.f2 - tt6.f2; + f1 | f2 | f1 | f2 +----+----+----+---- + 1 | 10 | 1 | 9 +(1 row) + +-- +-- regression test for problems of the sort depicted in bug #3588 +-- +create temp table xx (pkxx int) distributed replicated; +create temp table yy (pkyy int, pkxx int) distributed replicated; +insert into xx values (1); +insert into xx values (2); +insert into xx values (3); +insert into yy values (101, 1); +insert into yy values (201, 2); +insert into yy values (301, NULL); +select yy.pkyy as yy_pkyy, yy.pkxx as yy_pkxx, yya.pkyy as yya_pkyy, + xxa.pkxx as xxa_pkxx, xxb.pkxx as xxb_pkxx +from yy + left join (SELECT * FROM yy where pkyy = 101) as yya ON yy.pkyy = yya.pkyy + left join xx xxa on yya.pkxx = xxa.pkxx + left join xx xxb on coalesce (xxa.pkxx, 1) = xxb.pkxx; + yy_pkyy | yy_pkxx | yya_pkyy | xxa_pkxx | xxb_pkxx +---------+---------+----------+----------+---------- + 101 | 1 | 101 | 1 | 1 + 201 | 2 | | | 1 + 301 | | | | 1 +(3 rows) + +-- +-- regression test for improper pushing of constants across outer-join clauses +-- (as seen in early 8.2.x releases) +-- +create temp table zt1 (f1 int primary key); +create temp table zt2 (f2 int primary key); +create temp table zt3 (f3 int primary key) distributed replicated; +insert into zt1 values(53); +insert into zt2 values(53); +select * from + zt2 left join zt3 on (f2 = f3) + left join zt1 on (f3 = f1) +where f2 = 53; + f2 | f3 | f1 +----+----+---- + 53 | | +(1 row) + +create temp view zv1 as select *,'dummy'::text AS junk from zt1; +select * from + zt2 left join zt3 on (f2 = f3) + left join zv1 on (f3 = f1) +where f2 = 53; + f2 | f3 | f1 | junk +----+----+----+------ + 53 | | | +(1 row) + +-- +-- regression test for nest loop join of rpt and entry +-- +create temp table t_5628 (c1 int, c2 int) distributed replicated; +insert into t_5628 values (1,1), (2,2); +set enable_indexscan to off; +set enable_bitmapscan to off; +explain (costs off) select max(c1) from pg_class left join t_5628 on true; + QUERY PLAN +------------------------------------------------------------ + Aggregate + -> Nested Loop Left Join + -> Seq Scan on pg_class + -> Materialize + -> Gather Motion 1:1 (slice1; segments: 1) + -> Seq Scan on t_5628 + Optimizer: Postgres query optimizer +(7 rows) + +select max(c1) from pg_class left join t_5628 on true; + max +----- + 2 +(1 row) + +-- +-- Writeable CTE on replicated table join with other tables. +-- See issue https://github.com/greenplum-db/gpdb/issues/15860 +-- +select gp_debug_set_create_table_default_numsegments(2); + gp_debug_set_create_table_default_numsegments +----------------------------------------------- + 2 +(1 row) + +create table rpt_issue_15860_2_segments(c1 int, c2 int) distributed replicated; +create table hash_issue_15860_2_segments(c1 int, c2 int) distributed by (c1); +select gp_debug_reset_create_table_default_numsegments(); + gp_debug_reset_create_table_default_numsegments +------------------------------------------------- + +(1 row) + +create table rpt_issue_15860 (c1 int, c2 int) distributed replicated; +create table rpt2_issue_15860 (c1 int, c2 int) distributed replicated; +create table hash_issue_15860(c1 int, c2 int) distributed by (c1); +create table strewn_issue_15860(c1 int, c2 int) distributed randomly; +insert into rpt2_issue_15860 values (1, 2), (2, 3); +insert into rpt_issue_15860_2_segments values (1, 2), (2, 3); +analyze rpt_issue_15860; +analyze rpt2_issue_15860; +analyze hash_issue_15860; +analyze strewn_issue_15860; +analyze rpt_issue_15860_2_segments; +-- Replicated join SegmentGeneral. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 join rpt2_issue_15860 using(c1); + QUERY PLAN +--------------------------------------------------------------- + Explicit Gather Motion 3:1 (slice1; segments: 3) + -> Hash Join + Hash Cond: (rpt2_issue_15860.c1 = rpt_issue_15860.c1) + -> Seq Scan on rpt2_issue_15860 + -> Hash + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(8 rows) + +-- Replicated join SegmentGeneral, Replicated is not ok to replicate. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 left join rpt2_issue_15860 using(c1); + QUERY PLAN +--------------------------------------------------------------- + Hash Right Join + Hash Cond: (rpt2_issue_15860.c1 = rpt_issue_15860.c1) + -> Gather Motion 1:1 (slice1; segments: 1) + -> Seq Scan on rpt2_issue_15860 + -> Hash + -> Explicit Gather Motion 3:1 (slice2; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(9 rows) + +-- Replicated join SegmentGeneral, SegmentGeneral is not ok to replicate. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 right join rpt2_issue_15860 using(c1); + QUERY PLAN +--------------------------------------------------------------- + Hash Left Join + Hash Cond: (rpt2_issue_15860.c1 = cte1.c1) + -> Gather Motion 1:1 (slice1; segments: 1) + -> Seq Scan on rpt2_issue_15860 + -> Hash + -> Explicit Gather Motion 3:1 (slice2; segments: 3) + -> Subquery Scan on cte1 + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(10 rows) + +-- Replicated join SegmentGeneral, both are not ok to replicate. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 full join rpt2_issue_15860 using(c1); + QUERY PLAN +--------------------------------------------------------------- + Hash Full Join + Hash Cond: (rpt2_issue_15860.c1 = rpt_issue_15860.c1) + -> Gather Motion 1:1 (slice1; segments: 1) + -> Seq Scan on rpt2_issue_15860 + -> Hash + -> Explicit Gather Motion 3:1 (slice2; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(9 rows) + +-- Replicated join SegmentGeneral, num segments are not matched. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 join rpt_issue_15860_2_segments using(c1); + QUERY PLAN +------------------------------------------------------------------- + Hash Join + Hash Cond: (rpt_issue_15860_2_segments.c1 = rpt_issue_15860.c1) + -> Gather Motion 1:1 (slice1; segments: 1) + -> Seq Scan on rpt_issue_15860_2_segments + -> Hash + -> Explicit Gather Motion 3:1 (slice2; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(9 rows) + +-- Replicated join General. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 join generate_series(1, 5) i on i= cte1.c1 ; + QUERY PLAN +--------------------------------------------------- + Explicit Gather Motion 3:1 (slice1; segments: 3) + -> Hash Join + Hash Cond: (i.i = rpt_issue_15860.c1) + -> Function Scan on generate_series i + -> Hash + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(8 rows) + +-- Replicated join General, Replicated is not ok to replicate. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 left join generate_series(1, 5) i on i= cte1.c1 ; + QUERY PLAN +--------------------------------------------------------------- + Hash Right Join + Hash Cond: (i.i = rpt_issue_15860.c1) + -> Function Scan on generate_series i + -> Hash + -> Explicit Gather Motion 3:1 (slice1; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(8 rows) + +-- Replicated join General, General is not ok to replicate. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 right join generate_series(1, 5) i on i= cte1.c1 ; + QUERY PLAN +--------------------------------------------------------------- + Hash Left Join + Hash Cond: (i.i = rpt_issue_15860.c1) + -> Function Scan on generate_series i + -> Hash + -> Explicit Gather Motion 3:1 (slice1; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(8 rows) + +-- Replicated join General, both are not not ok to replicate. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 full join generate_series(1, 5) i on i= cte1.c1 ; + QUERY PLAN +--------------------------------------------------------------- + Hash Full Join + Hash Cond: (i.i = rpt_issue_15860.c1) + -> Function Scan on generate_series i + -> Hash + -> Explicit Gather Motion 3:1 (slice1; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(8 rows) + +-- Replicate join SingleQE. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 join (select count(*) as c from hash_issue_15860) a on a.c = cte1.c1; + QUERY PLAN +--------------------------------------------------------------- + Hash Join + Hash Cond: ((count(*)) = rpt_issue_15860.c1) + -> Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Seq Scan on hash_issue_15860 + -> Hash + -> Explicit Gather Motion 3:1 (slice2; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(10 rows) + +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 left join (select count(*) as c from hash_issue_15860) a on a.c = cte1.c1; + QUERY PLAN +--------------------------------------------------------------- + Hash Right Join + Hash Cond: ((count(*)) = rpt_issue_15860.c1) + -> Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Seq Scan on hash_issue_15860 + -> Hash + -> Explicit Gather Motion 3:1 (slice2; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(10 rows) + +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 right join (select count(*) as c from hash_issue_15860) a on a.c = cte1.c1; + QUERY PLAN +--------------------------------------------------------------- + Hash Left Join + Hash Cond: ((count(*)) = rpt_issue_15860.c1) + -> Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Seq Scan on hash_issue_15860 + -> Hash + -> Explicit Gather Motion 3:1 (slice2; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(10 rows) + +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 full join (select count(*) as c from hash_issue_15860) a on a.c = cte1.c1; + QUERY PLAN +--------------------------------------------------------------- + Hash Full Join + Hash Cond: ((count(*)) = rpt_issue_15860.c1) + -> Aggregate + -> Gather Motion 3:1 (slice1; segments: 3) + -> Seq Scan on hash_issue_15860 + -> Hash + -> Explicit Gather Motion 3:1 (slice2; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(10 rows) + +-- When external_fts is on +-- Seq scan on gp_segment_configuration would be replaced by +-- Function Scan on gp_get_segment_configuration +-- Inconsistence between CIs will cause such cases to fail. +-- Use other catalog to test Entry. +-- Replicate join Entry. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 join pg_class c on c.oid = cte1.c1; + QUERY PLAN +--------------------------------------------------------------- + Hash Join + Hash Cond: (c.oid = (rpt_issue_15860.c1)::oid) + -> Seq Scan on pg_class c + -> Hash + -> Explicit Gather Motion 3:1 (slice1; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(8 rows) + +-- +-- Begin of Replicated join Partitioned. +-- +-- Replicated join Hashed. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 join hash_issue_15860 using(c1); + QUERY PLAN +--------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Join + Hash Cond: (hash_issue_15860.c1 = rpt_issue_15860.c1) + -> Seq Scan on hash_issue_15860 + -> Hash + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(8 rows) + +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 right join hash_issue_15860 using(c1); + QUERY PLAN +---------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Left Join + Hash Cond: (hash_issue_15860.c1 = cte1.c1) + -> Seq Scan on hash_issue_15860 + -> Hash + -> Subquery Scan on cte1 + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(9 rows) + +-- Replicated join Hashed, Replicated is not ok to replicate +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 left join hash_issue_15860 using(c1); + QUERY PLAN +--------------------------------------------------------------- + Hash Right Join + Hash Cond: (hash_issue_15860.c1 = rpt_issue_15860.c1) + -> Gather Motion 3:1 (slice1; segments: 3) + -> Seq Scan on hash_issue_15860 + -> Hash + -> Explicit Gather Motion 3:1 (slice2; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(9 rows) + +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 full join hash_issue_15860 using(c1); + QUERY PLAN +--------------------------------------------------------------- + Hash Full Join + Hash Cond: (hash_issue_15860.c1 = rpt_issue_15860.c1) + -> Gather Motion 3:1 (slice1; segments: 3) + -> Seq Scan on hash_issue_15860 + -> Hash + -> Explicit Gather Motion 3:1 (slice2; segments: 3) + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(9 rows) + +-- Replicated join Hashed, num segments are not match. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 join hash_issue_15860_2_segments using(c1); + QUERY PLAN +-------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Join + Hash Cond: (hash_issue_15860_2_segments.c1 = rpt_issue_15860.c1) + -> Redistribute Motion 2:3 (slice2; segments: 2) + Hash Key: hash_issue_15860_2_segments.c1 + -> Seq Scan on hash_issue_15860_2_segments + -> Hash + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(10 rows) + +-- Replicated join Strewn = Strewn. +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 join strewn_issue_15860 using(c1); + QUERY PLAN +----------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Join + Hash Cond: (strewn_issue_15860.c1 = rpt_issue_15860.c1) + -> Seq Scan on strewn_issue_15860 + -> Hash + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(8 rows) + +-- Replicated join HashedOJ = HashedOJ +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select * from cte1 join (select * from hash_issue_15860 a full join hash_issue_15860 b using(c1)) c using(c1); + QUERY PLAN +------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) + -> Hash Join + Hash Cond: ((COALESCE(a.c1, b.c1)) = rpt_issue_15860.c1) + -> Hash Full Join + Hash Cond: (a.c1 = b.c1) + -> Seq Scan on hash_issue_15860 a + -> Hash + -> Seq Scan on hash_issue_15860 b + -> Hash + -> Insert on rpt_issue_15860 + -> Result + Optimizer: Postgres query optimizer +(12 rows) + +-- +-- End of Replicated join Partitioned. +-- +-- CBDB_FIXME: How to derive a plan? +-- Replicates join OuterQuery +explain(costs off) with cte1 as (insert into rpt_issue_15860 values (1, 2) returning *) select ( select foo.c1 from (select * from strewn_issue_15860) foo join cte1 using(c2) where foo.c1 = hash_issue_15860.c1) from hash_issue_15860; +ERROR: could not devise a query plan for the given query (pathnode.c:285) +-- Test case for Github Issue 17460 +create table t_17460 (a int ) distributed replicated; +create table foo_17460 (a int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +insert into t_17460 values(1); +insert into foo_17460 select i from generate_series(1, 10000) i; +analyze t_17460; +analyze foo_17460; +-- update|delete on replicated table should not use unique rowid skill +-- to plan semi join. +explain (costs off) delete from t_17460 where a in (select a from foo_17460); + QUERY PLAN +--------------------------------------------------------- + Delete on t_17460 + -> Hash Right Semi Join + Hash Cond: (foo_17460.a = t_17460.a) + -> Broadcast Motion 3:3 (slice1; segments: 3) + -> Seq Scan on foo_17460 + -> Hash + -> Seq Scan on t_17460 + Optimizer: Postgres query optimizer +(8 rows) + +delete from t_17460 where a in (select a from foo_17460); +drop schema rpt_joins cascade; +NOTICE: drop cascades to 13 other objects +DETAIL: drop cascades to table j1_tbl +drop cascades to table j2_tbl +drop cascades to table rpt_joins.t1 +drop cascades to table rpt_joins.t2 +drop cascades to table rpt_joins.t3 +drop cascades to table rpt_issue_15860_2_segments +drop cascades to table hash_issue_15860_2_segments +drop cascades to table rpt_issue_15860 +drop cascades to table rpt2_issue_15860 +drop cascades to table hash_issue_15860 +drop cascades to table strewn_issue_15860 +drop cascades to table t_17460 +drop cascades to table foo_17460 diff --git a/src/test/regress/expected/rpt_optimizer.out b/src/test/regress/expected/rpt_optimizer.out index a07e2c8f8dc..7f5dc43d61c 100644 --- a/src/test/regress/expected/rpt_optimizer.out +++ b/src/test/regress/expected/rpt_optimizer.out @@ -129,10 +129,10 @@ insert into foo values (1,'aaa'); insert into foo values (2,'bbb'); -- fail insert into foo values (1,'ccc'); -ERROR: duplicate key value violates unique constraint "foo_pkey" (seg0 192.168.99.102:25432 pid=22681) +ERROR: duplicate key value violates unique constraint "foo_pkey" (seg1 172.18.0.2:7003 pid=61557) DETAIL: Key (id)=(1) already exists. insert into foo values (3,'aaa'); -ERROR: duplicate key value violates unique constraint "foo_name_key" (seg2 192.168.99.102:25434 pid=22683) +ERROR: duplicate key value violates unique constraint "foo_name_key" (seg2 172.18.0.2:7004 pid=61555) DETAIL: Key (name)=(aaa) already exists. drop table if exists foo; -- @@ -232,8 +232,7 @@ drop table if exists bar; -- CTAS from partition table table create table foo as select i as c1, i as c2 from generate_series(1,3) i; -NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'c1' as the Apache Cloudberry data distribution key for this table. -HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause. Creating a NULL policy entry. create table bar as select * from foo distributed replicated; select * from bar; c1 | c2 @@ -248,13 +247,12 @@ drop table if exists bar; -- CTAS from singleQE create table foo as select i as c1, i as c2 from generate_series(1,3) i; -NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'c1' as the Apache Cloudberry data distribution key for this table. -HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause. Creating a NULL policy entry. select * from foo; c1 | c2 ----+---- - 1 | 1 2 | 2 + 1 | 1 3 | 3 (3 rows) @@ -291,7 +289,7 @@ insert into bar values(1,1); alter table foo drop column x; -- fail alter table bar drop column x; -NOTICE: dropping a column that is part of the distribution policy forces a random distribution policy +NOTICE: dropping a column that is part of the distribution policy forces a NULL distribution policy drop table if exists foo; drop table if exists foo1; NOTICE: table "foo1" does not exist, skipping @@ -350,59 +348,59 @@ Distributed Replicated select * from foo; x | y ----+---- + 5 | 5 + 6 | 6 + 9 | 9 + 10 | 10 1 | 1 2 | 2 3 | 3 4 | 4 - 5 | 5 - 6 | 6 7 | 7 8 | 8 - 9 | 9 - 10 | 10 (10 rows) select * from foo1; x | y ----+---- - 1 | 1 - 2 | 2 3 | 3 4 | 4 5 | 5 - 6 | 6 7 | 7 + 10 | 10 + 1 | 1 + 2 | 2 + 6 | 6 8 | 8 9 | 9 - 10 | 10 (10 rows) select * from bar; x | y ----+---- - 1 | 1 2 | 2 3 | 3 4 | 4 - 5 | 5 - 6 | 6 7 | 7 8 | 8 + 5 | 5 + 6 | 6 9 | 9 10 | 10 + 1 | 1 (10 rows) select * from bar1; x | y ----+---- 1 | 1 - 2 | 2 - 3 | 3 4 | 4 5 | 5 - 6 | 6 7 | 7 + 3 | 3 8 | 8 + 2 | 2 + 6 | 6 9 | 9 10 | 10 (10 rows) @@ -449,14 +447,14 @@ Distributed randomly select * from foo; x | y ----+---- - 1 | 1 2 | 2 3 | 3 4 | 4 - 5 | 5 - 6 | 6 7 | 7 8 | 8 + 1 | 1 + 5 | 5 + 6 | 6 9 | 9 10 | 10 (10 rows) @@ -464,46 +462,46 @@ select * from foo; select * from foo1; x | y ----+---- - 1 | 1 - 2 | 2 3 | 3 4 | 4 5 | 5 - 6 | 6 7 | 7 + 10 | 10 + 1 | 1 + 2 | 2 + 6 | 6 8 | 8 9 | 9 - 10 | 10 (10 rows) select * from bar; x | y ----+---- - 1 | 1 2 | 2 3 | 3 4 | 4 - 5 | 5 - 6 | 6 7 | 7 8 | 8 + 5 | 5 + 6 | 6 9 | 9 10 | 10 + 1 | 1 (10 rows) select * from bar1; x | y ----+---- - 1 | 1 - 2 | 2 - 3 | 3 4 | 4 - 5 | 5 - 6 | 6 7 | 7 + 3 | 3 + 10 | 10 + 1 | 1 + 5 | 5 8 | 8 + 2 | 2 + 6 | 6 9 | 9 - 10 | 10 (10 rows) drop table if exists foo; @@ -531,8 +529,8 @@ update foo set y = 1 from bar where bar.y = foo.y; select * from foo; x | y ---+--- - 1 | 1 2 | 1 + 1 | 1 (2 rows) delete from foo where y = 1; @@ -546,8 +544,8 @@ insert into foo values (1, 1), (2, 1); select * from bar where exists (select * from foo); x | y ---+--- - 2 | 2 1 | 2 + 2 | 2 (2 rows) ------ @@ -692,13 +690,12 @@ ERROR: PARTITION BY clause cannot be used with DISTRIBUTED REPLICATED clause CREATE TABLE foopart (a int4, b int4) PARTITION BY RANGE (a) (START (1) END (10)) ; NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. -NOTICE: CREATE TABLE will create partition "foopart_1_prt_1" for table "foopart" -- should fail ALTER TABLE foopart SET DISTRIBUTED REPLICATED; ERROR: can't set the distribution policy of a partition table to REPLICATED ALTER TABLE foopart_1_prt_1 SET DISTRIBUTED REPLICATED; ERROR: can't set the distribution policy of "foopart_1_prt_1" -HINT: Distribution policy can be set for an entire partitioned table, not for one of its leaf parts or an interior branch. +HINT: Distribution policy of a partition can only be the same as its parent's. DROP TABLE foopart; -- Test that replicated table can't inherit a parent table, and it also -- can't be inherited by a child table. @@ -741,8 +738,8 @@ create table t_hashdist(a int, b int, c int) distributed by (a); create table t_replicate_volatile(a int, b int, c int) distributed replicated; ---- pushed down filter explain (costs off) select * from t_replicate_volatile, t_hashdist where t_replicate_volatile.a > random(); - QUERY PLAN ----------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -750,13 +747,13 @@ explain (costs off) select * from t_replicate_volatile, t_hashdist where t_repli -> Materialize -> Seq Scan on t_replicate_volatile Filter: ((a)::double precision > random()) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) -- join qual explain (costs off) select * from t_hashdist, t_replicate_volatile x, t_replicate_volatile y where x.a + y.a > random(); - QUERY PLAN ------------------------------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: (((x.a + y.a))::double precision > random()) @@ -765,7 +762,7 @@ explain (costs off) select * from t_hashdist, t_replicate_volatile x, t_replicat -> Seq Scan on t_hashdist -> Seq Scan on t_replicate_volatile y -> Seq Scan on t_replicate_volatile x - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) -- sublink & subquery @@ -780,7 +777,7 @@ explain (costs off) select * from t_hashdist where a > All (select random() from Filter: ((CASE WHEN (sum((CASE WHEN ((t_hashdist.a)::double precision <= random()) THEN 1 ELSE 0 END)) IS NULL) THEN true WHEN (sum((CASE WHEN (random() IS NULL) THEN 1 ELSE 0 END)) > '0'::bigint) THEN NULL::boolean WHEN ((t_hashdist.a)::double precision IS NULL) THEN NULL::boolean WHEN (sum((CASE WHEN ((t_hashdist.a)::double precision <= random()) THEN 1 ELSE 0 END)) = '0'::bigint) THEN true ELSE false END) = true) -> Aggregate -> Seq Scan on t_replicate_volatile - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) explain (costs off) select * from t_hashdist where a in (select random()::int from t_replicate_volatile); @@ -794,7 +791,7 @@ explain (costs off) select * from t_hashdist where a in (select random()::int fr -> Redistribute Motion 1:3 (slice2; segments: 1) Hash Key: ((random())::integer) -> Seq Scan on t_replicate_volatile - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) -- subplan @@ -819,8 +816,8 @@ explain (costs off, verbose) select * from t_hashdist left join t_replicate_vola Output: t_replicate_volatile.a, t_replicate_volatile.b, t_replicate_volatile.c -> Seq Scan on rpt.t_replicate_volatile Output: t_replicate_volatile.a, t_replicate_volatile.b, t_replicate_volatile.c + Settings: optimizer = 'on', enable_seqscan = 'off' Optimizer: Postgres query optimizer - Settings: enable_seqscan=off, optimizer=on (20 rows) -- targetlist @@ -833,7 +830,7 @@ explain (costs off) select * from t_hashdist cross join (select random () from t -> Seq Scan on t_hashdist -> Materialize -> Seq Scan on t_replicate_volatile - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) explain (costs off) select * from t_hashdist cross join (select a, sum(random()) from t_replicate_volatile group by a) x; @@ -848,7 +845,7 @@ explain (costs off) select * from t_hashdist cross join (select a, sum(random()) -> Sort Sort Key: t_replicate_volatile.a -> Seq Scan on t_replicate_volatile - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) explain (costs off) select * from t_hashdist cross join (select random() as k, sum(a) from t_replicate_volatile group by k) x; @@ -865,12 +862,12 @@ explain (costs off) select * from t_hashdist cross join (select random() as k, s -> Materialize -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on t_hashdist - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) explain (costs off) select * from t_hashdist cross join (select a, sum(b) as s from t_replicate_volatile group by a having sum(b) > random() order by a) x ; - QUERY PLAN --------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Join Filter: true @@ -883,7 +880,7 @@ explain (costs off) select * from t_hashdist cross join (select a, sum(b) as s f -> Sort Sort Key: t_replicate_volatile.a -> Seq Scan on t_replicate_volatile - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) -- insert @@ -894,7 +891,7 @@ explain (costs off) insert into t_replicate_volatile select random() from t_repl -> Result -> Broadcast Motion 1:3 (slice1; segments: 1) -> Seq Scan on t_replicate_volatile t_replicate_volatile_1 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) explain (costs off) insert into t_replicate_volatile select random(), a, a from generate_series(1, 10) a; @@ -904,7 +901,7 @@ explain (costs off) insert into t_replicate_volatile select random(), a, a from -> Result -> Broadcast Motion 1:3 (slice1) -> Function Scan on generate_series - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) create sequence seq_for_insert_replicated_table; @@ -915,16 +912,16 @@ explain (costs off) insert into t_replicate_volatile select nextval('seq_for_ins -> Result -> Broadcast Motion 1:3 (slice1) -> Result - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (5 rows) explain (costs off) select a from t_replicate_volatile union all select * from nextval('seq_for_insert_replicated_table'); - QUERY PLAN + QUERY PLAN ------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Append -> Result - One-Time Filter: (gp_execution_segment() = 0) + One-Time Filter: (gp_execution_segment() = 1) -> Seq Scan on t_replicate_volatile -> Redistribute Motion 1:3 (slice2) -> Function Scan on nextval @@ -957,20 +954,20 @@ explain (costs off) create table rpt_ctas as select a from generate_series(1, 10 -- update & delete explain (costs off) update t_replicate_volatile set a = 1 where b > random(); -ERROR: could not devise a plan (cdbpath.c:2578) +ERROR: could not devise a plan (cdbpath.c:2907) 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) +ERROR: could not devise a plan (cdbpath.c:2907) 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) +ERROR: could not devise a plan (cdbpath.c:2907) explain (costs off) delete from t_replicate_volatile where a < random(); -ERROR: could not devise a plan (cdbpath.c:2578) +ERROR: could not devise a plan (cdbpath.c:2907) 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) +ERROR: could not devise a plan (cdbpath.c:2907) explain (costs off) update t_replicate_volatile set a = random(); -ERROR: could not devise a plan. (cdbpath.c:2441) +ERROR: could not devise a plan. (cdbpath.c:2697) -- limit explain (costs off) insert into t_replicate_volatile select * from t_replicate_volatile limit random(); - QUERY PLAN + QUERY PLAN --------------------------------------------------------------------------------------- Insert on t_replicate_volatile -> Result @@ -978,7 +975,7 @@ explain (costs off) insert into t_replicate_volatile select * from t_replicate_v -> Limit -> Gather Motion 1:1 (slice2; segments: 1) -> Seq Scan on t_replicate_volatile t_replicate_volatile_1 - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) explain (costs off) select * from t_hashdist cross join (select * from t_replicate_volatile limit random()) x; @@ -992,7 +989,7 @@ explain (costs off) select * from t_hashdist cross join (select * from t_replica -> Materialize -> Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on t_hashdist - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) -- ORCA @@ -1023,7 +1020,7 @@ explain select b from dist_tab where b in (select distinct c from rep_tab); -> Seq Scan on rep_tab (cost=0.00..431.00 rows=2 width=4) -> Index Scan using idx on dist_tab (cost=0.00..12.00 rows=1 width=4) Index Cond: (b = rep_tab.c) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (11 rows) select b from dist_tab where b in (select distinct c from rep_tab); @@ -1055,14 +1052,14 @@ explain select c from rep_tab where c in (select distinct c from rep_tab); -> Seq Scan on rep_tab (cost=0.00..431.00 rows=6 width=4) -> Hash (cost=431.00..431.00 rows=6 width=4) -> Seq Scan on rep_tab rep_tab_1 (cost=0.00..431.00 rows=6 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) select c from rep_tab where c in (select distinct c from rep_tab); c --- - 2 1 + 2 (2 rows) -- Table Side Derives @@ -1079,16 +1076,16 @@ explain select a from dist_tab where a in (select distinct c from rep_tab); -> Seq Scan on dist_tab (cost=0.00..431.00 rows=2 width=4) -> Hash (cost=431.00..431.00 rows=2 width=4) -> Seq Scan on rep_tab (cost=0.00..431.00 rows=2 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) select a from dist_tab where a in (select distinct c from rep_tab); a --- - 1 - 1 2 2 + 1 + 1 (4 rows) -- Table Side Derives @@ -1100,12 +1097,12 @@ explain select d from rand_tab where d in (select distinct c from rep_tab); QUERY PLAN ------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=2 width=4) - -> Hash Semi Join (cost=0.00..862.00 rows=1 width=4) + -> Hash Right Semi Join (cost=0.00..862.00 rows=1 width=4) Hash Cond: (rand_tab.d = rep_tab.c) - -> Seq Scan on rand_tab (cost=0.00..431.00 rows=1 width=4) - -> Hash (cost=431.00..431.00 rows=2 width=4) - -> Seq Scan on rep_tab (cost=0.00..431.00 rows=2 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + -> Seq Scan on rep_tab (cost=0.00..431.00 rows=2 width=4) + -> Hash (cost=431.00..431.00 rows=1 width=4) + -> Seq Scan on rand_tab (cost=0.00..431.00 rows=1 width=4) + Optimizer: GPORCA (7 rows) select d from rand_tab where d in (select distinct c from rep_tab); @@ -1124,23 +1121,24 @@ explain select c from rep_tab where c in (select distinct a from dist_tab); QUERY PLAN ---------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=2 width=4) - -> Hash Join (cost=0.00..862.00 rows=1 width=4) - Hash Cond: (dist_tab.a = rep_tab.c) + -> Hash Right Semi Join (cost=0.00..862.00 rows=1 width=4) + Hash Cond: (rep_tab.c = dist_tab.a) -> GroupAggregate (cost=0.00..431.00 rows=1 width=4) Group Key: dist_tab.a -> Sort (cost=0.00..431.00 rows=2 width=4) Sort Key: dist_tab.a -> Seq Scan on dist_tab (cost=0.00..431.00 rows=2 width=4) - -> Hash (cost=431.00..431.00 rows=2 width=4) - -> Seq Scan on rep_tab (cost=0.00..431.00 rows=2 width=4) - Optimizer: Pivotal Optimizer (GPORCA) -(11 rows) + -> Hash (cost=431.00..431.00 rows=1 width=4) + -> Result (cost=0.00..431.00 rows=1 width=4) + -> Seq Scan on rep_tab (cost=0.00..431.00 rows=2 width=4) + Optimizer: GPORCA +(12 rows) select c from rep_tab where c in (select distinct a from dist_tab); c --- - 1 2 + 1 (2 rows) -- Table Side Derives @@ -1149,25 +1147,25 @@ select c from rep_tab where c in (select distinct a from dist_tab); -- -- join derives EdtHashed explain select c from rep_tab where c in (select distinct d from rand_tab); - QUERY PLAN ------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=2 width=4) - -> Hash Semi Join (cost=0.00..862.00 rows=1 width=4) + -> Hash Right Semi Join (cost=0.00..862.00 rows=1 width=4) Hash Cond: (rep_tab.c = rand_tab.d) - -> Result (cost=0.00..431.00 rows=1 width=4) - -> Seq Scan on rep_tab (cost=0.00..431.00 rows=2 width=4) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) + Hash Key: rand_tab.d + -> Seq Scan on rand_tab (cost=0.00..431.00 rows=1 width=4) -> Hash (cost=431.00..431.00 rows=1 width=4) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) - Hash Key: rand_tab.d - -> Seq Scan on rand_tab (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + -> Result (cost=0.00..431.00 rows=1 width=4) + -> Seq Scan on rep_tab (cost=0.00..431.00 rows=2 width=4) + Optimizer: GPORCA (10 rows) select c from rep_tab where c in (select distinct d from rand_tab); c --- - 2 1 + 2 (2 rows) -- Github Issue 13532 @@ -1184,7 +1182,7 @@ explain (costs off) select * from t1_13532 x, t2_13532 y where y.a < random() an -> Index Scan using idx_t2_13532 on t2_13532 y Index Cond: (b = x.b) Filter: ((a)::double precision < random()) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) set enable_bitmapscan = off; @@ -1198,16 +1196,16 @@ explain (costs off) select * from t1_13532 x, t2_13532 y where y.a < random() an -> Index Scan using idx_t2_13532 on t2_13532 y Index Cond: (b = x.b) Filter: ((a)::double precision < random()) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) -- test for optimizer_enable_replicated_table explain (costs off) select * from rep_tab; - QUERY PLAN + QUERY PLAN ------------------------------------------ Gather Motion 1:1 (slice1; segments: 1) -> Seq Scan on rep_tab - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (3 rows) set optimizer_enable_replicated_table=off; @@ -1215,7 +1213,7 @@ set optimizer_trace_fallback=on; explain (costs off) select * from rep_tab; INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner DETAIL: Falling back to Postgres-based planner because GPORCA does not support the following feature: Use optimizer_enable_replicated_table to enable replicated tables - QUERY PLAN + QUERY PLAN ------------------------------------------ Gather Motion 1:1 (slice1; segments: 1) -> Seq Scan on rep_tab @@ -1237,7 +1235,7 @@ explain (costs off) select j, (select j) AS "Correlated Field" from t; SubPlan 1 -> Result -> Result - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (6 rows) select j, (select j) AS "Correlated Field" from t; @@ -1255,7 +1253,7 @@ explain (costs off) select j, (select 5) AS "Uncorrelated Field" from t; -> Seq Scan on t -> Materialize -> Result - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) select j, (select 5) AS "Uncorrelated Field" from t; @@ -1266,9 +1264,21 @@ select j, (select 5) AS "Uncorrelated Field" from t; -- start_ignore drop schema rpt cascade; -NOTICE: drop cascades to 7 other objects +NOTICE: drop cascades to 16 other objects DETAIL: drop cascades to table foo drop cascades to table bar +drop cascades to view v_foo drop cascades to table baz drop cascades to table qux +drop cascades to table cursor_update +drop cascades to table minmaxtest +drop cascades to table t_hashdist +drop cascades to table t_replicate_volatile +drop cascades to sequence seq_for_insert_replicated_table +drop cascades to table dist_tab +drop cascades to table rep_tab +drop cascades to table rand_tab +drop cascades to table t1_13532 +drop cascades to table t2_13532 +drop cascades to table t -- end_ignore diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out index 7b827ca937d..13b175bde10 100644 --- a/src/test/regress/expected/subselect.out +++ b/src/test/regress/expected/subselect.out @@ -84,6 +84,8 @@ CREATE TABLE SUBSELECT_TBL ( f2 integer, f3 float ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO SUBSELECT_TBL VALUES (1, 2, 3); INSERT INTO SUBSELECT_TBL VALUES (2, 3, 4); INSERT INTO SUBSELECT_TBL VALUES (3, 4, 5); @@ -95,14 +97,14 @@ INSERT INTO SUBSELECT_TBL VALUES (8, 9, NULL); SELECT * FROM SUBSELECT_TBL; f1 | f2 | f3 ----+----+---- - 1 | 2 | 3 2 | 3 | 4 3 | 4 | 5 - 1 | 1 | 1 2 | 2 | 2 3 | 3 | 3 - 6 | 7 | 8 8 | 9 | + 6 | 7 | 8 + 1 | 2 | 3 + 1 | 1 | 1 (8 rows) -- Uncorrelated subselects @@ -118,10 +120,10 @@ SELECT f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL); Uncorrelated Field -------------------- + 1 1 2 3 - 1 2 3 (6 rows) @@ -131,12 +133,12 @@ SELECT f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL f2 IN (SELECT f1 FROM SUBSELECT_TBL)); Uncorrelated Field -------------------- - 1 2 3 - 1 2 3 + 1 + 1 (6 rows) SELECT f1, f2 @@ -145,8 +147,8 @@ SELECT f1, f2 WHERE f3 IS NOT NULL); f1 | f2 ----+---- - 1 | 2 6 | 7 + 1 | 2 8 | 9 (3 rows) @@ -157,9 +159,9 @@ SELECT f1 AS "Correlated Field", f2 AS "Second Field" Correlated Field | Second Field ------------------+-------------- 1 | 2 + 1 | 1 2 | 3 3 | 4 - 1 | 1 2 | 2 3 | 3 (6 rows) @@ -170,9 +172,9 @@ SELECT f1 AS "Correlated Field", f3 AS "Second Field" (SELECT f2 FROM SUBSELECT_TBL WHERE CAST(upper.f2 AS float) = f3); Correlated Field | Second Field ------------------+-------------- + 1 | 1 2 | 4 3 | 5 - 1 | 1 2 | 2 3 | 3 (5 rows) @@ -183,10 +185,10 @@ SELECT f1 AS "Correlated Field", f3 AS "Second Field" WHERE f2 = CAST(f3 AS integer)); Correlated Field | Second Field ------------------+-------------- - 1 | 3 2 | 4 3 | 5 6 | 8 + 1 | 3 (4 rows) SELECT f1 AS "Correlated Field" @@ -197,9 +199,9 @@ SELECT f1 AS "Correlated Field" ------------------ 2 3 - 1 2 3 + 1 (5 rows) -- Subselects without aliases @@ -228,11 +230,11 @@ SELECT * FROM (SELECT * FROM (SELECT abs(f1) AS a1 FROM int4_tbl)), SELECT * FROM view_unnamed_ss; a1 | q1 | q2 ----+------------------+------------------- - 0 | 123 | 456 - 0 | 123 | 4567890123456789 0 | 4567890123456789 | -4567890123456789 0 | 4567890123456789 | 123 0 | 4567890123456789 | 4567890123456789 + 0 | 123 | 456 + 0 | 123 | 4567890123456789 (5 rows) \sv view_unnamed_ss @@ -274,11 +276,11 @@ SELECT ss.f1 AS "Correlated Field", ss.f3 AS "Second Field" WHERE f1 != ss.f1 AND f1 < 2147483647); Correlated Field | Second Field ------------------+-------------- + 6 | 8 2 | 4 3 | 5 2 | 2 3 | 3 - 6 | 8 8 | (6 rows) @@ -302,30 +304,34 @@ SELECT *, pg_typeof(f1) FROM -- ... unless there's context to suggest differently explain (verbose, costs off) select '42' union all select '43'; - QUERY PLAN ----------------------------- + QUERY PLAN +------------------------------------- Append -> Result Output: '42'::text -> Result Output: '43'::text -(5 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(7 rows) explain (verbose, costs off) select '42' union all select 43; - QUERY PLAN --------------------- + QUERY PLAN +------------------------------------- Append -> Result Output: 42 -> Result Output: 43 -(5 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(7 rows) -- check materialization of an initplan reference (bug #14524) explain (verbose, costs off) select 1 = all (select (select 1)); - QUERY PLAN ------------------------------------ + QUERY PLAN +------------------------------------- Result Output: (SubPlan 2) SubPlan 2 @@ -336,7 +342,9 @@ select 1 = all (select (select 1)); Output: 1 -> Result Output: $0 -(10 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(12 rows) select 1 = all (select (select 1)); ?column? @@ -353,11 +361,11 @@ select * from int4_tbl o where exists QUERY PLAN ------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join - Hash Cond: (o.f1 = i.f1) - -> Seq Scan on int4_tbl o + -> Hash Right Semi Join + Hash Cond: (i.f1 = o.f1) + -> Seq Scan on int4_tbl i -> Hash - -> Seq Scan on int4_tbl i + -> Seq Scan on int4_tbl o Optimizer: Postgres query optimizer (7 rows) @@ -427,7 +435,11 @@ select count(distinct ss.ten) from -- Luca Pireddu and Michael Fuhr. -- CREATE TEMP TABLE foo (id integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TEMP TABLE bar (id1 integer, id2 integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO foo VALUES (1); INSERT INTO bar VALUES (1, 1); INSERT INTO bar VALUES (2, 2); @@ -487,6 +499,8 @@ CREATE TABLE orderstest ( po_ref integer, ordercanceled boolean ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'approver_ref' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO orderstest VALUES (1, 1, false); INSERT INTO orderstest VALUES (66, 5, false); INSERT INTO orderstest VALUES (66, 6, false); @@ -537,7 +551,6 @@ FROM orderstest ord; SELECT * FROM orders_view; approver_ref | po_ref | ordercanceled | Approved | Status | Status_OK --------------+--------+---------------+----------+----------+----------- - 1 | 1 | f | --- | --- | --- 66 | 5 | f | Approved | PO | PO 66 | 6 | f | Approved | PO | PO 66 | 7 | f | Approved | PO | PO @@ -545,9 +558,10 @@ SELECT * FROM orders_view; 66 | 8 | f | Approved | PO | PO 66 | 1 | f | Approved | Approved | Approved 77 | 1 | f | Approved | Approved | Approved - 1 | 1 | f | --- | --- | --- 66 | 1 | f | Approved | Approved | Approved 1 | 1 | f | --- | --- | --- + 1 | 1 | f | --- | --- | --- + 1 | 1 | f | --- | --- | --- (11 rows) DROP TABLE orderstest cascade; @@ -560,12 +574,16 @@ create temp table parts ( partnum text, cost float8 ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'partnum' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp table shipped ( ttype char(2), ordnum int4, partnum text, value float8 ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'ttype' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp view shipped_view as select * from shipped where ttype = 'wt'; create rule shipped_view_insert as on insert to shipped_view do instead @@ -597,9 +615,9 @@ select f1, ss1 as relabel from from int4_tbl a) ss; f1 | relabel -------------+------------ - 0 | 2147607103 123456 | 2147607103 -123456 | 2147483647 + 0 | 2147607103 2147483647 | 2147483647 -2147483647 | 0 (5 rows) @@ -635,26 +653,30 @@ select * from ( -- pointless.) -- create temp table numeric_table (num_col numeric); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'num_col' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into numeric_table values (1), (1.000000000000000000001), (2), (3); create temp table float_table (float_col float8); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'float_col' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into float_table values (1), (2), (3); select * from float_table where float_col in (select num_col from numeric_table); float_col ----------- 1 - 2 3 + 2 (3 rows) select * from numeric_table where num_col in (select float_col from float_table); num_col ------------------------- - 1 1.000000000000000000001 - 2 3 + 1 + 2 (4 rows) -- @@ -680,6 +702,8 @@ ERROR: correlated subquery with skip-level correlations is not supported -- Test case for 8.3 "failed to locate grouping columns" bug -- create temp table t1 (f1 numeric(14,0), f2 varchar(30)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. select * from (select distinct f1, f2, (select f2 from t1 x where x.f1 = up.f1) as fs from t1 up) ss @@ -692,6 +716,8 @@ group by f1,f2,fs; -- Test case for bug #5514 (mishandling of whole-row Vars in subselects) -- create temp table table_a(id integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into table_a values (42); create temp view view_a as select * from table_a; select view_a from view_a; @@ -739,10 +765,10 @@ with q as (select max(f1) from int4_tbl group by f1 order by f1) select q from q; -- order none q --------------- - (-2147483647) (-123456) - (0) (123456) + (-2147483647) + (0) (2147483647) (5 rows) @@ -801,11 +827,15 @@ returning *; -- Test case for cross-type partial matching in hashed subplan (bug #7597) -- create temp table outer_7597 (f1 int4, f2 int4); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into outer_7597 values (0, 0); insert into outer_7597 values (1, 0); insert into outer_7597 values (0, null); insert into outer_7597 values (1, null); create temp table inner_7597(c1 int8, c2 int8); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into inner_7597 values(0, null); select * from outer_7597 where (f1, f2) not in (select * from inner_7597); f1 | f2 @@ -820,11 +850,15 @@ select * from outer_7597 where (f1, f2) not in (select * from inner_7597); -- (otherwise it would error in texteq()) -- create temp table outer_text (f1 text, f2 text); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into outer_text values ('a', 'a'); insert into outer_text values ('b', 'a'); insert into outer_text values ('a', null); insert into outer_text values ('b', null); create temp table inner_text (c1 text, c2 text); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into inner_text values ('a', null); insert into inner_text values ('123', '456'); select * from outer_text where (f1, f2) not in (select * from inner_text); @@ -850,7 +884,9 @@ select 'foo'::text in (select 'bar'::name union all select 'bar'::name); Output: 'bar'::name -> Result Output: 'bar'::name -(8 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(10 rows) select 'foo'::text in (select 'bar'::name union all select 'bar'::name); ?column? @@ -873,8 +909,9 @@ select row(row(row(1))) = any (select row(row(1))); Output: (ROW(ROW(1))) -> Result Output: ROW(ROW(1)) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(8 rows) +(9 rows) select row(row(row(1))) = any (select row(row(1))); ?column? @@ -916,6 +953,7 @@ select * from int8_tbl where q1 in (select c1 from inner_text); SubPlan 1 -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on inner_text + Optimizer: Postgres query optimizer (7 rows) select * from int8_tbl where q1 in (select c1 from inner_text); @@ -939,6 +977,7 @@ select * from int8_tbl where q1 in (select c1 from inner_text); SubPlan 1 -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on inner_text + Optimizer: Postgres query optimizer (7 rows) select * from int8_tbl where q1 in (select c1 from inner_text); @@ -990,6 +1029,7 @@ where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0); SubPlan 2 -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on tenk1 k + Optimizer: Postgres query optimizer (9 rows) select count(*) from tenk1 t @@ -1019,7 +1059,8 @@ where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0) -> Materialize -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on tenk1 k -(14 rows) + Optimizer: Postgres query optimizer +(15 rows) select count(*) from tenk1 t where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0) @@ -1031,8 +1072,12 @@ where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0) -- It's possible for the same EXISTS to get resolved both ways create temp table exists_tbl (c1 int, c2 int, c3 int) partition by list (c1); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp table exists_tbl_null partition of exists_tbl for values in (null); +NOTICE: table has parent, setting distribution columns to match parent table create temp table exists_tbl_def partition of exists_tbl default; +NOTICE: table has parent, setting distribution columns to match parent table insert into exists_tbl select x, x/2, x+1 from generate_series(0,10) x; analyze exists_tbl; explain (costs off) @@ -1069,12 +1114,12 @@ select * from exists_tbl t1 where (exists(select 1 from exists_tbl t2 where t1.c1 = t2.c2) or c3 < 0); c1 | c2 | c3 ----+----+---- - 0 | 0 | 1 - 1 | 0 | 2 2 | 1 | 3 3 | 1 | 4 4 | 2 | 5 5 | 2 | 6 + 0 | 0 | 1 + 1 | 0 | 2 (6 rows) -- @@ -1110,14 +1155,15 @@ explain (verbose, costs off) InitPlan 2 (returns $1) -> Result Output: 'regression'::name + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(9 rows) +(10 rows) explain (verbose, costs off) select x, x from (select (select random()) as x from (values(1),(2)) v(y)) ss; - QUERY PLAN ------------------------------------ + QUERY PLAN +------------------------------------- Subquery Scan on ss Output: ss.x, ss.x -> Values Scan on "*VALUES*" @@ -1125,8 +1171,9 @@ explain (verbose, costs off) InitPlan 1 (returns $0) -> Result Output: random() + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(8 rows) +(9 rows) explain (verbose, costs off) select x, x from @@ -1143,8 +1190,9 @@ explain (verbose, costs off) -> Result Output: 'regression'::name One-Time Filter: ("*VALUES*".column1 = "*VALUES*".column1) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(11 rows) +(12 rows) explain (verbose, costs off) select x, x from @@ -1159,8 +1207,9 @@ explain (verbose, costs off) -> Result Output: random() One-Time Filter: ("*VALUES*".column1 = "*VALUES*".column1) + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(9 rows) +(10 rows) -- -- Test rescan of a hashed subplan (the use of random() is to prevent the @@ -1282,13 +1331,17 @@ where o.ten = 1; -- Check we don't misoptimize a NOT IN where the subquery returns no rows. -- create temp table notinouter (a int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp table notininner (b int not null); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'b' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into notinouter values (null), (1); select * from notinouter where a not in (select b from notininner); a --- - 1 + (2 rows) -- @@ -1346,7 +1399,9 @@ select * from SubPlan 1 -> Values Scan on "*VALUES*_1" Output: "*VALUES*_1".column1 -(5 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(7 rows) select * from (values @@ -1393,8 +1448,9 @@ select * from int4_tbl where Output: a.unique1 -> Seq Scan on public.tenk1 a Output: a.unique1 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(25 rows) +(26 rows) select * from int4_tbl where (case when f1 in (select unique1 from tenk1 a) then f1 else null end) in @@ -1410,28 +1466,29 @@ select * from int4_tbl where explain (verbose, costs off) select * from int4_tbl o where (f1, f1) in (select f1, generate_series(1,50) / 10 g from int4_tbl i group by f1); - QUERY PLAN -------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: o.f1 - -> Hash Semi Join + -> Hash Right Semi Join Output: o.f1 - Hash Cond: (o.f1 = "ANY_subquery".f1) - -> Seq Scan on public.int4_tbl o - Output: o.f1 - -> Hash + Hash Cond: ("ANY_subquery".f1 = o.f1) + -> Subquery Scan on "ANY_subquery" Output: "ANY_subquery".f1, "ANY_subquery".g - -> Subquery Scan on "ANY_subquery" - Output: "ANY_subquery".f1, "ANY_subquery".g - Filter: ("ANY_subquery".f1 = "ANY_subquery".g) - -> Result - Output: i.f1, ((generate_series(1, 50)) / 10) - -> ProjectSet - Output: generate_series(1, 50), i.f1 - -> Seq Scan on public.int4_tbl i - Output: i.f1 + Filter: ("ANY_subquery".f1 = "ANY_subquery".g) + -> Result + Output: i.f1, ((generate_series(1, 50)) / 10) + -> ProjectSet + Output: generate_series(1, 50), i.f1 + -> Seq Scan on public.int4_tbl i + Output: i.f1 + -> Hash + Output: o.f1 + -> Seq Scan on public.int4_tbl o + Output: o.f1 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(19 rows) +(20 rows) select * from int4_tbl o where (f1, f1) in (select f1, generate_series(1,50) / 10 g from int4_tbl i group by f1); @@ -1451,9 +1508,9 @@ select (select q from from int4_tbl; q ----------- - (4,5,6.0) (1,2,3) (4,5,6.0) + (4,5,6.0) (1,2,3) (4,5,6.0) (5 rows) @@ -1495,7 +1552,9 @@ where b and f1 >= 0; Output: random() -> Result Output: true, 2 -(21 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(22 rows) select * from int4_tbl i4, @@ -1508,9 +1567,9 @@ select * from where b and f1 >= 0; f1 | b | id ------------+---+---- - 0 | t | 2 123456 | t | 1 123456 | t | 2 + 0 | t | 2 2147483647 | t | 1 2147483647 | t | 2 (5 rows) @@ -1566,7 +1625,9 @@ select * from -> ProjectSet Output: 9, unnest('{1,2,3,11,12,13}'::integer[]) -> Result -(6 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(8 rows) select * from (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss @@ -1599,7 +1660,9 @@ NOTICE: x = 9, y = 8 ProjectSet Output: 9, unnest('{1,2,3,11,12,13}'::integer[]) -> Result -(4 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(5 rows) select * from (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss @@ -1628,7 +1691,9 @@ select * from -> ProjectSet Output: 9, unnest('{1,2,3,11,12,13}'::integer[]) -> Result -(6 rows) + Settings: optimizer = 'off' + Optimizer: Postgres query optimizer +(8 rows) select * from (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss @@ -1703,7 +1768,7 @@ select * from (select pk,c2 from sq_limit order by c1,pk) as x limit 3; ----+---- 1 | 1 5 | 1 - 6 | 2 + 2 | 2 (3 rows) --end_ignore @@ -1721,12 +1786,7 @@ declare c1 scroll cursor for where i <> all (values (2),(3)); move forward all in c1; fetch backward all in c1; - i ---- - 4 - 1 -(2 rows) - +ERROR: backward scan is not supported in this version of Apache Cloudberry commit; --end_ignore -- @@ -1798,8 +1858,9 @@ order by t1.ten; Output: t1.ten, t1.unique1 -> Seq Scan on public.tenk1 t1 Output: t1.ten, t1.unique1 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(28 rows) +(29 rows) select t1.ten, sum(x) from tenk1 t1 left join lateral ( @@ -1861,8 +1922,9 @@ order by 1, 2; Hash Key: t1.q2 -> Seq Scan on public.int8_tbl t1 Output: t1.q1, t1.q2 + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(32 rows) +(33 rows) select t1.q1, x from int8_tbl t1 left join @@ -1893,15 +1955,15 @@ set gp_cte_sharing to on; explain (verbose, costs off) with x as (select * from (select f1 from subselect_tbl) ss) select * from x where f1 = 1; - QUERY PLAN ------------------------------------------- + QUERY PLAN +---------------------------------------------------- Gather Motion 1:1 (slice1; segments: 1) Output: subselect_tbl.f1 -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1 Filter: (subselect_tbl.f1 = 1) + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer - Settings: optimizer=off (7 rows) -- Explicitly request materialization @@ -1919,8 +1981,8 @@ select * from x where f1 = 1; Output: share0_ref1.f1 -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1 + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer - Settings: gp_cte_sharing=on (11 rows) -- Stable functions are safe to inline @@ -1934,8 +1996,8 @@ select * from x where f1 = 1; -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1, 'regression'::name Filter: (subselect_tbl.f1 = 1) + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer - Settings: gp_cte_sharing=on (7 rows) -- Volatile functions prevent inlining @@ -1955,12 +2017,13 @@ select * from x where f1 = 1; Output: share0_ref1.f1, share0_ref1.random -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1, random() + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(10 rows) +(11 rows) create temporary sequence ts; create table vol_test(a int, b int); -NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table. +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. explain (verbose, costs off) with x as (select * from (select a, nextval('ts') from vol_test) ss) @@ -1976,8 +2039,9 @@ select * from x where a = 1; Output: share0_ref1.a, share0_ref1.nextval -> Seq Scan on public.vol_test Output: vol_test.a, nextval('ts'::regclass) + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(10 rows) +(11 rows) drop sequence ts; drop table vol_test; @@ -1998,8 +2062,8 @@ select * from x where f1 = 1; -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1, subselect_tbl.ctid Filter: (subselect_tbl.f1 = 1) + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer - Settings: gp_cte_sharing=on, optimizer=off (9 rows) -- Multiply-referenced CTEs are inlined only when requested @@ -2027,7 +2091,7 @@ select * from x, x x2 where x.n = x2.n; Output: share0_ref1.f1, share0_ref1.n -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1, 'regression'::name - Settings: gp_cte_sharing=on + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer (21 rows) @@ -2053,8 +2117,8 @@ select * from x, x x2 where x.n = x2.n; Hash Key: ('regression'::name) -> Seq Scan on public.subselect_tbl subselect_tbl_1 Output: subselect_tbl_1.f1, 'regression'::name + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer - Settings: gp_cte_sharing=on (19 rows) -- Multiply-referenced CTEs can't be inlined if they contain outer self-refs @@ -2066,8 +2130,8 @@ with recursive x(a) as select z.a || z1.a as a from z cross join z as z1 where length(z.a || z1.a) < 5)) select * from x; - QUERY PLAN ---------------------------------------------------- + QUERY PLAN +---------------------------------------------------- Recursive Union -> Values Scan on "*VALUES*" Output: "*VALUES*".column1 @@ -2078,7 +2142,7 @@ select * from x; Output: x.a -> WorkTable Scan on x x_1 Output: x_1.a - Settings: optimizer = 'off' + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer (12 rows) @@ -2123,8 +2187,8 @@ with recursive x(a) as select z.a || z.a as a from z where length(z.a || z.a) < 5)) select * from x; - QUERY PLAN --------------------------------------------------- + QUERY PLAN +---------------------------------------------------- Recursive Union -> Values Scan on "*VALUES*" Output: "*VALUES*".column1 @@ -2133,7 +2197,7 @@ select * from x; -> WorkTable Scan on x Output: x.a Filter: (length((x.a || x.a)) < 5) - Settings: optimizer = 'off' + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer (10 rows) @@ -2158,28 +2222,29 @@ select * from x; explain (verbose, costs off) with x as (select * from int4_tbl) select * from (with y as (select * from x) select * from y) ss; - QUERY PLAN ------------------------------------------- + QUERY PLAN +---------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: int4_tbl.f1 -> Seq Scan on public.int4_tbl Output: int4_tbl.f1 + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(5 rows) +(6 rows) explain (verbose, costs off) with x as materialized (select * from int4_tbl) select * from (with y as (select * from x) select * from y) ss; - QUERY PLAN --------------------------------------------- + QUERY PLAN +---------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: share0_ref1.f1 -> Shared Scan (share slice:id 1:0) Output: share0_ref1.f1 -> Seq Scan on public.int4_tbl Output: int4_tbl.f1 + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer - Settings: gp_cte_sharing=on, optimizer=off (8 rows) -- Ensure that we inline the currect CTE when there are @@ -2187,11 +2252,13 @@ select * from (with y as (select * from x) select * from y) ss; explain (verbose, costs off) with x as (select 1 as y) select * from (with x as (select 2 as y) select * from x) ss; - QUERY PLAN -------------- + QUERY PLAN +---------------------------------------------------- Result Output: 2 -(2 rows) + Settings: optimizer = 'off', gp_cte_sharing = 'on' + Optimizer: Postgres query optimizer +(4 rows) -- Row marks are not pushed into CTEs explain (verbose, costs off) @@ -2203,8 +2270,9 @@ select * from x for update; Output: subselect_tbl.f1, subselect_tbl.f2, subselect_tbl.f3 -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1, subselect_tbl.f2, subselect_tbl.f3 + Settings: optimizer = 'off', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(5 rows) +(6 rows) set gp_cte_sharing to off; -- Ensure that both planners produce valid plans for the query with the nested @@ -2225,8 +2293,8 @@ select j, (select j from (select j) q2) from t group by i, j; - QUERY PLAN ------------------------------------------- + QUERY PLAN +----------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: t.j, ((SubPlan 1)), t.i -> HashAggregate @@ -2237,8 +2305,9 @@ group by i, j; SubPlan 1 -> Result Output: t.j - Optimizer: Postgres-based planner -(11 rows) + Settings: optimizer = 'off', gp_cte_sharing = 'off' + Optimizer: Postgres query optimizer +(12 rows) select j, (select j from (select j) q2) @@ -2280,8 +2349,9 @@ group by j, q1; SubPlan 1 -> Result Output: t.j - Optimizer: Postgres-based planner -(17 rows) + Settings: optimizer = 'off', gp_cte_sharing = 'off' + Optimizer: Postgres query optimizer +(18 rows) select j, 1 as c, (select j from (select j) q2) q1 @@ -2298,8 +2368,8 @@ group by j, q1; -- should correctly process args of the aggregation during normalization. explain (verbose, costs off) select (select max((select t.i))) from t; - QUERY PLAN ------------------------------------------------- + QUERY PLAN +----------------------------------------------------- Finalize Aggregate Output: (SubPlan 2) -> Gather Motion 3:1 (slice1; segments: 3) @@ -2314,8 +2384,9 @@ select (select max((select t.i))) from t; SubPlan 2 -> Result Output: max((SubPlan 1)) - Optimizer: Postgres-based planner -(15 rows) + Settings: optimizer = 'off', gp_cte_sharing = 'off' + Optimizer: Postgres query optimizer +(16 rows) select (select max((select t.i))) from t; max diff --git a/src/test/regress/expected/subselect_gp.out b/src/test/regress/expected/subselect_gp.out index 3e4ea0d16c9..e66749014f0 100644 --- a/src/test/regress/expected/subselect_gp.out +++ b/src/test/regress/expected/subselect_gp.out @@ -1,3 +1,7 @@ +-- start_ignore +create schema subselect_gp; +set search_path to subselect_gp, public; +-- end_ignore set optimizer_enable_master_only_queries = on; set optimizer_segments = 3; set optimizer_nestloop_factor = 1.0; @@ -196,14 +200,14 @@ analyze mrs_t1; explain select * from mrs_t1 where exists (select x from mrs_t1 where x < -1); QUERY PLAN ------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=3.27..6.87 rows=20 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.10..2.44 rows=20 width=4) InitPlan 1 (returns $0) (slice2) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..3.27 rows=1 width=0) - -> Seq Scan on mrs_t1 mrs_t1_1 (cost=0.00..3.25 rows=1 width=0) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..1.10 rows=1 width=4) + -> Seq Scan on mrs_t1 mrs_t1_1 (cost=0.00..1.08 rows=1 width=4) Filter: (x < '-1'::integer) - -> Result (cost=3.27..6.47 rows=7 width=4) + -> Result (cost=0.00..1.07 rows=7 width=4) One-Time Filter: $0 - -> Seq Scan on mrs_t1 (cost=3.27..6.47 rows=7 width=4) + -> Seq Scan on mrs_t1 (cost=0.00..1.07 rows=7 width=4) Optimizer: Postgres query optimizer (9 rows) @@ -215,14 +219,14 @@ select * from mrs_t1 where exists (select x from mrs_t1 where x < -1) order by 1 explain select * from mrs_t1 where exists (select x from mrs_t1 where x = 1); QUERY PLAN ------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=3.27..6.87 rows=20 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.10..2.44 rows=20 width=4) InitPlan 1 (returns $0) (slice2) - -> Gather Motion 1:1 (slice3; segments: 1) (cost=0.00..3.27 rows=1 width=0) - -> Seq Scan on mrs_t1 mrs_t1_1 (cost=0.00..3.25 rows=1 width=0) + -> Gather Motion 1:1 (slice3; segments: 1) (cost=0.00..1.10 rows=1 width=4) + -> Seq Scan on mrs_t1 mrs_t1_1 (cost=0.00..1.08 rows=1 width=4) Filter: (x = 1) - -> Result (cost=3.27..6.47 rows=7 width=4) + -> Result (cost=0.00..1.07 rows=7 width=4) One-Time Filter: $0 - -> Seq Scan on mrs_t1 (cost=3.27..6.47 rows=7 width=4) + -> Seq Scan on mrs_t1 (cost=0.00..1.07 rows=7 width=4) Optimizer: Postgres query optimizer (9 rows) @@ -254,12 +258,12 @@ select * from mrs_t1 where exists (select x from mrs_t1 where x = 1) order by 1; explain select * from mrs_t1 where x in (select x-95 from mrs_t1) or x < 5; QUERY PLAN --------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice2; segments: 3) (cost=3.30..6.60 rows=13 width=4) - -> Seq Scan on mrs_t1 (cost=3.30..6.60 rows=5 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.24 rows=12 width=4) + -> Seq Scan on mrs_t1 (cost=0.00..1.08 rows=4 width=4) Filter: ((hashed SubPlan 1) OR (x < 5)) SubPlan 1 - -> Broadcast Motion 3:3 (slice1; segments: 3) (cost=0.00..3.25 rows=7 width=4) - -> Seq Scan on mrs_t1 mrs_t1_1 (cost=0.00..3.25 rows=7 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.08 rows=7 width=4) + -> Seq Scan on mrs_t1 mrs_t1_1 (cost=0.00..1.08 rows=7 width=4) Optimizer: Postgres query optimizer (7 rows) @@ -363,12 +367,11 @@ analyze csq_d1; explain select array(select x from csq_m1); -- no initplan QUERY PLAN -------------------------------------------------------------- - Result (cost=1.01..1.02 rows=1 width=0) + Result (cost=1.01..1.02 rows=1 width=32) InitPlan 1 (returns $0) -> Seq Scan on csq_m1 (cost=0.00..1.01 rows=1 width=4) - Settings: optimizer_segments=3 - Optimizer status: Postgres query optimizer -(5 rows) + Optimizer: Postgres query optimizer +(4 rows) select array(select x from csq_m1); -- {1} array @@ -379,13 +382,12 @@ select array(select x from csq_m1); -- {1} explain select array(select x from csq_d1); -- initplan QUERY PLAN ------------------------------------------------------------------------------------ - Result (cost=1.01..1.02 rows=1 width=0) + Result (cost=1.03..1.04 rows=1 width=32) InitPlan 1 (returns $0) (slice1) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.01 rows=1 width=4) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=4) -> Seq Scan on csq_d1 (cost=0.00..1.01 rows=1 width=4) - Settings: optimizer_segments=3 - Optimizer status: Postgres query optimizer -(6 rows) + Optimizer: Postgres query optimizer +(5 rows) select array(select x from csq_d1); -- {1} array @@ -456,9 +458,9 @@ select * from csq_m1; select * from csq_d1; x --- - 1 2 4 + 1 (3 rows) -- @@ -467,11 +469,11 @@ select * from csq_d1; explain select * from csq_m1 where x not in (select x from csq_d1) or x < -100; -- gather motion QUERY PLAN ------------------------------------------------------------------------------------ - Seq Scan on csq_m1 (cost=2.02..3.07 rows=2 width=4) + Seq Scan on csq_m1 (cost=0.00..1.04 rows=2 width=4) Filter: ((NOT (hashed SubPlan 1)) OR (x < '-100'::integer)) SubPlan 1 - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.02 rows=2 width=4) - -> Seq Scan on csq_d1 (cost=0.00..2.02 rows=1 width=4) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.05 rows=3 width=4) + -> Seq Scan on csq_d1 (cost=0.00..1.01 rows=1 width=4) Optimizer: Postgres query optimizer (6 rows) @@ -487,11 +489,11 @@ select * from csq_m1 where x not in (select x from csq_d1) or x < -100; -- (3) explain select * from csq_d1 where x not in (select x from csq_m1) or x < -100; -- broadcast motion QUERY PLAN -------------------------------------------------------------------------------- - Gather Motion 3:1 (slice2; segments: 3) (cost=1.04..3.07 rows=2 width=4) - -> Seq Scan on csq_d1 (cost=1.04..3.07 rows=1 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.04 rows=2 width=4) + -> Seq Scan on csq_d1 (cost=0.00..1.01 rows=1 width=4) Filter: ((NOT (hashed SubPlan 1)) OR (x < '-100'::integer)) SubPlan 1 - -> Broadcast Motion 1:3 (slice1) (cost=0.00..1.03 rows=3 width=4) + -> Broadcast Motion 1:3 (slice2) (cost=0.00..1.03 rows=3 width=4) -> Seq Scan on csq_m1 (cost=0.00..1.03 rows=3 width=4) Optimizer: Postgres query optimizer (7 rows) @@ -535,10 +537,10 @@ INSERT INTO csq_r VALUES (1); -- with a correlated argument -- force_explain explain SELECT * FROM csq_r WHERE a IN (SELECT * FROM csq_f(csq_r.a)); - QUERY PLAN ----------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.02 rows=1 width=4) - -> Seq Scan on csq_r (cost=0.00..1.02 rows=1 width=4) + QUERY PLAN +---------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..997.00 rows=48150 width=4) + -> Seq Scan on csq_r (cost=0.00..355.00 rows=16050 width=4) Filter: (SubPlan 1) SubPlan 1 -> Function Scan on csq_f (cost=0.00..0.01 rows=1 width=4) @@ -553,10 +555,10 @@ SELECT * FROM csq_r WHERE a IN (SELECT * FROM csq_f(csq_r.a)); -- force_explain explain SELECT * FROM csq_r WHERE a not IN (SELECT * FROM csq_f(csq_r.a)); - QUERY PLAN ----------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.02 rows=1 width=4) - -> Seq Scan on csq_r (cost=0.00..1.02 rows=1 width=4) + QUERY PLAN +---------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..997.00 rows=48150 width=4) + -> Seq Scan on csq_r (cost=0.00..355.00 rows=16050 width=4) Filter: (SubPlan 1) SubPlan 1 -> Function Scan on csq_f (cost=0.00..0.01 rows=1 width=4) @@ -570,10 +572,10 @@ SELECT * FROM csq_r WHERE a not IN (SELECT * FROM csq_f(csq_r.a)); -- force_explain explain SELECT * FROM csq_r WHERE exists (SELECT * FROM csq_f(csq_r.a)); - QUERY PLAN ----------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.02 rows=1 width=4) - -> Seq Scan on csq_r (cost=0.00..1.02 rows=1 width=4) + QUERY PLAN +---------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..997.00 rows=48150 width=4) + -> Seq Scan on csq_r (cost=0.00..355.00 rows=16050 width=4) Filter: (SubPlan 1) SubPlan 1 -> Function Scan on csq_f (cost=0.00..0.01 rows=1 width=0) @@ -588,10 +590,10 @@ SELECT * FROM csq_r WHERE exists (SELECT * FROM csq_f(csq_r.a)); -- force_explain explain SELECT * FROM csq_r WHERE not exists (SELECT * FROM csq_f(csq_r.a)); - QUERY PLAN ----------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.02 rows=1 width=4) - -> Seq Scan on csq_r (cost=0.00..1.02 rows=1 width=4) + QUERY PLAN +---------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..997.00 rows=48150 width=4) + -> Seq Scan on csq_r (cost=0.00..355.00 rows=16050 width=4) Filter: (NOT (SubPlan 1)) SubPlan 1 -> Function Scan on csq_f (cost=0.00..0.01 rows=1 width=0) @@ -605,10 +607,10 @@ SELECT * FROM csq_r WHERE not exists (SELECT * FROM csq_f(csq_r.a)); -- force_explain explain SELECT * FROM csq_r WHERE a > (SELECT csq_f FROM csq_f(csq_r.a) limit 1); - QUERY PLAN ------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.02 rows=1 width=4) - -> Seq Scan on csq_r (cost=0.00..1.02 rows=1 width=4) + QUERY PLAN +---------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..863.25 rows=32100 width=4) + -> Seq Scan on csq_r (cost=0.00..435.25 rows=10700 width=4) Filter: (a > (SubPlan 1)) SubPlan 1 -> Limit (cost=0.00..0.01 rows=1 width=4) @@ -623,10 +625,10 @@ SELECT * FROM csq_r WHERE a > (SELECT csq_f FROM csq_f(csq_r.a) limit 1); -- force_explain explain SELECT * FROM csq_r WHERE a < ANY (SELECT csq_f FROM csq_f(csq_r.a)); - QUERY PLAN ----------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.02 rows=1 width=4) - -> Seq Scan on csq_r (cost=0.00..1.02 rows=1 width=4) + QUERY PLAN +---------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..997.00 rows=48150 width=4) + -> Seq Scan on csq_r (cost=0.00..355.00 rows=16050 width=4) Filter: (SubPlan 1) SubPlan 1 -> Function Scan on csq_f (cost=0.00..0.01 rows=1 width=4) @@ -640,10 +642,10 @@ SELECT * FROM csq_r WHERE a < ANY (SELECT csq_f FROM csq_f(csq_r.a)); -- force_explain explain SELECT * FROM csq_r WHERE a <= ALL (SELECT csq_f FROM csq_f(csq_r.a)); - QUERY PLAN ----------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.02 rows=1 width=4) - -> Seq Scan on csq_r (cost=0.00..1.02 rows=1 width=4) + QUERY PLAN +---------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..997.00 rows=48150 width=4) + -> Seq Scan on csq_r (cost=0.00..355.00 rows=16050 width=4) Filter: (SubPlan 1) SubPlan 1 -> Function Scan on csq_f (cost=0.00..0.01 rows=1 width=4) @@ -658,17 +660,17 @@ SELECT * FROM csq_r WHERE a <= ALL (SELECT csq_f FROM csq_f(csq_r.a)); -- force_explain explain SELECT * FROM csq_r WHERE a IN (SELECT csq_f FROM csq_f(csq_r.a),csq_r); - QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..10000000001.54 rows=1 width=4) - -> Seq Scan on csq_r (cost=0.00..10000000001.54 rows=1 width=4) + QUERY PLAN +---------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..997.00 rows=48150 width=4) + -> Seq Scan on csq_r (cost=0.00..355.00 rows=16050 width=4) Filter: (SubPlan 1) SubPlan 1 - -> Nested Loop (cost=10000000000.00..10000000001.06 rows=4 width=4) + -> Nested Loop (cost=10000000000.00..10000003083.51 rows=96300 width=4) -> Function Scan on csq_f (cost=0.00..0.01 rows=1 width=4) - -> Materialize (cost=0.00..1.03 rows=1 width=0) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=0) - -> Seq Scan on csq_r csq_r_1 (cost=0.00..1.01 rows=1 width=0) + -> Materialize (cost=0.00..2120.50 rows=96300 width=0) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1639.00 rows=96300 width=0) + -> Seq Scan on csq_r csq_r_1 (cost=0.00..355.00 rows=32100 width=0) Optimizer: Postgres query optimizer (10 rows) @@ -700,19 +702,18 @@ insert into csq_pullup values ('def',3, 1, 'abc'); explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.t); QUERY PLAN ------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..2.11 rows=4 width=19) - -> Hash Join (cost=1.06..2.11 rows=2 width=19) - Hash Cond: t0.t = "Expr_SUBQUERY".csq_c0 - -> Seq Scan on csq_pullup t0 (cost=0.00..1.01 rows=1 width=19) - -> Hash (cost=1.04..1.04 rows=1 width=32) - -> Subquery Scan on "Expr_SUBQUERY" (cost=1.02..1.04 rows=1 width=32) - -> HashAggregate (cost=1.02..1.03 rows=1 width=40) - Filter: count(*) = 1 - Group By: t1.t + Gather Motion 3:1 (slice1; segments: 3) (cost=1.05..2.12 rows=3 width=17) + -> Hash Join (cost=1.05..2.07 rows=1 width=17) + Hash Cond: (t0.t = "Expr_SUBQUERY".csq_c0) + -> Seq Scan on csq_pullup t0 (cost=0.00..1.01 rows=1 width=17) + -> Hash (cost=1.04..1.04 rows=1 width=4) + -> Subquery Scan on "Expr_SUBQUERY" (cost=1.01..1.04 rows=1 width=4) + -> HashAggregate (cost=1.01..1.03 rows=1 width=12) + Group Key: t1.t + Filter: (1 = count(*)) -> Seq Scan on csq_pullup t1 (cost=0.00..1.01 rows=1 width=4) - Settings: optimizer_segments=3 - Optimizer status: Postgres query optimizer -(12 rows) + Optimizer: Postgres query optimizer +(11 rows) select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.t); t | n | i | v @@ -728,16 +729,16 @@ select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.v); QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice2; segments: 3) (cost=1.06..2.11 rows=4 width=17) - -> Hash Join (cost=1.06..2.11 rows=2 width=17) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.07..2.14 rows=3 width=17) + -> Hash Join (cost=1.07..2.09 rows=1 width=17) Hash Cond: (t0.t = "Expr_SUBQUERY".csq_c0) -> Seq Scan on csq_pullup t0 (cost=0.00..1.01 rows=1 width=17) - -> Hash (cost=1.05..1.05 rows=1 width=32) - -> Subquery Scan on "Expr_SUBQUERY" (cost=1.03..1.05 rows=1 width=32) - -> HashAggregate (cost=1.03..1.04 rows=1 width=40) + -> Hash (cost=1.06..1.06 rows=1 width=32) + -> Subquery Scan on "Expr_SUBQUERY" (cost=1.03..1.06 rows=1 width=32) + -> HashAggregate (cost=1.03..1.05 rows=1 width=40) Group Key: ((t1.v)::text) Filter: (1 = count(*)) - -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=32) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=32) Hash Key: ((t1.v)::text) -> Seq Scan on csq_pullup t1 (cost=0.00..1.01 rows=1 width=32) Optimizer: Postgres query optimizer @@ -757,17 +758,17 @@ select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.n=t1.n); QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice3; segments: 3) (cost=1.13..2.17 rows=4 width=17) - -> Hash Join (cost=1.13..2.17 rows=2 width=17) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.14..2.20 rows=3 width=17) + -> Hash Join (cost=1.14..2.16 rows=1 width=17) Hash Cond: (t0.n = "Expr_SUBQUERY".csq_c0) -> Seq Scan on csq_pullup t0 (cost=0.00..1.01 rows=1 width=17) - -> Hash (cost=1.09..1.09 rows=1 width=5) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=1.03..1.09 rows=1 width=5) - -> Subquery Scan on "Expr_SUBQUERY" (cost=1.03..1.05 rows=1 width=5) - -> HashAggregate (cost=1.03..1.04 rows=1 width=13) + -> Hash (cost=1.10..1.10 rows=3 width=5) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=1.03..1.10 rows=3 width=5) + -> Subquery Scan on "Expr_SUBQUERY" (cost=1.03..1.06 rows=1 width=5) + -> HashAggregate (cost=1.03..1.05 rows=1 width=13) Group Key: t1.n Filter: (1 = count(*)) - -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=5) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.03 rows=1 width=5) Hash Key: t1.n -> Seq Scan on csq_pullup t1 (cost=0.00..1.01 rows=1 width=5) Optimizer: Postgres query optimizer @@ -777,8 +778,8 @@ select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t t | n | i | v -----+---+---+----- def | 3 | 1 | abc - xyz | 2 | 3 | def abc | 1 | 2 | xyz + xyz | 2 | 3 | def (3 rows) -- @@ -787,18 +788,18 @@ select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.n + 1=t1.n + 1); QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice3; segments: 3) (cost=1.07..2.13 rows=4 width=17) - -> Hash Join (cost=1.07..2.13 rows=2 width=17) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.07..2.16 rows=3 width=17) + -> Hash Join (cost=1.07..2.12 rows=1 width=17) Hash Cond: ((t0.n + '1'::numeric) = "Expr_SUBQUERY".csq_c0) - -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=17) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=17) Hash Key: (t0.n + '1'::numeric) -> Seq Scan on csq_pullup t0 (cost=0.00..1.01 rows=1 width=17) - -> Hash (cost=1.05..1.05 rows=1 width=32) - -> Subquery Scan on "Expr_SUBQUERY" (cost=1.03..1.05 rows=1 width=32) - -> HashAggregate (cost=1.03..1.04 rows=1 width=40) + -> Hash (cost=1.06..1.06 rows=1 width=32) + -> Subquery Scan on "Expr_SUBQUERY" (cost=1.04..1.06 rows=1 width=32) + -> HashAggregate (cost=1.04..1.05 rows=1 width=40) Group Key: ((t1.n + '1'::numeric)) Filter: (1 = count(*)) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=32) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.03 rows=1 width=32) Hash Key: ((t1.n + '1'::numeric)) -> Seq Scan on csq_pullup t1 (cost=0.00..1.01 rows=1 width=32) Optimizer: Postgres query optimizer @@ -807,9 +808,9 @@ explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.n + 1=t1.n + 1); t | n | i | v -----+---+---+----- - def | 3 | 1 | abc - xyz | 2 | 3 | def abc | 1 | 2 | xyz + xyz | 2 | 3 | def + def | 3 | 1 | abc (3 rows) -- @@ -818,18 +819,18 @@ select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.n + 1=t1.i + 1); QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice3; segments: 3) (cost=1.07..2.14 rows=4 width=17) - -> Hash Join (cost=1.07..2.14 rows=2 width=17) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.08..2.17 rows=3 width=17) + -> Hash Join (cost=1.08..2.12 rows=1 width=17) Hash Cond: ((t0.n + '1'::numeric) = "Expr_SUBQUERY".csq_c0) - -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=17) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=17) Hash Key: (t0.n + '1'::numeric) -> Seq Scan on csq_pullup t0 (cost=0.00..1.01 rows=1 width=17) - -> Hash (cost=1.06..1.06 rows=1 width=32) - -> Subquery Scan on "Expr_SUBQUERY" (cost=1.03..1.06 rows=1 width=32) - -> HashAggregate (cost=1.03..1.05 rows=1 width=40) + -> Hash (cost=1.07..1.07 rows=1 width=32) + -> Subquery Scan on "Expr_SUBQUERY" (cost=1.04..1.07 rows=1 width=32) + -> HashAggregate (cost=1.04..1.06 rows=1 width=40) Group Key: (((t1.i + 1))::numeric) Filter: (1 = count(*)) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=32) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.03 rows=1 width=32) Hash Key: (((t1.i + 1))::numeric) -> Seq Scan on csq_pullup t1 (cost=0.00..1.01 rows=1 width=32) Optimizer: Postgres query optimizer @@ -867,9 +868,9 @@ explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.t LIMIT 1); t | n | i | v -----+---+---+----- + abc | 1 | 2 | xyz xyz | 2 | 3 | def def | 3 | 1 | abc - abc | 1 | 2 | xyz (3 rows) -- subquery contains a HAVING clause @@ -893,9 +894,9 @@ explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.t HAVING count(*) < 10); t | n | i | v -----+---+---+----- + abc | 1 | 2 | xyz xyz | 2 | 3 | def def | 3 | 1 | abc - abc | 1 | 2 | xyz (3 rows) -- subquery contains quals of form 'function(outervar, innervar1) = innvervar2' @@ -942,8 +943,8 @@ explain select * from csq_pullup t0 where not exists (select 1 from csq_pullup t select * from csq_pullup t0 where not exists (select 1 from csq_pullup t1 where t0.t=t1.t and t1.i = 1); t | n | i | v -----+---+---+----- - abc | 1 | 2 | xyz xyz | 2 | 3 | def + abc | 1 | 2 | xyz (2 rows) -- @@ -972,9 +973,7 @@ select * from csq_pullup t0 where not exists (select 1 from csq_pullup t1 where -- wrong results bug MPP-16477 -- drop table if exists subselect_t1; -NOTICE: table "subselect_t1" does not exist, skipping drop table if exists subselect_t2; -NOTICE: table "subselect_t2" does not exist, skipping create table subselect_t1(x int) distributed by (x); insert into subselect_t1 values(1),(2); create table subselect_t2(y int) distributed by (y); @@ -996,24 +995,24 @@ explain select * from subselect_t1 where x in (select y from subselect_t2); select * from subselect_t1 where x in (select y from subselect_t2); x --- - 1 2 + 1 (2 rows) -- start_ignore -- Known_opt_diff: MPP-21351 -- end_ignore explain select * from subselect_t1 where x in (select y from subselect_t2 union all select y from subselect_t2); - QUERY PLAN ---------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.05..3.12 rows=3 width=4) - -> Hash Semi Join (cost=2.05..3.08 rows=1 width=4) - Hash Cond: (subselect_t1.x = subselect_t2.y) - -> Seq Scan on subselect_t1 (cost=0.00..1.01 rows=1 width=4) - -> Hash (cost=2.03..2.03 rows=2 width=4) - -> Append (cost=0.00..2.03 rows=2 width=4) - -> Seq Scan on subselect_t2 (cost=0.00..1.01 rows=1 width=4) - -> Seq Scan on subselect_t2 subselect_t2_1 (cost=0.00..1.01 rows=1 width=4) + QUERY PLAN +--------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=1.02..3.11 rows=3 width=4) + -> Hash Right Semi Join (cost=1.02..3.07 rows=1 width=4) + Hash Cond: (subselect_t2.y = subselect_t1.x) + -> Append (cost=0.00..2.03 rows=2 width=4) + -> Seq Scan on subselect_t2 (cost=0.00..1.01 rows=1 width=4) + -> Seq Scan on subselect_t2 subselect_t2_1 (cost=0.00..1.01 rows=1 width=4) + -> Hash (cost=1.01..1.01 rows=1 width=4) + -> Seq Scan on subselect_t1 (cost=0.00..1.01 rows=1 width=4) Optimizer: Postgres query optimizer (9 rows) @@ -1047,17 +1046,17 @@ select count(*) from subselect_t1 where x in (select y from subselect_t2); -- Known_opt_diff: MPP-21351 -- end_ignore explain select count(*) from subselect_t1 where x in (select y from subselect_t2 union all select y from subselect_t2); - QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Aggregate (cost=3.14..3.15 rows=1 width=8) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=2.06..3.13 rows=3 width=0) - -> Hash Semi Join (cost=2.06..3.09 rows=1 width=0) - Hash Cond: (subselect_t1.x = subselect_t2.y) - -> Seq Scan on subselect_t1 (cost=0.00..1.01 rows=1 width=4) - -> Hash (cost=2.04..2.04 rows=2 width=4) - -> Append (cost=0.00..2.02 rows=2 width=4) - -> Seq Scan on subselect_t2 (cost=0.00..1.01 rows=1 width=4) - -> Seq Scan on subselect_t2 subselect_t2_1 (cost=0.00..1.01 rows=1 width=4) + QUERY PLAN +--------------------------------------------------------------------------------------------------- + Aggregate (cost=3.12..3.13 rows=1 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=1.02..3.11 rows=3 width=0) + -> Hash Right Semi Join (cost=1.02..3.07 rows=1 width=0) + Hash Cond: (subselect_t2.y = subselect_t1.x) + -> Append (cost=0.00..2.03 rows=2 width=4) + -> Seq Scan on subselect_t2 (cost=0.00..1.01 rows=1 width=4) + -> Seq Scan on subselect_t2 subselect_t2_1 (cost=0.00..1.01 rows=1 width=4) + -> Hash (cost=1.01..1.01 rows=1 width=4) + -> Seq Scan on subselect_t1 (cost=0.00..1.01 rows=1 width=4) Optimizer: Postgres query optimizer (10 rows) @@ -1080,9 +1079,13 @@ select count(*) from -- Query was deadlocking because of not squelching subplans (MPP-18936) -- drop table if exists t1; +NOTICE: table "t1" does not exist, skipping drop table if exists t2; +NOTICE: table "t2" does not exist, skipping drop table if exists t3; +NOTICE: table "t3" does not exist, skipping drop table if exists t4; +NOTICE: table "t4" does not exist, skipping CREATE TABLE t1 AS (SELECT generate_series(1, 5000) AS i, generate_series(5001, 10000) AS j); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'i' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. @@ -1159,13 +1162,12 @@ select * from t1 where a=1 and a=2 and a > (select t2.b from t2); explain select * from t1, (select * from t1 where a=1 and a=2 and a > (select t2.b from t2)) foo where t1.a = foo.a; - QUERY PLAN ------------------------------------------------------------------------------ - Result (cost=1063.00..1063.01 rows=1 width=0) + QUERY PLAN +------------------------------------------------ + Result (cost=1639.00..1639.00 rows=0 width=8) One-Time Filter: false - Settings: optimizer=off; optimizer_nestloop_factor=1; optimizer_segments=3 - Optimizer status: Postgres query optimizer -(4 rows) + Optimizer: Postgres query optimizer +(3 rows) select * from t1, (select * from t1 where a=1 and a=2 and a > (select t2.b from t2)) foo @@ -1180,34 +1182,34 @@ where t1.a = foo.a; insert into t1 values (1); insert into t2 values (1); explain select 1 from t1 where a in (select b from t2 where a = 1 limit 1); - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.53 rows=1 width=0) - -> Seq Scan on t1 (cost=0.00..1.53 rows=1 width=0) + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..997.00 rows=48150 width=4) + -> Seq Scan on t1 (cost=0.00..355.00 rows=16050 width=4) Filter: (SubPlan 1) SubPlan 1 - -> Limit (cost=0.00..1.03 rows=1 width=4) - -> Result (cost=0.00..1.03 rows=1 width=4) + -> Limit (cost=0.00..0.03 rows=1 width=4) + -> Result (cost=0.00..3083.50 rows=96300 width=4) One-Time Filter: (t1.a = 1) - -> Materialize (cost=0.00..1.03 rows=1 width=4) - -> Broadcast Motion 3:3 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=4) - -> Seq Scan on t2 (cost=0.00..1.01 rows=1 width=4) + -> Materialize (cost=0.00..2120.50 rows=96300 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1639.00 rows=96300 width=4) + -> Seq Scan on t2 (cost=0.00..355.00 rows=32100 width=4) Optimizer: Postgres query optimizer (11 rows) explain select 1 from t1 where a in (select b from t2 where a = 1 offset 1); - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..2.05 rows=1 width=0) - -> Seq Scan on t1 (cost=0.00..2.05 rows=1 width=0) + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..997.00 rows=48150 width=4) + -> Seq Scan on t1 (cost=0.00..355.00 rows=16050 width=4) Filter: (SubPlan 1) SubPlan 1 - -> Limit (cost=1.03..1.03 rows=1 width=4) - -> Result (cost=0.00..1.03 rows=1 width=4) + -> Limit (cost=0.03..3083.50 rows=96299 width=4) + -> Result (cost=0.00..3083.50 rows=96300 width=4) One-Time Filter: (t1.a = 1) - -> Materialize (cost=0.00..1.03 rows=1 width=4) - -> Broadcast Motion 3:3 (slice1; segments: 3) (cost=0.00..1.03 rows=1 width=4) - -> Seq Scan on t2 (cost=0.00..1.01 rows=1 width=4) + -> Materialize (cost=0.00..2120.50 rows=96300 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1639.00 rows=96300 width=4) + -> Seq Scan on t2 (cost=0.00..355.00 rows=32100 width=4) Optimizer: Postgres query optimizer (11 rows) @@ -1279,26 +1281,25 @@ explain select row_number() over (order by seq asc) as id, foo.cnt from (select seq, (select count(*) from t1_mpp_24563 t1 where t1.id = t2.id) cnt from t2_mpp_24563 t2 where value = 7) foo; - QUERY PLAN ------------------------------------------------------------------------------------------------------- - WindowAgg (cost=1.02..2.12 rows=1 width=8) + QUERY PLAN +------------------------------------------------------------------------------------------------------------- + WindowAgg (cost=359.19..232173.17 rows=78 width=20) Order By: t2.seq - -> Gather Motion 3:1 (slice2; segments: 3) (cost=1.02..1.05 rows=1 width=8) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=359.19..360.30 rows=78 width=8) Merge Key: t2.seq - -> Sort (cost=1.02..1.03 rows=1 width=8) + -> Sort (cost=359.19..359.26 rows=26 width=8) Sort Key: t2.seq - -> Seq Scan on t2_mpp_24563 t2 (cost=0.00..1.01 rows=1 width=8) - Filter: value = 7 + -> Seq Scan on t2_mpp_24563 t2 (cost=0.00..358.58 rows=26 width=8) + Filter: (value = 7) SubPlan 1 - -> Aggregate (cost=1.06..1.07 rows=1 width=8) - -> Result (cost=1.01..1.02 rows=1 width=0) - Filter: t1.id = $0 - -> Materialize (cost=1.01..1.02 rows=1 width=0) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.01 rows=1 width=0) - -> Seq Scan on t1_mpp_24563 t1 (cost=0.00..1.01 rows=1 width=0) - Settings: optimizer_segments=3 - Optimizer status: Postgres query optimizer -(17 rows) + -> Aggregate (cost=2975.75..2975.76 rows=1 width=8) + -> Result (cost=0.00..2760.50 rows=86100 width=0) + Filter: (t1.id = t2.id) + -> Materialize (cost=0.00..1899.50 rows=86100 width=4) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1469.00 rows=86100 width=4) + -> Seq Scan on t1_mpp_24563 t1 (cost=0.00..321.00 rows=28700 width=4) + Optimizer: Postgres query optimizer +(16 rows) drop table t1_mpp_24563; drop table t2_mpp_24563; @@ -1532,42 +1533,42 @@ ANALYZE SUBSELECT_TBL; -- Uncorrelated subselects EXPLAIN SELECT '' AS six, f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL) ORDER BY 2; - QUERY PLAN ------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice2; segments: 3) (cost=6.66..6.84 rows=8 width=36) + QUERY PLAN +----------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=2.20..2.31 rows=8 width=36) Merge Key: subselect_tbl.f1 - -> Sort (cost=6.66..6.68 rows=3 width=36) + -> Sort (cost=2.20..2.20 rows=3 width=36) Sort Key: subselect_tbl.f1 - -> Hash Semi Join (cost=3.34..6.54 rows=3 width=36) - Hash Cond: (subselect_tbl.f1 = subselect_tbl_1.f2) - -> Seq Scan on subselect_tbl (cost=0.00..3.08 rows=3 width=4) - -> Hash (cost=3.24..3.24 rows=3 width=4) - -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..3.24 rows=3 width=4) - Hash Key: subselect_tbl_1.f2 - -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..3.08 rows=3 width=4) + -> Hash Right Semi Join (cost=1.06..2.18 rows=3 width=36) + Hash Cond: (subselect_tbl_1.f2 = subselect_tbl.f1) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.08 rows=3 width=4) + Hash Key: subselect_tbl_1.f2 + -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.03..1.03 rows=3 width=4) + -> Seq Scan on subselect_tbl (cost=0.00..1.03 rows=3 width=4) Optimizer: Postgres query optimizer (12 rows) EXPLAIN SELECT '' AS six, f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE f2 IN (SELECT f1 FROM SUBSELECT_TBL)) ORDER BY 2; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=3.28..3.40 rows=8 width=36) + QUERY PLAN +----------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=3.29..3.40 rows=8 width=36) Merge Key: subselect_tbl.f1 - -> Sort (cost=3.28..3.29 rows=3 width=36) + -> Sort (cost=3.29..3.29 rows=3 width=36) Sort Key: subselect_tbl.f1 - -> Hash Semi Join (cost=2.20..3.27 rows=3 width=36) - Hash Cond: (subselect_tbl.f1 = subselect_tbl_1.f2) - -> Seq Scan on subselect_tbl (cost=0.00..1.03 rows=3 width=4) - -> Hash (cost=2.17..2.17 rows=2 width=8) - -> Hash Semi Join (cost=1.06..2.17 rows=2 width=8) - Hash Cond: (subselect_tbl_1.f2 = subselect_tbl_2.f1) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.08 rows=3 width=4) - Hash Key: subselect_tbl_1.f2 - -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..1.03 rows=3 width=4) - -> Hash (cost=1.03..1.03 rows=3 width=4) - -> Seq Scan on subselect_tbl subselect_tbl_2 (cost=0.00..1.03 rows=3 width=4) + -> Hash Right Semi Join (cost=2.12..3.27 rows=3 width=36) + Hash Cond: (subselect_tbl_1.f2 = subselect_tbl.f1) + -> Hash Semi Join (cost=1.06..2.17 rows=2 width=8) + Hash Cond: (subselect_tbl_1.f2 = subselect_tbl_2.f1) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.08 rows=3 width=4) + Hash Key: subselect_tbl_1.f2 + -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.03..1.03 rows=3 width=4) + -> Seq Scan on subselect_tbl subselect_tbl_2 (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.03..1.03 rows=3 width=4) + -> Seq Scan on subselect_tbl (cost=0.00..1.03 rows=3 width=4) Optimizer: Postgres query optimizer (16 rows) @@ -1596,22 +1597,22 @@ EXPLAIN SELECT * FROM tenk1 a, tenk1 b WHERE (a.unique1,b.unique2) IN (SELECT unique1,unique2 FROM tenk1 c); QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=356.67..706.67 rows=10000 width=488) - -> Hash Join (cost=356.67..573.33 rows=3333 width=488) + Gather Motion 3:1 (slice1; segments: 3) (cost=353.67..703.67 rows=10000 width=488) + -> Hash Join (cost=353.67..570.33 rows=3333 width=488) Hash Cond: (c.unique2 = b.unique2) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=185.00..355.83 rows=3333 width=248) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=183.00..353.83 rows=3333 width=248) Hash Key: c.unique2 - -> Hash Join (cost=185.00..289.17 rows=3333 width=248) + -> Hash Join (cost=183.00..287.17 rows=3333 width=248) Hash Cond: (c.unique1 = a.unique1) - -> HashAggregate (cost=80.00..113.33 rows=10000 width=8) + -> HashAggregate (cost=79.00..112.33 rows=10000 width=8) Group Key: c.unique1, c.unique2 - -> Seq Scan on tenk1 c (cost=0.00..63.33 rows=3333 width=8) - -> Hash (cost=63.33..63.33 rows=3333 width=244) - -> Seq Scan on tenk1 a (cost=0.00..63.33 rows=3333 width=244) - -> Hash (cost=130.00..130.00 rows=3333 width=244) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..130.00 rows=3333 width=244) + -> Seq Scan on tenk1 c (cost=0.00..62.33 rows=3333 width=8) + -> Hash (cost=62.33..62.33 rows=3333 width=244) + -> Seq Scan on tenk1 a (cost=0.00..62.33 rows=3333 width=244) + -> Hash (cost=129.00..129.00 rows=3333 width=244) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..129.00 rows=3333 width=244) Hash Key: b.unique2 - -> Seq Scan on tenk1 b (cost=0.00..63.33 rows=3333 width=244) + -> Seq Scan on tenk1 b (cost=0.00..62.33 rows=3333 width=244) Optimizer: Postgres query optimizer (17 rows) @@ -1621,9 +1622,9 @@ EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f2 AS "Second Field" WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE f1 = upper.f1) ORDER BY 2,3; QUERY PLAN ------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.10..2.11 rows=4 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=2.10..2.15 rows=3 width=40) Merge Key: upper.f1, upper.f2 - -> Sort (cost=2.10..2.11 rows=2 width=8) + -> Sort (cost=2.10..2.11 rows=1 width=40) Sort Key: upper.f1, upper.f2 -> Hash Semi Join (cost=1.05..2.09 rows=1 width=40) Hash Cond: (upper.f1 = subselect_tbl.f1) @@ -1638,22 +1639,21 @@ EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f3 AS "Second Field" FROM SUBSELECT_TBL upper WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE CAST(upper.f2 AS float) = f3) ORDER BY 2,3; - QUERY PLAN ------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice2; segments: 3) (cost=2.13..2.14 rows=4 width=12) + QUERY PLAN +---------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=2.20..2.28 rows=6 width=44) Merge Key: upper.f1, upper.f3 - -> Sort (cost=2.13..2.14 rows=2 width=12) + -> Sort (cost=2.20..2.20 rows=2 width=44) Sort Key: upper.f1, upper.f3 - -> Hash Semi Join (cost=1.12..2.19 rows=2 width=44) - Hash Cond: (((upper.f2)::double precision = subselect_tbl.f3) AND (upper.f1 = subselect_tbl.f2)) - -> Seq Scan on subselect_tbl upper (cost=0.00..1.03 rows=3 width=16) - -> Hash (cost=1.08..1.08 rows=3 width=12) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.08 rows=3 width=12) - Hash Key: subselect_tbl.f2 - -> Seq Scan on subselect_tbl (cost=0.00..1.01 rows=1 width=12) - Settings: optimizer=off - Optimizer status: Postgres query optimizer -(13 rows) + -> Hash Right Semi Join (cost=1.07..2.19 rows=2 width=44) + Hash Cond: ((subselect_tbl.f3 = (upper.f2)::double precision) AND (subselect_tbl.f2 = upper.f1)) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.08 rows=3 width=12) + Hash Key: subselect_tbl.f2 + -> Seq Scan on subselect_tbl (cost=0.00..1.03 rows=3 width=12) + -> Hash (cost=1.03..1.03 rows=3 width=16) + -> Seq Scan on subselect_tbl upper (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer +(12 rows) EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f3 AS "Second Field" FROM SUBSELECT_TBL upper @@ -1684,20 +1684,20 @@ EXPLAIN SELECT '' AS five, f1 AS "Correlated Field" FROM SUBSELECT_TBL WHERE (f1, f2) IN (SELECT f2, CAST(f3 AS int4) FROM SUBSELECT_TBL WHERE f3 IS NOT NULL) ORDER BY 2; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice2; segments: 3) (cost=6.67..6.69 rows=8 width=4) + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=2.20..2.30 rows=7 width=36) Merge Key: subselect_tbl.f1 - -> Sort (cost=6.67..6.69 rows=3 width=4) + -> Sort (cost=2.20..2.20 rows=2 width=36) Sort Key: subselect_tbl.f1 - -> Hash Semi Join (cost=1.11..2.18 rows=2 width=36) - Hash Cond: ((subselect_tbl.f1 = subselect_tbl_1.f2) AND (subselect_tbl.f2 = (subselect_tbl_1.f3)::integer)) - -> Seq Scan on subselect_tbl (cost=0.00..1.03 rows=3 width=8) - -> Hash (cost=1.07..1.07 rows=2 width=12) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.07 rows=2 width=12) - Hash Key: subselect_tbl_1.f2 - -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..1.03 rows=2 width=12) - Filter: (f3 IS NOT NULL) + -> Hash Right Semi Join (cost=1.07..2.18 rows=2 width=36) + Hash Cond: ((subselect_tbl_1.f2 = subselect_tbl.f1) AND ((subselect_tbl_1.f3)::integer = subselect_tbl.f2)) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.07 rows=2 width=12) + Hash Key: subselect_tbl_1.f2 + -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..1.03 rows=2 width=12) + Filter: (f3 IS NOT NULL) + -> Hash (cost=1.03..1.03 rows=3 width=8) + -> Seq Scan on subselect_tbl (cost=0.00..1.03 rows=3 width=8) Optimizer: Postgres query optimizer (13 rows) @@ -1781,18 +1781,18 @@ EXPLAIN select count(*) from where unique1 IN (select hundred from tenk1 b)) ss; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------- - Finalize Aggregate (cost=643.26..643.27 rows=1 width=8) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=643.23..643.26 rows=1 width=8) - -> Partial Aggregate (cost=643.23..643.24 rows=1 width=8) - -> Hash Join (cost=415.48..642.98 rows=34 width=0) + Finalize Aggregate (cost=210.51..210.52 rows=1 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=210.45..210.50 rows=3 width=8) + -> Partial Aggregate (cost=210.45..210.46 rows=1 width=8) + -> Hash Join (cost=138.92..210.37 rows=33 width=0) Hash Cond: (a.unique1 = b.hundred) - -> Seq Scan on tenk1 a (cost=0.00..189.00 rows=3334 width=4) - -> Hash (cost=414.23..414.23 rows=34 width=4) - -> HashAggregate (cost=413.90..414.23 rows=34 width=4) + -> Seq Scan on tenk1 a (cost=0.00..62.33 rows=3333 width=4) + -> Hash (cost=137.67..137.67 rows=100 width=4) + -> HashAggregate (cost=137.33..137.67 rows=100 width=4) Group Key: b.hundred - -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..389.00 rows=3334 width=4) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..129.00 rows=3333 width=4) Hash Key: b.hundred - -> Seq Scan on tenk1 b (cost=0.00..189.00 rows=3334 width=4) + -> Seq Scan on tenk1 b (cost=0.00..62.33 rows=3333 width=4) Optimizer: Postgres query optimizer (13 rows) @@ -1801,24 +1801,24 @@ EXPLAIN select count(distinct ss.ten) from where unique1 IN (select hundred from tenk1 b)) ss; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------- - Finalize Aggregate (cost=643.64..643.65 rows=1 width=8) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=643.61..643.64 rows=1 width=8) - -> Partial Aggregate (cost=643.61..643.62 rows=1 width=8) - -> HashAggregate (cost=643.57..643.60 rows=1 width=4) + Finalize Aggregate (cost=210.98..210.99 rows=1 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=210.92..210.97 rows=3 width=8) + -> Partial Aggregate (cost=210.92..210.93 rows=1 width=8) + -> HashAggregate (cost=210.88..210.91 rows=3 width=4) Group Key: a.ten - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=643.48..643.57 rows=1 width=4) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=210.54..210.83 rows=10 width=4) Hash Key: a.ten - -> Streaming HashAggregate (cost=643.48..643.51 rows=1 width=4) + -> Streaming HashAggregate (cost=210.54..210.64 rows=10 width=4) Group Key: a.ten - -> Hash Join (cost=415.48..642.98 rows=34 width=4) + -> Hash Join (cost=138.92..210.37 rows=33 width=4) Hash Cond: (a.unique1 = b.hundred) - -> Seq Scan on tenk1 a (cost=0.00..189.00 rows=3334 width=8) - -> Hash (cost=414.23..414.23 rows=34 width=4) - -> HashAggregate (cost=413.90..414.23 rows=34 width=4) + -> Seq Scan on tenk1 a (cost=0.00..62.33 rows=3333 width=8) + -> Hash (cost=137.67..137.67 rows=100 width=4) + -> HashAggregate (cost=137.33..137.67 rows=100 width=4) Group Key: b.hundred - -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..389.00 rows=3334 width=4) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..129.00 rows=3333 width=4) Hash Key: b.hundred - -> Seq Scan on tenk1 b (cost=0.00..189.00 rows=3334 width=4) + -> Seq Scan on tenk1 b (cost=0.00..62.33 rows=3333 width=4) Optimizer: Postgres query optimizer (19 rows) @@ -1827,18 +1827,18 @@ EXPLAIN select count(*) from where unique1 IN (select distinct hundred from tenk1 b)) ss; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------- - Finalize Aggregate (cost=643.26..643.27 rows=1 width=8) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=643.23..643.26 rows=1 width=8) - -> Partial Aggregate (cost=643.23..643.24 rows=1 width=8) - -> Hash Join (cost=415.48..642.98 rows=34 width=0) + Finalize Aggregate (cost=210.51..210.52 rows=1 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=210.45..210.50 rows=3 width=8) + -> Partial Aggregate (cost=210.45..210.46 rows=1 width=8) + -> Hash Join (cost=138.92..210.37 rows=33 width=0) Hash Cond: (a.unique1 = b.hundred) - -> Seq Scan on tenk1 a (cost=0.00..189.00 rows=3334 width=4) - -> Hash (cost=414.23..414.23 rows=34 width=4) - -> HashAggregate (cost=413.90..414.23 rows=34 width=4) + -> Seq Scan on tenk1 a (cost=0.00..62.33 rows=3333 width=4) + -> Hash (cost=137.67..137.67 rows=100 width=4) + -> HashAggregate (cost=137.33..137.67 rows=100 width=4) Group Key: b.hundred - -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..389.00 rows=3334 width=4) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..129.00 rows=3333 width=4) Hash Key: b.hundred - -> Seq Scan on tenk1 b (cost=0.00..62.33 rows=3333 width=4) + -> Seq Scan on tenk1 b (cost=0.00..62.33 rows=3333 width=4) Optimizer: Postgres query optimizer (13 rows) @@ -1847,22 +1847,22 @@ EXPLAIN select count(distinct ss.ten) from where unique1 IN (select distinct hundred from tenk1 b)) ss; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------- - Finalize Aggregate (cost=643.64..643.65 rows=1 width=8) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=643.61..643.64 rows=1 width=8) - -> Partial Aggregate (cost=643.61..643.62 rows=1 width=8) - -> HashAggregate (cost=643.57..643.60 rows=1 width=4) + Finalize Aggregate (cost=210.98..210.99 rows=1 width=8) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=210.92..210.97 rows=3 width=8) + -> Partial Aggregate (cost=210.92..210.93 rows=1 width=8) + -> HashAggregate (cost=210.88..210.91 rows=3 width=4) Group Key: a.ten - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=643.48..643.57 rows=1 width=4) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=210.54..210.83 rows=10 width=4) Hash Key: a.ten - -> Streaming HashAggregate (cost=643.48..643.51 rows=1 width=4) + -> Streaming HashAggregate (cost=210.54..210.64 rows=10 width=4) Group Key: a.ten - -> Hash Join (cost=415.48..642.98 rows=34 width=4) + -> Hash Join (cost=138.92..210.37 rows=33 width=4) Hash Cond: (a.unique1 = b.hundred) - -> Seq Scan on tenk1 a (cost=0.00..189.00 rows=3334 width=8) - -> Hash (cost=414.23..414.23 rows=34 width=4) - -> HashAggregate (cost=413.90..414.23 rows=34 width=4) + -> Seq Scan on tenk1 a (cost=0.00..62.33 rows=3333 width=8) + -> Hash (cost=137.67..137.67 rows=100 width=4) + -> HashAggregate (cost=137.33..137.67 rows=100 width=4) Group Key: b.hundred - -> Redistribute Motion 3:3 (slice1; segments: 3) (cost=0.00..389.00 rows=3334 width=4) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..129.00 rows=3333 width=4) Hash Key: b.hundred -> Seq Scan on tenk1 b (cost=0.00..62.33 rows=3333 width=4) Optimizer: Postgres query optimizer @@ -1877,9 +1877,9 @@ EXPLAIN select count(distinct ss.ten) from EXPLAIN SELECT EXISTS(SELECT * FROM tenk1 WHERE tenk1.unique1 = tenk2.unique1) FROM tenk2 LIMIT 1; QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Limit (cost=17.76..17.79 rows=1 width=1) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=17.76..17.85 rows=3 width=1) - -> Limit (cost=17.76..17.81 rows=1 width=1) + Limit (cost=0.00..0.03 rows=1 width=1) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..0.09 rows=3 width=1) + -> Limit (cost=0.00..0.05 rows=1 width=1) -> Seq Scan on tenk2 (cost=0.00..177.56 rows=3333 width=1) SubPlan 2 -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..62.33 rows=3333 width=4) @@ -1922,22 +1922,20 @@ ANALYZE dedup_test1; ANALYZE dedup_test2; ANALYZE dedup_test3; EXPLAIN SELECT * FROM dedup_test1 INNER JOIN dedup_test2 ON dedup_test1.a= dedup_test2.e WHERE (a) IN (SELECT a FROM dedup_test3); - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.11..3.18 rows=3 width=16) - -> Hash Join (cost=2.11..3.14 rows=1 width=16) - Hash Cond: (dedup_test2.e = dedup_test1.a) - -> Seq Scan on dedup_test2 (cost=0.00..1.01 rows=1 width=8) - -> Hash (cost=2.09..2.09 rows=1 width=12) - -> Hash Join (cost=1.06..2.09 rows=1 width=12) - Hash Cond: (dedup_test1.a = dedup_test3.a) + QUERY PLAN +------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=2.06..3.18 rows=3 width=16) + -> Hash Join (cost=2.06..3.13 rows=1 width=16) + Hash Cond: (dedup_test1.a = dedup_test2.e) + -> Hash Right Semi Join (cost=1.03..2.09 rows=1 width=12) + Hash Cond: (dedup_test3.a = dedup_test1.a) + -> Seq Scan on dedup_test3_1_prt_1 dedup_test3 (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.01..1.01 rows=1 width=8) -> Seq Scan on dedup_test1 (cost=0.00..1.01 rows=1 width=8) - -> Hash (cost=1.05..1.05 rows=1 width=4) - -> HashAggregate (cost=1.04..1.05 rows=1 width=4) - Group Key: dedup_test3.a - -> Seq Scan on dedup_test3_1_prt_1 dedup_test3 (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.01..1.01 rows=1 width=8) + -> Seq Scan on dedup_test2 (cost=0.00..1.01 rows=1 width=8) Optimizer: Postgres query optimizer -(13 rows) +(11 rows) SELECT * FROM dedup_test1 INNER JOIN dedup_test2 ON dedup_test1.a= dedup_test2.e WHERE (a) IN (SELECT a FROM dedup_test3); a | b | e | f @@ -1949,7 +1947,7 @@ SELECT * FROM dedup_test1 INNER JOIN dedup_test2 ON dedup_test1.a= dedup_test2.e EXPLAIN SELECT * FROM dedup_test3, dedup_test1 WHERE c = 7 AND dedup_test3.b IN (SELECT b FROM dedup_test1); QUERY PLAN ------------------------------------------ - Result (cost=0.00..0.01 rows=1 width=0) + Result (cost=0.00..0.00 rows=0 width=8) One-Time Filter: false Optimizer: Postgres query optimizer (3 rows) @@ -1957,7 +1955,7 @@ EXPLAIN SELECT * FROM dedup_test3, dedup_test1 WHERE c = 7 AND dedup_test3.b IN EXPLAIN SELECT * FROM dedup_test3, dedup_test1 WHERE c = 7 AND dedup_test3.b IN (SELECT a FROM dedup_test1); QUERY PLAN ------------------------------------------ - Result (cost=0.00..0.01 rows=1 width=0) + Result (cost=0.00..0.00 rows=0 width=8) One-Time Filter: false Optimizer: Postgres query optimizer (3 rows) @@ -1965,7 +1963,7 @@ EXPLAIN SELECT * FROM dedup_test3, dedup_test1 WHERE c = 7 AND dedup_test3.b IN EXPLAIN SELECT * FROM dedup_test3, dedup_test1 WHERE c = 7 AND EXISTS (SELECT b FROM dedup_test1) AND dedup_test3.b IN (SELECT b FROM dedup_test1); QUERY PLAN ------------------------------------------ - Result (cost=1.53..0.54 rows=1 width=0) + Result (cost=0.27..0.27 rows=0 width=8) One-Time Filter: false Optimizer: Postgres query optimizer (3 rows) @@ -2068,8 +2066,8 @@ select * from dedup_srf() r(a) where r.a in (select t.a/10 from dedup_tab t); select * from dedup_srf() r(a) where r.a in (select t.a/10 from dedup_tab t); a --- - 1 2 + 1 3 (3 rows) @@ -2155,7 +2153,7 @@ select * from dedup_func() r(a) where r.a in (select t.a/10 from dedup_tab t); -> Seq Scan on dedup_tab t Filter: (5 = (a / 10)) Optimizer: Postgres query optimizer -(15 rows) +(7 rows) select * from dedup_func() r(a) where r.a in (select t.a/10 from dedup_tab t); a @@ -2174,7 +2172,7 @@ select * from dedup_func_stable() r(a) where r.a in (select t.a/10 from dedup_ta -> Seq Scan on dedup_tab t Filter: (5 = (a / 10)) Optimizer: Postgres query optimizer -(15 rows) +(7 rows) select * from dedup_func_stable() r(a) where r.a in (select t.a/10 from dedup_tab t); a @@ -2313,8 +2311,8 @@ select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where t1.i = t2.i limit 1); i --- - 2 1 + 2 (2 rows) explain (costs off) @@ -2381,8 +2379,8 @@ select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where t1.i = t2.i limit all); i --- - 2 1 + 2 (2 rows) explain (costs off) @@ -2419,8 +2417,8 @@ select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where t1.i = t2.i limit NULL); i --- - 2 1 + 2 (2 rows) explain (costs off) @@ -2454,8 +2452,8 @@ select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i); i --- - 2 1 + 2 (2 rows) explain (costs off) @@ -2484,8 +2482,8 @@ select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i offset 0); i --- - 2 1 + 2 (2 rows) explain (costs off) @@ -2606,22 +2604,22 @@ select * from foo left outer join baz on (select bar.i from bar where bar.i = fo Output: bar.i -> Seq Scan on subselect_gp.bar Output: bar.i + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (29 rows) select * from foo left outer join baz on (select bar.i from bar where bar.i = foo.i) + 1 = baz.j; i | j | i | j ----+----+---+--- - 10 | 10 | | - 9 | 9 | | - 6 | 6 | | - 5 | 5 | | 8 | 8 | | 7 | 7 | | 4 | 4 | | 3 | 3 | | 2 | 2 | | + 10 | 10 | | + 9 | 9 | | + 6 | 6 | | + 5 | 5 | | 1 | 1 | | (10 rows) @@ -2636,48 +2634,42 @@ explain (verbose, costs off) select * from foo where (case when foo.i in (select a.i from baz a) then foo.i else null end) in (select b.i from baz b); - QUERY PLAN ------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Output: foo.i, foo.j - -> HashAggregate + -> Hash Right Semi Join Output: foo.i, foo.j - Group Key: (RowIdExpr) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Output: foo.i, foo.j, (RowIdExpr) - Hash Key: (RowIdExpr) - -> Hash Join - Output: foo.i, foo.j, (RowIdExpr) - Hash Cond: (b.i = CASE WHEN ((hashed SubPlan 1)) THEN foo.i ELSE NULL::integer END) - -> Seq Scan on subselect_gp.baz b - Output: b.i, b.j - -> Hash - Output: foo.i, foo.j, ((hashed SubPlan 1)), (RowIdExpr) - -> Redistribute Motion 3:3 (slice3; segments: 3) - Output: foo.i, foo.j, ((hashed SubPlan 1)), (RowIdExpr) - Hash Key: CASE WHEN ((hashed SubPlan 1)) THEN foo.i ELSE NULL::integer END - -> Seq Scan on subselect_gp.foo - Output: foo.i, foo.j, (hashed SubPlan 1), RowIdExpr - SubPlan 1 - -> Broadcast Motion 3:3 (slice4; segments: 3) - Output: a.i - -> Seq Scan on subselect_gp.baz a - Output: a.i + Hash Cond: (b.i = CASE WHEN ((hashed SubPlan 1)) THEN foo.i ELSE NULL::integer END) + -> Seq Scan on subselect_gp.baz b + Output: b.i, b.j + -> Hash + Output: foo.i, foo.j, ((hashed SubPlan 1)) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Output: foo.i, foo.j, ((hashed SubPlan 1)) + Hash Key: CASE WHEN ((hashed SubPlan 1)) THEN foo.i ELSE NULL::integer END + -> Seq Scan on subselect_gp.foo + Output: foo.i, foo.j, (hashed SubPlan 1) + SubPlan 1 + -> Broadcast Motion 3:3 (slice3; segments: 3) + Output: a.i + -> Seq Scan on subselect_gp.baz a + Output: a.i + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off -(27 rows) +(21 rows) select * from foo where (case when foo.i in (select a.i from baz a) then foo.i else null end) in (select b.i from baz b); i | j ----+---- + 5 | 5 6 | 6 - 7 | 7 + 9 | 9 10 | 10 - 5 | 5 + 7 | 7 8 | 8 - 9 | 9 (6 rows) -- When creating plan with subquery and CTE, it sets the useless flow for the plan. @@ -2730,8 +2722,9 @@ where dt < '2010-01-01'::date; Output: extra_flow_dist.c, extra_flow_dist.b -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(25 rows) +(26 rows) with run_dt as ( select @@ -2744,8 +2737,8 @@ select * from run_dt, extra_flow_dist1 where dt < '2010-01-01'::date; dt | a | b ------------+----+---- - 10-01-1949 | 20 | 20 10-01-1949 | 22 | 22 + 10-01-1949 | 20 | 20 10-01-1949 | 21 | 21 (3 rows) @@ -2786,8 +2779,9 @@ where dt < '2010-01-01'::date; Output: extra_flow_dist1.a, extra_flow_dist1.b -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(24 rows) +(25 rows) with run_dt as ( select @@ -2844,8 +2838,9 @@ where dt < '2010-01-01'::date; Output: extra_flow_dist.c, extra_flow_dist.b -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(28 rows) +(29 rows) with run_dt as ( select @@ -2858,9 +2853,9 @@ select * from run_dt, extra_flow_dist1 where dt < '2010-01-01'::date; dt | a | b ------------+----+---- - 10-01-1949 | 20 | 20 - 10-01-1949 | 21 | 21 10-01-1949 | 22 | 22 + 10-01-1949 | 21 | 21 + 10-01-1949 | 20 | 20 (3 rows) -- case 4 subplan with outer segment general locus without param in subplan (CTE and subquery) @@ -2901,8 +2896,9 @@ where dt < extra_flow_dist1.a; Output: extra_flow_dist1.a, extra_flow_dist1.b -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(28 rows) +(29 rows) -- case 5 for subplan with outer entry locus without param in subplan (CTE and subquery) explain (verbose, costs off) with run_dt as ( @@ -2944,8 +2940,9 @@ where dt < extra_flow_dist1.a; Output: extra_flow_dist1.a, extra_flow_dist1.b -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(30 rows) +(31 rows) -- case 6 without CTE, nested subquery should not add extral flow explain (verbose, costs off) select * from ( @@ -3013,8 +3010,9 @@ where dt < '2010-01-01'::date; Output: extra_flow_dist_1.c, extra_flow_dist_1.b -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b + Settings: optimizer = 'off' Optimizer: Postgres query optimizer -(47 rows) +(48 rows) -- Check DISTINCT ON clause and ORDER BY clause in SubLink, See https://github.com/greenplum-db/gpdb/issues/12656. -- For EXISTS SubLink, we don’t need to care about the data deduplication problem, we can delete DISTINCT ON clause and @@ -3049,8 +3047,8 @@ select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issu Sort Key: issue_12656_1.i -> Seq Scan on subselect_gp.issue_12656 issue_12656_1 Output: issue_12656_1.i, issue_12656_1.j + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (20 rows) select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issue_12656); @@ -3082,8 +3080,8 @@ select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issu Sort Key: issue_12656_1.i, issue_12656_1.j -> Seq Scan on subselect_gp.issue_12656 issue_12656_1 Output: issue_12656_1.i, issue_12656_1.j + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (20 rows) select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issue_12656 order by i, j asc); @@ -3114,8 +3112,8 @@ select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issu Sort Key: issue_12656_1.i, issue_12656_1.j DESC -> Seq Scan on subselect_gp.issue_12656 issue_12656_1 Output: issue_12656_1.i, issue_12656_1.j + Settings: optimizer = 'off' Optimizer: Postgres query optimizer - Settings: optimizer=off (20 rows) select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issue_12656 order by i, j desc); @@ -3133,7 +3131,7 @@ explain select * from issue_12656 a where (i, j) in -> Seq Scan on issue_12656 a (cost=0.00..321.00 rows=14350 width=8) Filter: (SubPlan 1) SubPlan 1 - -> Unique (cost=9818.00..10033.25 rows=1000 width=8) + -> Unique (cost=9818.00..10033.25 rows=1 width=8) -> Sort (cost=9818.00..10033.25 rows=86100 width=8) Sort Key: b.j -> Result (cost=0.00..2760.50 rows=86100 width=8) @@ -3245,8 +3243,8 @@ with cte(table_oid, size) as select pc.relname, ts.size from pg_class pc, cte ts where pc.oid = ts.table_oid; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: pc.relname, (sum((pg_relation_size((pg_class.oid)::regclass, 'main'::text)))) -> Nested Loop @@ -3267,8 +3265,9 @@ where pc.oid = ts.table_oid; Hash Key: pg_class.oid -> Seq Scan on pg_catalog.pg_class Output: pg_class.oid, pg_relation_size((pg_class.oid)::regclass, 'main'::text) + Settings: optimizer = 'off', gp_enable_multiphase_agg = 'on', enable_hashjoin = 'off', enable_nestloop = 'on', enable_indexscan = 'off', enable_bitmapscan = 'off' Optimizer: Postgres query optimizer -(21 rows) +(22 rows) set gp_enable_multiphase_agg = off; explain (verbose on, costs off) @@ -3287,8 +3286,8 @@ with cte(table_oid, size) as select pc.relname, ts.size from pg_class pc, cte ts where pc.oid = ts.table_oid; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: pc.relname, (sum((pg_relation_size((pg_class.oid)::regclass, 'main'::text)))) -> Nested Loop @@ -3309,8 +3308,9 @@ where pc.oid = ts.table_oid; Hash Key: pg_class.oid -> Seq Scan on pg_catalog.pg_class Output: pg_class.oid, pg_relation_size((pg_class.oid)::regclass, 'main'::text) + Settings: optimizer = 'off', gp_enable_multiphase_agg = 'off', enable_hashjoin = 'off', enable_nestloop = 'on', enable_indexscan = 'off', enable_bitmapscan = 'off' Optimizer: Postgres query optimizer -(21 rows) +(22 rows) reset gp_enable_multiphase_agg; reset enable_hashjoin; @@ -3323,12 +3323,12 @@ set optimizer to off; explain select t.* from sublink_outer_table t join (select y ,10*avg(x) s from sublink_inner_table group by y) RR on RR.y = t.b and t.a > rr.s; QUERY PLAN -------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=436.00..1310.77 rows=28700 width=8) - -> Hash Join (cost=436.00..928.11 rows=9567 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=432.67..1307.44 rows=28700 width=8) + -> Hash Join (cost=432.67..924.77 rows=9567 width=8) Hash Cond: (t.b = sublink_inner_table.y) Join Filter: ((t.a)::numeric > (('10'::numeric * avg(sublink_inner_table.x)))) -> Seq Scan on sublink_outer_table t (cost=0.00..321.00 rows=28700 width=8) - -> Hash (cost=431.83..431.83 rows=333 width=40) + -> Hash (cost=428.50..428.50 rows=333 width=40) -> HashAggregate (cost=423.50..428.50 rows=333 width=40) Group Key: sublink_inner_table.y -> Seq Scan on sublink_inner_table (cost=0.00..293.67 rows=25967 width=12) @@ -3338,13 +3338,13 @@ explain select t.* from sublink_outer_table t join (select y ,10*avg(x) s from s explain select * from sublink_outer_table T where a > (select 10*avg(x) from sublink_inner_table R where T.b=R.y); QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=436.00..1310.77 rows=28700 width=8) - -> Hash Join (cost=436.00..928.11 rows=9567 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=433.78..1308.55 rows=28700 width=8) + -> Hash Join (cost=433.78..925.89 rows=9567 width=8) Hash Cond: (t.b = "Expr_SUBQUERY".csq_c0) Join Filter: ((t.a)::numeric > "Expr_SUBQUERY".csq_c1) -> Seq Scan on sublink_outer_table t (cost=0.00..321.00 rows=28700 width=8) - -> Hash (cost=431.83..431.83 rows=333 width=40) - -> Subquery Scan on "Expr_SUBQUERY" (cost=423.50..431.83 rows=333 width=40) + -> Hash (cost=429.61..429.61 rows=333 width=40) + -> Subquery Scan on "Expr_SUBQUERY" (cost=423.50..429.61 rows=333 width=40) -> HashAggregate (cost=423.50..428.50 rows=333 width=40) Group Key: r.y -> Seq Scan on sublink_inner_table r (cost=0.00..293.67 rows=25967 width=12) @@ -3355,12 +3355,12 @@ set enable_hashagg to off; explain select t.* from sublink_outer_table t join (select y ,10*avg(x) s from sublink_inner_table group by y) RR on RR.y = t.b and t.a > rr.s; QUERY PLAN -------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2404.84..3279.62 rows=28700 width=8) - -> Hash Join (cost=2404.84..2896.95 rows=9567 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=2401.51..3276.28 rows=28700 width=8) + -> Hash Join (cost=2401.51..2893.62 rows=9567 width=8) Hash Cond: (t.b = sublink_inner_table.y) Join Filter: ((t.a)::numeric > (('10'::numeric * avg(sublink_inner_table.x)))) -> Seq Scan on sublink_outer_table t (cost=0.00..321.00 rows=28700 width=8) - -> Hash (cost=2400.67..2400.67 rows=333 width=40) + -> Hash (cost=2397.34..2397.34 rows=333 width=40) -> GroupAggregate (cost=2197.59..2397.34 rows=333 width=40) Group Key: sublink_inner_table.y -> Sort (cost=2197.59..2262.51 rows=25967 width=12) @@ -3372,13 +3372,13 @@ explain select t.* from sublink_outer_table t join (select y ,10*avg(x) s from s explain select * from sublink_outer_table T where a > (select 10*avg(x) from sublink_inner_table R where T.b=R.y); QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2404.84..3279.62 rows=28700 width=8) - -> Hash Join (cost=2404.84..2896.95 rows=9567 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=2402.62..3277.39 rows=28700 width=8) + -> Hash Join (cost=2402.62..2894.73 rows=9567 width=8) Hash Cond: (t.b = "Expr_SUBQUERY".csq_c0) Join Filter: ((t.a)::numeric > "Expr_SUBQUERY".csq_c1) -> Seq Scan on sublink_outer_table t (cost=0.00..321.00 rows=28700 width=8) - -> Hash (cost=2400.67..2400.67 rows=333 width=40) - -> Subquery Scan on "Expr_SUBQUERY" (cost=2197.59..2400.67 rows=333 width=40) + -> Hash (cost=2398.45..2398.45 rows=333 width=40) + -> Subquery Scan on "Expr_SUBQUERY" (cost=2197.59..2398.45 rows=333 width=40) -> GroupAggregate (cost=2197.59..2397.34 rows=333 width=40) Group Key: r.y -> Sort (cost=2197.59..2262.51 rows=25967 width=12) @@ -3562,10 +3562,10 @@ SELECT c FROM t0; -- Test push predicate into subquery -- more details could be found at https://github.com/greenplum-db/gpdb/issues/8429 CREATE TABLE foo_predicate_pushdown (a int, b int); -NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table. +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TABLE bar_predicate_pushdown (c int, d int); -NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c' as the Greenplum Database data distribution key for this table. +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. explain (costs off) select * from ( select distinct (select bar.c from bar_predicate_pushdown bar where c = foo.b) as ss from foo_predicate_pushdown foo @@ -3629,7 +3629,7 @@ explain (costs off) select * from table_left where exists (select 1 from table_r -> Hash -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on table_left - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (12 rows) select * from table_left where exists (select 1 from table_right where l1 = r1); @@ -3652,7 +3652,7 @@ explain (costs off) select * from table_left where l1 in (select r1 from table_r -> Hash -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on table_left - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (12 rows) select * from table_left where exists (select 1 from table_right where l1 = r1); @@ -3667,15 +3667,13 @@ explain (costs off) select * from table_left where exists (select 1 from table_r QUERY PLAN ----------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) - -> Hash Join + -> Hash Right Semi Join Hash Cond: (table_right.r1 = table_left.l1) - -> HashAggregate - Group Key: table_right.r1 - -> Seq Scan on table_right + -> Seq Scan on table_right -> Hash -> Seq Scan on table_left - Optimizer: Postgres-based planner -(9 rows) + Optimizer: Postgres query optimizer +(7 rows) select * from table_left where exists (select 1 from table_right where l1 = r1); l1 | l2 @@ -3687,15 +3685,13 @@ explain (costs off) select * from table_left where l1 in (select r1 from table_r QUERY PLAN ----------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) - -> Hash Join + -> Hash Right Semi Join Hash Cond: (table_right.r1 = table_left.l1) - -> HashAggregate - Group Key: table_right.r1 - -> Seq Scan on table_right + -> Seq Scan on table_right -> Hash -> Seq Scan on table_left - Optimizer: Postgres-based planner -(9 rows) + Optimizer: Postgres query optimizer +(7 rows) select * from table_left where exists (select 1 from table_right where l1 = r1); l1 | l2 @@ -3796,7 +3792,7 @@ explain (costs off) select foo.a from foo where foo.a <= LEAST(foo.b, (SELECT 1) -> Result -> Seq Scan on foo Filter: (a <= LEAST(b, $0, NULL::integer)) - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (6 rows) select foo.a from foo where foo.a <= LEAST(foo.b, (SELECT 1), NULL); @@ -3813,7 +3809,7 @@ explain (costs off) select foo.a from foo where foo.a <= GREATEST(foo.b, (SELECT -> Result -> Seq Scan on foo Filter: (a <= GREATEST(b, $0, NULL::integer)) - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (6 rows) select foo.a from foo where foo.a <= GREATEST(foo.b, (SELECT 1), NULL); @@ -3833,7 +3829,7 @@ explain (costs off) select least((select 5), greatest(b, NULL, (select 1)), a) f InitPlan 2 (returns $1) (slice3) -> Result -> Seq Scan on foo - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (7 rows) select least((select 5), greatest(b, NULL, (select 1)), a) from foo; @@ -3858,7 +3854,7 @@ explain (costs off) select (select a from bar)[1] from bar; -> Gather Motion 3:1 (slice3; segments: 3) -> Seq Scan on bar bar_1 -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (6 rows) select (select a from bar)[1] from bar; @@ -3877,7 +3873,7 @@ explain (costs off) select (select a from bar)[(select 1)] from bar; -> Gather Motion 3:1 (slice4; segments: 3) -> Seq Scan on bar bar_1 -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (8 rows) select (select a from bar)[(select 1)] from bar; @@ -3894,7 +3890,7 @@ explain (costs off) select (select b from bar)[1][1:3] from bar; -> Gather Motion 3:1 (slice3; segments: 3) -> Seq Scan on bar bar_1 -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (6 rows) select (select b from bar)[1][1:3] from bar; @@ -3913,7 +3909,7 @@ explain (costs off) select (select b from bar)[(select 1)][1:3] from bar; -> Gather Motion 3:1 (slice4; segments: 3) -> Seq Scan on bar bar_1 -> Seq Scan on bar - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (8 rows) select (select b from bar)[(select 1)][1:3] from bar; @@ -3943,7 +3939,7 @@ explain (costs off) select t1.a from outer_foo t1, LATERAL(SELECT distinct t2. -> Materialize -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on inner_bar t2 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (13 rows) explain (costs off) select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q; @@ -3960,7 +3956,7 @@ explain (costs off) select t1.a from outer_foo t1, LATERAL(SELECT distinct t2. -> Materialize -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on inner_bar t2 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (12 rows) select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q order by 1; @@ -4002,7 +3998,7 @@ select * from t where a > (select count(1) from cte where x > t.a + random()); -> Materialize -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on inner_bar t2 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (22 rows) with cte(x) as (select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q order by 1) diff --git a/src/test/regress/expected/subselect_gp_optimizer.out b/src/test/regress/expected/subselect_gp_optimizer.out index c847505320f..02eee085e6a 100644 --- a/src/test/regress/expected/subselect_gp_optimizer.out +++ b/src/test/regress/expected/subselect_gp_optimizer.out @@ -1,3 +1,7 @@ +-- start_ignore +create schema subselect_gp; +set search_path to subselect_gp, public; +-- end_ignore set optimizer_enable_master_only_queries = on; set optimizer_segments = 3; set optimizer_nestloop_factor = 1.0; @@ -118,6 +122,8 @@ partition by range (y) ( start (0) end (4) every (1)) insert into csq_t1 select * from csq_t1_base; insert into csq_t2 select * from csq_t2_base; explain select * from csq_t1 where csq_t1.x >ALL (select csq_t2.x from csq_t2 where csq_t2.y=csq_t1.y) order by 1; +NOTICE: One or more columns in the following table(s) do not have statistics: csq_t1, csq_t2 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Result (cost=0.00..1293.00 rows=1 width=8) @@ -126,7 +132,7 @@ explain select * from csq_t1 where csq_t1.x >ALL (select csq_t2.x from csq_t2 wh Sort Key: csq_t1.x -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Dynamic Seq Scan on csq_t1 (cost=0.00..431.00 rows=1 width=8) - Number of partitions to scan: 4 + Number of partitions to scan: 4 (out of 4) SubPlan 1 -> Result (cost=0.00..431.00 rows=1 width=1) Filter: ((CASE WHEN (sum((CASE WHEN (csq_t1.x <= csq_t2.x) THEN 1 ELSE 0 END)) IS NULL) THEN true WHEN (sum((CASE WHEN (csq_t2.x IS NULL) THEN 1 ELSE 0 END)) > '0'::bigint) THEN NULL::boolean WHEN (csq_t1.x IS NULL) THEN NULL::boolean WHEN (sum((CASE WHEN (csq_t1.x <= csq_t2.x) THEN 1 ELSE 0 END)) = '0'::bigint) THEN true ELSE false END) = true) @@ -136,11 +142,13 @@ explain select * from csq_t1 where csq_t1.x >ALL (select csq_t2.x from csq_t2 wh -> Materialize (cost=0.00..431.00 rows=1 width=8) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=8) -> Dynamic Seq Scan on csq_t2 (cost=0.00..431.00 rows=1 width=8) - Number of partitions to scan: 4 - Optimizer: Pivotal Optimizer (GPORCA) + Number of partitions to scan: 4 (out of 4) + Optimizer: GPORCA (18 rows) select * from csq_t1 where csq_t1.x >ALL (select csq_t2.x from csq_t2 where csq_t2.y=csq_t1.y) order by 1; -- expected (4,2) +NOTICE: One or more columns in the following table(s) do not have statistics: csq_t1, csq_t2 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. x | y ---+--- 4 | 2 @@ -166,12 +174,12 @@ explain select * from mrs_t1 where exists (select x from mrs_t1 where x < -1); Join Filter: true -> Seq Scan on mrs_t1 mrs_t1_1 (cost=0.00..431.00 rows=7 width=4) -> Materialize (cost=0.00..431.00 rows=1 width=1) - -> Broadcast Motion 1:3 (slice2) (cost=0.00..431.00 rows=3 width=1) + -> Broadcast Motion 1:3 (slice2) (cost=0.00..431.00 rows=1 width=1) -> Limit (cost=0.00..431.00 rows=1 width=1) -> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=1) -> Seq Scan on mrs_t1 (cost=0.00..431.00 rows=1 width=1) - Filter: x < (-1) - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 + Filter: (x < '-1'::integer) + Optimizer: GPORCA (11 rows) select * from mrs_t1 where exists (select x from mrs_t1 where x < -1) order by 1; @@ -187,12 +195,12 @@ explain select * from mrs_t1 where exists (select x from mrs_t1 where x = 1); Join Filter: true -> Seq Scan on mrs_t1 mrs_t1_1 (cost=0.00..431.00 rows=7 width=4) -> Materialize (cost=0.00..431.00 rows=1 width=1) - -> Broadcast Motion 1:3 (slice2) (cost=0.00..431.00 rows=3 width=1) + -> Broadcast Motion 1:3 (slice2) (cost=0.00..431.00 rows=1 width=1) -> Limit (cost=0.00..431.00 rows=1 width=1) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..431.00 rows=2 width=1) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=1) -> Seq Scan on mrs_t1 (cost=0.00..431.00 rows=1 width=1) - Filter: x = 1 - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 + Filter: (x = 1) + Optimizer: GPORCA (11 rows) select * from mrs_t1 where exists (select x from mrs_t1 where x = 1) order by 1; @@ -237,7 +245,7 @@ explain select * from mrs_t1 where x in (select x-95 from mrs_t1) or x < 5; -> Result (cost=0.00..431.00 rows=20 width=5) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=20 width=4) -> Seq Scan on mrs_t1 (cost=0.00..431.00 rows=7 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (15 rows) select * from mrs_t1 where x in (select x-95 from mrs_t1) or x < 5 order by 1; @@ -356,12 +364,11 @@ analyze csq_d1; explain select array(select x from csq_m1); -- no initplan QUERY PLAN -------------------------------------------------------------- - Result (cost=1.01..1.02 rows=1 width=0) + Result (cost=1.01..1.02 rows=1 width=32) InitPlan 1 (returns $0) -> Seq Scan on csq_m1 (cost=0.00..1.01 rows=1 width=4) - Settings: optimizer_segments=3 - Optimizer status: Postgres query optimizer -(5 rows) + Optimizer: Postgres query optimizer +(4 rows) select array(select x from csq_m1); -- {1} array @@ -372,13 +379,12 @@ select array(select x from csq_m1); -- {1} explain select array(select x from csq_d1); -- initplan QUERY PLAN ------------------------------------------------------------------------------------ - Result (cost=1.01..1.02 rows=1 width=0) + Result (cost=1.03..1.04 rows=1 width=32) InitPlan 1 (returns $0) (slice1) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.01 rows=1 width=4) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..1.03 rows=1 width=4) -> Seq Scan on csq_d1 (cost=0.00..1.01 rows=1 width=4) - Settings: optimizer_segments=3 - Optimizer status: Postgres query optimizer -(6 rows) + Optimizer: Postgres query optimizer +(5 rows) select array(select x from csq_d1); -- {1} array @@ -473,7 +479,7 @@ explain select * from csq_m1 where x not in (select x from csq_d1) or x < -100; -> Result (cost=0.00..431.00 rows=3 width=5) -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=3 width=4) -> Seq Scan on csq_d1 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (14 rows) select * from csq_m1 where x not in (select x from csq_d1) or x < -100; -- (3) @@ -488,7 +494,7 @@ select * from csq_m1 where x not in (select x from csq_d1) or x < -100; -- (3) explain select * from csq_d1 where x not in (select x from csq_m1) or x < -100; -- broadcast motion QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1293.00 rows=2 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1293.00 rows=3 width=4) -> Result (cost=0.00..1293.00 rows=1 width=4) Filter: (CASE WHEN ((count((true))) > '0'::bigint) THEN CASE WHEN ((sum((CASE WHEN ((csq_d1.x = csq_m1.x) IS NULL) THEN 1 ELSE 0 END))) = (count((true)))) THEN NULL::boolean ELSE false END ELSE true END OR (csq_d1.x < '-100'::integer)) -> GroupAggregate (cost=0.00..1293.00 rows=1 width=20) @@ -502,7 +508,7 @@ explain select * from csq_d1 where x not in (select x from csq_m1) or x < -100; -> Result (cost=0.00..431.00 rows=3 width=5) -> Broadcast Motion 1:3 (slice2) (cost=0.00..431.00 rows=3 width=4) -> Seq Scan on csq_m1 (cost=0.00..431.00 rows=3 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (15 rows) select * from csq_d1 where x not in (select x from csq_m1) or x < -100; -- (4) @@ -551,7 +557,7 @@ explain SELECT * FROM csq_r WHERE a IN (SELECT * FROM csq_f(csq_r.a)); Filter: (a = (SubPlan 1)) SubPlan 1 -> Result (cost=0.00..0.00 rows=1 width=1) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (6 rows) SELECT * FROM csq_r WHERE a IN (SELECT * FROM csq_f(csq_r.a)); @@ -569,7 +575,7 @@ explain SELECT * FROM csq_r WHERE a not IN (SELECT * FROM csq_f(csq_r.a)); Filter: (a <> (SubPlan 1)) SubPlan 1 -> Result (cost=0.00..0.00 rows=1 width=1) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (6 rows) SELECT * FROM csq_r WHERE a not IN (SELECT * FROM csq_f(csq_r.a)); @@ -586,7 +592,7 @@ explain SELECT * FROM csq_r WHERE exists (SELECT * FROM csq_f(csq_r.a)); Filter: (SubPlan 1) SubPlan 1 -> Result (cost=0.00..0.00 rows=1 width=1) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (6 rows) SELECT * FROM csq_r WHERE exists (SELECT * FROM csq_f(csq_r.a)); @@ -604,7 +610,7 @@ explain SELECT * FROM csq_r WHERE not exists (SELECT * FROM csq_f(csq_r.a)); Filter: (SubPlan 1) SubPlan 1 -> Result (cost=0.00..0.00 rows=1 width=1) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (6 rows) SELECT * FROM csq_r WHERE not exists (SELECT * FROM csq_f(csq_r.a)); @@ -622,7 +628,7 @@ explain SELECT * FROM csq_r WHERE a > (SELECT csq_f FROM csq_f(csq_r.a) limit 1) SubPlan 1 -> Limit (cost=0.00..0.00 rows=1 width=4) -> Result (cost=0.00..0.00 rows=1 width=1) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (7 rows) SELECT * FROM csq_r WHERE a > (SELECT csq_f FROM csq_f(csq_r.a) limit 1); @@ -639,7 +645,7 @@ explain SELECT * FROM csq_r WHERE a < ANY (SELECT csq_f FROM csq_f(csq_r.a)); Filter: (a < (SubPlan 1)) SubPlan 1 -> Result (cost=0.00..0.00 rows=1 width=1) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (6 rows) SELECT * FROM csq_r WHERE a < ANY (SELECT csq_f FROM csq_f(csq_r.a)); @@ -656,7 +662,7 @@ explain SELECT * FROM csq_r WHERE a <= ALL (SELECT csq_f FROM csq_f(csq_r.a)); Filter: (a <= (SubPlan 1)) SubPlan 1 -> Result (cost=0.00..0.00 rows=1 width=1) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (6 rows) SELECT * FROM csq_r WHERE a <= ALL (SELECT csq_f FROM csq_f(csq_r.a)); @@ -679,7 +685,7 @@ explain SELECT * FROM csq_r WHERE a IN (SELECT csq_f FROM csq_f(csq_r.a),csq_r); -> Materialize (cost=0.00..431.00 rows=1 width=1) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=1) -> Seq Scan on csq_r csq_r_1 (cost=0.00..431.00 rows=1 width=1) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (11 rows) SELECT * FROM csq_r WHERE a IN (SELECT csq_f FROM csq_f(csq_r.a),csq_r); @@ -708,8 +714,8 @@ insert into csq_pullup values ('def',3, 1, 'abc'); -- text, text -- explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.t); - QUERY PLAN -------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=1 width=17) -> Result (cost=0.00..862.00 rows=1 width=17) Filter: (1 = COALESCE((count(*)), '0'::bigint)) @@ -722,15 +728,15 @@ explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 -> Sort (cost=0.00..431.00 rows=1 width=4) Sort Key: t1.t -> Seq Scan on csq_pullup t1 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (13 rows) select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.t); t | n | i | v -----+---+---+----- - xyz | 2 | 3 | def def | 3 | 1 | abc abc | 1 | 2 | xyz + xyz | 2 | 3 | def (3 rows) -- @@ -753,15 +759,15 @@ explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) Hash Key: t1.v -> Seq Scan on csq_pullup t1 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (15 rows) select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.v); t | n | i | v -----+---+---+----- + abc | 1 | 2 | xyz xyz | 2 | 3 | def def | 3 | 1 | abc - abc | 1 | 2 | xyz (3 rows) -- @@ -785,15 +791,15 @@ explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=5) Hash Key: t1.n -> Seq Scan on csq_pullup t1 (cost=0.00..431.00 rows=1 width=5) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (16 rows) select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.n=t1.n); t | n | i | v -----+---+---+----- + abc | 1 | 2 | xyz xyz | 2 | 3 | def def | 3 | 1 | abc - abc | 1 | 2 | xyz (3 rows) -- @@ -813,15 +819,15 @@ explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 -> Materialize (cost=0.00..431.00 rows=1 width=5) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=5) -> Seq Scan on csq_pullup t1 (cost=0.00..431.00 rows=1 width=5) - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 + Optimizer: GPORCA (12 rows) select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.n + 1=t1.n + 1); t | n | i | v -----+---+---+----- + def | 3 | 1 | abc abc | 1 | 2 | xyz xyz | 2 | 3 | def - def | 3 | 1 | abc (3 rows) -- @@ -841,7 +847,7 @@ explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 -> Materialize (cost=0.00..431.00 rows=1 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on csq_pullup t1 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (12 rows) select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.n + 1=t1.i + 1); @@ -859,7 +865,7 @@ select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.t LIMIT 1); QUERY PLAN ----------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..5172.20 rows=1 width=17) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..5172.20 rows=1 width=17) -> Result (cost=0.00..5172.20 rows=1 width=17) Filter: (1 = (SubPlan 1)) -> Seq Scan on csq_pullup t0 (cost=0.00..5172.19 rows=334 width=36) @@ -869,23 +875,23 @@ explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 -> Result (cost=0.00..431.00 rows=1 width=1) Filter: (t0.t = t1.t) -> Materialize (cost=0.00..431.00 rows=1 width=4) - -> Broadcast Motion 3:3 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=4) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on csq_pullup t1 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (13 rows) select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.t LIMIT 1); t | n | i | v -----+---+---+----- + abc | 1 | 2 | xyz xyz | 2 | 3 | def def | 3 | 1 | abc - abc | 1 | 2 | xyz (3 rows) -- subquery contains a HAVING clause explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.t HAVING count(*) < 10); - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=1 width=17) -> Result (cost=0.00..862.00 rows=1 width=17) Filter: (1 = COALESCE((count(*)), '0'::bigint)) @@ -900,15 +906,15 @@ explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 -> Sort (cost=0.00..431.00 rows=1 width=4) Sort Key: t1.t -> Seq Scan on csq_pullup t1 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (15 rows) select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.t=t1.t HAVING count(*) < 10); t | n | i | v -----+---+---+----- + abc | 1 | 2 | xyz xyz | 2 | 3 | def def | 3 | 1 | abc - abc | 1 | 2 | xyz (3 rows) -- subquery contains quals of form 'function(outervar, innervar1) = innvervar2' @@ -926,7 +932,7 @@ explain select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 -> Materialize (cost=0.00..431.00 rows=1 width=9) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=9) -> Seq Scan on csq_pullup t1 (cost=0.00..431.00 rows=1 width=9) - Optimizer: Pivotal Optimizer (GPORCA) version 3.93.0 + Optimizer: GPORCA (12 rows) select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t0.n + t1.n =t1.i); @@ -941,8 +947,8 @@ select * from csq_pullup t0 where 1= (select count(*) from csq_pullup t1 where t -- text, text -- explain select * from csq_pullup t0 where not exists (select 1 from csq_pullup t1 where t0.t=t1.t and t1.i = 1); - QUERY PLAN -------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=1 width=17) -> Hash Anti Join (cost=0.00..862.00 rows=1 width=17) Hash Cond: (t0.t = t1.t) @@ -950,7 +956,7 @@ explain select * from csq_pullup t0 where not exists (select 1 from csq_pullup t -> Hash (cost=431.00..431.00 rows=1 width=4) -> Seq Scan on csq_pullup t1 (cost=0.00..431.00 rows=1 width=4) Filter: (i = 1) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (8 rows) select * from csq_pullup t0 where not exists (select 1 from csq_pullup t1 where t0.t=t1.t and t1.i = 1); @@ -973,7 +979,7 @@ explain select * from csq_pullup t0 where not exists (select 1 from csq_pullup t -> Hash (cost=431.00..431.00 rows=1 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on csq_pullup t1 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (8 rows) select * from csq_pullup t0 where not exists (select 1 from csq_pullup t1 where t0.i=t1.i + 1); @@ -986,9 +992,7 @@ select * from csq_pullup t0 where not exists (select 1 from csq_pullup t1 where -- wrong results bug MPP-16477 -- drop table if exists subselect_t1; -NOTICE: table "subselect_t1" does not exist, skipping drop table if exists subselect_t2; -NOTICE: table "subselect_t2" does not exist, skipping create table subselect_t1(x int) distributed by (x); insert into subselect_t1 values(1),(2); create table subselect_t2(y int) distributed by (y); @@ -1004,22 +1008,22 @@ explain select * from subselect_t1 where x in (select y from subselect_t2); -> Seq Scan on subselect_t1 (cost=0.00..431.00 rows=1 width=4) -> Hash (cost=431.00..431.00 rows=1 width=4) -> Seq Scan on subselect_t2 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) version 2.64.0 + Optimizer: GPORCA (7 rows) select * from subselect_t1 where x in (select y from subselect_t2); x --- - 1 2 + 1 (2 rows) -- start_ignore -- Known_opt_diff: MPP-21351 -- end_ignore explain select * from subselect_t1 where x in (select y from subselect_t2 union all select y from subselect_t2); - QUERY PLAN ------------------------------------------------------------------------------------------------------------ + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1293.00 rows=2 width=4) -> Hash Join (cost=0.00..1293.00 rows=1 width=4) Hash Cond: (subselect_t1.x = subselect_t2.y) @@ -1032,7 +1036,7 @@ explain select * from subselect_t1 where x in (select y from subselect_t2 union -> Append (cost=0.00..862.00 rows=2 width=4) -> Seq Scan on subselect_t2 (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on subselect_t2 subselect_t2_1 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) select * from subselect_t1 where x in (select y from subselect_t2 union all select y from subselect_t2); @@ -1052,7 +1056,7 @@ explain select count(*) from subselect_t1 where x in (select y from subselect_t2 -> Seq Scan on subselect_t1 (cost=0.00..431.00 rows=1 width=4) -> Hash (cost=431.00..431.00 rows=1 width=4) -> Seq Scan on subselect_t2 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) select count(*) from subselect_t1 where x in (select y from subselect_t2); @@ -1080,7 +1084,7 @@ explain select count(*) from subselect_t1 where x in (select y from subselect_t2 -> Append (cost=0.00..862.00 rows=2 width=4) -> Seq Scan on subselect_t2 (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on subselect_t2 subselect_t2_1 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (14 rows) select count(*) from subselect_t1 where x in (select y from subselect_t2 union all select y from subselect_t2); @@ -1155,21 +1159,21 @@ select * from t1 where a=1 and a=2 and a > (select t2.b from t2); (0 rows) explain select * from t1 where a=1 and a=2 and a > (select t2.b from t2); - QUERY PLAN ------------------------------------------------------- + QUERY PLAN +------------------------------------------ Result (cost=0.00..0.00 rows=0 width=4) One-Time Filter: false - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (3 rows) explain select * from t1 where a=1 and a=2 and a > (select t2.b from t2) union all select * from t1 where a=1 and a=2 and a > (select t2.b from t2); - QUERY PLAN ------------------------------------------------------- + QUERY PLAN +------------------------------------------ Result (cost=0.00..0.00 rows=0 width=4) One-Time Filter: false - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (3 rows) select * from t1 where a=1 and a=2 and a > (select t2.b from t2) @@ -1182,11 +1186,11 @@ select * from t1 where a=1 and a=2 and a > (select t2.b from t2); explain select * from t1, (select * from t1 where a=1 and a=2 and a > (select t2.b from t2)) foo where t1.a = foo.a; - QUERY PLAN ------------------------------------------------------- + QUERY PLAN +------------------------------------------ Result (cost=0.00..0.00 rows=0 width=8) One-Time Filter: false - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (3 rows) select * from t1, @@ -1216,8 +1220,8 @@ explain select 1 from t1 where a in (select b from t2 where a = 1 limit 1); -> Materialize (cost=0.00..431.00 rows=1 width=4) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on t2 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 -(12 rows) + Optimizer: GPORCA +(13 rows) explain select 1 from t1 where a in (select b from t2 where a = 1 offset 1); QUERY PLAN @@ -1234,8 +1238,8 @@ explain select 1 from t1 where a in (select b from t2 where a = 1 offset 1); -> Materialize (cost=0.00..431.00 rows=1 width=4) -> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on t2 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 -(12 rows) + Optimizer: GPORCA +(13 rows) select 1 from t1 where a in (select b from t2 where a = 1 limit 1); ?column? @@ -1305,8 +1309,8 @@ explain select row_number() over (order by seq asc) as id, foo.cnt from (select seq, (select count(*) from t1_mpp_24563 t1 where t1.id = t2.id) cnt from t2_mpp_24563 t2 where value = 7) foo; - QUERY PLAN --------------------------------------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- WindowAgg (cost=0.00..862.00 rows=1 width=16) Order By: t2.seq -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=1 width=12) @@ -1324,7 +1328,7 @@ from -> Sort (cost=0.00..431.00 rows=1 width=4) Sort Key: t1.id -> Seq Scan on t1_mpp_24563 t1 (cost=0.00..431.00 rows=1 width=4) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (18 rows) drop table t1_mpp_24563; @@ -1353,8 +1357,10 @@ CASE ELSE 'Q2'::text END AS cc, 1 AS nn FROM t_mpp_20470 b; explain SELECT cc, sum(nn) over() FROM v1_mpp_20470; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: t_mpp_20470 +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- WindowAgg (cost=0.00..862.00 rows=2 width=16) -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=2 width=12) -> Hash Left Join (cost=0.00..862.00 rows=1 width=16) @@ -1370,7 +1376,7 @@ explain SELECT cc, sum(nn) over() FROM v1_mpp_20470; Hash Key: a.col_name -> Dynamic Seq Scan on t_mpp_20470 a (cost=0.00..431.00 rows=1 width=12) Number of partitions to scan: 2 (out of 2) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (16 rows) drop view v1_mpp_20470; @@ -1452,6 +1458,8 @@ create table bar(a int, b int) distributed by (a); with CT as (select a from foo except select a from bar) select * from foo where exists (select 1 from CT where CT.a = foo.a); +NOTICE: One or more columns in the following table(s) do not have statistics: foo +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a | b ---+--- (0 rows) @@ -1480,6 +1488,8 @@ HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sur INSERT INTO foo_s VALUES (9,9); INSERT INTO foo_s VALUES (2,9); SELECT bar_s.c from bar_s, foo_s WHERE foo_s.a=2 AND foo_s.b = (SELECT max(b) FROM foo_s WHERE bar_s.c = 9); +NOTICE: One or more columns in the following table(s) do not have statistics: foo_s +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. c --- 9 @@ -1494,6 +1504,8 @@ ANALYZE baz_s; -- because it avoids picking SubPlans from an equivalence class, when it has -- other choices. SELECT bar_s.c FROM bar_s, foo_s WHERE foo_s.b = (SELECT max(i) FROM baz_s WHERE bar_s.c = 9) AND foo_s.b = bar_s.d::int4; +NOTICE: One or more columns in the following table(s) do not have statistics: foo_s +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. c --- 9 @@ -1503,10 +1515,12 @@ SELECT bar_s.c FROM bar_s, foo_s WHERE foo_s.b = (SELECT max(i) FROM baz_s WHERE -- Same as above, but with another subquery, so it must use a SubPlan. There -- are two references to the same SubPlan in the plan, on different slices. explain SELECT bar_s.c FROM bar_s, foo_s WHERE foo_s.b = (SELECT max(i) FROM baz_s WHERE bar_s.c = 9) AND foo_s.b = (select bar_s.d::int4); +NOTICE: One or more columns in the following table(s) do not have statistics: foo_s +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN ----------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1356273068.35 rows=1 width=4) - -> Hash Join (cost=0.00..1356273068.35 rows=1 width=4) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1356273072.98 rows=1000 width=4) + -> Hash Join (cost=0.00..1356273072.97 rows=334 width=4) Hash Cond: ((((SubPlan 1)) = foo_s.b) AND (((SubPlan 2)) = foo_s.b)) -> Seq Scan on bar_s (cost=0.00..1324053.98 rows=334 width=16) SubPlan 1 @@ -1522,11 +1536,13 @@ explain SELECT bar_s.c FROM bar_s, foo_s WHERE foo_s.b = (SELECT max(i) FROM baz -> Hash (cost=431.00..431.00 rows=1 width=4) -> Broadcast Motion 3:3 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=4) -> Dynamic Seq Scan on foo_s (cost=0.00..431.00 rows=1 width=4) - Number of partitions to scan: 2 - Optimizer: Pivotal Optimizer (GPORCA) + Number of partitions to scan: 2 (out of 2) + Optimizer: GPORCA (19 rows) SELECT bar_s.c FROM bar_s, foo_s WHERE foo_s.b = (SELECT max(i) FROM baz_s WHERE bar_s.c = 9) AND foo_s.b = (select bar_s.d::int4); +NOTICE: One or more columns in the following table(s) do not have statistics: foo_s +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. c --- 9 @@ -1561,19 +1577,19 @@ EXPLAIN SELECT '' AS six, f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL) ORDER BY 2; QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Result (cost=0.00..862.00 rows=3 width=12) + Result (cost=0.00..862.00 rows=7 width=12) -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=7 width=4) Merge Key: subselect_tbl.f1 -> Sort (cost=0.00..862.00 rows=3 width=4) Sort Key: subselect_tbl.f1 -> Hash Semi Join (cost=0.00..862.00 rows=3 width=4) - Hash Cond: subselect_tbl.f1 = subselect_tbl_1.f2 + Hash Cond: (subselect_tbl.f1 = subselect_tbl_1.f2) -> Seq Scan on subselect_tbl (cost=0.00..431.00 rows=3 width=4) -> Hash (cost=431.00..431.00 rows=3 width=4) -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=3 width=4) Hash Key: subselect_tbl_1.f2 -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..431.00 rows=3 width=4) - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 + Optimizer: GPORCA (13 rows) EXPLAIN SELECT '' AS six, f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL @@ -1581,13 +1597,13 @@ EXPLAIN SELECT '' AS six, f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL f2 IN (SELECT f1 FROM SUBSELECT_TBL)) ORDER BY 2; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------- - Result (cost=0.00..1293.00 rows=2 width=12) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1293.00 rows=5 width=4) + Result (cost=0.00..1293.00 rows=4 width=12) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1293.00 rows=4 width=4) Merge Key: subselect_tbl.f1 -> Sort (cost=0.00..1293.00 rows=2 width=4) Sort Key: subselect_tbl.f1 -> Hash Join (cost=0.00..1293.00 rows=2 width=4) - Hash Cond: subselect_tbl.f1 = subselect_tbl_1.f2 + Hash Cond: (subselect_tbl.f1 = subselect_tbl_1.f2) -> Seq Scan on subselect_tbl (cost=0.00..431.00 rows=3 width=4) -> Hash (cost=862.00..862.00 rows=2 width=4) -> GroupAggregate (cost=0.00..862.00 rows=2 width=4) @@ -1595,32 +1611,32 @@ EXPLAIN SELECT '' AS six, f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL -> Sort (cost=0.00..862.00 rows=3 width=4) Sort Key: subselect_tbl_1.f2 -> Hash Semi Join (cost=0.00..862.00 rows=3 width=4) - Hash Cond: subselect_tbl_1.f2 = subselect_tbl_2.f1 + Hash Cond: (subselect_tbl_1.f2 = subselect_tbl_2.f1) -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=3 width=4) Hash Key: subselect_tbl_1.f2 -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..431.00 rows=3 width=4) -> Hash (cost=431.00..431.00 rows=3 width=4) -> Seq Scan on subselect_tbl subselect_tbl_2 (cost=0.00..431.00 rows=3 width=4) - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 + Optimizer: GPORCA (21 rows) EXPLAIN SELECT '' AS three, f1, f2 FROM SUBSELECT_TBL WHERE (f1, f2) NOT IN (SELECT f2, CAST(f3 AS int4) FROM SUBSELECT_TBL WHERE f3 IS NOT NULL) ORDER BY 2,3; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=10000000009.64..10000000009.64 rows=4 width=8) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=10000000004.35..10000000004.40 rows=3 width=40) Merge Key: subselect_tbl.f1, subselect_tbl.f2 - -> Sort (cost=10000000009.64..10000000009.64 rows=2 width=8) + -> Sort (cost=10000000004.35..10000000004.35 rows=1 width=40) Sort Key: subselect_tbl.f1, subselect_tbl.f2 - -> Nested Loop Left Anti Semi (Not-In) Join (cost=10000000000.00..10000000009.61 rows=2 width=8) - Join Filter: subselect_tbl.f1 = subselect_tbl_1.f2 AND subselect_tbl.f2 = subselect_tbl_1.f3::integer - -> Seq Scan on subselect_tbl (cost=0.00..3.08 rows=3 width=8) - -> Materialize (cost=0.00..3.47 rows=7 width=12) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..3.36 rows=7 width=12) - -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..3.08 rows=3 width=12) - Filter: f3 IS NOT NULL + -> Nested Loop Left Anti Semi (Not-In) Join (cost=10000000000.00..10000000004.34 rows=1 width=40) + Join Filter: ((subselect_tbl.f1 = subselect_tbl_1.f2) AND (subselect_tbl.f2 = (subselect_tbl_1.f3)::integer)) + -> Seq Scan on subselect_tbl (cost=0.00..1.03 rows=3 width=8) + -> Materialize (cost=0.00..1.15 rows=7 width=12) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.12 rows=7 width=12) + -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..1.03 rows=2 width=12) + Filter: (f3 IS NOT NULL) Optimizer: Postgres query optimizer (12 rows) @@ -1629,22 +1645,22 @@ EXPLAIN SELECT * FROM tenk1 a, tenk1 b WHERE (a.unique1,b.unique2) IN (SELECT unique1,unique2 FROM tenk1 c); QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=356.67..706.67 rows=10000 width=488) - -> Hash Join (cost=356.67..573.33 rows=3333 width=488) + Gather Motion 3:1 (slice1; segments: 3) (cost=353.67..703.67 rows=10000 width=488) + -> Hash Join (cost=353.67..570.33 rows=3333 width=488) Hash Cond: (c.unique2 = b.unique2) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=185.00..355.83 rows=3333 width=248) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=183.00..353.83 rows=3333 width=248) Hash Key: c.unique2 - -> Hash Join (cost=185.00..289.17 rows=3333 width=248) + -> Hash Join (cost=183.00..287.17 rows=3333 width=248) Hash Cond: (c.unique1 = a.unique1) - -> HashAggregate (cost=80.00..113.33 rows=10000 width=8) + -> HashAggregate (cost=79.00..112.33 rows=10000 width=8) Group Key: c.unique1, c.unique2 - -> Seq Scan on tenk1 c (cost=0.00..63.33 rows=3333 width=8) - -> Hash (cost=63.33..63.33 rows=3333 width=244) - -> Seq Scan on tenk1 a (cost=0.00..63.33 rows=3333 width=244) - -> Hash (cost=130.00..130.00 rows=3333 width=244) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..130.00 rows=3333 width=244) + -> Seq Scan on tenk1 c (cost=0.00..62.33 rows=3333 width=8) + -> Hash (cost=62.33..62.33 rows=3333 width=244) + -> Seq Scan on tenk1 a (cost=0.00..62.33 rows=3333 width=244) + -> Hash (cost=129.00..129.00 rows=3333 width=244) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..129.00 rows=3333 width=244) Hash Key: b.unique2 - -> Seq Scan on tenk1 b (cost=0.00..63.33 rows=3333 width=244) + -> Seq Scan on tenk1 b (cost=0.00..62.33 rows=3333 width=244) Optimizer: Postgres query optimizer (17 rows) @@ -1652,82 +1668,83 @@ WHERE (a.unique1,b.unique2) IN (SELECT unique1,unique2 FROM tenk1 c); EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f2 AS "Second Field" FROM SUBSELECT_TBL upper WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE f1 = upper.f1) ORDER BY 2,3; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Result (cost=0.00..862.00 rows=3 width=16) + QUERY PLAN +-------------------------------------------------------------------------------------------------- + Result (cost=0.00..862.00 rows=8 width=16) -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=8 width=8) Merge Key: upper.f1, upper.f2 -> Sort (cost=0.00..862.00 rows=3 width=8) Sort Key: upper.f1, upper.f2 -> Hash Semi Join (cost=0.00..862.00 rows=3 width=8) - Hash Cond: upper.f1 = subselect_tbl.f1 AND upper.f1 = subselect_tbl.f2 + Hash Cond: ((upper.f1 = subselect_tbl.f1) AND (upper.f1 = subselect_tbl.f2)) -> Seq Scan on subselect_tbl upper (cost=0.00..431.00 rows=3 width=8) + Filter: (NOT (f1 IS NULL)) -> Hash (cost=431.00..431.00 rows=3 width=8) -> Seq Scan on subselect_tbl (cost=0.00..431.00 rows=3 width=8) - Optimizer: Pivotal Optimizer (GPORCA) version 2.75.0 -(11 rows) + Optimizer: GPORCA +(12 rows) EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f3 AS "Second Field" FROM SUBSELECT_TBL upper WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE CAST(upper.f2 AS float) = f3) ORDER BY 2,3; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------- - Result (cost=0.00..862.00 rows=3 width=20) + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------- + Result (cost=0.00..862.00 rows=8 width=20) -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=8 width=12) Merge Key: upper.f1, upper.f3 -> Sort (cost=0.00..862.00 rows=3 width=12) Sort Key: upper.f1, upper.f3 -> Hash Semi Join (cost=0.00..862.00 rows=3 width=12) - Hash Cond: upper.f2::double precision = subselect_tbl.f3 AND upper.f1 = subselect_tbl.f2 + Hash Cond: (((upper.f2)::double precision = subselect_tbl.f3) AND (upper.f1 = subselect_tbl.f2)) -> Seq Scan on subselect_tbl upper (cost=0.00..431.00 rows=3 width=16) -> Hash (cost=431.00..431.00 rows=3 width=12) -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=3 width=12) Hash Key: subselect_tbl.f2 -> Seq Scan on subselect_tbl (cost=0.00..431.00 rows=3 width=12) - Optimizer: Pivotal Optimizer (GPORCA) version 2.75.0 + Optimizer: GPORCA (13 rows) EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f3 AS "Second Field" FROM SUBSELECT_TBL upper WHERE f3 IN (SELECT upper.f1 + f2 FROM SUBSELECT_TBL WHERE f2 = CAST(f3 AS integer)) ORDER BY 2,3; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------- - Result (cost=0.00..1324033.89 rows=3 width=20) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324033.89 rows=8 width=12) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------- + Result (cost=0.00..1324033.90 rows=8 width=20) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324033.90 rows=8 width=12) Merge Key: upper.f1, upper.f3 - -> Sort (cost=0.00..1324033.89 rows=3 width=12) + -> Sort (cost=0.00..1324033.90 rows=3 width=12) Sort Key: upper.f1, upper.f3 - -> Seq Scan on subselect_tbl upper (cost=0.00..1324033.89 rows=3 width=12) + -> Seq Scan on subselect_tbl upper (cost=0.00..1324033.90 rows=3 width=12) Filter: (SubPlan 1) SubPlan 1 -> Result (cost=0.00..431.00 rows=4 width=4) -> Materialize (cost=0.00..431.00 rows=4 width=4) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=4 width=4) -> Seq Scan on subselect_tbl (cost=0.00..431.00 rows=2 width=4) - Filter: f2 = f3::integer - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 + Filter: (f2 = (f3)::integer) + Optimizer: GPORCA (14 rows) EXPLAIN SELECT '' AS five, f1 AS "Correlated Field" FROM SUBSELECT_TBL WHERE (f1, f2) IN (SELECT f2, CAST(f3 AS int4) FROM SUBSELECT_TBL WHERE f3 IS NOT NULL) ORDER BY 2; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=6.67..6.69 rows=8 width=4) + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=2.20..2.30 rows=7 width=36) Merge Key: subselect_tbl.f1 - -> Sort (cost=6.67..6.69 rows=3 width=4) + -> Sort (cost=2.20..2.20 rows=2 width=36) Sort Key: subselect_tbl.f1 - -> Hash Semi Join (cost=3.33..6.55 rows=3 width=4) - Hash Cond: subselect_tbl.f1 = subselect_tbl_1.f2 AND subselect_tbl.f2 = subselect_tbl_1.f3::integer - -> Seq Scan on subselect_tbl (cost=0.00..3.08 rows=3 width=8) - -> Hash (cost=3.22..3.22 rows=3 width=12) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.22 rows=3 width=12) - Hash Key: subselect_tbl_1.f2 - -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..3.08 rows=3 width=12) - Filter: f3 IS NOT NULL + -> Hash Right Semi Join (cost=1.07..2.18 rows=2 width=36) + Hash Cond: ((subselect_tbl_1.f2 = subselect_tbl.f1) AND ((subselect_tbl_1.f3)::integer = subselect_tbl.f2)) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.07 rows=2 width=12) + Hash Key: subselect_tbl_1.f2 + -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..1.03 rows=2 width=12) + Filter: (f3 IS NOT NULL) + -> Hash (cost=1.03..1.03 rows=3 width=8) + -> Seq Scan on subselect_tbl (cost=0.00..1.03 rows=3 width=8) Optimizer: Postgres query optimizer (13 rows) @@ -1735,8 +1752,8 @@ EXPLAIN SELECT '' AS five, f1 AS "Correlated Field" EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f2 AS "Second Field" FROM SUBSELECT_TBL upper WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE f1 = upper.f1 GROUP BY f2); - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------- Result (cost=0.00..862.00 rows=8 width=16) -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=8 width=8) -> Hash Semi Join (cost=0.00..862.00 rows=3 width=8) @@ -1744,17 +1761,17 @@ EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f2 AS "Second Field" -> Seq Scan on subselect_tbl upper (cost=0.00..431.00 rows=3 width=8) -> Hash (cost=431.00..431.00 rows=3 width=8) -> Seq Scan on subselect_tbl (cost=0.00..431.00 rows=3 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (8 rows) EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f2 AS "Second Field" FROM SUBSELECT_TBL upper WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE f1 = upper.f1 GROUP BY f2 LIMIT 3); - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------- - Result (cost=0.00..1324038.67 rows=8 width=16) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324038.67 rows=8 width=8) - -> Seq Scan on subselect_tbl upper (cost=0.00..1324038.67 rows=3 width=8) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Result (cost=0.00..1324038.68 rows=8 width=16) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324038.68 rows=8 width=8) + -> Seq Scan on subselect_tbl upper (cost=0.00..1324038.68 rows=3 width=8) Filter: (SubPlan 1) SubPlan 1 -> Limit (cost=0.00..431.01 rows=1 width=4) @@ -1765,14 +1782,14 @@ EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f2 AS "Second Field" -> Materialize (cost=0.00..431.00 rows=8 width=8) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=8 width=8) -> Seq Scan on subselect_tbl (cost=0.00..431.00 rows=3 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (14 rows) EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f2 AS "Second Field" FROM SUBSELECT_TBL upper WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE f1 = upper.f1 ORDER BY f2); - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------- Result (cost=0.00..862.00 rows=8 width=16) -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=8 width=8) -> Hash Semi Join (cost=0.00..862.00 rows=3 width=8) @@ -1781,17 +1798,17 @@ EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f2 AS "Second Field" Filter: (NOT (f1 IS NULL)) -> Hash (cost=431.00..431.00 rows=3 width=8) -> Seq Scan on subselect_tbl (cost=0.00..431.00 rows=3 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f2 AS "Second Field" FROM SUBSELECT_TBL upper WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE f1 = upper.f1 ORDER BY f2 LIMIT 3); - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------- - Result (cost=0.00..1324038.66 rows=8 width=16) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324038.66 rows=8 width=8) - -> Seq Scan on subselect_tbl upper (cost=0.00..1324038.66 rows=3 width=8) + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Result (cost=0.00..1324039.05 rows=8 width=16) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324039.05 rows=8 width=8) + -> Seq Scan on subselect_tbl upper (cost=0.00..1324039.05 rows=3 width=8) Filter: ((NOT (f1 IS NULL)) AND (SubPlan 1)) SubPlan 1 -> Limit (cost=0.00..431.01 rows=1 width=4) @@ -1802,7 +1819,7 @@ EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f2 AS "Second Field" -> Materialize (cost=0.00..431.00 rows=8 width=8) -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=8 width=8) -> Seq Scan on subselect_tbl (cost=0.00..431.00 rows=3 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (14 rows) -- @@ -1983,8 +2000,8 @@ EXPLAIN SELECT * FROM dedup_test1 INNER JOIN dedup_test2 ON dedup_test1.a= dedup Sort Key: dedup_test3.a -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..431.00 rows=4 width=4) -> Dynamic Seq Scan on dedup_test3 (cost=0.00..431.00 rows=4 width=4) - Number of partitions to scan: 1 - Optimizer: Pivotal Optimizer (GPORCA) + Number of partitions to scan: 1 (out of 1) + Optimizer: GPORCA (23 rows) SELECT * FROM dedup_test1 INNER JOIN dedup_test2 ON dedup_test1.a= dedup_test2.e WHERE (a) IN (SELECT a FROM dedup_test3); @@ -2003,7 +2020,7 @@ EXPLAIN SELECT * FROM dedup_test3, dedup_test1 WHERE c = 7 AND dedup_test3.b IN -> Result (cost=0.00..0.00 rows=0 width=12) One-Time Filter: false -> Seq Scan on dedup_test1 (cost=0.00..431.00 rows=2 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) EXPLAIN SELECT * FROM dedup_test3, dedup_test1 WHERE c = 7 AND dedup_test3.b IN (SELECT a FROM dedup_test1); @@ -2015,7 +2032,7 @@ EXPLAIN SELECT * FROM dedup_test3, dedup_test1 WHERE c = 7 AND dedup_test3.b IN -> Result (cost=0.00..0.00 rows=0 width=12) One-Time Filter: false -> Seq Scan on dedup_test1 (cost=0.00..431.00 rows=2 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) EXPLAIN SELECT * FROM dedup_test3, dedup_test1 WHERE c = 7 AND EXISTS (SELECT b FROM dedup_test1) AND dedup_test3.b IN (SELECT b FROM dedup_test1); @@ -2027,7 +2044,7 @@ EXPLAIN SELECT * FROM dedup_test3, dedup_test1 WHERE c = 7 AND EXISTS (SELECT b -> Result (cost=0.00..0.00 rows=0 width=12) One-Time Filter: false -> Seq Scan on dedup_test1 (cost=0.00..431.00 rows=2 width=8) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (7 rows) -- More dedup semi-join tests. @@ -2044,22 +2061,19 @@ analyze dedup_reptab; -- row otherwise. explain (costs off, locus) select * from dedup_reptab r where r.a in (select t.a/10 from dedup_tab t); - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> Hash Join - Hash Cond: (((t.a / 10)) = r.a) - -> GroupAggregate - Group Key: ((t.a / 10)) - -> Sort - Sort Key: ((t.a / 10)) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: ((t.a / 10)) - -> Seq Scan on dedup_tab t + -> Hash Right Semi Join + Hash Cond: (r.a = ((t.a / 10))) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: ((t.a / 10)) + -> Seq Scan on dedup_tab t -> Hash - -> Seq Scan on dedup_reptab r - Optimizer: Pivotal Optimizer (GPORCA) -(13 rows) + -> Result + -> Seq Scan on dedup_reptab r + Optimizer: GPORCA +(10 rows) select * from dedup_reptab r where r.a in (select t.a/10 from dedup_tab t); a @@ -2105,21 +2119,21 @@ select * from dedup_srf() r(a) where r.a in (select t.a/10 from dedup_tab t); -> Redistribute Motion 3:3 (slice2; segments: 3) Hash Key: ((t.a / 10)) -> Seq Scan on dedup_tab t - Optimizer: Pivotal Optimizer (GPORCA) version 3.94.0 + Optimizer: GPORCA (10 rows) select * from dedup_srf() r(a) where r.a in (select t.a/10 from dedup_tab t); a --- - 1 2 3 + 1 (3 rows) explain (costs off) select * from dedup_srf_stable() r(a) where r.a in (select t.a/10 from dedup_tab t); - QUERY PLAN -------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Semi Join Hash Cond: (dedup_srf_stable.dedup_srf_stable = ((t.a / 10))) @@ -2130,21 +2144,21 @@ select * from dedup_srf_stable() r(a) where r.a in (select t.a/10 from dedup_tab -> Redistribute Motion 3:3 (slice3; segments: 3) Hash Key: ((t.a / 10)) -> Seq Scan on dedup_tab t - Optimizer: Pivotal Optimizer (GPORCA) version 3.94.0 + Optimizer: GPORCA (11 rows) select * from dedup_srf_stable() r(a) where r.a in (select t.a/10 from dedup_tab t); a --- - 1 2 3 + 1 (3 rows) explain (costs off) select * from dedup_srf_volatile() r(a) where r.a in (select t.a/10 from dedup_tab t); - QUERY PLAN ------------------------------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Semi Join Hash Cond: (dedup_srf_volatile.dedup_srf_volatile = ((t.a / 10))) @@ -2155,15 +2169,15 @@ select * from dedup_srf_volatile() r(a) where r.a in (select t.a/10 from dedup_t -> Redistribute Motion 3:3 (slice3; segments: 3) Hash Key: ((t.a / 10)) -> Seq Scan on dedup_tab t - Optimizer: Pivotal Optimizer (GPORCA) version 3.94.0 + Optimizer: GPORCA (11 rows) select * from dedup_srf_volatile() r(a) where r.a in (select t.a/10 from dedup_tab t); a --- - 1 2 3 + 1 (3 rows) -- Also test it with non-SRFs. In principle, since the function returns exactly @@ -2181,22 +2195,19 @@ create function dedup_func_volatile() RETURNS int AS $$ $$ LANGUAGE SQL VOLATILE; explain (costs off) select * from dedup_func() r(a) where r.a in (select t.a/10 from dedup_tab t); - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> Hash Join - Hash Cond: (((a / 10)) = (5)) - -> GroupAggregate - Group Key: ((a / 10)) - -> Sort - Sort Key: ((a / 10)) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: ((a / 10)) - -> Seq Scan on dedup_tab t + -> Hash Right Semi Join + Hash Cond: ((5) = ((a / 10))) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: ((a / 10)) + -> Seq Scan on dedup_tab t -> Hash -> Result - Optimizer: Pivotal Optimizer (GPORCA) -(13 rows) + -> Result + Optimizer: GPORCA +(10 rows) select * from dedup_func() r(a) where r.a in (select t.a/10 from dedup_tab t); a @@ -2206,22 +2217,19 @@ select * from dedup_func() r(a) where r.a in (select t.a/10 from dedup_tab t); explain (costs off) select * from dedup_func_stable() r(a) where r.a in (select t.a/10 from dedup_tab t); - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> Hash Join - Hash Cond: (((a / 10)) = (5)) - -> GroupAggregate - Group Key: ((a / 10)) - -> Sort - Sort Key: ((a / 10)) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: ((a / 10)) - -> Seq Scan on dedup_tab t + -> Hash Right Semi Join + Hash Cond: ((5) = ((a / 10))) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: ((a / 10)) + -> Seq Scan on dedup_tab t -> Hash -> Result - Optimizer: Pivotal Optimizer (GPORCA) -(13 rows) + -> Result + Optimizer: GPORCA +(10 rows) select * from dedup_func_stable() r(a) where r.a in (select t.a/10 from dedup_tab t); a @@ -2231,22 +2239,19 @@ select * from dedup_func_stable() r(a) where r.a in (select t.a/10 from dedup_ta explain (costs off) select * from dedup_func_volatile() r(a) where r.a in (select t.a/10 from dedup_tab t); - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> Hash Join - Hash Cond: (((a / 10)) = (5)) - -> GroupAggregate - Group Key: ((a / 10)) - -> Sort - Sort Key: ((a / 10)) - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: ((a / 10)) - -> Seq Scan on dedup_tab t + -> Hash Right Semi Join + Hash Cond: ((5) = ((a / 10))) + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: ((a / 10)) + -> Seq Scan on dedup_tab t -> Hash -> Result - Optimizer: Pivotal Optimizer (GPORCA) -(13 rows) + -> Result + Optimizer: GPORCA +(10 rows) select * from dedup_func_volatile() r(a) where r.a in (select t.a/10 from dedup_tab t); a @@ -2276,6 +2281,7 @@ select * from init_main_plan_parallel where exists (select * from pg_class); -- hashExpr are in its targetlist, test the motion node above it also updated -- its targetlist, otherwise, a wrong answer or a crash happens. DROP TABLE IF EXISTS TEST_IN; +NOTICE: table "test_in" does not exist, skipping CREATE TABLE TEST_IN( C01 FLOAT, C02 NUMERIC(10,0) @@ -2301,8 +2307,7 @@ WHERE A.C01 IN(SELECT C02 FROM TEST_IN); -- mutate a plan tree (plan_tree_mutator()). -- create temp table onerowtmp as select 1; -NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named '?column?' as the Apache Cloudberry data distribution key for this table. -HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause. Creating a NULL policy entry. select val.x from generate_series(1,10) as s(i), lateral ( @@ -2340,8 +2345,8 @@ analyze simplify_sub; -- limit n explain (costs off) select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where t1.i = t2.i limit 1); - QUERY PLAN -------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------- Result Filter: (SubPlan 1) -> Gather Motion 3:1 (slice1; segments: 3) @@ -2355,20 +2360,20 @@ select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where -> Materialize -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on simplify_sub t2 - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (14 rows) select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where t1.i = t2.i limit 1); i --- - 2 1 + 2 (2 rows) explain (costs off) select * from simplify_sub t1 where not exists (select 1 from simplify_sub t2 where t1.i = t2.i limit 1); - QUERY PLAN -------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------- Result Filter: (SubPlan 1) -> Gather Motion 3:1 (slice1; segments: 3) @@ -2381,7 +2386,7 @@ select * from simplify_sub t1 where not exists (select 1 from simplify_sub t2 wh -> Materialize -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on simplify_sub t2 - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (13 rows) select * from simplify_sub t1 where not exists (select 1 from simplify_sub t2 where t1.i = t2.i limit 1); @@ -2391,8 +2396,8 @@ select * from simplify_sub t1 where not exists (select 1 from simplify_sub t2 wh explain (costs off) select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where t1.i = t2.i limit 0); - QUERY PLAN ------------------------------------------------------- + QUERY PLAN +-------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Semi Join Join Filter: true @@ -2401,7 +2406,7 @@ select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where -> Limit -> Result One-Time Filter: false - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (9 rows) select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where t1.i = t2.i limit 0); @@ -2411,28 +2416,28 @@ select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where explain (costs off) select * from simplify_sub t1 where not exists (select 1 from simplify_sub t2 where t1.i = t2.i limit 0); - QUERY PLAN ------------------------------------------------------- + QUERY PLAN +------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Anti Join Join Filter: true -> Seq Scan on simplify_sub t1 -> Result One-Time Filter: false - Optimizer: Pivotal Optimizer (GPORCA) version 3.55.0 + Optimizer: GPORCA (7 rows) select * from simplify_sub t1 where not exists (select 1 from simplify_sub t2 where t1.i = t2.i limit 0); i --- - 1 2 + 1 (2 rows) explain (costs off) select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where t1.i = t2.i limit all); - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +----------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Semi Join Hash Cond: (t1.i = t2.i) @@ -2440,7 +2445,7 @@ select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where Filter: (NOT (i IS NULL)) -> Hash -> Seq Scan on simplify_sub t2 - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (8 rows) select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where t1.i = t2.i limit all); @@ -2452,15 +2457,15 @@ select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where explain (costs off) select * from simplify_sub t1 where not exists (select 1 from simplify_sub t2 where t1.i = t2.i limit all); - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +----------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Anti Join Hash Cond: (t1.i = t2.i) -> Seq Scan on simplify_sub t1 -> Hash -> Seq Scan on simplify_sub t2 - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (7 rows) select * from simplify_sub t1 where not exists (select 1 from simplify_sub t2 where t1.i = t2.i limit all); @@ -2470,8 +2475,8 @@ select * from simplify_sub t1 where not exists (select 1 from simplify_sub t2 wh explain (costs off) select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where t1.i = t2.i limit NULL); - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +----------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Semi Join Hash Cond: (t1.i = t2.i) @@ -2479,27 +2484,27 @@ select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where Filter: (NOT (i IS NULL)) -> Hash -> Seq Scan on simplify_sub t2 - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (8 rows) select * from simplify_sub t1 where exists (select 1 from simplify_sub t2 where t1.i = t2.i limit NULL); i --- - 2 1 + 2 (2 rows) explain (costs off) select * from simplify_sub t1 where not exists (select 1 from simplify_sub t2 where t1.i = t2.i limit NULL); - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +----------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Hash Anti Join Hash Cond: (t1.i = t2.i) -> Seq Scan on simplify_sub t1 -> Hash -> Seq Scan on simplify_sub t2 - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (7 rows) select * from simplify_sub t1 where not exists (select 1 from simplify_sub t2 where t1.i = t2.i limit NULL); @@ -2510,11 +2515,11 @@ select * from simplify_sub t1 where not exists (select 1 from simplify_sub t2 wh -- aggregates without GROUP BY or HAVING explain (costs off) select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i); - QUERY PLAN ------------------------------------------------------- + QUERY PLAN +------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on simplify_sub t1 - Optimizer: Pivotal Optimizer (GPORCA) version 3.55.0 + Optimizer: GPORCA (3 rows) select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i); @@ -2526,11 +2531,11 @@ select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t explain (costs off) select * from simplify_sub t1 where not exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i); - QUERY PLAN ------------------------------------------------------- + QUERY PLAN +-------------------------- Result One-Time Filter: false - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (3 rows) select * from simplify_sub t1 where not exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i); @@ -2540,27 +2545,27 @@ select * from simplify_sub t1 where not exists (select sum(t2.i) from simplify_s explain (costs off) select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i offset 0); - QUERY PLAN ------------------------------------------------------- + QUERY PLAN +------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> Seq Scan on simplify_sub t1 - Optimizer: Pivotal Optimizer (GPORCA) version 3.55.0 + Optimizer: GPORCA (3 rows) select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i offset 0); i --- - 2 1 + 2 (2 rows) explain (costs off) select * from simplify_sub t1 where not exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i offset 0); - QUERY PLAN ------------------------------------------------------- + QUERY PLAN +-------------------------- Result One-Time Filter: false - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (3 rows) select * from simplify_sub t1 where not exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i offset 0); @@ -2570,8 +2575,8 @@ select * from simplify_sub t1 where not exists (select sum(t2.i) from simplify_s explain (costs off) select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i offset 1); - QUERY PLAN -------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------- Result Filter: (SubPlan 1) -> Gather Motion 3:1 (slice1; segments: 3) @@ -2584,7 +2589,7 @@ select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t -> Materialize -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on simplify_sub t2 - Optimizer: Pivotal Optimizer (GPORCA) version 3.55.0 + Optimizer: GPORCA (13 rows) select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i offset 1); @@ -2594,8 +2599,8 @@ select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t explain (costs off) select * from simplify_sub t1 where not exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i offset 1); - QUERY PLAN -------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------- Result Filter: (SubPlan 1) -> Gather Motion 3:1 (slice1; segments: 3) @@ -2608,7 +2613,7 @@ select * from simplify_sub t1 where not exists (select sum(t2.i) from simplify_s -> Materialize -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on simplify_sub t2 - Optimizer: Pivotal Optimizer (GPORCA) version 3.55.0 + Optimizer: GPORCA (13 rows) select * from simplify_sub t1 where not exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i offset 1); @@ -2620,8 +2625,8 @@ select * from simplify_sub t1 where not exists (select sum(t2.i) from simplify_s explain (costs off) select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i offset NULL); - QUERY PLAN -------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------- Result Filter: (SubPlan 1) -> Gather Motion 3:1 (slice1; segments: 3) @@ -2634,7 +2639,7 @@ select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t -> Materialize -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on simplify_sub t2 - Optimizer: Pivotal Optimizer (GPORCA) version 3.55.0 + Optimizer: GPORCA (13 rows) select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i offset NULL); @@ -2646,8 +2651,8 @@ select * from simplify_sub t1 where exists (select sum(t2.i) from simplify_sub t explain (costs off) select * from simplify_sub t1 where not exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i offset NULL); - QUERY PLAN -------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------- Result Filter: (SubPlan 1) -> Gather Motion 3:1 (slice1; segments: 3) @@ -2660,7 +2665,7 @@ select * from simplify_sub t1 where not exists (select sum(t2.i) from simplify_s -> Materialize -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on simplify_sub t2 - Optimizer: Pivotal Optimizer (GPORCA) version 3.55.0 + Optimizer: GPORCA (13 rows) select * from simplify_sub t1 where not exists (select sum(t2.i) from simplify_sub t2 where t1.i = t2.i offset NULL); @@ -2712,22 +2717,22 @@ select * from foo left outer join baz on (select bar.i from bar where bar.i = fo Output: bar.i -> Seq Scan on subselect_gp.bar Output: bar.i + Settings: optimizer = 'on' Optimizer: Postgres query optimizer - Settings: optimizer=on (29 rows) select * from foo left outer join baz on (select bar.i from bar where bar.i = foo.i) + 1 = baz.j; i | j | i | j ----+----+---+--- - 10 | 10 | | - 9 | 9 | | - 6 | 6 | | - 5 | 5 | | 8 | 8 | | 7 | 7 | | 4 | 4 | | 3 | 3 | | 2 | 2 | | + 10 | 10 | | + 9 | 9 | | + 6 | 6 | | + 5 | 5 | | 1 | 1 | | (10 rows) @@ -2767,8 +2772,8 @@ select * from foo where Output: b.i -> Seq Scan on subselect_gp.baz b Output: b.i - Optimizer: Pivotal Optimizer (GPORCA) version 3.93.0 - Settings: optimizer=on + Settings: optimizer = 'on' + Optimizer: GPORCA (25 rows) select * from foo where @@ -2776,12 +2781,12 @@ select * from foo where (select b.i from baz b); i | j ----+---- + 5 | 5 6 | 6 - 7 | 7 + 9 | 9 10 | 10 - 5 | 5 + 7 | 7 8 | 8 - 9 | 9 (6 rows) -- When creating plan with subquery and CTE, it sets the useless flow for the plan. @@ -2836,8 +2841,9 @@ where dt < '2010-01-01'::date; Output: extra_flow_dist1.a, extra_flow_dist1.b -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b - Optimizer: Pivotal Optimizer (GPORCA) -(27 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(28 rows) with run_dt as ( select @@ -2851,8 +2857,8 @@ where dt < '2010-01-01'::date; dt | a | b ------------+----+---- 10-01-1949 | 22 | 22 - 10-01-1949 | 20 | 20 10-01-1949 | 21 | 21 + 10-01-1949 | 20 | 20 (3 rows) create table extra_flow_rand(a int) distributed replicated; @@ -2893,8 +2899,9 @@ where dt < '2010-01-01'::date; Output: extra_flow_dist.b, extra_flow_dist.c -> Seq Scan on subselect_gp.extra_flow_dist Output: extra_flow_dist.b, extra_flow_dist.c - Optimizer: Pivotal Optimizer (GPORCA) -(23 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(26 rows) with run_dt as ( select @@ -2907,9 +2914,9 @@ select * from run_dt, extra_flow_dist1 where dt < '2010-01-01'::date; dt | a | b ------------+----+---- - 10-01-1949 | 22 | 22 10-01-1949 | 21 | 21 10-01-1949 | 20 | 20 + 10-01-1949 | 22 | 22 (3 rows) -- case 3 for subplan with outer entry locus (CTE and subquery) @@ -2953,8 +2960,9 @@ where dt < '2010-01-01'::date; Output: extra_flow_dist1.a, extra_flow_dist1.b -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b - Optimizer: Pivotal Optimizer (GPORCA) -(30 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(31 rows) with run_dt as ( select @@ -3010,8 +3018,9 @@ where dt < extra_flow_dist1.a; Output: extra_flow_dist1.a, extra_flow_dist1.b -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b + Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(28 rows) +(29 rows) -- case 5 for subplan with outer entry locus without param in subplan (CTE and subquery) explain (verbose, costs off) with run_dt as ( @@ -3053,8 +3062,9 @@ where dt < extra_flow_dist1.a; Output: extra_flow_dist1.a, extra_flow_dist1.b -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b + Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(30 rows) +(31 rows) -- case 6 without CTE, nested subquery should not add extral flow explain (verbose, costs off) select * from ( @@ -3133,7 +3143,7 @@ where dt < '2010-01-01'::date; Output: extra_flow_dist_1.b, extra_flow_dist_1.c -> Seq Scan on subselect_gp.extra_flow_dist extra_flow_dist_1 Output: extra_flow_dist_1.b, extra_flow_dist_1.c - Settings: enable_parallel = 'off', optimizer = 'on' + Settings: optimizer = 'on' Optimizer: GPORCA (59 rows) @@ -3170,8 +3180,8 @@ select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issu Sort Key: issue_12656_1.i -> Seq Scan on subselect_gp.issue_12656 issue_12656_1 Output: issue_12656_1.i, issue_12656_1.j + Settings: optimizer = 'on' Optimizer: Postgres query optimizer - Settings: optimizer=on (20 rows) select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issue_12656); @@ -3203,8 +3213,8 @@ select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issu Sort Key: issue_12656_1.i, issue_12656_1.j -> Seq Scan on subselect_gp.issue_12656 issue_12656_1 Output: issue_12656_1.i, issue_12656_1.j + Settings: optimizer = 'on' Optimizer: Postgres query optimizer - Settings: optimizer=on (20 rows) select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issue_12656 order by i, j asc); @@ -3235,8 +3245,8 @@ select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issu Sort Key: issue_12656_1.i, issue_12656_1.j DESC -> Seq Scan on subselect_gp.issue_12656 issue_12656_1 Output: issue_12656_1.i, issue_12656_1.j + Settings: optimizer = 'on' Optimizer: Postgres query optimizer - Settings: optimizer=on (20 rows) select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issue_12656 order by i, j desc); @@ -3254,7 +3264,7 @@ explain select * from issue_12656 a where (i, j) in -> Seq Scan on issue_12656 a (cost=0.00..321.00 rows=14350 width=8) Filter: (SubPlan 1) SubPlan 1 - -> Unique (cost=9818.00..10033.25 rows=1000 width=8) + -> Unique (cost=9818.00..10033.25 rows=1 width=8) -> Sort (cost=9818.00..10033.25 rows=86100 width=8) Sort Key: b.j -> Result (cost=0.00..2760.50 rows=86100 width=8) @@ -3366,8 +3376,8 @@ with cte(table_oid, size) as select pc.relname, ts.size from pg_class pc, cte ts where pc.oid = ts.table_oid; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: pc.relname, (sum((pg_relation_size((pg_class.oid)::regclass, 'main'::text)))) -> Nested Loop @@ -3388,8 +3398,9 @@ where pc.oid = ts.table_oid; Hash Key: pg_class.oid -> Seq Scan on pg_catalog.pg_class Output: pg_class.oid, pg_relation_size((pg_class.oid)::regclass, 'main'::text) + Settings: optimizer = 'on', gp_enable_multiphase_agg = 'on', enable_hashjoin = 'off', enable_nestloop = 'on', enable_indexscan = 'off', enable_bitmapscan = 'off' Optimizer: Postgres query optimizer -(21 rows) +(22 rows) set gp_enable_multiphase_agg = off; explain (verbose on, costs off) @@ -3408,8 +3419,8 @@ with cte(table_oid, size) as select pc.relname, ts.size from pg_class pc, cte ts where pc.oid = ts.table_oid; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: pc.relname, (sum((pg_relation_size((pg_class.oid)::regclass, 'main'::text)))) -> Nested Loop @@ -3430,8 +3441,9 @@ where pc.oid = ts.table_oid; Hash Key: pg_class.oid -> Seq Scan on pg_catalog.pg_class Output: pg_class.oid, pg_relation_size((pg_class.oid)::regclass, 'main'::text) + Settings: optimizer = 'on', gp_enable_multiphase_agg = 'off', enable_hashjoin = 'off', enable_nestloop = 'on', enable_indexscan = 'off', enable_bitmapscan = 'off' Optimizer: Postgres query optimizer -(21 rows) +(22 rows) reset gp_enable_multiphase_agg; reset enable_hashjoin; @@ -3444,12 +3456,12 @@ set optimizer to off; explain select t.* from sublink_outer_table t join (select y ,10*avg(x) s from sublink_inner_table group by y) RR on RR.y = t.b and t.a > rr.s; QUERY PLAN -------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=436.00..1310.77 rows=28700 width=8) - -> Hash Join (cost=436.00..928.11 rows=9567 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=432.67..1307.44 rows=28700 width=8) + -> Hash Join (cost=432.67..924.77 rows=9567 width=8) Hash Cond: (t.b = sublink_inner_table.y) Join Filter: ((t.a)::numeric > (('10'::numeric * avg(sublink_inner_table.x)))) -> Seq Scan on sublink_outer_table t (cost=0.00..321.00 rows=28700 width=8) - -> Hash (cost=431.83..431.83 rows=333 width=40) + -> Hash (cost=428.50..428.50 rows=333 width=40) -> HashAggregate (cost=423.50..428.50 rows=333 width=40) Group Key: sublink_inner_table.y -> Seq Scan on sublink_inner_table (cost=0.00..293.67 rows=25967 width=12) @@ -3459,13 +3471,13 @@ explain select t.* from sublink_outer_table t join (select y ,10*avg(x) s from s explain select * from sublink_outer_table T where a > (select 10*avg(x) from sublink_inner_table R where T.b=R.y); QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=436.00..1310.77 rows=28700 width=8) - -> Hash Join (cost=436.00..928.11 rows=9567 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=433.78..1308.55 rows=28700 width=8) + -> Hash Join (cost=433.78..925.89 rows=9567 width=8) Hash Cond: (t.b = "Expr_SUBQUERY".csq_c0) Join Filter: ((t.a)::numeric > "Expr_SUBQUERY".csq_c1) -> Seq Scan on sublink_outer_table t (cost=0.00..321.00 rows=28700 width=8) - -> Hash (cost=431.83..431.83 rows=333 width=40) - -> Subquery Scan on "Expr_SUBQUERY" (cost=423.50..431.83 rows=333 width=40) + -> Hash (cost=429.61..429.61 rows=333 width=40) + -> Subquery Scan on "Expr_SUBQUERY" (cost=423.50..429.61 rows=333 width=40) -> HashAggregate (cost=423.50..428.50 rows=333 width=40) Group Key: r.y -> Seq Scan on sublink_inner_table r (cost=0.00..293.67 rows=25967 width=12) @@ -3476,12 +3488,12 @@ set enable_hashagg to off; explain select t.* from sublink_outer_table t join (select y ,10*avg(x) s from sublink_inner_table group by y) RR on RR.y = t.b and t.a > rr.s; QUERY PLAN -------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2404.84..3279.62 rows=28700 width=8) - -> Hash Join (cost=2404.84..2896.95 rows=9567 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=2401.51..3276.28 rows=28700 width=8) + -> Hash Join (cost=2401.51..2893.62 rows=9567 width=8) Hash Cond: (t.b = sublink_inner_table.y) Join Filter: ((t.a)::numeric > (('10'::numeric * avg(sublink_inner_table.x)))) -> Seq Scan on sublink_outer_table t (cost=0.00..321.00 rows=28700 width=8) - -> Hash (cost=2400.67..2400.67 rows=333 width=40) + -> Hash (cost=2397.34..2397.34 rows=333 width=40) -> GroupAggregate (cost=2197.59..2397.34 rows=333 width=40) Group Key: sublink_inner_table.y -> Sort (cost=2197.59..2262.51 rows=25967 width=12) @@ -3493,13 +3505,13 @@ explain select t.* from sublink_outer_table t join (select y ,10*avg(x) s from s explain select * from sublink_outer_table T where a > (select 10*avg(x) from sublink_inner_table R where T.b=R.y); QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2404.84..3279.62 rows=28700 width=8) - -> Hash Join (cost=2404.84..2896.95 rows=9567 width=8) + Gather Motion 3:1 (slice1; segments: 3) (cost=2402.62..3277.39 rows=28700 width=8) + -> Hash Join (cost=2402.62..2894.73 rows=9567 width=8) Hash Cond: (t.b = "Expr_SUBQUERY".csq_c0) Join Filter: ((t.a)::numeric > "Expr_SUBQUERY".csq_c1) -> Seq Scan on sublink_outer_table t (cost=0.00..321.00 rows=28700 width=8) - -> Hash (cost=2400.67..2400.67 rows=333 width=40) - -> Subquery Scan on "Expr_SUBQUERY" (cost=2197.59..2400.67 rows=333 width=40) + -> Hash (cost=2398.45..2398.45 rows=333 width=40) + -> Subquery Scan on "Expr_SUBQUERY" (cost=2197.59..2398.45 rows=333 width=40) -> GroupAggregate (cost=2197.59..2397.34 rows=333 width=40) Group Key: r.y -> Sort (cost=2197.59..2262.51 rows=25967 width=12) @@ -3528,7 +3540,7 @@ explain (costs off) select * from r where b in (select b from s where c=10 order -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on s Filter: (c = 10) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) select * from r where b in (select b from s where c=10 order by r.c); @@ -3549,7 +3561,7 @@ explain (costs off) select * from r where b in (select b from s where c=10 order -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on s Filter: (c = 10) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (10 rows) select * from r where b in (select b from s where c=10 order by r.c limit 2); @@ -3569,7 +3581,7 @@ explain (costs off) select * from r where b in (select b from s where c=10 order -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on s Filter: (c = 10) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) select * from r where b in (select b from s where c=10 order by r.c, b); @@ -3593,7 +3605,7 @@ explain (costs off) select * from r where b in (select b from s where c=10 order Sort Key: s.b -> Seq Scan on s Filter: (c = 10) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) select * from r where b in (select b from s where c=10 order by r.c, b limit 2); @@ -3613,7 +3625,7 @@ explain (costs off) select * from r where b in (select b from s where c=10 order -> Broadcast Motion 3:3 (slice2; segments: 3) -> Seq Scan on s Filter: (c = 10) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (9 rows) select * from r where b in (select b from s where c=10 order by c); @@ -3637,7 +3649,7 @@ explain (costs off) select * from r where b in (select b from s where c=10 order Sort Key: s.c -> Seq Scan on s Filter: (c = 10) - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) select * from r where b in (select b from s where c=10 order by c limit 2); @@ -3682,16 +3694,16 @@ SELECT c FROM t0; -- Test push predicate into subquery -- more details could be found at https://github.com/greenplum-db/gpdb/issues/8429 CREATE TABLE foo_predicate_pushdown (a int, b int); -NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table. +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TABLE bar_predicate_pushdown (c int, d int); -NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c' as the Greenplum Database data distribution key for this table. +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. explain (costs off) select * from ( select distinct (select bar.c from bar_predicate_pushdown bar where c = foo.b) as ss from foo_predicate_pushdown foo ) ABC where ABC.ss = 5; - QUERY PLAN -------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> GroupAggregate Group Key: ((SubPlan 1)) @@ -3735,18 +3747,18 @@ analyze table_left; analyze table_right; -- two types of semi join tests explain (costs off) select * from table_left where exists (select 1 from table_right where l1 = r1); - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join + -> Hash Right Semi Join Hash Cond: (table_left.l1 = table_right.r1) - -> Seq Scan on table_left - Filter: (NOT (l1 IS NULL)) + -> Result + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: table_right.r1 + -> Seq Scan on table_right -> Hash - -> Result - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: table_right.r1 - -> Seq Scan on table_right + -> Seq Scan on table_left + Filter: (NOT (l1 IS NULL)) Optimizer: GPORCA (11 rows) @@ -3757,16 +3769,16 @@ select * from table_left where exists (select 1 from table_right where l1 = r1); (1 row) explain (costs off) select * from table_left where l1 in (select r1 from table_right); - QUERY PLAN ------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join + -> Hash Right Semi Join Hash Cond: (table_left.l1 = table_right.r1) - -> Seq Scan on table_left + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: table_right.r1 + -> Seq Scan on table_right -> Hash - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: table_right.r1 - -> Seq Scan on table_right + -> Seq Scan on table_left Optimizer: GPORCA (9 rows) @@ -3829,19 +3841,19 @@ insert into table_right select i, i from generate_series(1, 299) i; insert into table_right select 1, 1 from generate_series(1, 100) i; analyze table_right; explain (costs off) select * from table_left where exists (select 1 from table_right where l1 = r1); - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join + -> Hash Right Semi Join Hash Cond: (table_left.l1 = table_right.r1) - -> Seq Scan on table_left - Filter: (NOT (l1 IS NULL)) + -> Result + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: table_right.r1 + -> Dynamic Seq Scan on table_right + Number of partitions to scan: 3 (out of 3) -> Hash - -> Result - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: table_right.r1 - -> Dynamic Seq Scan on table_right - Number of partitions to scan: 3 (out of 3) + -> Seq Scan on table_left + Filter: (NOT (l1 IS NULL)) Optimizer: GPORCA (12 rows) @@ -3852,17 +3864,17 @@ select * from table_left where exists (select 1 from table_right where l1 = r1); (1 row) explain (costs off) select * from table_left where l1 in (select r1 from table_right); - QUERY PLAN ----------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join + -> Hash Right Semi Join Hash Cond: (table_left.l1 = table_right.r1) - -> Seq Scan on table_left + -> Redistribute Motion 3:3 (slice2; segments: 3) + Hash Key: table_right.r1 + -> Dynamic Seq Scan on table_right + Number of partitions to scan: 3 (out of 3) -> Hash - -> Redistribute Motion 3:3 (slice2; segments: 3) - Hash Key: table_right.r1 - -> Dynamic Seq Scan on table_right - Number of partitions to scan: 3 (out of 3) + -> Seq Scan on table_left Optimizer: GPORCA (10 rows) @@ -3925,9 +3937,9 @@ explain (costs off) select foo.a from foo where foo.a <= GREATEST(foo.b, (SELECT select foo.a from foo where foo.a <= GREATEST(foo.b, (SELECT 1), NULL); a --- + 1 2 3 - 1 (3 rows) explain (costs off) select least((select 5), greatest(b, NULL, (select 1)), a) from foo; @@ -4081,7 +4093,7 @@ explain (costs off) select t1.a from outer_foo t1, LATERAL(SELECT distinct t2. -> Materialize -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on inner_bar t2 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (13 rows) explain (costs off) select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q; @@ -4098,7 +4110,7 @@ explain (costs off) select t1.a from outer_foo t1, LATERAL(SELECT distinct t2. -> Materialize -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on inner_bar t2 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (12 rows) select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q order by 1; @@ -4140,7 +4152,7 @@ select * from t where a > (select count(1) from cte where x > t.a + random()); -> Materialize -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on inner_bar t2 - Optimizer: Postgres-based planner + Optimizer: Postgres query optimizer (22 rows) with cte(x) as (select t1.a from outer_foo t1, LATERAL(SELECT distinct t2.a from inner_bar t2 where t1.b=t2.b) q order by 1) diff --git a/src/test/regress/expected/subselect_optimizer.out b/src/test/regress/expected/subselect_optimizer.out index 53ac286306f..c2a96f0e82b 100644 --- a/src/test/regress/expected/subselect_optimizer.out +++ b/src/test/regress/expected/subselect_optimizer.out @@ -84,6 +84,8 @@ CREATE TABLE SUBSELECT_TBL ( f2 integer, f3 float ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO SUBSELECT_TBL VALUES (1, 2, 3); INSERT INTO SUBSELECT_TBL VALUES (2, 3, 4); INSERT INTO SUBSELECT_TBL VALUES (3, 4, 5); @@ -95,14 +97,14 @@ INSERT INTO SUBSELECT_TBL VALUES (8, 9, NULL); SELECT * FROM SUBSELECT_TBL; f1 | f2 | f3 ----+----+---- - 1 | 1 | 1 - 1 | 2 | 3 - 2 | 2 | 2 2 | 3 | 4 - 3 | 3 | 3 3 | 4 | 5 - 6 | 7 | 8 + 2 | 2 | 2 + 3 | 3 | 3 8 | 9 | + 1 | 2 | 3 + 1 | 1 | 1 + 6 | 7 | 8 (8 rows) -- Uncorrelated subselects @@ -118,12 +120,12 @@ SELECT f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL); Uncorrelated Field -------------------- - 1 - 1 - 2 2 3 + 2 3 + 1 + 1 (6 rows) SELECT f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL @@ -131,12 +133,12 @@ SELECT f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL f2 IN (SELECT f1 FROM SUBSELECT_TBL)); Uncorrelated Field -------------------- - 1 - 1 - 2 2 3 + 2 3 + 1 + 1 (6 rows) SELECT f1, f2 @@ -145,9 +147,9 @@ SELECT f1, f2 WHERE f3 IS NOT NULL); f1 | f2 ----+---- + 8 | 9 1 | 2 6 | 7 - 8 | 9 (3 rows) -- Correlated subselects @@ -156,12 +158,12 @@ SELECT f1 AS "Correlated Field", f2 AS "Second Field" WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE f1 = upper.f1); Correlated Field | Second Field ------------------+-------------- - 1 | 1 - 1 | 2 - 2 | 2 2 | 3 - 3 | 3 3 | 4 + 2 | 2 + 3 | 3 + 1 | 2 + 1 | 1 (6 rows) SELECT f1 AS "Correlated Field", f3 AS "Second Field" @@ -170,11 +172,11 @@ SELECT f1 AS "Correlated Field", f3 AS "Second Field" (SELECT f2 FROM SUBSELECT_TBL WHERE CAST(upper.f2 AS float) = f3); Correlated Field | Second Field ------------------+-------------- - 1 | 1 - 2 | 2 2 | 4 - 3 | 3 3 | 5 + 2 | 2 + 3 | 3 + 1 | 1 (5 rows) SELECT f1 AS "Correlated Field", f3 AS "Second Field" @@ -183,10 +185,10 @@ SELECT f1 AS "Correlated Field", f3 AS "Second Field" WHERE f2 = CAST(f3 AS integer)); Correlated Field | Second Field ------------------+-------------- + 6 | 8 1 | 3 2 | 4 3 | 5 - 6 | 8 (4 rows) SELECT f1 AS "Correlated Field" @@ -197,8 +199,8 @@ SELECT f1 AS "Correlated Field" ------------------ 1 2 - 2 3 + 2 3 (5 rows) @@ -216,6 +218,8 @@ SELECT COUNT(*) FROM (SELECT DISTINCT name FROM road); (1 row) SELECT * FROM (SELECT * FROM int4_tbl), (VALUES (123456)) WHERE f1 = column1; +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. f1 | column1 --------+--------- 123456 | 123456 @@ -226,13 +230,15 @@ SELECT * FROM (SELECT * FROM (SELECT abs(f1) AS a1 FROM int4_tbl)), (SELECT * FROM int8_tbl) WHERE a1 < 10 AND q1 > a1 ORDER BY q1, q2; SELECT * FROM view_unnamed_ss; +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. a1 | q1 | q2 ----+------------------+------------------- 0 | 123 | 456 0 | 123 | 4567890123456789 + 0 | 4567890123456789 | -4567890123456789 0 | 4567890123456789 | 123 0 | 4567890123456789 | 4567890123456789 - 0 | 4567890123456789 | -4567890123456789 (5 rows) \sv view_unnamed_ss @@ -272,14 +278,16 @@ SELECT ss.f1 AS "Correlated Field", ss.f3 AS "Second Field" FROM SUBSELECT_TBL ss WHERE f1 NOT IN (SELECT f1+1 FROM INT4_TBL WHERE f1 != ss.f1 AND f1 < 2147483647); +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. Correlated Field | Second Field ------------------+-------------- - 2 | 2 2 | 4 - 3 | 3 3 | 5 - 6 | 8 + 2 | 2 + 3 | 3 8 | + 6 | 8 (6 rows) select q1, float8(count(*)) / (select count(*) from int8_tbl) @@ -309,23 +317,27 @@ explain (verbose, costs off) select '42' union all select '43'; Output: '42'::text -> Result Output: '43'::text -(5 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(7 rows) explain (verbose, costs off) select '42' union all select 43; - QUERY PLAN --------------------- + QUERY PLAN +---------------------------- Append -> Result Output: 42 -> Result Output: 43 -(5 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(7 rows) -- check materialization of an initplan reference (bug #14524) explain (verbose, costs off) select 1 = all (select (select 1)); - QUERY PLAN ---------------------------------------- + QUERY PLAN +------------------------------------- Nested Loop Left Join Output: (1 = (1)) Join Filter: true @@ -342,8 +354,9 @@ select 1 = all (select (select 1)); Output: (1) -> Result Output: 1 - Optimizer: Pivotal Optimizer (GPORCA) -(17 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(18 rows) select 1 = all (select (select 1)); ?column? @@ -357,21 +370,25 @@ select 1 = all (select (select 1)); explain (costs off) select * from int4_tbl o where exists (select 1 from int4_tbl i where i.f1=o.f1 limit null); - QUERY PLAN ------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) - -> Hash Semi Join + -> Hash Right Semi Join Hash Cond: (o.f1 = i.f1) - -> Seq Scan on int4_tbl o - Filter: (NOT (f1 IS NULL)) + -> Seq Scan on int4_tbl i -> Hash - -> Seq Scan on int4_tbl i - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + -> Seq Scan on int4_tbl o + Filter: (NOT (f1 IS NULL)) + Optimizer: GPORCA (8 rows) explain (costs off) select * from int4_tbl o where not exists (select 1 from int4_tbl i where i.f1=o.f1 limit 1); +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN -------------------------------------------------------------------------- Result @@ -386,14 +403,16 @@ select * from int4_tbl o where not exists -> Materialize -> Gather Motion 3:1 (slice2; segments: 3) -> Seq Scan on int4_tbl i - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (13 rows) explain (costs off) select * from int4_tbl o where exists (select 1 from int4_tbl i where i.f1=o.f1 limit 0); - QUERY PLAN ------------------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +-------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) -> Nested Loop Semi Join Join Filter: true @@ -402,7 +421,7 @@ select * from int4_tbl o where exists -> Limit -> Result One-Time Filter: false - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 + Optimizer: GPORCA (9 rows) -- @@ -447,7 +466,11 @@ select count(distinct ss.ten) from -- Luca Pireddu and Michael Fuhr. -- CREATE TEMP TABLE foo (id integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. CREATE TEMP TABLE bar (id1 integer, id2 integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO foo VALUES (1); INSERT INTO bar VALUES (1, 1); INSERT INTO bar VALUES (2, 2); @@ -507,6 +530,8 @@ CREATE TABLE orderstest ( po_ref integer, ordercanceled boolean ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'approver_ref' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. INSERT INTO orderstest VALUES (1, 1, false); INSERT INTO orderstest VALUES (66, 5, false); INSERT INTO orderstest VALUES (66, 6, false); @@ -557,7 +582,6 @@ FROM orderstest ord; SELECT * FROM orders_view; approver_ref | po_ref | ordercanceled | Approved | Status | Status_OK --------------+--------+---------------+----------+----------+----------- - 1 | 1 | f | --- | --- | --- 66 | 5 | f | Approved | PO | PO 66 | 6 | f | Approved | PO | PO 66 | 7 | f | Approved | PO | PO @@ -565,9 +589,10 @@ SELECT * FROM orders_view; 66 | 8 | f | Approved | PO | PO 66 | 1 | f | Approved | Approved | Approved 77 | 1 | f | Approved | Approved | Approved - 1 | 1 | f | --- | --- | --- 66 | 1 | f | Approved | Approved | Approved 1 | 1 | f | --- | --- | --- + 1 | 1 | f | --- | --- | --- + 1 | 1 | f | --- | --- | --- (11 rows) DROP TABLE orderstest cascade; @@ -580,12 +605,16 @@ create temp table parts ( partnum text, cost float8 ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'partnum' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp table shipped ( ttype char(2), ordnum int4, partnum text, value float8 ); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'ttype' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp view shipped_view as select * from shipped where ttype = 'wt'; create rule shipped_view_insert as on insert to shipped_view do instead @@ -606,6 +635,8 @@ update shipped_view set value = 11 from int4_tbl a join int4_tbl b on (a.f1 = (select f1 from int4_tbl c where c.f1=b.f1)) where ordnum = a.f1; +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. select * from shipped_view; ttype | ordnum | partnum | value -------+--------+---------+------- @@ -615,11 +646,13 @@ select * from shipped_view; select f1, ss1 as relabel from (select *, (select sum(f1) from int4_tbl b where f1 >= a.f1) as ss1 from int4_tbl a) ss; +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. f1 | relabel -------------+------------ - 0 | 2147607103 123456 | 2147607103 -123456 | 2147483647 + 0 | 2147607103 2147483647 | 2147483647 -2147483647 | 0 (5 rows) @@ -655,15 +688,19 @@ select * from ( -- pointless.) -- create temp table numeric_table (num_col numeric); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'num_col' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into numeric_table values (1), (1.000000000000000000001), (2), (3); create temp table float_table (float_col float8); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'float_col' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into float_table values (1), (2), (3); select * from float_table where float_col in (select num_col from numeric_table); float_col ----------- - 1 2 + 1 3 (3 rows) @@ -672,9 +709,9 @@ select * from numeric_table num_col ------------------------- 1 - 2 1.000000000000000000001 3 + 2 (4 rows) -- @@ -705,6 +742,8 @@ from tc; -- Test case for 8.3 "failed to locate grouping columns" bug -- create temp table t1 (f1 numeric(14,0), f2 varchar(30)); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. select * from (select distinct f1, f2, (select f2 from t1 x where x.f1 = up.f1) as fs from t1 up) ss @@ -717,6 +756,8 @@ group by f1,f2,fs; -- Test case for bug #5514 (mishandling of whole-row Vars in subselects) -- create temp table table_a(id integer); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into table_a values (42); create temp view view_a as select * from table_a; select view_a from view_a; @@ -764,10 +805,10 @@ with q as (select max(f1) from int4_tbl group by f1 order by f1) select q from q; -- order none q --------------- - (-2147483647) (-123456) - (0) (123456) + (-2147483647) + (0) (2147483647) (5 rows) @@ -799,6 +840,8 @@ from from int8_tbl) sq0 join int4_tbl i4 on dummy = i4.f1; +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. qq1 ----- (0 rows) @@ -821,19 +864,23 @@ on conflict (key) do update set val = (select u from aa) returning *; key | val -----+---------- - 1 | int4_tbl 999 | y + 1 | int4_tbl (2 rows) -- -- Test case for cross-type partial matching in hashed subplan (bug #7597) -- create temp table outer_7597 (f1 int4, f2 int4); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into outer_7597 values (0, 0); insert into outer_7597 values (1, 0); insert into outer_7597 values (0, null); insert into outer_7597 values (1, null); create temp table inner_7597(c1 int8, c2 int8); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into inner_7597 values(0, null); select * from outer_7597 where (f1, f2) not in (select * from inner_7597); f1 | f2 @@ -848,11 +895,15 @@ select * from outer_7597 where (f1, f2) not in (select * from inner_7597); -- (otherwise it would error in texteq()) -- create temp table outer_text (f1 text, f2 text); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'f1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into outer_text values ('a', 'a'); insert into outer_text values ('b', 'a'); insert into outer_text values ('a', null); insert into outer_text values ('b', null); create temp table inner_text (c1 text, c2 text); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into inner_text values ('a', null); insert into inner_text values ('123', '456'); select * from outer_text where (f1, f2) not in (select * from inner_text); @@ -878,7 +929,9 @@ select 'foo'::text in (select 'bar'::name union all select 'bar'::name); Output: 'bar'::name -> Result Output: 'bar'::name -(8 rows) + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer +(10 rows) select 'foo'::text in (select 'bar'::name union all select 'bar'::name); ?column? @@ -901,7 +954,9 @@ select row(row(row(1))) = any (select row(row(1))); Output: (ROW(ROW(1))) -> Result Output: ROW(ROW(1)) -(8 rows) + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer +(9 rows) select row(row(row(1))) = any (select row(row(1))); ?column? @@ -935,8 +990,8 @@ language sql as 'select $1::text = $2'; create operator = (procedure=bogus_int8_text_eq, leftarg=int8, rightarg=text); explain (costs off) select * from int8_tbl where q1 in (select c1 from inner_text); - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> GroupAggregate Group Key: int8_tbl.q1, int8_tbl.q2, int8_tbl.ctid, int8_tbl.gp_segment_id @@ -949,7 +1004,7 @@ select * from int8_tbl where q1 in (select c1 from inner_text); -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on inner_text -> Seq Scan on int8_tbl - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) select * from int8_tbl where q1 in (select c1 from inner_text); @@ -965,8 +1020,8 @@ create or replace function bogus_int8_text_eq(int8, text) returns boolean language sql as 'select $1::text = $2 and $1::text = $2'; explain (costs off) select * from int8_tbl where q1 in (select c1 from inner_text); - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> GroupAggregate Group Key: int8_tbl.q1, int8_tbl.q2, int8_tbl.ctid, int8_tbl.gp_segment_id @@ -979,7 +1034,7 @@ select * from int8_tbl where q1 in (select c1 from inner_text); -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on inner_text -> Seq Scan on int8_tbl - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) select * from int8_tbl where q1 in (select c1 from inner_text); @@ -995,8 +1050,8 @@ create or replace function bogus_int8_text_eq(int8, text) returns boolean language sql as 'select $2 = $1::text'; explain (costs off) select * from int8_tbl where q1 in (select c1 from inner_text); - QUERY PLAN ------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) -> GroupAggregate Group Key: int8_tbl.q1, int8_tbl.q2, int8_tbl.ctid, int8_tbl.gp_segment_id @@ -1009,7 +1064,7 @@ select * from int8_tbl where q1 in (select c1 from inner_text); -> Broadcast Motion 3:3 (slice3; segments: 3) -> Seq Scan on inner_text -> Seq Scan on int8_tbl - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (13 rows) select * from int8_tbl where q1 in (select c1 from inner_text); @@ -1026,8 +1081,8 @@ rollback; -- to get rid of the bogus operator explain (costs off) select count(*) from tenk1 t where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0); - QUERY PLAN ------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------------ Finalize Aggregate -> Gather Motion 3:1 (slice1; segments: 3) -> Partial Aggregate @@ -1042,7 +1097,7 @@ where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0); -> HashAggregate Group Key: k.unique1 -> Seq Scan on tenk1 k - Optimizer: Pivotal Optimizer (GPORCA) + Optimizer: GPORCA (15 rows) select count(*) from tenk1 t @@ -1087,8 +1142,12 @@ where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0) -- It's possible for the same EXISTS to get resolved both ways create temp table exists_tbl (c1 int, c2 int, c3 int) partition by list (c1); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c1' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp table exists_tbl_null partition of exists_tbl for values in (null); +NOTICE: table has parent, setting distribution columns to match parent table create temp table exists_tbl_def partition of exists_tbl default; +NOTICE: table has parent, setting distribution columns to match parent table insert into exists_tbl select x, x/2, x+1 from generate_series(0,10) x; analyze exists_tbl; explain (costs off) @@ -1119,12 +1178,12 @@ select * from exists_tbl t1 where (exists(select 1 from exists_tbl t2 where t1.c1 = t2.c2) or c3 < 0); c1 | c2 | c3 ----+----+---- - 0 | 0 | 1 - 1 | 0 | 2 + 5 | 2 | 6 2 | 1 | 3 3 | 1 | 4 4 | 2 | 5 - 5 | 2 | 6 + 0 | 0 | 1 + 1 | 0 | 2 (6 rows) -- @@ -1160,14 +1219,15 @@ explain (verbose, costs off) InitPlan 2 (returns $1) -> Result Output: 'regression'::name + Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(9 rows) +(10 rows) explain (verbose, costs off) select x, x from (select (select random()) as x from (values(1),(2)) v(y)) ss; - QUERY PLAN ------------------------------------ + QUERY PLAN +------------------------------------- Subquery Scan on ss Output: ss.x, ss.x -> Values Scan on "*VALUES*" @@ -1175,8 +1235,9 @@ explain (verbose, costs off) InitPlan 1 (returns $0) -> Result Output: random() + Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(8 rows) +(9 rows) explain (verbose, costs off) select x, x from @@ -1193,9 +1254,9 @@ explain (verbose, costs off) -> Result Output: 'regression'::name One-Time Filter: ("*VALUES*".column1 = "*VALUES*".column1) + Settings: optimizer = 'on' Optimizer: Postgres query optimizer - Settings: optimizer=on -(9 rows) +(12 rows) explain (verbose, costs off) select x, x from @@ -1210,8 +1271,9 @@ explain (verbose, costs off) -> Result Output: random() One-Time Filter: ("*VALUES*".column1 = "*VALUES*".column1) + Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(9 rows) +(10 rows) -- -- Test rescan of a hashed subplan (the use of random() is to prevent the @@ -1295,8 +1357,8 @@ select sum(o.four), sum(ss.a) from select * from x ) ss where o.ten = 1; - QUERY PLAN ---------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------- Finalize Aggregate -> Gather Motion 3:1 (slice1; segments: 3) -> Partial Aggregate @@ -1333,7 +1395,11 @@ where o.ten = 1; -- Check we don't misoptimize a NOT IN where the subquery returns no rows. -- create temp table notinouter (a int); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. create temp table notininner (b int not null); +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'b' as the Apache Cloudberry data distribution key for this table. +HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. insert into notinouter values (null), (1); select * from notinouter where a not in (select b from notininner); a @@ -1406,8 +1472,9 @@ select * from Output: CASE WHEN (3 = column1) THEN 1 ELSE 0 END, CASE WHEN (column1 IS NULL) THEN 1 ELSE 0 END -> Result Output: false - Optimizer: Pivotal Optimizer (GPORCA) -(15 rows) + Settings: optimizer = 'on' + Optimizer: GPORCA +(16 rows) select * from (values @@ -1428,6 +1495,8 @@ explain (verbose, costs off) select * from int4_tbl where (case when f1 in (select unique1 from tenk1 a) then f1 else null end) in (select ten from tenk1 b); +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. QUERY PLAN -------------------------------------------------------------- Result @@ -1453,13 +1522,15 @@ select * from int4_tbl where Output: b.ten -> Seq Scan on public.tenk1 b Output: b.ten - Optimizer: Pivotal Optimizer (GPORCA) version 3.83.0 - Settings: optimizer=on + Settings: optimizer = 'on' + Optimizer: GPORCA (25 rows) select * from int4_tbl where (case when f1 in (select unique1 from tenk1 a) then f1 else null end) in (select ten from tenk1 b); +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. f1 ---- 0 @@ -1471,28 +1542,29 @@ select * from int4_tbl where explain (verbose, costs off) select * from int4_tbl o where (f1, f1) in (select f1, generate_series(1,50) / 10 g from int4_tbl i group by f1); - QUERY PLAN -------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: o.f1 - -> Hash Semi Join + -> Hash Right Semi Join Output: o.f1 - Hash Cond: (o.f1 = "ANY_subquery".f1) - -> Seq Scan on public.int4_tbl o - Output: o.f1 - -> Hash + Hash Cond: ("ANY_subquery".f1 = o.f1) + -> Subquery Scan on "ANY_subquery" Output: "ANY_subquery".f1, "ANY_subquery".g - -> Subquery Scan on "ANY_subquery" - Output: "ANY_subquery".f1, "ANY_subquery".g - Filter: ("ANY_subquery".f1 = "ANY_subquery".g) - -> Result - Output: i.f1, ((generate_series(1, 50)) / 10) - -> ProjectSet - Output: generate_series(1, 50), i.f1 - -> Seq Scan on public.int4_tbl i - Output: i.f1 + Filter: ("ANY_subquery".f1 = "ANY_subquery".g) + -> Result + Output: i.f1, ((generate_series(1, 50)) / 10) + -> ProjectSet + Output: generate_series(1, 50), i.f1 + -> Seq Scan on public.int4_tbl i + Output: i.f1 + -> Hash + Output: o.f1 + -> Seq Scan on public.int4_tbl o + Output: o.f1 + Settings: optimizer = 'on' Optimizer: Postgres query optimizer -(19 rows) +(20 rows) select * from int4_tbl o where (f1, f1) in (select f1, generate_series(1,50) / 10 g from int4_tbl i group by f1); @@ -1512,9 +1584,9 @@ select (select q from from int4_tbl; q ----------- - (4,5,6.0) (4,5,6.0) (1,2,3) + (4,5,6.0) (1,2,3) (4,5,6.0) (5 rows) @@ -1556,7 +1628,9 @@ where b and f1 >= 0; Output: random() -> Result Output: true, 2 -(21 rows) + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer +(22 rows) select * from int4_tbl i4, @@ -1570,10 +1644,10 @@ where b and f1 >= 0; f1 | b | id ------------+---+---- 0 | t | 2 - 123456 | t | 1 - 123456 | t | 2 2147483647 | t | 1 2147483647 | t | 2 + 123456 | t | 1 + 123456 | t | 2 (5 rows) -- @@ -1628,8 +1702,8 @@ select * from Output: 9, unnest('{1,2,3,11,12,13}'::integer[]) -> Result Output: true - Optimizer: Pivotal Optimizer (GPORCA) - Settings: optimizer=on + Settings: optimizer = 'on' + Optimizer: GPORCA (9 rows) select * from @@ -1666,13 +1740,18 @@ select * from Output: 9, unnest('{1,2,3,11,12,13}'::integer[]) -> Result Output: true - Optimizer: Pivotal Optimizer (GPORCA) - Settings: optimizer=on + Settings: optimizer = 'on' + Optimizer: GPORCA (9 rows) select * from (select 9 as x, unnest(array[1,2,3,11,12,13]) as u) ss where tattle(x, 8); +NOTICE: x = 9, y = 8 +NOTICE: x = 9, y = 8 +NOTICE: x = 9, y = 8 +NOTICE: x = 9, y = 8 +NOTICE: x = 9, y = 8 NOTICE: x = 9, y = 8 x | u ---+---- @@ -1698,8 +1777,8 @@ select * from Output: 9, unnest('{1,2,3,11,12,13}'::integer[]) -> Result Output: true - Optimizer: Pivotal Optimizer (GPORCA) - Settings: optimizer=on + Settings: optimizer = 'on' + Optimizer: GPORCA (9 rows) select * from @@ -1806,8 +1885,8 @@ select relname::information_schema.sql_identifier as tname, * from (select * from pg_class c) ss1) ss2 right join pg_attribute a on a.attrelid = ss2.oid where tname = 'tenk1' and attnum = 1; - QUERY PLAN ------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------- Hash Join Hash Cond: (a.attrelid = c.oid) -> Seq Scan on pg_attribute a @@ -1815,6 +1894,7 @@ where tname = 'tenk1' and attnum = 1; -> Hash -> Index Scan using pg_class_relname_nsp_index on pg_class c Index Cond: (relname = 'tenk1'::name) + Optimizer: Postgres query optimizer (8 rows) select tname, attname from ( @@ -1835,8 +1915,8 @@ select t1.ten, sum(x) from ) ss on t1.unique1 = ss.fivethous group by t1.ten order by t1.ten; - QUERY PLAN ----------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Output: t1.ten, (sum((t1.ten + t2.ten))) Merge Key: t1.ten @@ -1864,6 +1944,8 @@ order by t1.ten; Output: t1.ten, t1.unique1 -> Seq Scan on public.tenk1 t1 Output: t1.ten, t1.unique1 + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer (29 rows) select t1.ten, sum(x) from @@ -1893,8 +1975,8 @@ select t1.q1, x from lateral (select t2.q1+t3.q1 as x, * from int8_tbl t3) t3 on t2.q2 = t3.q2) on t1.q2 = t2.q2 order by 1, 2; - QUERY PLAN --------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Output: t1.q1, ((t2.q1 + t3.q1)) Merge Key: t1.q1, ((t2.q1 + t3.q1)) @@ -1926,6 +2008,8 @@ order by 1, 2; Hash Key: t1.q2 -> Seq Scan on public.int8_tbl t1 Output: t1.q1, t1.q2 + Settings: optimizer = 'on' + Optimizer: Postgres query optimizer (33 rows) select t1.q1, x from @@ -1957,30 +2041,30 @@ set gp_cte_sharing to on; explain (verbose, costs off) with x as (select * from (select f1 from subselect_tbl) ss) select * from x where f1 = 1; - QUERY PLAN -------------------------------------------- + QUERY PLAN +--------------------------------------------------- Gather Motion 1:1 (slice1; segments: 1) Output: f1 -> Seq Scan on public.subselect_tbl Output: f1 Filter: (subselect_tbl.f1 = 1) - Optimizer: Pivotal Optimizer (GPORCA) - Settings: gp_cte_sharing=on, optimizer=on + Settings: optimizer = 'on', gp_cte_sharing = 'on' + Optimizer: GPORCA (7 rows) -- Explicitly request materialization explain (verbose, costs off) with x as materialized (select * from (select f1 from subselect_tbl) ss) select * from x where f1 = 1; - QUERY PLAN -------------------------------------------- + QUERY PLAN +--------------------------------------------------- Gather Motion 1:1 (slice1; segments: 1) Output: f1 -> Seq Scan on public.subselect_tbl Output: f1 Filter: (subselect_tbl.f1 = 1) - Optimizer: Pivotal Optimizer (GPORCA) - Settings: gp_cte_sharing=on, optimizer=on + Settings: optimizer = 'on', gp_cte_sharing = 'on' + Optimizer: GPORCA (7 rows) -- Stable functions are safe to inline @@ -1994,8 +2078,8 @@ select * from x where f1 = 1; -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1, 'regression'::name Filter: (subselect_tbl.f1 = 1) + Settings: optimizer = 'on', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer - Settings: optimizer=off (7 rows) -- Volatile functions prevent inlining @@ -2020,13 +2104,13 @@ select * from x where f1 = 1; Filter: (share0_ref2.f1 = 1) -> Shared Scan (share slice:id 1:0) Output: share0_ref2.f1, share0_ref2.random - Optimizer: Pivotal Optimizer (GPORCA) - Settings: gp_cte_sharing=on, optimizer=on + Settings: optimizer = 'on', gp_cte_sharing = 'on' + Optimizer: GPORCA (16 rows) create temporary sequence ts; create table vol_test(a int, b int); -NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Greenplum Database data distribution key for this table. +NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. explain (verbose, costs off) with x as (select * from (select a, nextval('ts') from vol_test) ss) @@ -2047,8 +2131,8 @@ select * from x where a = 1; Filter: (share0_ref2.a = 1) -> Shared Scan (share slice:id 1:0) Output: share0_ref2.a, share0_ref2.nextval - Optimizer: Pivotal Optimizer (GPORCA) - Settings: gp_cte_sharing=on, optimizer=on + Settings: optimizer = 'on', gp_cte_sharing = 'on' + Optimizer: GPORCA (16 rows) drop sequence ts; @@ -2061,15 +2145,15 @@ drop table vol_test; explain (verbose, costs off) with x as (select * from (select f1 from subselect_tbl for update) ss) select * from x where f1 = 1; - QUERY PLAN -------------------------------------------- + QUERY PLAN +--------------------------------------------------- Gather Motion 1:1 (slice1; segments: 1) Output: f1 -> Seq Scan on public.subselect_tbl Output: f1 Filter: (subselect_tbl.f1 = 1) - Optimizer: Pivotal Optimizer (GPORCA) - Settings: gp_cte_sharing=on, optimizer=on + Settings: optimizer = 'on', gp_cte_sharing = 'on' + Optimizer: GPORCA (7 rows) -- Multiply-referenced CTEs are inlined only when requested @@ -2097,7 +2181,7 @@ select * from x, x x2 where x.n = x2.n; Output: share0_ref1.f1, share0_ref1.n -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1, 'regression'::name - Settings: gp_cte_sharing=on, optimizer=on + Settings: optimizer = 'on', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer (21 rows) @@ -2123,8 +2207,8 @@ select * from x, x x2 where x.n = x2.n; Hash Key: ('regression'::name) -> Seq Scan on public.subselect_tbl subselect_tbl_1 Output: subselect_tbl_1.f1, 'regression'::name + Settings: optimizer = 'on', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer - Settings: gp_cte_sharing=on, optimizer=on (19 rows) -- Multiply-referenced CTEs can't be inlined if they contain outer self-refs @@ -2148,8 +2232,8 @@ select * from x; Output: x.a -> WorkTable Scan on x x_1 Output: x_1.a + Settings: optimizer = 'on', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer - Settings: gp_cte_sharing=on, optimizer=on (12 rows) with recursive x(a) as @@ -2193,8 +2277,8 @@ with recursive x(a) as select z.a || z.a as a from z where length(z.a || z.a) < 5)) select * from x; - QUERY PLAN --------------------------------------------------- + QUERY PLAN +--------------------------------------------------- Recursive Union -> Values Scan on "*VALUES*" Output: "*VALUES*".column1 @@ -2203,8 +2287,8 @@ select * from x; -> WorkTable Scan on x Output: x.a Filter: (length((x.a || x.a)) < 5) + Settings: optimizer = 'on', gp_cte_sharing = 'on' Optimizer: Postgres query optimizer - Settings: gp_cte_sharing=on, optimizer=on (10 rows) with recursive x(a) as @@ -2228,27 +2312,31 @@ select * from x; explain (verbose, costs off) with x as (select * from int4_tbl) select * from (with y as (select * from x) select * from y) ss; - QUERY PLAN -------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +--------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: f1 -> Seq Scan on public.int4_tbl Output: f1 - Optimizer: Pivotal Optimizer (GPORCA) - Settings: gp_cte_sharing=on, optimizer=on + Settings: optimizer = 'on', gp_cte_sharing = 'on' + Optimizer: GPORCA (6 rows) explain (verbose, costs off) with x as materialized (select * from int4_tbl) select * from (with y as (select * from x) select * from y) ss; - QUERY PLAN -------------------------------------------- +NOTICE: One or more columns in the following table(s) do not have statistics: int4_tbl +HINT: For non-partitioned tables, run analyze (). For partitioned tables, run analyze rootpartition (). See log for columns missing statistics. + QUERY PLAN +--------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: f1 -> Seq Scan on public.int4_tbl Output: f1 - Optimizer: Pivotal Optimizer (GPORCA) - Settings: gp_cte_sharing=on, optimizer=on + Settings: optimizer = 'on', gp_cte_sharing = 'on' + Optimizer: GPORCA (6 rows) -- Ensure that we inline the currect CTE when there are @@ -2256,26 +2344,26 @@ select * from (with y as (select * from x) select * from y) ss; explain (verbose, costs off) with x as (select 1 as y) select * from (with x as (select 2 as y) select * from x) ss; - QUERY PLAN -------------------------------------------- + QUERY PLAN +--------------------------------------------------- Result Output: 2 - Optimizer: Pivotal Optimizer (GPORCA) - Settings: gp_cte_sharing=on, optimizer=on + Settings: optimizer = 'on', gp_cte_sharing = 'on' + Optimizer: GPORCA (4 rows) -- Row marks are not pushed into CTEs explain (verbose, costs off) with x as (select * from subselect_tbl) select * from x for update; - QUERY PLAN -------------------------------------------- + QUERY PLAN +--------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: f1, f2, f3 -> Seq Scan on public.subselect_tbl Output: f1, f2, f3 - Optimizer: Pivotal Optimizer (GPORCA) - Settings: gp_cte_sharing=on, optimizer=on + Settings: optimizer = 'on', gp_cte_sharing = 'on' + Optimizer: GPORCA (6 rows) set gp_cte_sharing to off; @@ -2297,8 +2385,8 @@ select j, (select j from (select j) q2) from t group by i, j; - QUERY PLAN ------------------------------------------- + QUERY PLAN +---------------------------------------------------- Gather Motion 3:1 (slice1; segments: 3) Output: j, ((SubPlan 1)) -> GroupAggregate @@ -2314,8 +2402,9 @@ group by i, j; Output: t.j -> Result Output: true + Settings: optimizer = 'on', gp_cte_sharing = 'off' Optimizer: GPORCA -(16 rows) +(17 rows) select j, (select j from (select j) q2) @@ -2361,8 +2450,9 @@ group by j, q1; Output: t.j -> Result Output: true + Settings: optimizer = 'on', gp_cte_sharing = 'off' Optimizer: GPORCA -(21 rows) +(22 rows) select j, 1 as c, (select j from (select j) q2) q1 @@ -2379,8 +2469,8 @@ group by j, q1; -- should correctly process args of the aggregation during normalization. explain (verbose, costs off) select (select max((select t.i))) from t; - QUERY PLAN ------------------------------------------------- + QUERY PLAN +---------------------------------------------------- Finalize Aggregate Output: (SubPlan 2) -> Gather Motion 3:1 (slice1; segments: 3) @@ -2397,8 +2487,9 @@ select (select max((select t.i))) from t; Output: max((SubPlan 1)) -> Result Output: true + Settings: optimizer = 'on', gp_cte_sharing = 'off' Optimizer: GPORCA -(17 rows) +(18 rows) select (select max((select t.i))) from t; max diff --git a/src/test/regress/expected/table_functions.out b/src/test/regress/expected/table_functions.out index 834e7c643b1..0921bdd1df9 100644 --- a/src/test/regress/expected/table_functions.out +++ b/src/test/regress/expected/table_functions.out @@ -329,59 +329,59 @@ HINT: No function matches the given name and argument types. You might need to SELECT row(a+5, b)::example from example; row ------------------- - (6," value1.1/4") - (8," value3.1/2") - (6," value1.2/4") - (8," value3.2/2") - (6," value1.3/4") - (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") + (6," value1.1/4") + (6," value1.2/4") + (6," value1.3/4") + (6," value1.4/4") (10 rows) SELECT scalar_tf_1(5); scalar_tf_1 ------------------- - (6," value1.1/4") - (8," value3.1/2") - (6," value1.2/4") - (8," value3.2/2") - (6," value1.3/4") - (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") + (6," value1.1/4") + (6," value1.2/4") + (6," value1.3/4") + (6," value1.4/4") (10 rows) SELECT scalar_tf_2(5); scalar_tf_2 ------------------- - (6," value1.1/4") - (8," value3.1/2") - (6," value1.2/4") - (8," value3.2/2") - (6," value1.3/4") - (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") + (6," value1.1/4") + (6," value1.2/4") + (6," value1.3/4") + (6," value1.4/4") (10 rows) SELECT scalar_tf_3(5); scalar_tf_3 ------------------- (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (10 rows) @@ -389,29 +389,29 @@ SELECT scalar_tf_3(5); SELECT scalar_tf_4(5); scalar_tf_4 ------------------- - (7," value2.1/3") - (9," value4.1/1") - (7," value2.2/3") - (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") + (7," value2.1/3") + (8," value3.1/2") + (9," value4.1/1") + (7," value2.2/3") + (8," value3.2/2") + (7," value2.3/3") (10 rows) SELECT scalar_tf_5(5); scalar_tf_5 ------------------- (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (10 rows) @@ -420,13 +420,13 @@ SELECT scalar_tf_6(5); scalar_tf_6 ------------------- (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (10 rows) @@ -435,13 +435,13 @@ SELECT scalar_tf_1((select 5)); scalar_tf_1 ------------------- (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (10 rows) @@ -449,76 +449,76 @@ SELECT scalar_tf_1((select 5)); SELECT scalar_tf_2((select 5)); scalar_tf_2 ------------------- - (6," value1.1/4") - (8," value3.1/2") - (6," value1.2/4") - (8," value3.2/2") - (6," value1.3/4") - (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") + (6," value1.1/4") + (6," value1.2/4") + (6," value1.3/4") + (6," value1.4/4") (10 rows) SELECT scalar_tf_3((select 5)); scalar_tf_3 ------------------- - (7," value2.1/3") - (9," value4.1/1") - (7," value2.2/3") - (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") + (7," value2.1/3") + (8," value3.1/2") + (9," value4.1/1") + (7," value2.2/3") + (8," value3.2/2") + (7," value2.3/3") (10 rows) SELECT scalar_tf_4((select 5)); scalar_tf_4 ------------------- - (6," value1.1/4") - (8," value3.1/2") - (6," value1.2/4") - (8," value3.2/2") - (6," value1.3/4") - (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") + (6," value1.1/4") + (6," value1.2/4") + (6," value1.3/4") + (6," value1.4/4") (10 rows) SELECT scalar_tf_5((select 5)); scalar_tf_5 ------------------- - (6," value1.1/4") - (8," value3.1/2") - (6," value1.2/4") - (8," value3.2/2") - (6," value1.3/4") - (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") + (6," value1.1/4") + (6," value1.2/4") + (6," value1.3/4") + (6," value1.4/4") (10 rows) SELECT scalar_tf_6((select 5)); scalar_tf_6 ------------------- - (7," value2.1/3") - (9," value4.1/1") - (7," value2.2/3") - (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") + (7," value2.1/3") + (8," value3.1/2") + (9," value4.1/1") + (7," value2.2/3") + (8," value3.2/2") + (7," value2.3/3") (10 rows) -- end equivalent @@ -1348,9 +1348,9 @@ SELECT a from multiset_setof_value( TABLE(SELECT 1) ) as a; -- end equivalent -- ERROR: Table Functions do not currently support SFRM_Materialize SELECT * FROM multiset_materialize_good( TABLE( SELECT * from example ) ); -ERROR: set-valued function called in context that cannot accept a set (seg1 slice1 @hostname@:40041 pid=12397) +ERROR: set-valued function called in context that cannot accept a set (seg0 slice1 172.18.0.2:7002 pid=30259) SELECT * FROM multiset_materialize_bad( TABLE( SELECT * from example ) ); -ERROR: table functions must use SFRM_ValuePerCall protocol (seg1 slice1 @hostname@:40041 pid=12397) +ERROR: table functions must use SFRM_ValuePerCall protocol (seg1 slice1 172.18.0.2:7003 pid=30250) -- name resolution rules should work correctly between scalar and anytable, -- i.e. there cannot be any automatic conversion. CREATE FUNCTION nameres(int) RETURNS int @@ -1416,11 +1416,11 @@ DROP FUNCTION nameres(anyelement); explain SELECT * FROM multiset_5( TABLE( SELECT * FROM example SCATTER BY a+1) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.23 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..3.23 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.12 rows=4 width=16) - Hash Key: (example.a + 1) - -> Seq Scan on example (cost=0.00..3.12 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.61 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.21 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.11 rows=3 width=20) + Hash Key: ((example.a + 1)) + -> Seq Scan on example (cost=0.00..1.04 rows=3 width=20) Optimizer: Postgres query optimizer (6 rows) @@ -1552,254 +1552,254 @@ SELECT * FROM multiset_5( TABLE(SELECT a, b from example)) where (a,b) in (selec -- end equivalent -- Explain a couple interesting cases explain SELECT * FROM multiset_5( TABLE (SELECT dbid, gpname FROM gp_id) ); - QUERY PLAN ------------------------------------------------------------------------ - Table Function Scan on multiset_5 (cost=0.00..1.11 rows=64 width=36) - -> Seq Scan on gp_id (cost=0.00..1.01 rows=8 width=66) - Settings: gp_segments_for_planner=8 + QUERY PLAN +---------------------------------------------------------------------- + Table Function Scan on multiset_5 (cost=0.00..1.02 rows=1 width=36) + -> Seq Scan on gp_id (cost=0.00..1.01 rows=1 width=66) + Optimizer: Postgres query optimizer (3 rows) explain SELECT * FROM multiset_5( TABLE (SELECT dbid, gpname FROM gp_id SCATTER BY dbid) ); QUERY PLAN ---------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.11 rows=4 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..1.11 rows=4 width=36) - -> Redistribute Motion 1:3 (slice2) (cost=0.00..1.01 rows=8 width=66) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.18 rows=9 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.06 rows=3 width=36) + -> Redistribute Motion 1:3 (slice2) (cost=0.00..1.03 rows=1 width=66) Hash Key: gp_id.dbid - -> Seq Scan on gp_id (cost=0.00..1.01 rows=8 width=66) - Settings: gp_segments_for_planner=8 + -> Seq Scan on gp_id (cost=0.00..1.01 rows=1 width=66) + Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT dbid, gpname FROM gp_id SCATTER RANDOMLY) ); QUERY PLAN ---------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.11 rows=4 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..1.11 rows=4 width=36) - -> Redistribute Motion 1:3 (slice2) (cost=0.00..1.01 rows=8 width=66) - -> Seq Scan on gp_id (cost=0.00..1.01 rows=8 width=66) - Settings: gp_segments_for_planner=8 + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.18 rows=9 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.06 rows=3 width=36) + -> Redistribute Motion 1:3 (slice2) (cost=0.00..1.03 rows=1 width=66) + -> Seq Scan on gp_id (cost=0.00..1.01 rows=1 width=66) + Optimizer: Postgres query optimizer (5 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.53 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (4 rows) explain SELECT * from multiset_5( TABLE (SELECT * FROM example ORDER BY a limit 10 ) ); - QUERY PLAN ------------------------------------------------------------------------------------------ - Table Function Scan on multiset_5 (cost=2.27..2.62 rows=80 width=36) - -> Limit (cost=2.27..2.49 rows=10 width=16) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.49 rows=5 width=16) + QUERY PLAN +------------------------------------------------------------------------------------------ + Table Function Scan on multiset_5 (cost=1.06..1.30 rows=10 width=36) + -> Limit (cost=1.06..1.20 rows=10 width=16) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.20 rows=10 width=16) Merge Key: example.a - -> Limit (cost=2.27..2.29 rows=5 width=16) - -> Sort (cost=2.27..2.29 rows=5 width=16) - Sort Key (Limit): example.a - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Limit (cost=1.06..1.07 rows=3 width=16) + -> Sort (cost=1.06..1.07 rows=3 width=16) + Sort Key: example.a + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (9 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example SCATTER BY a) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.53 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (4 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example SCATTER BY b) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..2.10 rows=5 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.60 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.20 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=3 width=16) Hash Key: example.b - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example SCATTER RANDOMLY) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..2.10 rows=5 width=16) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.60 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.20 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=3 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (5 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY a, b) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.42 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.42 rows=5 width=36) - -> Sort (cost=2.27..2.29 rows=5 width=16) + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.57 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.17 rows=10 width=36) + -> Sort (cost=1.06..1.07 rows=3 width=16) Sort Key: example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY a, b SCATTER BY a) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.42 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.42 rows=5 width=36) - -> Sort (cost=2.27..2.29 rows=5 width=16) + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.57 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.17 rows=10 width=36) + -> Sort (cost=1.06..1.07 rows=3 width=16) Sort Key: example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY b, a SCATTER BY b) ); QUERY PLAN ----------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.42 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.42 rows=5 width=36) - -> Sort (cost=2.27..2.29 rows=5 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.13..1.64 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.13..1.24 rows=10 width=36) + -> Sort (cost=1.13..1.14 rows=3 width=16) Sort Key: example.b, example.a - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..2.10 rows=5 width=16) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=3 width=16) Hash Key: example.b - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (8 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY b, a SCATTER RANDOMLY) ); QUERY PLAN ----------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.42 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.42 rows=5 width=36) - -> Sort (cost=2.27..2.29 rows=5 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.13..1.64 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.13..1.24 rows=10 width=36) + -> Sort (cost=1.13..1.14 rows=3 width=16) Sort Key: example.b, example.a - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..2.10 rows=5 width=16) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=3 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (7 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY a, b LIMIT 10 SCATTER BY a) ); - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.62 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.62 rows=5 width=36) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=2.27..2.49 rows=10 width=16) + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.84 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.44 rows=10 width=36) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.06..1.34 rows=3 width=16) Hash Key: example.a - -> Limit (cost=2.27..2.49 rows=10 width=16) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=2.27..2.49 rows=5 width=16) + -> Limit (cost=1.06..1.20 rows=10 width=16) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.06..1.20 rows=10 width=16) Merge Key: example.a, example.b - -> Limit (cost=2.27..2.29 rows=5 width=16) - -> Sort (cost=2.27..2.29 rows=5 width=16) - Sort Key (Limit): example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Limit (cost=1.06..1.07 rows=3 width=16) + -> Sort (cost=1.06..1.07 rows=3 width=16) + Sort Key: example.a, example.b + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (12 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY b, a LIMIT 10 SCATTER BY b) ); - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.62 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.62 rows=5 width=36) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=2.27..2.49 rows=10 width=16) + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.84 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.44 rows=10 width=36) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.06..1.34 rows=3 width=16) Hash Key: example.b - -> Limit (cost=2.27..2.49 rows=10 width=16) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=2.27..2.49 rows=5 width=16) + -> Limit (cost=1.06..1.20 rows=10 width=16) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.06..1.20 rows=10 width=16) Merge Key: example.b, example.a - -> Limit (cost=2.27..2.29 rows=5 width=16) - -> Sort (cost=2.27..2.29 rows=5 width=16) - Sort Key (Limit): example.b, example.a - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Limit (cost=1.06..1.07 rows=3 width=16) + -> Sort (cost=1.06..1.07 rows=3 width=16) + Sort Key: example.b, example.a + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (12 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY b, a LIMIT 10 SCATTER RANDOMLY) ); - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.62 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.62 rows=5 width=36) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=2.27..2.49 rows=10 width=16) - -> Limit (cost=2.27..2.49 rows=10 width=16) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=2.27..2.49 rows=5 width=16) + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.84 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.44 rows=10 width=36) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.06..1.34 rows=3 width=16) + -> Limit (cost=1.06..1.20 rows=10 width=16) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.06..1.20 rows=10 width=16) Merge Key: example.b, example.a - -> Limit (cost=2.27..2.29 rows=5 width=16) - -> Sort (cost=2.27..2.29 rows=5 width=16) - Sort Key (Limit): example.b, example.a - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Limit (cost=1.06..1.07 rows=3 width=16) + -> Sort (cost=1.06..1.07 rows=3 width=16) + Sort Key: example.b, example.a + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (11 rows) explain SELECT ARRAY(SELECT a FROM multiset_5( TABLE ( SELECT a, b from example)) order by a); - QUERY PLAN ------------------------------------------------------------------------------------------ - Result (cost=2.42..2.43 rows=1 width=0) + QUERY PLAN +------------------------------------------------------------------------------------------ + Result (cost=1.72..1.73 rows=1 width=32) InitPlan 1 (returns $0) (slice1) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=2.39..2.42 rows=5 width=4) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=1.30..1.72 rows=30 width=4) Merge Key: a - -> Sort (cost=2.39..2.42 rows=5 width=4) - Sort Key: multiset_5.a - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=4) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Sort (cost=1.30..1.32 rows=10 width=4) + Sort Key: a + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=4) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (9 rows) explain SELECT ARRAY(SELECT a FROM multiset_5( TABLE ( SELECT a, b from example order by a))); - QUERY PLAN ------------------------------------------------------------------------------------- - Result (cost=2.42..2.43 rows=1 width=0) + QUERY PLAN +------------------------------------------------------------------------------------- + Result (cost=1.57..1.58 rows=1 width=32) InitPlan 1 (returns $0) (slice1) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=2.27..2.42 rows=5 width=4) - -> Table Function Scan on multiset_5 (cost=2.27..2.42 rows=5 width=4) - -> Sort (cost=2.27..2.29 rows=5 width=16) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=1.06..1.57 rows=30 width=4) + -> Table Function Scan on multiset_5 (cost=1.06..1.17 rows=10 width=4) + -> Sort (cost=1.06..1.07 rows=3 width=16) Sort Key: example.a - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (8 rows) explain SELECT * FROM example where (a,b) in (select * from multiset_5( TABLE(SELECT a, b from example) )); - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=3.55..6.83 rows=10 width=16) - -> Hash Semi Join (cost=3.55..6.83 rows=4 width=16) - Hash Cond: example.a = a AND example.b = b - -> Seq Scan on example (cost=0.00..3.10 rows=4 width=16) - -> Hash (cost=3.40..3.40 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.40 rows=4 width=36) - Hash Key: a - -> Table Function Scan on multiset_5 (cost=0.00..3.20 rows=4 width=36) - -> Seq Scan on example example_1 (cost=0.00..3.10 rows=4 width=16) + QUERY PLAN +------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.08..2.66 rows=10 width=16) + -> Hash Right Semi Join (cost=1.08..2.53 rows=3 width=16) + Hash Cond: ((a = example.a) AND (b = example.b)) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.33 rows=10 width=36) + Hash Key: a + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example example_1 (cost=0.00..1.03 rows=3 width=16) + -> Hash (cost=1.03..1.03 rows=3 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (10 rows) explain SELECT * FROM example where (a,b) in (select * from multiset_5( TABLE(SELECT a, b from example scatter by b) )); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=3.55..6.83 rows=10 width=16) - -> Hash Semi Join (cost=3.55..6.83 rows=4 width=16) - Hash Cond: example.a = a AND example.b = b - -> Seq Scan on example (cost=0.00..3.10 rows=4 width=16) - -> Hash (cost=3.40..3.40 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.40 rows=4 width=36) - Hash Key: a - -> Table Function Scan on multiset_5 (cost=0.00..3.20 rows=4 width=36) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..3.10 rows=4 width=16) - Hash Key: example_1.b - -> Seq Scan on example example_1 (cost=0.00..3.10 rows=4 width=16) + QUERY PLAN +----------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=1.08..2.73 rows=10 width=16) + -> Hash Right Semi Join (cost=1.08..2.59 rows=3 width=16) + Hash Cond: ((a = example.a) AND (b = example.b)) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.40 rows=10 width=36) + Hash Key: a + -> Table Function Scan on multiset_5 (cost=0.00..1.20 rows=10 width=36) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.10 rows=3 width=16) + Hash Key: example_1.b + -> Seq Scan on example example_1 (cost=0.00..1.03 rows=3 width=16) + -> Hash (cost=1.03..1.03 rows=3 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (12 rows) explain SELECT * FROM multiset_5( TABLE(SELECT a, b from example)) where (a,b) in (select a,b from example); - QUERY PLAN ---------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=1.32..2.58 rows=4 width=36) - -> Hash Semi Join (cost=1.32..2.52 rows=1 width=36) - Hash Cond: ((a = example.a) AND (b = example.b)) - -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) - -> Seq Scan on example example_1 (cost=0.00..1.03 rows=3 width=16) - -> Hash (cost=1.17..1.17 rows=10 width=16) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.17 rows=10 width=16) - -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + QUERY PLAN +--------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=1.28..2.59 rows=4 width=36) + -> Hash Right Semi Join (cost=1.28..2.54 rows=1 width=36) + Hash Cond: ((example.a = a) AND (example.b = b)) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.17 rows=10 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + -> Hash (cost=1.13..1.13 rows=10 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example example_1 (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (9 rows) @@ -1820,107 +1820,107 @@ explain SELECT * FROM multiset_5( TABLE(SELECT a, b from example scatter by b)) (11 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * from example_r) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Seq Scan on example_r (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.53 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example_r (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (4 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * FROM example_r SCATTER by a||b) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.28 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..3.28 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.18 rows=4 width=16) - Hash Key: (example_r.a::text || example_r.b) - -> Seq Scan on example_r (cost=0.00..3.18 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.62 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.23 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.12 rows=3 width=48) + Hash Key: (((example_r.a)::text || example_r.b)) + -> Seq Scan on example_r (cost=0.00..1.06 rows=3 width=48) Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * FROM example_r SCATTER by b, a, a||b) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.28 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..3.28 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.18 rows=4 width=16) - Hash Key: example_r.b, example_r.a, (example_r.a::text || example_r.b) - -> Seq Scan on example_r (cost=0.00..3.18 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.62 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.23 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.12 rows=3 width=48) + Hash Key: example_r.b, example_r.a, (((example_r.a)::text || example_r.b)) + -> Seq Scan on example_r (cost=0.00..1.06 rows=3 width=48) Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * FROM example_r SCATTER RANDOMLY) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..2.10 rows=5 width=16) - -> Seq Scan on example_r (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.60 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.20 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=3 width=16) + -> Seq Scan on example_r (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (5 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example) ); QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.09..2.29 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.09..2.29 rows=4 width=36) - -> HashAggregate (cost=2.09..2.19 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.05..1.58 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.05..1.18 rows=10 width=36) + -> HashAggregate (cost=1.05..1.08 rows=3 width=16) Group Key: example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example SCATTER BY a) ); QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.09..2.29 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.09..2.29 rows=4 width=36) - -> HashAggregate (cost=2.09..2.19 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.05..1.58 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.05..1.18 rows=10 width=36) + -> HashAggregate (cost=1.05..1.08 rows=3 width=16) Group Key: example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a / 2, b FROM example SCATTER BY a / 2) ); QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.38..2.80 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.38..2.80 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.38..2.70 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.12..1.73 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.12..1.33 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.12..1.23 rows=3 width=16) Hash Key: ((example.a / 2)) - -> HashAggregate (cost=2.38..2.50 rows=4 width=16) + -> HashAggregate (cost=1.12..1.17 rows=3 width=16) Group Key: ((example.a / 2)), example.b - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..2.33 rows=4 width=16) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.11 rows=3 width=16) Hash Key: ((example.a / 2)), example.b - -> Seq Scan on example (cost=0.00..2.12 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.04 rows=3 width=16) Optimizer: Postgres query optimizer (10 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example SCATTER BY b) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.09..2.49 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.09..2.49 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.09..2.39 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.05..1.65 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.05..1.25 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.05..1.15 rows=3 width=16) Hash Key: example.b - -> HashAggregate (cost=2.09..2.19 rows=4 width=16) + -> HashAggregate (cost=1.05..1.08 rows=3 width=16) Group Key: example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (8 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example ORDER BY b, a SCATTER RANDOMLY) ); QUERY PLAN ----------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.62..2.74 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.62..2.74 rows=4 width=36) - -> Sort (cost=2.62..2.64 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.18..1.69 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.18..1.29 rows=10 width=36) + -> Sort (cost=1.18..1.19 rows=3 width=16) Sort Key: example.b, example.a - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.15..2.45 rows=4 width=16) - -> HashAggregate (cost=2.15..2.25 rows=4 width=16) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.05..1.15 rows=3 width=16) + -> HashAggregate (cost=1.05..1.08 rows=3 width=16) Group Key: example.b, example.a - -> Seq Scan on example (cost=0.00..2.10 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (9 rows) @@ -1940,28 +1940,28 @@ explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example ORDER explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example ORDER BY b, a SCATTER BY b) ); QUERY PLAN ----------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.62..2.74 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.62..2.74 rows=4 width=36) - -> Sort (cost=2.62..2.64 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.18..1.69 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.18..1.29 rows=10 width=36) + -> Sort (cost=1.18..1.19 rows=3 width=16) Sort Key: example.b, example.a - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.15..2.45 rows=4 width=16) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.05..1.15 rows=3 width=16) Hash Key: example.b - -> HashAggregate (cost=2.15..2.25 rows=4 width=16) + -> HashAggregate (cost=1.05..1.08 rows=3 width=16) Group Key: example.b, example.a - -> Seq Scan on example (cost=0.00..2.10 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (10 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example ORDER BY b, a LIMIT 2 SCATTER RANDOMLY) ); QUERY PLAN -------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=1.07..1.28 rows=9 width=36) - -> Table Function Scan on multiset_5 (cost=1.07..1.16 rows=3 width=36) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.07..1.13 rows=1 width=16) - -> Limit (cost=1.07..1.10 rows=2 width=16) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.07..1.16 rows=6 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.27 rows=9 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.15 rows=3 width=36) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.06..1.12 rows=1 width=16) + -> Limit (cost=1.06..1.09 rows=2 width=16) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.06..1.16 rows=6 width=16) Merge Key: example.b, example.a - -> Limit (cost=1.07..1.08 rows=2 width=16) + -> Limit (cost=1.06..1.08 rows=2 width=16) -> Unique (cost=1.06..1.09 rows=3 width=16) Group Key: example.b, example.a -> Sort (cost=1.06..1.07 rows=3 width=16) @@ -1973,64 +1973,64 @@ explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example ORDER explain SELECT * FROM multiset_5( TABLE( SELECT count(*)::integer, 'hello'::text from example_r ) ); QUERY PLAN ---------------------------------------------------------------------------------------- - Table Function Scan on multiset_5 (cost=3.16..3.18 rows=1 width=36) - -> Finalize Aggregate (cost=3.16..3.17 rows=1 width=36) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=3.12..3.15 rows=1 width=8) - -> Partial Aggregate (cost=3.12..3.13 rows=1 width=8) - -> Seq Scan on example_r (cost=0.00..3.10 rows=4 width=0) + Table Function Scan on multiset_5 (cost=1.10..1.12 rows=1 width=36) + -> Finalize Aggregate (cost=1.10..1.11 rows=1 width=36) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=1.04..1.09 rows=3 width=8) + -> Partial Aggregate (cost=1.04..1.05 rows=1 width=8) + -> Seq Scan on example_r (cost=0.00..1.03 rows=3 width=0) Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM example_r WHERE (10, 'hello') in (SELECT * FROM multiset_5( TABLE( SELECT count(*)::integer, 'hello'::text from example_r ))); QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.10 rows=5 width=16) - -> Seq Scan on example_r (cost=0.00..3.10 rows=2 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.10 rows=5 width=16) + -> Seq Scan on example_r (cost=0.00..1.03 rows=2 width=16) Filter: (hashed SubPlan 1) SubPlan 1 - -> Broadcast Motion 1:3 (slice2) (cost=3.16..3.18 rows=1 width=36) - -> Table Function Scan on multiset_5 (cost=3.16..3.18 rows=1 width=36) - -> Finalize Aggregate (cost=3.16..3.17 rows=1 width=36) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=3.12..3.15 rows=1 width=8) - -> Partial Aggregate (cost=3.12..3.13 rows=1 width=8) - -> Seq Scan on example_r example_r_1 (cost=0.00..3.10 rows=4 width=0) + -> Broadcast Motion 1:3 (slice2) (cost=1.10..1.12 rows=1 width=36) + -> Table Function Scan on multiset_5 (cost=1.10..1.12 rows=1 width=36) + -> Finalize Aggregate (cost=1.10..1.11 rows=1 width=36) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.04..1.09 rows=3 width=8) + -> Partial Aggregate (cost=1.04..1.05 rows=1 width=8) + -> Seq Scan on example_r example_r_1 (cost=0.00..1.03 rows=3 width=0) Optimizer: Postgres query optimizer (11 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * from example_v) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.53 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (4 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * FROM example WHERE a >= (SELECT min(a) FROM example))); QUERY PLAN ------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.17..4.33 rows=4 width=36) - -> Table Function Scan on multiset_5 (cost=2.17..4.33 rows=2 width=36) - -> Seq Scan on example (cost=2.17..4.29 rows=2 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.11..2.32 rows=10 width=36) + -> Table Function Scan on multiset_5 (cost=1.11..2.18 rows=3 width=36) + -> Seq Scan on example (cost=1.11..2.15 rows=1 width=16) Filter: (a >= $0) InitPlan 1 (returns $0) (slice2) - -> Finalize Aggregate (cost=2.16..2.17 rows=1 width=4) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=2.12..2.15 rows=1 width=4) - -> Partial Aggregate (cost=2.12..2.13 rows=1 width=4) - -> Seq Scan on example example_1 (cost=0.00..2.10 rows=4 width=4) + -> Finalize Aggregate (cost=1.10..1.11 rows=1 width=4) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.04..1.09 rows=3 width=4) + -> Partial Aggregate (cost=1.04..1.05 rows=1 width=4) + -> Seq Scan on example example_1 (cost=0.00..1.03 rows=3 width=4) Optimizer: Postgres query optimizer (10 rows) explain WITH cte AS (SELECT * FROM example) SELECT * FROM multiset_5( TABLE ( SELECT * FROM cte ) ) order by a, b; - QUERY PLAN ----------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.39..2.42 rows=5 width=36) + QUERY PLAN +----------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=1.30..1.72 rows=30 width=36) Merge Key: a, b - -> Sort (cost=2.39..2.42 rows=5 width=36) - Sort Key: multiset_5.a, multiset_5.b - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Sort (cost=1.30..1.32 rows=10 width=36) + Sort Key: a, b + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (7 rows) explain WITH cte AS (SELECT * FROM example) SELECT x.* FROM multiset_5( TABLE ( SELECT * FROM cte ) ) x, (SELECT count(*) FROM cte) y order by x.a, x.b; @@ -2056,81 +2056,81 @@ explain WITH cte AS (SELECT * FROM example) SELECT x.* FROM multiset_5( TABLE ( explain select * from multiset_2( TABLE( SELECT distinct a.a, b.b from example a, example b where a.a = b.a) ) order by 1,2; QUERY PLAN ---------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=8.19..8.26 rows=30 width=36) + Gather Motion 3:1 (slice1; segments: 3) (cost=3.41..4.68 rows=90 width=36) Merge Key: a, b - -> Sort (cost=8.19..8.26 rows=10 width=36) + -> Sort (cost=3.41..3.48 rows=30 width=36) Sort Key: a, b - -> Table Function Scan on multiset_2 (cost=6.85..7.45 rows=10 width=36) - -> HashAggregate (cost=6.85..7.15 rows=10 width=36) + -> Table Function Scan on multiset_2 (cost=2.27..2.67 rows=30 width=36) + -> HashAggregate (cost=2.27..2.37 rows=10 width=16) Group Key: a.a, b.b - -> Hash Join (cost=3.23..6.70 rows=11 width=16) - Hash Cond: a.a = b.a - -> Seq Scan on example a (cost=0.00..3.10 rows=4 width=4) - -> Hash (cost=3.10..3.10 rows=4 width=16) - -> Seq Scan on example b (cost=0.00..3.10 rows=4 width=16) + -> Hash Join (cost=1.08..2.22 rows=10 width=16) + Hash Cond: (a.a = b.a) + -> Seq Scan on example a (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.03..1.03 rows=3 width=16) + -> Seq Scan on example b (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (13 rows) explain select * from multiset_2( TABLE( SELECT distinct a.a, b.b from example a join example b using (a) ) ) order by 1,2; QUERY PLAN ---------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=8.19..8.26 rows=30 width=36) + Gather Motion 3:1 (slice1; segments: 3) (cost=3.41..4.68 rows=90 width=36) Merge Key: a, b - -> Sort (cost=8.19..8.26 rows=10 width=36) + -> Sort (cost=3.41..3.48 rows=30 width=36) Sort Key: a, b - -> Table Function Scan on multiset_2 (cost=6.85..7.45 rows=10 width=36) - -> HashAggregate (cost=6.85..7.15 rows=10 width=36) + -> Table Function Scan on multiset_2 (cost=2.27..2.67 rows=30 width=36) + -> HashAggregate (cost=2.27..2.37 rows=10 width=16) Group Key: a.a, b.b - -> Hash Join (cost=3.23..6.70 rows=11 width=16) - Hash Cond: a.a = b.a - -> Seq Scan on example a (cost=0.00..3.10 rows=4 width=4) - -> Hash (cost=3.10..3.10 rows=4 width=16) - -> Seq Scan on example b (cost=0.00..3.10 rows=4 width=16) + -> Hash Join (cost=1.08..2.22 rows=10 width=16) + Hash Cond: (a.a = b.a) + -> Seq Scan on example a (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.03..1.03 rows=3 width=16) + -> Seq Scan on example b (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (13 rows) explain select * from multiset_2( TABLE ( SELECT * FROM example WHERE a = 2 ) ) WHERE a = 2; QUERY PLAN ----------------------------------------------------------------------------- - Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..2.17 rows=1 width=36) - -> Table Function Scan on multiset_2 (cost=0.00..2.17 rows=1 width=36) - Filter: a = 2 - -> Seq Scan on example (cost=0.00..2.12 rows=2 width=16) - Filter: a = 2 - Settings: gp_segments_for_planner=8 + Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..1.10 rows=1 width=36) + -> Table Function Scan on multiset_2 (cost=0.00..1.08 rows=1 width=36) + Filter: (a = 2) + -> Seq Scan on example (cost=0.00..1.04 rows=1 width=16) + Filter: (a = 2) + Optimizer: Postgres query optimizer (6 rows) -- Not rescannable, should produce materialize node explain SELECT x.* FROM multiset_5( TABLE ( SELECT 1 ) ) x right join (SELECT 1) y on (true); QUERY PLAN ------------------------------------------------------------------------------------ - Nested Loop Left Join (cost=0.03..1.33 rows=27 width=36) + Nested Loop Left Join (cost=10000000000.00..10000000000.04 rows=3 width=36) -> Result (cost=0.00..0.01 rows=1 width=0) - -> Materialize (cost=0.03..0.11 rows=4 width=36) - -> Table Function Scan on multiset_5 x (cost=0.00..0.02 rows=8 width=36) - -> Result (cost=0.00..0.01 rows=1 width=0) - Settings: gp_segments_for_planner=8 + -> Materialize (cost=0.00..0.03 rows=1 width=36) + -> Table Function Scan on multiset_5 x (cost=0.00..0.02 rows=1 width=36) + -> Result (cost=0.00..0.01 rows=1 width=4) + Optimizer: Postgres query optimizer (6 rows) -- Do an explain analyze while we are at it: explain analyze SELECT * FROM multiset_5( TABLE( SELECT count(*)::integer, 'hello'::text from example_r scatter randomly) ); QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=3.16..3.22 rows=1 width=36) (actual time=1.893..2.348 rows=1 loops=1) - -> Table Function Scan on multiset_5 (cost=3.16..3.20 rows=1 width=36) (actual time=1.553..1.557 rows=1 loops=1) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=3.16..3.19 rows=1 width=36) (actual time=1.539..1.540 rows=1 loops=1) - -> Finalize Aggregate (cost=3.16..3.17 rows=1 width=36) (actual time=1.146..1.147 rows=1 loops=1) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=3.12..3.15 rows=1 width=8) (actual time=0.872..1.133 rows=3 loops=1) - -> Partial Aggregate (cost=3.12..3.13 rows=1 width=8) (actual time=0.054..0.054 rows=1 loops=1) - -> Seq Scan on example_r (cost=0.00..3.10 rows=4 width=0) (actual time=0.044..0.046 rows=4 loops=1) - Planning time: 0.533 ms - (slice0) Executor memory: 127K bytes. - (slice1) Executor memory: 35K bytes avg x 3 workers, 40K bytes max (seg0). - (slice2) Executor memory: 63K bytes (seg0). - (slice3) Executor memory: 70K bytes avg x 3 workers, 92K bytes max (seg0). + Gather Motion 3:1 (slice1; segments: 3) (cost=1.10..1.28 rows=9 width=36) (actual time=4.229..4.421 rows=1 loops=1) + -> Table Function Scan on multiset_5 (cost=1.10..1.16 rows=3 width=36) (actual time=4.464..4.467 rows=1 loops=1) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.10..1.13 rows=1 width=36) (actual time=4.459..4.460 rows=1 loops=1) + -> Finalize Aggregate (cost=1.10..1.11 rows=1 width=36) (actual time=2.144..2.144 rows=1 loops=1) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.04..1.09 rows=3 width=8) (actual time=2.131..2.133 rows=3 loops=1) + -> Partial Aggregate (cost=1.04..1.05 rows=1 width=8) (actual time=0.024..0.025 rows=1 loops=1) + -> Seq Scan on example_r (cost=0.00..1.03 rows=3 width=0) (actual time=0.027..0.028 rows=4 loops=1) + Planning Time: 0.050 ms + (slice0) Executor memory: 37K bytes. + (slice1) Executor memory: 10K bytes avg x 3x(0) workers, 10K bytes max (seg0). + (slice2) Executor memory: 118K bytes (seg0). + (slice3) Executor memory: 117K bytes avg x 3x(0) workers, 118K bytes max (seg1). Memory used: 128000kB Optimizer: Postgres query optimizer - Execution time: 3.194 ms + Execution Time: 14.046 ms (15 rows) -- Test for an old bug in aggregate planning - this used to crash. @@ -2377,9 +2377,9 @@ explain SELECT *, generate_series(1,2) FROM multi_args( TABLE(SELECT 1::int, 'he explain SELECT * FROM multi_args( TABLE(SELECT 1::int, 'hello'::text), 2); QUERY PLAN ---------------------------------------------------------------------- - Table Function Scan on multi_args (cost=0.00..0.02 rows=8 width=36) - -> Result (cost=0.00..0.01 rows=1 width=0) - Settings: gp_segments_for_planner=8 + Table Function Scan on multi_args (cost=0.00..0.02 rows=1 width=36) + -> Result (cost=0.00..0.01 rows=1 width=36) + Optimizer: Postgres query optimizer (3 rows) -- Error: don't support sets as arguments that are not TableValueExpr @@ -2393,11 +2393,11 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'a' HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. QUERY PLAN ----------------------------------------------------------------------------------- - Redistribute Motion 1:3 (slice1; segments: 1) (cost=0.00..0.02 rows=8 width=36) - Hash Key: a - -> Table Function Scan on multi_args (cost=0.00..0.02 rows=8 width=36) - -> Result (cost=0.00..0.01 rows=1 width=0) - Settings: gp_segments_for_planner=8 + Redistribute Motion 1:3 (slice1; segments: 1) (cost=0.00..0.04 rows=1 width=36) + Hash Key: multi_args.a + -> Table Function Scan on multi_args (cost=0.00..0.02 rows=1 width=36) + -> Result (cost=0.00..0.01 rows=1 width=36) + Optimizer: Postgres query optimizer (5 rows) CREATE TABLE example_out AS SELECT * FROM multi_args( TABLE(SELECT 1::int, 'hello'::text), 2); @@ -2415,11 +2415,11 @@ DROP TABLE example_out; -- =============== DROP VIEW example_v; ALTER TABLE example DROP column a; -NOTICE: dropping a column that is part of the distribution policy forces a random distribution policy +NOTICE: dropping a column that is part of the distribution policy forces a NULL distribution policy -- ERROR: input tuple does not conform to expectations of multiset_5 SELECT * FROM multiset_5( TABLE( SELECT 'hello'::text) ) as tf; ERROR: invalid input tuple for function multiset_example -HINT: expected (integer, text) +HINT: Expected (integer, text). -- However, this should work despite the output tupdesc having a dropped column. SELECT * FROM multiset_5( TABLE( SELECT 1::integer, 'hello'::text) ) as tf; b @@ -2433,6 +2433,7 @@ SELECT * FROM multiset_5( TABLE( SELECT 1::integer, 'hello'::text) ) as tf; -- start_ignore -- These may have been created by previous test create language plpython3u; +ERROR: extension "plpython3u" already exists -- end_ignore CREATE FUNCTION tf_sql(anytable) returns int AS $$ SELECT 1 $$ language sql CONTAINS SQL; ERROR: SQL functions cannot have arguments of type anytable @@ -2987,14 +2988,14 @@ SELECT * FROM project( TABLE( SELECT * FROM pg_am WHERE amname not in ('pax') ), amname ----------- heap - ao_row - ao_column btree hash gist gin spgist brin + ao_row + ao_column bitmap heap2 (11 rows) @@ -3004,14 +3005,14 @@ SELECT * FROM project( TABLE( SELECT * FROM pg_am WHERE amname not in ('pax') ), amname ----------- heap - ao_row - ao_column btree hash gist gin spgist brin + ao_row + ao_column bitmap heap2 (11 rows) @@ -3026,7 +3027,7 @@ SELECT "time"+1 FROM project( TABLE( SELECT * FROM history ), 2); ERROR: operator does not exist: timestamp without time zone + integer LINE 1: SELECT "time"+1 FROM project( TABLE( SELECT * FROM history )... ^ -HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. +HINT: No operator matches the given name and argument types. You might need to add explicit type casts. -- ERROR: select columns projected out by the function SELECT id FROM project( TABLE( SELECT * FROM history ), 2); ERROR: column "id" does not exist @@ -3095,13 +3096,13 @@ CREATE FUNCTION noop_project(anytable) RETURNS setof RECORD SELECT * FROM noop_project( TABLE( SELECT * FROM history ) ) AS s (id integer, time timestamp); id | time ----+-------------------------- - 1 | Mon Aug 22 10:15:04 2011 - 1 | Mon Aug 22 10:16:10 2011 1 | Sun Aug 21 10:15:02 2011 1 | Sun Aug 21 10:15:30 2011 + 1 | Mon Aug 22 10:15:04 2011 + 1 | Mon Aug 22 10:16:10 2011 2 | Sun Aug 21 10:15:02 2011 - 2 | Sun Aug 21 10:16:02 2011 2 | Sun Aug 21 22:15:02 2011 + 2 | Sun Aug 21 10:16:02 2011 2 | Sun Aug 21 22:16:02 2011 3 | Fri Aug 19 19:05:13 2011 3 | Fri Aug 19 19:06:50 2011 @@ -3151,9 +3152,9 @@ SELECT * FROM noop_project( TABLE( SELECT count(*) FROM history GROUP BY time SC 1 1 1 + 2 1 1 - 2 (17 rows) -- ======================== diff --git a/src/test/regress/expected/table_functions_optimizer.out b/src/test/regress/expected/table_functions_optimizer.out index a3e855d8988..a098eb95764 100644 --- a/src/test/regress/expected/table_functions_optimizer.out +++ b/src/test/regress/expected/table_functions_optimizer.out @@ -331,14 +331,14 @@ SELECT row(a+5, b)::example from example; row ------------------- (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (10 rows) @@ -346,43 +346,43 @@ SELECT scalar_tf_1(5); scalar_tf_1 ------------------- (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (10 rows) SELECT scalar_tf_2(5); scalar_tf_2 ------------------- - (6," value1.1/4") - (8," value3.1/2") - (6," value1.2/4") - (8," value3.2/2") - (6," value1.3/4") - (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") + (6," value1.1/4") + (6," value1.2/4") + (6," value1.3/4") + (6," value1.4/4") (10 rows) SELECT scalar_tf_3(5); scalar_tf_3 ------------------- (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (10 rows) @@ -391,13 +391,13 @@ SELECT scalar_tf_4(5); scalar_tf_4 ------------------- (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (10 rows) @@ -406,13 +406,13 @@ SELECT scalar_tf_5(5); scalar_tf_5 ------------------- (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (10 rows) @@ -420,29 +420,29 @@ SELECT scalar_tf_5(5); SELECT scalar_tf_6(5); scalar_tf_6 ------------------- - (7," value2.1/3") - (9," value4.1/1") - (7," value2.2/3") - (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") + (7," value2.1/3") + (8," value3.1/2") + (9," value4.1/1") + (7," value2.2/3") + (8," value3.2/2") + (7," value2.3/3") (10 rows) SELECT scalar_tf_1((select 5)); scalar_tf_1 ------------------- (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (10 rows) @@ -450,29 +450,29 @@ SELECT scalar_tf_1((select 5)); SELECT scalar_tf_2((select 5)); scalar_tf_2 ------------------- - (6," value1.1/4") - (8," value3.1/2") - (6," value1.2/4") - (8," value3.2/2") - (6," value1.3/4") - (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") + (6," value1.1/4") + (6," value1.2/4") + (6," value1.3/4") + (6," value1.4/4") (10 rows) SELECT scalar_tf_3((select 5)); scalar_tf_3 ------------------- (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (10 rows) @@ -480,44 +480,44 @@ SELECT scalar_tf_3((select 5)); SELECT scalar_tf_4((select 5)); scalar_tf_4 ------------------- - (6," value1.1/4") - (8," value3.1/2") - (6," value1.2/4") - (8," value3.2/2") - (6," value1.3/4") - (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") + (6," value1.1/4") + (6," value1.2/4") + (6," value1.3/4") + (6," value1.4/4") (10 rows) SELECT scalar_tf_5((select 5)); scalar_tf_5 ------------------- - (6," value1.1/4") - (8," value3.1/2") - (6," value1.2/4") - (8," value3.2/2") - (6," value1.3/4") - (6," value1.4/4") (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") + (6," value1.1/4") + (6," value1.2/4") + (6," value1.3/4") + (6," value1.4/4") (10 rows) SELECT scalar_tf_6((select 5)); scalar_tf_6 ------------------- (7," value2.1/3") + (8," value3.1/2") (9," value4.1/1") (7," value2.2/3") + (8," value3.2/2") (7," value2.3/3") (6," value1.1/4") - (8," value3.1/2") (6," value1.2/4") - (8," value3.2/2") (6," value1.3/4") (6," value1.4/4") (10 rows) @@ -1349,9 +1349,9 @@ SELECT a from multiset_setof_value( TABLE(SELECT 1) ) as a; -- end equivalent -- ERROR: Table Functions do not currently support SFRM_Materialize SELECT * FROM multiset_materialize_good( TABLE( SELECT * from example ) ); -ERROR: set-valued function called in context that cannot accept a set (seg1 slice1 @hostname@:40041 pid=12397) +ERROR: set-valued function called in context that cannot accept a set (seg1 slice1 172.18.0.2:7003 pid=30707) SELECT * FROM multiset_materialize_bad( TABLE( SELECT * from example ) ); -ERROR: table functions must use SFRM_ValuePerCall protocol (seg1 slice1 @hostname@:40041 pid=12397) +ERROR: table functions must use SFRM_ValuePerCall protocol (seg0 slice1 172.18.0.2:7002 pid=30711) -- name resolution rules should work correctly between scalar and anytable, -- i.e. there cannot be any automatic conversion. CREATE FUNCTION nameres(int) RETURNS int @@ -1417,11 +1417,11 @@ DROP FUNCTION nameres(anyelement); explain SELECT * FROM multiset_5( TABLE( SELECT * FROM example SCATTER BY a+1) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.23 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..3.23 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.12 rows=4 width=16) - Hash Key: (example.a + 1) - -> Seq Scan on example (cost=0.00..3.12 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.61 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.21 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.11 rows=3 width=20) + Hash Key: ((example.a + 1)) + -> Seq Scan on example (cost=0.00..1.04 rows=3 width=20) Optimizer: Postgres query optimizer (6 rows) @@ -1553,254 +1553,254 @@ SELECT * FROM multiset_5( TABLE(SELECT a, b from example)) where (a,b) in (selec -- end equivalent -- Explain a couple interesting cases explain SELECT * FROM multiset_5( TABLE (SELECT dbid, gpname FROM gp_id) ); - QUERY PLAN ------------------------------------------------------------------------ - Table Function Scan on multiset_5 (cost=0.00..1.11 rows=64 width=36) - -> Seq Scan on gp_id (cost=0.00..1.01 rows=8 width=66) - Settings: gp_segments_for_planner=8 + QUERY PLAN +---------------------------------------------------------------------- + Table Function Scan on multiset_5 (cost=0.00..1.02 rows=1 width=36) + -> Seq Scan on gp_id (cost=0.00..1.01 rows=1 width=66) + Optimizer: Postgres query optimizer (3 rows) explain SELECT * FROM multiset_5( TABLE (SELECT dbid, gpname FROM gp_id SCATTER BY dbid) ); QUERY PLAN ---------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.11 rows=4 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..1.11 rows=4 width=36) - -> Redistribute Motion 1:3 (slice2) (cost=0.00..1.01 rows=8 width=66) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.18 rows=9 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.06 rows=3 width=36) + -> Redistribute Motion 1:3 (slice2) (cost=0.00..1.03 rows=1 width=66) Hash Key: gp_id.dbid - -> Seq Scan on gp_id (cost=0.00..1.01 rows=8 width=66) - Settings: gp_segments_for_planner=8 + -> Seq Scan on gp_id (cost=0.00..1.01 rows=1 width=66) + Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT dbid, gpname FROM gp_id SCATTER RANDOMLY) ); QUERY PLAN ---------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.11 rows=4 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..1.11 rows=4 width=36) - -> Redistribute Motion 1:3 (slice2) (cost=0.00..1.01 rows=8 width=66) - -> Seq Scan on gp_id (cost=0.00..1.01 rows=8 width=66) - Settings: gp_segments_for_planner=8 + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.18 rows=9 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.06 rows=3 width=36) + -> Redistribute Motion 1:3 (slice2) (cost=0.00..1.03 rows=1 width=66) + -> Seq Scan on gp_id (cost=0.00..1.01 rows=1 width=66) + Optimizer: Postgres query optimizer (5 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.53 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (4 rows) explain SELECT * from multiset_5( TABLE (SELECT * FROM example ORDER BY a limit 10 ) ); - QUERY PLAN ------------------------------------------------------------------------------------------ - Table Function Scan on multiset_5 (cost=2.27..2.62 rows=80 width=36) - -> Limit (cost=2.27..2.49 rows=10 width=16) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.49 rows=5 width=16) + QUERY PLAN +------------------------------------------------------------------------------------------ + Table Function Scan on multiset_5 (cost=1.06..1.30 rows=10 width=36) + -> Limit (cost=1.06..1.20 rows=10 width=16) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.20 rows=10 width=16) Merge Key: example.a - -> Limit (cost=2.27..2.29 rows=5 width=16) - -> Sort (cost=2.27..2.29 rows=5 width=16) - Sort Key (Limit): example.a - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Limit (cost=1.06..1.07 rows=3 width=16) + -> Sort (cost=1.06..1.07 rows=3 width=16) + Sort Key: example.a + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (9 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example SCATTER BY a) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.53 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (4 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example SCATTER BY b) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..2.10 rows=5 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.60 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.20 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=3 width=16) Hash Key: example.b - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example SCATTER RANDOMLY) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..2.10 rows=5 width=16) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.60 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.20 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=3 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (5 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY a, b) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.42 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.42 rows=5 width=36) - -> Sort (cost=2.27..2.29 rows=5 width=16) + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.57 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.17 rows=10 width=36) + -> Sort (cost=1.06..1.07 rows=3 width=16) Sort Key: example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY a, b SCATTER BY a) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.42 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.42 rows=5 width=36) - -> Sort (cost=2.27..2.29 rows=5 width=16) + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.57 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.17 rows=10 width=36) + -> Sort (cost=1.06..1.07 rows=3 width=16) Sort Key: example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY b, a SCATTER BY b) ); QUERY PLAN ----------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.42 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.42 rows=5 width=36) - -> Sort (cost=2.27..2.29 rows=5 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.13..1.64 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.13..1.24 rows=10 width=36) + -> Sort (cost=1.13..1.14 rows=3 width=16) Sort Key: example.b, example.a - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..2.10 rows=5 width=16) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=3 width=16) Hash Key: example.b - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (8 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY b, a SCATTER RANDOMLY) ); QUERY PLAN ----------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.42 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.42 rows=5 width=36) - -> Sort (cost=2.27..2.29 rows=5 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.13..1.64 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.13..1.24 rows=10 width=36) + -> Sort (cost=1.13..1.14 rows=3 width=16) Sort Key: example.b, example.a - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..2.10 rows=5 width=16) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=3 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (7 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY a, b LIMIT 10 SCATTER BY a) ); - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.62 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.62 rows=5 width=36) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=2.27..2.49 rows=10 width=16) + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.84 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.44 rows=10 width=36) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.06..1.34 rows=3 width=16) Hash Key: example.a - -> Limit (cost=2.27..2.49 rows=10 width=16) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=2.27..2.49 rows=5 width=16) + -> Limit (cost=1.06..1.20 rows=10 width=16) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.06..1.20 rows=10 width=16) Merge Key: example.a, example.b - -> Limit (cost=2.27..2.29 rows=5 width=16) - -> Sort (cost=2.27..2.29 rows=5 width=16) - Sort Key (Limit): example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Limit (cost=1.06..1.07 rows=3 width=16) + -> Sort (cost=1.06..1.07 rows=3 width=16) + Sort Key: example.a, example.b + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (12 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY b, a LIMIT 10 SCATTER BY b) ); - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.62 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.62 rows=5 width=36) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=2.27..2.49 rows=10 width=16) + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.84 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.44 rows=10 width=36) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.06..1.34 rows=3 width=16) Hash Key: example.b - -> Limit (cost=2.27..2.49 rows=10 width=16) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=2.27..2.49 rows=5 width=16) + -> Limit (cost=1.06..1.20 rows=10 width=16) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.06..1.20 rows=10 width=16) Merge Key: example.b, example.a - -> Limit (cost=2.27..2.29 rows=5 width=16) - -> Sort (cost=2.27..2.29 rows=5 width=16) - Sort Key (Limit): example.b, example.a - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Limit (cost=1.06..1.07 rows=3 width=16) + -> Sort (cost=1.06..1.07 rows=3 width=16) + Sort Key: example.b, example.a + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (12 rows) explain SELECT * FROM multiset_5( TABLE (SELECT * FROM example ORDER BY b, a LIMIT 10 SCATTER RANDOMLY) ); - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.27..2.62 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=2.27..2.62 rows=5 width=36) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=2.27..2.49 rows=10 width=16) - -> Limit (cost=2.27..2.49 rows=10 width=16) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=2.27..2.49 rows=5 width=16) + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.84 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.44 rows=10 width=36) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.06..1.34 rows=3 width=16) + -> Limit (cost=1.06..1.20 rows=10 width=16) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.06..1.20 rows=10 width=16) Merge Key: example.b, example.a - -> Limit (cost=2.27..2.29 rows=5 width=16) - -> Sort (cost=2.27..2.29 rows=5 width=16) - Sort Key (Limit): example.b, example.a - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Limit (cost=1.06..1.07 rows=3 width=16) + -> Sort (cost=1.06..1.07 rows=3 width=16) + Sort Key: example.b, example.a + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (11 rows) explain SELECT ARRAY(SELECT a FROM multiset_5( TABLE ( SELECT a, b from example)) order by a); - QUERY PLAN ------------------------------------------------------------------------------------------ - Result (cost=2.42..2.43 rows=1 width=0) + QUERY PLAN +------------------------------------------------------------------------------------------ + Result (cost=1.72..1.73 rows=1 width=32) InitPlan 1 (returns $0) (slice1) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=2.39..2.42 rows=5 width=4) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=1.30..1.72 rows=30 width=4) Merge Key: a - -> Sort (cost=2.39..2.42 rows=5 width=4) - Sort Key: multiset_5.a - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=4) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Sort (cost=1.30..1.32 rows=10 width=4) + Sort Key: a + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=4) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (9 rows) explain SELECT ARRAY(SELECT a FROM multiset_5( TABLE ( SELECT a, b from example order by a))); - QUERY PLAN ------------------------------------------------------------------------------------- - Result (cost=2.42..2.43 rows=1 width=0) + QUERY PLAN +------------------------------------------------------------------------------------- + Result (cost=1.57..1.58 rows=1 width=32) InitPlan 1 (returns $0) (slice1) - -> Gather Motion 3:1 (slice2; segments: 3) (cost=2.27..2.42 rows=5 width=4) - -> Table Function Scan on multiset_5 (cost=2.27..2.42 rows=5 width=4) - -> Sort (cost=2.27..2.29 rows=5 width=16) + -> Gather Motion 3:1 (slice2; segments: 3) (cost=1.06..1.57 rows=30 width=4) + -> Table Function Scan on multiset_5 (cost=1.06..1.17 rows=10 width=4) + -> Sort (cost=1.06..1.07 rows=3 width=16) Sort Key: example.a - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (8 rows) explain SELECT * FROM example where (a,b) in (select * from multiset_5( TABLE(SELECT a, b from example) )); - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=3.55..6.83 rows=10 width=16) - -> Hash Semi Join (cost=3.55..6.83 rows=4 width=16) - Hash Cond: example.a = a AND example.b = b - -> Seq Scan on example (cost=0.00..3.10 rows=4 width=16) - -> Hash (cost=3.40..3.40 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.40 rows=4 width=36) - Hash Key: a - -> Table Function Scan on multiset_5 (cost=0.00..3.20 rows=4 width=36) - -> Seq Scan on example example_1 (cost=0.00..3.10 rows=4 width=16) + QUERY PLAN +------------------------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=1.08..2.66 rows=10 width=16) + -> Hash Right Semi Join (cost=1.08..2.53 rows=3 width=16) + Hash Cond: ((a = example.a) AND (b = example.b)) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.33 rows=10 width=36) + Hash Key: a + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example example_1 (cost=0.00..1.03 rows=3 width=16) + -> Hash (cost=1.03..1.03 rows=3 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (10 rows) explain SELECT * FROM example where (a,b) in (select * from multiset_5( TABLE(SELECT a, b from example scatter by b) )); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=3.55..6.83 rows=10 width=16) - -> Hash Semi Join (cost=3.55..6.83 rows=4 width=16) - Hash Cond: example.a = a AND example.b = b - -> Seq Scan on example (cost=0.00..3.10 rows=4 width=16) - -> Hash (cost=3.40..3.40 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.40 rows=4 width=36) - Hash Key: a - -> Table Function Scan on multiset_5 (cost=0.00..3.20 rows=4 width=36) - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..3.10 rows=4 width=16) - Hash Key: example_1.b - -> Seq Scan on example example_1 (cost=0.00..3.10 rows=4 width=16) + QUERY PLAN +----------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=1.08..2.73 rows=10 width=16) + -> Hash Right Semi Join (cost=1.08..2.59 rows=3 width=16) + Hash Cond: ((a = example.a) AND (b = example.b)) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.40 rows=10 width=36) + Hash Key: a + -> Table Function Scan on multiset_5 (cost=0.00..1.20 rows=10 width=36) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.10 rows=3 width=16) + Hash Key: example_1.b + -> Seq Scan on example example_1 (cost=0.00..1.03 rows=3 width=16) + -> Hash (cost=1.03..1.03 rows=3 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (12 rows) explain SELECT * FROM multiset_5( TABLE(SELECT a, b from example)) where (a,b) in (select a,b from example); - QUERY PLAN ---------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=1.32..2.58 rows=4 width=36) - -> Hash Semi Join (cost=1.32..2.52 rows=1 width=36) - Hash Cond: ((a = example.a) AND (b = example.b)) - -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) - -> Seq Scan on example example_1 (cost=0.00..1.03 rows=3 width=16) - -> Hash (cost=1.17..1.17 rows=10 width=16) - -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.17 rows=10 width=16) - -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + QUERY PLAN +--------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=1.28..2.59 rows=4 width=36) + -> Hash Right Semi Join (cost=1.28..2.54 rows=1 width=36) + Hash Cond: ((example.a = a) AND (example.b = b)) + -> Broadcast Motion 3:3 (slice2; segments: 3) (cost=0.00..1.17 rows=10 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + -> Hash (cost=1.13..1.13 rows=10 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example example_1 (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (9 rows) @@ -1821,107 +1821,107 @@ explain SELECT * FROM multiset_5( TABLE(SELECT a, b from example scatter by b)) (11 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * from example_r) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Seq Scan on example_r (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.53 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example_r (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (4 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * FROM example_r SCATTER by a||b) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.28 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..3.28 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.18 rows=4 width=16) - Hash Key: (example_r.a::text || example_r.b) - -> Seq Scan on example_r (cost=0.00..3.18 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.62 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.23 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.12 rows=3 width=48) + Hash Key: (((example_r.a)::text || example_r.b)) + -> Seq Scan on example_r (cost=0.00..1.06 rows=3 width=48) Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * FROM example_r SCATTER by b, a, a||b) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.28 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..3.28 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..3.18 rows=4 width=16) - Hash Key: example_r.b, example_r.a, (example_r.a::text || example_r.b) - -> Seq Scan on example_r (cost=0.00..3.18 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.62 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.23 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.12 rows=3 width=48) + Hash Key: example_r.b, example_r.a, (((example_r.a)::text || example_r.b)) + -> Seq Scan on example_r (cost=0.00..1.06 rows=3 width=48) Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * FROM example_r SCATTER RANDOMLY) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..2.10 rows=5 width=16) - -> Seq Scan on example_r (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.60 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.20 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..1.10 rows=3 width=16) + -> Seq Scan on example_r (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (5 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example) ); QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.09..2.29 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.09..2.29 rows=4 width=36) - -> HashAggregate (cost=2.09..2.19 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.05..1.58 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.05..1.18 rows=10 width=36) + -> HashAggregate (cost=1.05..1.08 rows=3 width=16) Group Key: example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example SCATTER BY a) ); QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=2.09..2.29 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.09..2.29 rows=4 width=36) - -> HashAggregate (cost=2.09..2.19 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.05..1.58 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.05..1.18 rows=10 width=36) + -> HashAggregate (cost=1.05..1.08 rows=3 width=16) Group Key: example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a / 2, b FROM example SCATTER BY a / 2) ); QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.38..2.80 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.38..2.80 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.38..2.70 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.12..1.73 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.12..1.33 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.12..1.23 rows=3 width=16) Hash Key: ((example.a / 2)) - -> HashAggregate (cost=2.38..2.50 rows=4 width=16) + -> HashAggregate (cost=1.12..1.17 rows=3 width=16) Group Key: ((example.a / 2)), example.b - -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..2.33 rows=4 width=16) + -> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..1.11 rows=3 width=16) Hash Key: ((example.a / 2)), example.b - -> Seq Scan on example (cost=0.00..2.12 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.04 rows=3 width=16) Optimizer: Postgres query optimizer (10 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example SCATTER BY b) ); QUERY PLAN ----------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.09..2.49 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.09..2.49 rows=4 width=36) - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.09..2.39 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.05..1.65 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.05..1.25 rows=10 width=36) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.05..1.15 rows=3 width=16) Hash Key: example.b - -> HashAggregate (cost=2.09..2.19 rows=4 width=16) + -> HashAggregate (cost=1.05..1.08 rows=3 width=16) Group Key: example.a, example.b - -> Seq Scan on example (cost=0.00..2.10 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (8 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example ORDER BY b, a SCATTER RANDOMLY) ); QUERY PLAN ----------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.62..2.74 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.62..2.74 rows=4 width=36) - -> Sort (cost=2.62..2.64 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.18..1.69 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.18..1.29 rows=10 width=36) + -> Sort (cost=1.18..1.19 rows=3 width=16) Sort Key: example.b, example.a - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.15..2.45 rows=4 width=16) - -> HashAggregate (cost=2.15..2.25 rows=4 width=16) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.05..1.15 rows=3 width=16) + -> HashAggregate (cost=1.05..1.08 rows=3 width=16) Group Key: example.b, example.a - -> Seq Scan on example (cost=0.00..2.10 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (9 rows) @@ -1941,28 +1941,28 @@ explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example ORDER explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example ORDER BY b, a SCATTER BY b) ); QUERY PLAN ----------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.62..2.74 rows=10 width=36) - -> Table Function Scan on multiset_5 (cost=2.62..2.74 rows=4 width=36) - -> Sort (cost=2.62..2.64 rows=4 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.18..1.69 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=1.18..1.29 rows=10 width=36) + -> Sort (cost=1.18..1.19 rows=3 width=16) Sort Key: example.b, example.a - -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=2.15..2.45 rows=4 width=16) + -> Redistribute Motion 3:3 (slice2; segments: 3) (cost=1.05..1.15 rows=3 width=16) Hash Key: example.b - -> HashAggregate (cost=2.15..2.25 rows=4 width=16) + -> HashAggregate (cost=1.05..1.08 rows=3 width=16) Group Key: example.b, example.a - -> Seq Scan on example (cost=0.00..2.10 rows=4 width=16) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (10 rows) explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example ORDER BY b, a LIMIT 2 SCATTER RANDOMLY) ); QUERY PLAN -------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=1.07..1.28 rows=9 width=36) - -> Table Function Scan on multiset_5 (cost=1.07..1.16 rows=3 width=36) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.07..1.13 rows=1 width=16) - -> Limit (cost=1.07..1.10 rows=2 width=16) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.07..1.16 rows=6 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.06..1.27 rows=9 width=36) + -> Table Function Scan on multiset_5 (cost=1.06..1.15 rows=3 width=36) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.06..1.12 rows=1 width=16) + -> Limit (cost=1.06..1.09 rows=2 width=16) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.06..1.16 rows=6 width=16) Merge Key: example.b, example.a - -> Limit (cost=1.07..1.08 rows=2 width=16) + -> Limit (cost=1.06..1.08 rows=2 width=16) -> Unique (cost=1.06..1.09 rows=3 width=16) Group Key: example.b, example.a -> Sort (cost=1.06..1.07 rows=3 width=16) @@ -1974,72 +1974,72 @@ explain SELECT * FROM multiset_5( TABLE (SELECT DISTINCT a, b FROM example ORDER explain SELECT * FROM multiset_5( TABLE( SELECT count(*)::integer, 'hello'::text from example_r ) ); QUERY PLAN ---------------------------------------------------------------------------------------- - Table Function Scan on multiset_5 (cost=3.16..3.18 rows=1 width=36) - -> Finalize Aggregate (cost=3.16..3.17 rows=1 width=36) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=3.12..3.15 rows=1 width=8) - -> Partial Aggregate (cost=3.12..3.13 rows=1 width=8) - -> Seq Scan on example_r (cost=0.00..3.10 rows=4 width=0) + Table Function Scan on multiset_5 (cost=1.10..1.12 rows=1 width=36) + -> Finalize Aggregate (cost=1.10..1.11 rows=1 width=36) + -> Gather Motion 3:1 (slice1; segments: 3) (cost=1.04..1.09 rows=3 width=8) + -> Partial Aggregate (cost=1.04..1.05 rows=1 width=8) + -> Seq Scan on example_r (cost=0.00..1.03 rows=3 width=0) Optimizer: Postgres query optimizer (6 rows) explain SELECT * FROM example_r WHERE (10, 'hello') in (SELECT * FROM multiset_5( TABLE( SELECT count(*)::integer, 'hello'::text from example_r ))); QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..3.10 rows=5 width=16) - -> Seq Scan on example_r (cost=0.00..3.10 rows=2 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.10 rows=5 width=16) + -> Seq Scan on example_r (cost=0.00..1.03 rows=2 width=16) Filter: (hashed SubPlan 1) SubPlan 1 - -> Broadcast Motion 1:3 (slice2) (cost=3.16..3.18 rows=1 width=36) - -> Table Function Scan on multiset_5 (cost=3.16..3.18 rows=1 width=36) - -> Finalize Aggregate (cost=3.16..3.17 rows=1 width=36) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=3.12..3.15 rows=1 width=8) - -> Partial Aggregate (cost=3.12..3.13 rows=1 width=8) - -> Seq Scan on example_r example_r_1 (cost=0.00..3.10 rows=4 width=0) + -> Broadcast Motion 1:3 (slice2) (cost=1.10..1.12 rows=1 width=36) + -> Table Function Scan on multiset_5 (cost=1.10..1.12 rows=1 width=36) + -> Finalize Aggregate (cost=1.10..1.11 rows=1 width=36) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.04..1.09 rows=3 width=8) + -> Partial Aggregate (cost=1.04..1.05 rows=1 width=8) + -> Seq Scan on example_r example_r_1 (cost=0.00..1.03 rows=3 width=0) Optimizer: Postgres query optimizer (11 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * from example_v) ); - QUERY PLAN ------------------------------------------------------------------------------ - Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2.23 rows=5 width=36) - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + QUERY PLAN +------------------------------------------------------------------------------ + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1.53 rows=30 width=36) + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (4 rows) explain SELECT * FROM multiset_5( TABLE( SELECT * FROM example WHERE a >= (SELECT min(a) FROM example))); QUERY PLAN ------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.17..4.33 rows=4 width=36) - -> Table Function Scan on multiset_5 (cost=2.17..4.33 rows=2 width=36) - -> Seq Scan on example (cost=2.17..4.29 rows=2 width=16) + Gather Motion 3:1 (slice1; segments: 3) (cost=1.11..2.32 rows=10 width=36) + -> Table Function Scan on multiset_5 (cost=1.11..2.18 rows=3 width=36) + -> Seq Scan on example (cost=1.11..2.15 rows=1 width=16) Filter: (a >= $0) InitPlan 1 (returns $0) (slice2) - -> Finalize Aggregate (cost=2.16..2.17 rows=1 width=4) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=2.12..2.15 rows=1 width=4) - -> Partial Aggregate (cost=2.12..2.13 rows=1 width=4) - -> Seq Scan on example example_1 (cost=0.00..2.10 rows=4 width=4) + -> Finalize Aggregate (cost=1.10..1.11 rows=1 width=4) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.04..1.09 rows=3 width=4) + -> Partial Aggregate (cost=1.04..1.05 rows=1 width=4) + -> Seq Scan on example example_1 (cost=0.00..1.03 rows=3 width=4) Optimizer: Postgres query optimizer (10 rows) explain WITH cte AS (SELECT * FROM example) SELECT * FROM multiset_5( TABLE ( SELECT * FROM cte ) ) order by a, b; - QUERY PLAN ----------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=2.39..2.42 rows=5 width=36) + QUERY PLAN +----------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=1.30..1.72 rows=30 width=36) Merge Key: a, b - -> Sort (cost=2.39..2.42 rows=5 width=36) - Sort Key: multiset_5.a, multiset_5.b - -> Table Function Scan on multiset_5 (cost=0.00..2.23 rows=5 width=36) - -> Seq Scan on example (cost=0.00..2.10 rows=5 width=16) - Settings: gp_segments_for_planner=8 + -> Sort (cost=1.30..1.32 rows=10 width=36) + Sort Key: a, b + -> Table Function Scan on multiset_5 (cost=0.00..1.13 rows=10 width=36) + -> Seq Scan on example (cost=0.00..1.03 rows=3 width=16) + Optimizer: Postgres query optimizer (7 rows) explain WITH cte AS (SELECT * FROM example) SELECT x.* FROM multiset_5( TABLE ( SELECT * FROM cte ) ) x, (SELECT count(*) FROM cte) y order by x.a, x.b; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=10000000004.89..10000000005.12 rows=10 width=36) + QUERY PLAN +---------------------------------------------------------------------------------------------------------------- + Gather Motion 3:1 (slice1; segments: 3) (cost=10000000002.39..10000000002.53 rows=10 width=36) Merge Key: a, b - -> Sort (cost=10000000004.89..10000000004.92 rows=4 width=36) + -> Sort (cost=10000000002.39..10000000002.39 rows=3 width=36) Sort Key: a, b -> Nested Loop (cost=10000000001.08..10000000002.36 rows=3 width=36) -> Broadcast Motion 1:3 (slice2; segments: 1) (cost=1.08..1.12 rows=1 width=0) @@ -2057,81 +2057,81 @@ explain WITH cte AS (SELECT * FROM example) SELECT x.* FROM multiset_5( TABLE ( explain select * from multiset_2( TABLE( SELECT distinct a.a, b.b from example a, example b where a.a = b.a) ) order by 1,2; QUERY PLAN ---------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=8.19..8.26 rows=30 width=36) + Gather Motion 3:1 (slice1; segments: 3) (cost=3.41..4.68 rows=90 width=36) Merge Key: a, b - -> Sort (cost=8.19..8.26 rows=10 width=36) + -> Sort (cost=3.41..3.48 rows=30 width=36) Sort Key: a, b - -> Table Function Scan on multiset_2 (cost=6.85..7.45 rows=10 width=36) - -> HashAggregate (cost=6.85..7.15 rows=10 width=36) + -> Table Function Scan on multiset_2 (cost=2.27..2.67 rows=30 width=36) + -> HashAggregate (cost=2.27..2.37 rows=10 width=16) Group Key: a.a, b.b - -> Hash Join (cost=3.23..6.70 rows=11 width=16) - Hash Cond: a.a = b.a - -> Seq Scan on example a (cost=0.00..3.10 rows=4 width=4) - -> Hash (cost=3.10..3.10 rows=4 width=16) - -> Seq Scan on example b (cost=0.00..3.10 rows=4 width=16) + -> Hash Join (cost=1.08..2.22 rows=10 width=16) + Hash Cond: (a.a = b.a) + -> Seq Scan on example a (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.03..1.03 rows=3 width=16) + -> Seq Scan on example b (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (13 rows) explain select * from multiset_2( TABLE( SELECT distinct a.a, b.b from example a join example b using (a) ) ) order by 1,2; QUERY PLAN ---------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=8.19..8.26 rows=30 width=36) + Gather Motion 3:1 (slice1; segments: 3) (cost=3.41..4.68 rows=90 width=36) Merge Key: a, b - -> Sort (cost=8.19..8.26 rows=10 width=36) + -> Sort (cost=3.41..3.48 rows=30 width=36) Sort Key: a, b - -> Table Function Scan on multiset_2 (cost=6.85..7.45 rows=10 width=36) - -> HashAggregate (cost=6.85..7.15 rows=10 width=36) + -> Table Function Scan on multiset_2 (cost=2.27..2.67 rows=30 width=36) + -> HashAggregate (cost=2.27..2.37 rows=10 width=16) Group Key: a.a, b.b - -> Hash Join (cost=3.23..6.70 rows=11 width=16) - Hash Cond: a.a = b.a - -> Seq Scan on example a (cost=0.00..3.10 rows=4 width=4) - -> Hash (cost=3.10..3.10 rows=4 width=16) - -> Seq Scan on example b (cost=0.00..3.10 rows=4 width=16) + -> Hash Join (cost=1.08..2.22 rows=10 width=16) + Hash Cond: (a.a = b.a) + -> Seq Scan on example a (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.03..1.03 rows=3 width=16) + -> Seq Scan on example b (cost=0.00..1.03 rows=3 width=16) Optimizer: Postgres query optimizer (13 rows) explain select * from multiset_2( TABLE ( SELECT * FROM example WHERE a = 2 ) ) WHERE a = 2; QUERY PLAN ----------------------------------------------------------------------------- - Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..2.17 rows=1 width=36) - -> Table Function Scan on multiset_2 (cost=0.00..2.17 rows=1 width=36) - Filter: a = 2 - -> Seq Scan on example (cost=0.00..2.12 rows=2 width=16) - Filter: a = 2 - Settings: gp_segments_for_planner=8 + Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..1.10 rows=1 width=36) + -> Table Function Scan on multiset_2 (cost=0.00..1.08 rows=1 width=36) + Filter: (a = 2) + -> Seq Scan on example (cost=0.00..1.04 rows=1 width=16) + Filter: (a = 2) + Optimizer: Postgres query optimizer (6 rows) -- Not rescannable, should produce materialize node explain SELECT x.* FROM multiset_5( TABLE ( SELECT 1 ) ) x right join (SELECT 1) y on (true); QUERY PLAN ------------------------------------------------------------------------------------ - Nested Loop Left Join (cost=0.03..1.33 rows=27 width=36) + Nested Loop Left Join (cost=10000000000.00..10000000000.04 rows=3 width=36) -> Result (cost=0.00..0.01 rows=1 width=0) - -> Materialize (cost=0.03..0.11 rows=4 width=36) - -> Table Function Scan on multiset_5 x (cost=0.00..0.02 rows=8 width=36) - -> Result (cost=0.00..0.01 rows=1 width=0) - Settings: gp_segments_for_planner=8 + -> Materialize (cost=0.00..0.03 rows=1 width=36) + -> Table Function Scan on multiset_5 x (cost=0.00..0.02 rows=1 width=36) + -> Result (cost=0.00..0.01 rows=1 width=4) + Optimizer: Postgres query optimizer (6 rows) -- Do an explain analyze while we are at it: explain analyze SELECT * FROM multiset_5( TABLE( SELECT count(*)::integer, 'hello'::text from example_r scatter randomly) ); QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) (cost=3.16..3.22 rows=1 width=36) (actual time=1.893..2.348 rows=1 loops=1) - -> Table Function Scan on multiset_5 (cost=3.16..3.20 rows=1 width=36) (actual time=1.553..1.557 rows=1 loops=1) - -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=3.16..3.19 rows=1 width=36) (actual time=1.539..1.540 rows=1 loops=1) - -> Finalize Aggregate (cost=3.16..3.17 rows=1 width=36) (actual time=1.146..1.147 rows=1 loops=1) - -> Gather Motion 3:1 (slice3; segments: 3) (cost=3.12..3.15 rows=1 width=8) (actual time=0.872..1.133 rows=3 loops=1) - -> Partial Aggregate (cost=3.12..3.13 rows=1 width=8) (actual time=0.054..0.054 rows=1 loops=1) - -> Seq Scan on example_r (cost=0.00..3.10 rows=4 width=0) (actual time=0.044..0.046 rows=4 loops=1) - Planning time: 0.533 ms - (slice0) Executor memory: 127K bytes. - (slice1) Executor memory: 35K bytes avg x 3 workers, 40K bytes max (seg0). - (slice2) Executor memory: 63K bytes (seg0). - (slice3) Executor memory: 70K bytes avg x 3 workers, 92K bytes max (seg0). + Gather Motion 3:1 (slice1; segments: 3) (cost=1.10..1.28 rows=9 width=36) (actual time=5.582..5.617 rows=1 loops=1) + -> Table Function Scan on multiset_5 (cost=1.10..1.16 rows=3 width=36) (actual time=5.327..5.329 rows=1 loops=1) + -> Redistribute Motion 1:3 (slice2; segments: 1) (cost=1.10..1.13 rows=1 width=36) (actual time=5.321..5.322 rows=1 loops=1) + -> Finalize Aggregate (cost=1.10..1.11 rows=1 width=36) (actual time=0.012..0.013 rows=1 loops=1) + -> Gather Motion 3:1 (slice3; segments: 3) (cost=1.04..1.09 rows=3 width=8) (actual time=0.003..0.005 rows=3 loops=1) + -> Partial Aggregate (cost=1.04..1.05 rows=1 width=8) (actual time=0.016..0.016 rows=1 loops=1) + -> Seq Scan on example_r (cost=0.00..1.03 rows=3 width=0) (actual time=0.012..0.013 rows=5 loops=1) + Planning Time: 0.204 ms + (slice0) Executor memory: 37K bytes. + (slice1) Executor memory: 10K bytes avg x 3x(0) workers, 10K bytes max (seg0). + (slice2) Executor memory: 118K bytes (seg0). + (slice3) Executor memory: 117K bytes avg x 3x(0) workers, 118K bytes max (seg1). Memory used: 128000kB Optimizer: Postgres query optimizer - Execution time: 3.194 ms + Execution Time: 12.357 ms (15 rows) -- Test for an old bug in aggregate planning - this used to crash. @@ -2378,9 +2378,9 @@ explain SELECT *, generate_series(1,2) FROM multi_args( TABLE(SELECT 1::int, 'he explain SELECT * FROM multi_args( TABLE(SELECT 1::int, 'hello'::text), 2); QUERY PLAN ---------------------------------------------------------------------- - Table Function Scan on multi_args (cost=0.00..0.02 rows=8 width=36) - -> Result (cost=0.00..0.01 rows=1 width=0) - Settings: gp_segments_for_planner=8 + Table Function Scan on multi_args (cost=0.00..0.02 rows=1 width=36) + -> Result (cost=0.00..0.01 rows=1 width=36) + Optimizer: Postgres query optimizer (3 rows) -- Error: don't support sets as arguments that are not TableValueExpr @@ -2394,11 +2394,11 @@ NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'a' HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. QUERY PLAN ----------------------------------------------------------------------------------- - Redistribute Motion 1:3 (slice1; segments: 1) (cost=0.00..0.02 rows=8 width=36) - Hash Key: a - -> Table Function Scan on multi_args (cost=0.00..0.02 rows=8 width=36) - -> Result (cost=0.00..0.01 rows=1 width=0) - Settings: gp_segments_for_planner=8 + Redistribute Motion 1:3 (slice1; segments: 1) (cost=0.00..0.04 rows=1 width=36) + Hash Key: multi_args.a + -> Table Function Scan on multi_args (cost=0.00..0.02 rows=1 width=36) + -> Result (cost=0.00..0.01 rows=1 width=36) + Optimizer: Postgres query optimizer (5 rows) CREATE TABLE example_out AS SELECT * FROM multi_args( TABLE(SELECT 1::int, 'hello'::text), 2); @@ -2416,7 +2416,7 @@ DROP TABLE example_out; -- =============== DROP VIEW example_v; ALTER TABLE example DROP column a; -NOTICE: dropping a column that is part of the distribution policy forces a random distribution policy +NOTICE: dropping a column that is part of the distribution policy forces a NULL distribution policy -- ERROR: input tuple does not conform to expectations of multiset_5 SELECT * FROM multiset_5( TABLE( SELECT 'hello'::text) ) as tf; ERROR: invalid input tuple for function multiset_example @@ -2434,6 +2434,7 @@ SELECT * FROM multiset_5( TABLE( SELECT 1::integer, 'hello'::text) ) as tf; -- start_ignore -- These may have been created by previous test create language plpython3u; +ERROR: extension "plpython3u" already exists -- end_ignore CREATE FUNCTION tf_sql(anytable) returns int AS $$ SELECT 1 $$ language sql CONTAINS SQL; ERROR: SQL functions cannot have arguments of type anytable @@ -2988,14 +2989,14 @@ SELECT * FROM project( TABLE( SELECT * FROM pg_am WHERE amname not in ('pax') ), amname ----------- heap - ao_row - ao_column btree hash gist gin spgist brin + ao_row + ao_column bitmap heap2 (11 rows) @@ -3005,14 +3006,14 @@ SELECT * FROM project( TABLE( SELECT * FROM pg_am WHERE amname not in ('pax') ), amname ----------- heap - ao_row - ao_column btree hash gist gin spgist brin + ao_row + ao_column bitmap heap2 (11 rows) @@ -3027,7 +3028,7 @@ SELECT "time"+1 FROM project( TABLE( SELECT * FROM history ), 2); ERROR: operator does not exist: timestamp without time zone + integer LINE 1: SELECT "time"+1 FROM project( TABLE( SELECT * FROM history )... ^ -HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. +HINT: No operator matches the given name and argument types. You might need to add explicit type casts. -- ERROR: select columns projected out by the function SELECT id FROM project( TABLE( SELECT * FROM history ), 2); ERROR: column "id" does not exist @@ -3096,13 +3097,9 @@ CREATE FUNCTION noop_project(anytable) RETURNS setof RECORD SELECT * FROM noop_project( TABLE( SELECT * FROM history ) ) AS s (id integer, time timestamp); id | time ----+-------------------------- - 1 | Mon Aug 22 10:15:04 2011 - 1 | Mon Aug 22 10:16:10 2011 - 1 | Sun Aug 21 10:15:02 2011 - 1 | Sun Aug 21 10:15:30 2011 2 | Sun Aug 21 10:15:02 2011 - 2 | Sun Aug 21 10:16:02 2011 2 | Sun Aug 21 22:15:02 2011 + 2 | Sun Aug 21 10:16:02 2011 2 | Sun Aug 21 22:16:02 2011 3 | Fri Aug 19 19:05:13 2011 3 | Fri Aug 19 19:06:50 2011 @@ -3114,6 +3111,10 @@ SELECT * FROM noop_project( TABLE( SELECT * FROM history ) ) AS s (id integer, t 3 | Sat Aug 20 10:11:29 2011 3 | Sat Aug 20 10:17:10 2011 3 | Sat Aug 20 10:17:42 2011 + 1 | Sun Aug 21 10:15:02 2011 + 1 | Sun Aug 21 10:15:30 2011 + 1 | Mon Aug 22 10:15:04 2011 + 1 | Mon Aug 22 10:16:10 2011 (18 rows) -- SCATTER BY vs MEDIAN @@ -3138,6 +3139,7 @@ SELECT * FROM noop_project( TABLE( SELECT count(*) FROM history SCATTER BY media SELECT * FROM noop_project( TABLE( SELECT count(*) FROM history GROUP BY time SCATTER BY median(id) ) ) AS s (cnt bigint); cnt ----- + 2 1 1 1 @@ -3154,7 +3156,6 @@ SELECT * FROM noop_project( TABLE( SELECT count(*) FROM history GROUP BY time SC 1 1 1 - 2 (17 rows) -- ======================== diff --git a/src/test/regress/greenplum_schedule b/src/test/regress/greenplum_schedule index 84e8766844b..37ede5fe22c 100755 --- a/src/test/regress/greenplum_schedule +++ b/src/test/regress/greenplum_schedule @@ -214,6 +214,9 @@ test: rpt rpt_joins rpt_tpch rpt_returning test: bfv_cte test: bfv_joins bfv_subquery bfv_planner bfv_legacy bfv_temp bfv_dml +# GPORCA right semi / right anti hash join (optimizer_enable_right_semi_join) +test: rightsemijoin + # test tpcds query 04 test: tpcds_q04 diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql index 4afd7f9f45b..52b39c10fdc 100644 --- a/src/test/regress/sql/join.sql +++ b/src/test/regress/sql/join.sql @@ -213,11 +213,16 @@ SELECT * -- -- semijoin selectivity for <> -- -explain (costs off) -select * from int4_tbl i4, tenk1 a -where exists(select * from tenk1 b - where a.twothousand = b.twothousand and a.fivethous <> b.fivethous) - and i4.f1 = a.tenthous; +-- start_ignore +-- GPDB: the exact plan shape depends on the optimizer (Postgres planner vs +-- GPORCA) and on MPP motion placement, so the plan is ignored here; this +-- query is retained from upstream only to exercise neqjoinsel's path. +explain (costs off) +select * from tenk1 a, tenk1 b +where exists(select * from tenk1 c + where b.twothousand = c.twothousand and b.fivethous <> c.fivethous) + and a.tenthous = b.tenthous and a.tenthous < 5000; +-- end_ignore -- @@ -731,6 +736,41 @@ where not exists (select 1 from tbl_ra t2 where t2.b = t1.a) and t1.b < 2; reset enable_hashjoin; reset enable_nestloop; +-- +-- regression test for bug with hash-right-semi join +-- +create temp table tbl_rs(a int, b int); +insert into tbl_rs select i, i from generate_series(1,10)i; +analyze tbl_rs; + +set enable_nestloop to off; +set enable_hashagg to off; + +-- ensure we get a hash right semi join with SubPlan in hash clauses +-- start_ignore +-- GPDB: the plan shape (and whether a right-semi join is chosen) depends on +-- the optimizer and MPP motions, so the plan is ignored; correctness of the +-- rescan match-flag reset is verified by the result of the query below. +explain (costs off) +select * from tbl_rs t1 +where (select a from tbl_rs t2 + where exists (select 1 from + (select (b in (select b from tbl_rs t3)) as c from tbl_rs t4 where t4.a = 1) s + where c in (select t1.a = 1 from tbl_rs t5 union all select true)) + order by a limit 1) >= 0; +-- end_ignore + +-- and check we get the expected results +select * from tbl_rs t1 +where (select a from tbl_rs t2 + where exists (select 1 from + (select (b in (select b from tbl_rs t3)) as c from tbl_rs t4 where t4.a = 1) s + where c in (select t1.a = 1 from tbl_rs t5 union all select true)) + order by a limit 1) >= 0; + +reset enable_nestloop; +reset enable_hashagg; + -- -- regression test for bug #13908 (hash join with skew tuples & nbatch increase) -- diff --git a/src/test/regress/sql/rightsemijoin.sql b/src/test/regress/sql/rightsemijoin.sql new file mode 100644 index 00000000000..c0e0a5fafda --- /dev/null +++ b/src/test/regress/sql/rightsemijoin.sql @@ -0,0 +1,76 @@ +-- +-- Right Semi / Right Anti Join (GPORCA) +-- +-- GPORCA can build the hash table on the (smaller) left-hand side of a semi or +-- anti join and probe it with the larger right-hand side, which avoids having +-- to de-duplicate the large right side. The behaviour is controlled by the +-- developer GUC optimizer_enable_right_semi_join (ON by default). +-- +-- These cases force GPORCA (set optimizer=on) so the new +-- CPhysicalRightSemiHashJoin / CPhysicalRightAntiSemiHashJoin xforms are +-- exercised; the matching answer file rightsemijoin_optimizer.out captures the +-- right-semi/right-anti plan shapes, while rightsemijoin.out captures the +-- Postgres planner plans. +-- +create schema rsj; +set search_path = rsj, public; + +-- stabilize the join method across planners +set enable_nestloop = off; +set enable_mergejoin = off; + +create table rsj_small(a int, b int) distributed by (a); +create table rsj_big(a int, b int) distributed by (a); + +-- small LHS: 1..50, plus two values absent from rsj_big +insert into rsj_small select i, i from generate_series(1,50) i; +insert into rsj_small values (600001, 1), (600002, 2); + +-- large, high-NDV RHS: de-duplicating it would be expensive, so the right-semi +-- plan (build on the small LHS) wins. +insert into rsj_big select i, i from generate_series(1,500000) i; + +analyze rsj_small; +analyze rsj_big; + +-- +-- Semi join (IN): GUC on -> Hash Right Semi Join (build on small LHS) +-- +set optimizer_enable_right_semi_join = on; +explain (costs off) +select * from rsj_small s where s.a in (select a from rsj_big b); + +-- GUC off -> regular Hash Semi Join (build on RHS) +set optimizer_enable_right_semi_join = off; +explain (costs off) +select * from rsj_small s where s.a in (select a from rsj_big b); + +-- +-- Anti join (NOT EXISTS): GUC on -> Hash Right Anti Join (build on small LHS) +-- +set optimizer_enable_right_semi_join = on; +explain (costs off) +select * from rsj_small s where not exists (select 1 from rsj_big b where b.a = s.a); + +-- GUC off -> regular Hash Anti Join +set optimizer_enable_right_semi_join = off; +explain (costs off) +select * from rsj_small s where not exists (select 1 from rsj_big b where b.a = s.a); + +-- +-- Correctness: results are identical regardless of the GUC / plan shape. +-- +set optimizer_enable_right_semi_join = on; +select count(*) as semi_on from rsj_small s where s.a in (select a from rsj_big b); +select count(*) as anti_on from rsj_small s where not exists (select 1 from rsj_big b where b.a = s.a); +set optimizer_enable_right_semi_join = off; +select count(*) as semi_off from rsj_small s where s.a in (select a from rsj_big b); +select count(*) as anti_off from rsj_small s where not exists (select 1 from rsj_big b where b.a = s.a); + +reset optimizer_enable_right_semi_join; +reset enable_nestloop; +reset enable_mergejoin; +reset search_path; +set client_min_messages = warning; +drop schema rsj cascade; +reset client_min_messages; diff --git a/src/test/singlenode_regress/expected/aggregates.out b/src/test/singlenode_regress/expected/aggregates.out index faff600bfd1..1315f407d05 100644 --- a/src/test/singlenode_regress/expected/aggregates.out +++ b/src/test/singlenode_regress/expected/aggregates.out @@ -2924,7 +2924,7 @@ FROM (SELECT * FROM tenk1 Output: tenk1_2.unique1 -> Seq Scan on public.tenk1 tenk1_3 Output: tenk1_3.unique1 - Settings: enable_indexonlyscan = 'off', min_parallel_table_scan_size = '0', parallel_setup_cost = '0', parallel_tuple_cost = '0' + Settings: parallel_setup_cost = '0', parallel_tuple_cost = '0', min_parallel_table_scan_size = '0', enable_indexonlyscan = 'off' Optimizer: Postgres query optimizer (13 rows) @@ -2959,7 +2959,7 @@ FROM (SELECT * FROM tenk1 Output: tenk1_2.unique1 -> Seq Scan on public.tenk1 tenk1_3 Output: tenk1_3.unique1 - Settings: enable_indexonlyscan = 'off', min_parallel_table_scan_size = '0', parallel_setup_cost = '0', parallel_tuple_cost = '0' + Settings: parallel_setup_cost = '0', parallel_tuple_cost = '0', min_parallel_table_scan_size = '0', enable_indexonlyscan = 'off' Optimizer: Postgres query optimizer (13 rows) @@ -3024,18 +3024,16 @@ set enable_memoize to off; explain (costs off) select 1 from tenk1 where (hundred, thousand) in (select twothousand, twothousand from onek); - QUERY PLAN -------------------------------------------------------------- - Hash Join - Hash Cond: (tenk1.hundred = onek.twothousand) - -> Seq Scan on tenk1 - Filter: (hundred = thousand) + QUERY PLAN +------------------------------------------------- + Hash Right Semi Join + Hash Cond: (onek.twothousand = tenk1.hundred) + -> Seq Scan on onek -> Hash - -> HashAggregate - Group Key: onek.twothousand, onek.twothousand - -> Seq Scan on onek + -> Seq Scan on tenk1 + Filter: (hundred = thousand) Optimizer: Postgres query optimizer -(9 rows) +(7 rows) reset enable_memoize; -- @@ -3225,17 +3223,17 @@ drop table agg_hash_4; */ set enable_indexonlyscan = off; explain analyze select count(*) from pg_class, (select count(*) >0 from (select count(*) from pg_class where relname like 't%')x)y; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- - Aggregate (cost=10000000047.47..10000000047.48 rows=1 width=8) (actual time=0.515..0.516 rows=1 loops=1) - -> Nested Loop (cost=10000000000.02..10000000043.98 rows=1397 width=0) (actual time=0.014..0.460 rows=889 loops=1) - -> Aggregate (cost=0.02..0.03 rows=1 width=1) (actual time=0.004..0.005 rows=1 loops=1) - -> Result (cost=0.00..0.01 rows=1 width=8) (actual time=0.001..0.002 rows=1 loops=1) - -> Seq Scan on pg_class (cost=0.00..29.97 rows=1397 width=0) (actual time=0.009..0.371 rows=889 loops=1) - Planning Time: 0.760 ms - (slice0) Executor memory: 128K bytes. + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- + Aggregate (cost=10000000083.05..10000000083.06 rows=1 width=8) (actual time=0.485..0.486 rows=1 loops=1) + -> Nested Loop (cost=10000000000.02..10000000076.16 rows=2756 width=0) (actual time=0.019..0.420 rows=1115 loops=1) + -> Aggregate (cost=0.02..0.03 rows=1 width=1) (actual time=0.002..0.002 rows=1 loops=1) + -> Result (cost=0.00..0.01 rows=1 width=8) (actual time=0.000..0.001 rows=1 loops=1) + -> Seq Scan on pg_class (cost=0.00..48.56 rows=2756 width=0) (actual time=0.017..0.306 rows=1115 loops=1) + Planning Time: 0.238 ms + (slice0) Executor memory: 125K bytes. Memory used: 128000kB Optimizer: Postgres query optimizer - Execution Time: 0.603 ms + Execution Time: 0.540 ms (10 rows) diff --git a/src/test/singlenode_regress/expected/join.out b/src/test/singlenode_regress/expected/join.out index 39d9b380994..e11ba089706 100644 --- a/src/test/singlenode_regress/expected/join.out +++ b/src/test/singlenode_regress/expected/join.out @@ -218,13 +218,13 @@ SELECT t1.a, t2.e WHERE t1.a = t2.d; a | e ---+---- - 0 | 1 | -1 2 | 2 - 2 | 4 3 | -3 + 2 | 4 5 | -5 5 | -5 + 0 | (7 rows) -- @@ -1573,13 +1573,13 @@ SELECT * FROM J1_TBL INNER JOIN J2_TBL USING (i); i | j | t | k ---+---+-------+---- - 0 | | zero | 1 | 4 | one | -1 2 | 3 | two | 2 - 2 | 3 | two | 4 3 | 2 | three | -3 + 2 | 3 | two | 4 5 | 0 | five | -5 5 | 0 | five | -5 + 0 | | zero | (7 rows) -- Same as above, slightly different syntax @@ -1587,13 +1587,13 @@ SELECT * FROM J1_TBL JOIN J2_TBL USING (i); i | j | t | k ---+---+-------+---- - 0 | | zero | 1 | 4 | one | -1 2 | 3 | two | 2 - 2 | 3 | two | 4 3 | 2 | three | -3 + 2 | 3 | two | 4 5 | 0 | five | -5 5 | 0 | five | -5 + 0 | | zero | (7 rows) SELECT * @@ -1681,35 +1681,35 @@ SELECT * FROM J1_TBL NATURAL JOIN J2_TBL; i | j | t | k ---+---+-------+---- - 0 | | zero | 1 | 4 | one | -1 2 | 3 | two | 2 - 2 | 3 | two | 4 3 | 2 | three | -3 + 2 | 3 | two | 4 5 | 0 | five | -5 5 | 0 | five | -5 + 0 | | zero | (7 rows) SELECT * FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (a, d); a | b | c | d ---+---+-------+---- - 0 | | zero | 1 | 4 | one | -1 2 | 3 | two | 2 - 2 | 3 | two | 4 3 | 2 | three | -3 + 2 | 3 | two | 4 5 | 0 | five | -5 5 | 0 | five | -5 + 0 | | zero | (7 rows) SELECT * FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a); a | b | c | d ---+---+------+--- - 0 | | zero | 2 | 3 | two | 2 4 | 1 | four | 2 + 0 | | zero | (3 rows) -- mismatch number of columns @@ -1718,13 +1718,13 @@ SELECT * FROM J1_TBL t1 (a, b) NATURAL JOIN J2_TBL t2 (a); a | b | t | k ---+---+-------+---- - 0 | | zero | 1 | 4 | one | -1 2 | 3 | two | 2 - 2 | 3 | two | 4 3 | 2 | three | -3 + 2 | 3 | two | 4 5 | 0 | five | -5 5 | 0 | five | -5 + 0 | | zero | (7 rows) -- @@ -1734,22 +1734,22 @@ SELECT * FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.i); i | j | t | i | k ---+---+-------+---+---- - 0 | | zero | 0 | 1 | 4 | one | 1 | -1 2 | 3 | two | 2 | 2 - 2 | 3 | two | 2 | 4 3 | 2 | three | 3 | -3 + 2 | 3 | two | 2 | 4 5 | 0 | five | 5 | -5 5 | 0 | five | 5 | -5 + 0 | | zero | 0 | (7 rows) SELECT * FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.k); i | j | t | i | k ---+---+------+---+--- - 0 | | zero | | 0 2 | 3 | two | 2 | 2 4 | 1 | four | 2 | 4 + 0 | | zero | | 0 (3 rows) -- @@ -1818,13 +1818,13 @@ SELECT * FROM J1_TBL RIGHT OUTER JOIN J2_TBL USING (i); i | j | t | k ---+---+-------+---- - 0 | | zero | 1 | 4 | one | -1 2 | 3 | two | 2 - 2 | 3 | two | 4 3 | 2 | three | -3 + 2 | 3 | two | 4 5 | 0 | five | -5 5 | 0 | five | -5 + 0 | | zero | | | | | | | 0 (9 rows) @@ -1833,13 +1833,13 @@ SELECT * FROM J1_TBL RIGHT JOIN J2_TBL USING (i); i | j | t | k ---+---+-------+---- - 0 | | zero | 1 | 4 | one | -1 2 | 3 | two | 2 - 2 | 3 | two | 4 3 | 2 | three | -3 + 2 | 3 | two | 4 5 | 0 | five | -5 5 | 0 | five | -5 + 0 | | zero | | | | | | | 0 (9 rows) @@ -1909,18 +1909,18 @@ select * from int4_tbl i4, tenk1 a where exists(select * from tenk1 b where a.twothousand = b.twothousand and a.fivethous <> b.fivethous) and i4.f1 = a.tenthous; - QUERY PLAN ----------------------------------------------- - Hash Semi Join - Hash Cond: (a.twothousand = b.twothousand) + QUERY PLAN +------------------------------------------------- + Hash Right Semi Join + Hash Cond: (b.twothousand = a.twothousand) Join Filter: (a.fivethous <> b.fivethous) - -> Hash Join - Hash Cond: (a.tenthous = i4.f1) - -> Seq Scan on tenk1 a - -> Hash - -> Seq Scan on int4_tbl i4 + -> Seq Scan on tenk1 b -> Hash - -> Seq Scan on tenk1 b + -> Hash Join + Hash Cond: (a.tenthous = i4.f1) + -> Seq Scan on tenk1 a + -> Hash + -> Seq Scan on int4_tbl i4 Optimizer: Postgres query optimizer (11 rows) @@ -1945,8 +1945,8 @@ SELECT * FROM t1 FULL JOIN t2 USING (name) FULL JOIN t3 USING (name); ------+----+----+---- bb | 11 | 12 | 13 cc | | 22 | 23 - dd | | | 33 ee | | 42 | + dd | | | 33 (4 rows) -- @@ -1985,8 +1985,8 @@ USING (name); ------+----+---- bb | 12 | 13 cc | 22 | 23 - dd | | 33 ee | 42 | + dd | | 33 (4 rows) -- Cases with non-nullable expressions in subquery results; @@ -2020,8 +2020,8 @@ NATURAL FULL JOIN ------+------+------+------+------ bb | 12 | 2 | 13 | 3 cc | 22 | 2 | 23 | 3 - dd | | | 33 | 3 ee | 42 | 2 | | + dd | | | 33 | 3 (4 rows) SELECT * FROM @@ -2045,8 +2045,8 @@ NATURAL FULL JOIN ------+------+------+------+------+------+------ bb | 11 | 1 | 12 | 2 | 13 | 3 cc | | | 22 | 2 | 23 | 3 - dd | | | | | 33 | 3 ee | | | 42 | 2 | | + dd | | | | | 33 | 3 (4 rows) SELECT * FROM @@ -2061,8 +2061,8 @@ NATURAL FULL JOIN ------+------+------+------ bb | 11 | 12 | 13 cc | | 22 | 23 - dd | | | 33 ee | | 42 | + dd | | | 33 (4 rows) SELECT * FROM @@ -2077,8 +2077,8 @@ NATURAL FULL JOIN ------+------+------+------+------ bb | 11 | 12 | 2 | 13 cc | | 22 | 2 | 23 - dd | | | | 33 ee | | 42 | 2 | + dd | | | | 33 (4 rows) -- Constants as join keys can also be problematic @@ -2089,10 +2089,10 @@ FULL JOIN ON (s1_n = s2_n); name | s1_n | name | s2_n ------+------+------+------ - | | bb | 2 - | | cc | 2 - | | ee | 2 bb | 11 | | + | | ee | 2 + | | cc | 2 + | | bb | 2 (4 rows) -- Test for propagation of nullability constraints into sub-joins @@ -2395,23 +2395,23 @@ select * from ---+---+-------+---+---- | | | | 0 | | | | - | 0 | zero | | - | | null | | - 8 | 8 | eight | | - 7 | 7 | seven | | - 6 | 6 | six | | | | | 5 | -5 | | | 5 | -5 - 5 | 0 | five | | - 4 | 1 | four | | | | | 3 | -3 - 3 | 2 | three | | 2 | 3 | two | 2 | 2 | | | 2 | 4 | | | 1 | -1 | | | 0 | + | 0 | zero | | + | | null | | + 6 | 6 | six | | + 8 | 8 | eight | | 1 | 4 | one | | 0 | | zero | | + 5 | 0 | five | | + 7 | 7 | seven | | + 4 | 1 | four | | + 3 | 2 | three | | (19 rows) reset enable_mergejoin; @@ -2595,8 +2595,8 @@ WHERE d.f1 IS NULL; f1 ------ 0 - 1 9999 + 1 (3 rows) -- @@ -4584,8 +4584,8 @@ explain (verbose, costs off) select a.q2, b.q1 from int8_tbl a left join int8_tbl b on a.q2 = coalesce(b.q1, 1) where coalesce(b.q1, 1) > 0; - QUERY PLAN -------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Nested Loop Left Join Output: a.q2, b.q1 Join Filter: (a.q2 = COALESCE(b.q1, '1'::bigint)) @@ -4605,16 +4605,16 @@ select a.q2, b.q1 where coalesce(b.q1, 1) > 0; q2 | q1 -------------------+------------------ - -4567890123456789 | - 123 | 123 - 123 | 123 456 | 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 + 123 | 123 + 123 | 123 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 + -4567890123456789 | (10 rows) reset enable_hashjoin; @@ -4875,11 +4875,11 @@ SELECT * FROM ON true; x | q1 | q2 | y ---+------------------+-------------------+------------------ - 1 | 123 | 456 | 123 - 1 | 123 | 4567890123456789 | 123 1 | 4567890123456789 | 123 | 42 - 1 | 4567890123456789 | 4567890123456789 | 4567890123456789 1 | 4567890123456789 | -4567890123456789 | 4567890123456789 + 1 | 123 | 456 | 123 + 1 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 1 | 123 | 4567890123456789 | 123 (5 rows) rollback; @@ -5561,10 +5561,10 @@ select v.* from 4567890123456789 | -4567890123456789 123 | 4567890123456789 4567890123456789 | -4567890123456789 - 123 | - 456 | 4567890123456789 | -4567890123456789 | + 123 | + 456 | (20 rows) select v.* from @@ -5589,10 +5589,10 @@ select v.* from 4567890123456789 | -4567890123456789 123 | 4567890123456789 4567890123456789 | -4567890123456789 - 123 | - 456 | 4567890123456789 | -4567890123456789 | + 123 | + 456 | (20 rows) explain (verbose, costs off) @@ -5984,7 +5984,7 @@ select * from int8_tbl i8 left join lateral Output: f1, i8.q2 One-Time Filter: false Optimizer: Postgres query optimizer -(10 rows) +(9 rows) explain (verbose, costs off) select * from int8_tbl i8 left join lateral diff --git a/src/test/singlenode_regress/expected/join_gp.out b/src/test/singlenode_regress/expected/join_gp.out index 4d8be480687..b04437290d0 100644 --- a/src/test/singlenode_regress/expected/join_gp.out +++ b/src/test/singlenode_regress/expected/join_gp.out @@ -28,8 +28,8 @@ explain select * from nhtest a join nhtest b using (i); select * from nhtest a join nhtest b using (i); i ----------- - 300000.19 100000.22 + 300000.19 (2 rows) create temp table l(a int); @@ -67,6 +67,7 @@ set enable_mergejoin to on; set enable_nestloop to off; DROP TABLE IF EXISTS alpha; DROP TABLE IF EXISTS theta; +NOTICE: table "theta" does not exist, skipping CREATE TABLE alpha (i int, j int); CREATE TABLE theta (i int, j char(10000000)); INSERT INTO alpha values (1, 1), (2, 2); @@ -194,10 +195,10 @@ select count(*) from hjn_test, (select 3 as bar) foo where hjn_test.i = least (f select * from int4_tbl a join int4_tbl b on (a.f1 = (select f1 from int4_tbl c where c.f1=b.f1)); f1 | f1 -------------+------------- - -2147483647 | -2147483647 123456 | 123456 - -123456 | -123456 + -2147483647 | -2147483647 0 | 0 + -123456 | -123456 2147483647 | 2147483647 (5 rows) @@ -212,9 +213,9 @@ insert into part4_tbl values select * from part4_tbl a join part4_tbl b on (a.f1 = (select f1 from int4_tbl c where c.f1=b.f1)); f1 | f1 ---------+--------- - 123456 | 123456 -123456 | -123456 0 | 0 + 123456 | 123456 (3 rows) -- @@ -235,18 +236,18 @@ from tjoin1 left outer join (tjoin2 left outer join tjoin3 on tjoin2.id=tjoin3.id) on tjoin1.id=tjoin3.id; id | t | t ----+-----+----- - 1 | 2-1 | 2-1 - 1 | 2-1 | 1-1 + 1 | 1-1 | 2-1 1 | 1-1 | 2-1 1 | 1-1 | 1-1 - 3 | | + 1 | 1-1 | 1-1 + 1 | 2-1 | 2-1 1 | 2-1 | 2-1 1 | 2-1 | 1-1 - 1 | 1-1 | 2-1 - 1 | 1-1 | 1-1 - 3 | | + 1 | 2-1 | 1-1 2 | | 2 | | + 3 | | + 3 | | (12 rows) set enable_hashjoin to off; @@ -279,9 +280,9 @@ select * from int4_tbl a join int4_tbl b on (a.f1 = (select f1 from int4_tbl c w f1 | f1 -------------+------------- -2147483647 | -2147483647 - 123456 | 123456 -123456 | -123456 0 | 0 + 123456 | 123456 2147483647 | 2147483647 (5 rows) @@ -454,8 +455,8 @@ insert into test_float2 values(3, 10), (4, 20); select t1.id, t1.data, t2.id, t2.data from test_float1 t1, test_float2 t2 where t1.data = t2.data; id | data | id | data ----+------+----+------ - 2 | 20 | 4 | 20 1 | 10 | 3 | 10 + 2 | 20 | 4 | 20 (2 rows) -- test int type @@ -647,8 +648,8 @@ explain (costs off) select * from t1 left join t2 on (t1.a = t2.a) join t3 on (t select * from t1 left join t2 on (t1.a = t2.a) join t3 on (t1.b = t3.b) where (t2.a is distinct from t3.a); a | b | c | a | b | c | a | b | c ---+---+---+---+---+---+---+---+--- - 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 + 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 (2 rows) -- ensure plan has a filter over left outer join @@ -712,10 +713,10 @@ select * from (select t1.a t1a, t1.b t1b, t2.a t2a, t2.b t2b from t1 left join t join t3 t3_1 on tt1.t1b = t3_1.b and (tt1.t2a is NULL OR tt1.t1b = t3.b); t1a | t1b | t2a | t2b | a | b | c | t1a | t1b | t2a | t2b | a | b | c -----+-----+-----+-----+---+---+---+-----+-----+-----+-----+---+---+--- - 2 | 2 | 2 | 2 | | 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 - 2 | 2 | 2 | 2 | | 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 2 | 2 | 2 | 2 | 1 | 2 | 3 | 2 | 2 | 2 | 2 | | 2 | 2 + 2 | 2 | 2 | 2 | | 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 2 | 2 | 2 | 2 | 1 | 2 | 3 | 2 | 2 | 2 | 2 | 1 | 2 | 3 + 2 | 2 | 2 | 2 | | 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 (4 rows) -- test different join order enumeration methods @@ -731,8 +732,8 @@ set optimizer_join_order = greedy; select * from t1 join t2 on t1.a = t2.a join t3 on t1.b = t3.b; a | b | c | a | b | c | a | b | c ---+---+---+---+---+---+---+---+--- - 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 3 + 2 | 2 | 2 | 2 | 2 | 2 | | 2 | 2 (2 rows) set optimizer_join_order = exhaustive; @@ -778,10 +779,10 @@ set enable_bitmapscan = 0; explain select tenk1.unique2 >= 0 from tenk1 left join tenk2 on true limit 1; QUERY PLAN -------------------------------------------------------------------------------------------------- - Limit (cost=0.57..0.63 rows=1 width=1) - -> Nested Loop Left Join (cost=0.57..6353036.29 rows=100000000 width=1) + Limit (cost=0.57..0.60 rows=1 width=1) + -> Nested Loop Left Join (cost=0.57..2953036.28 rows=100000000 width=1) -> Index Only Scan using tenk1_unique2 on tenk1 (cost=0.29..186.28 rows=10000 width=4) - -> Index Only Scan using tenk2_hundred on tenk2 (cost=0.29..510.29 rows=10000 width=0) + -> Index Only Scan using tenk2_hundred on tenk2 (cost=0.29..170.28 rows=10000 width=0) Optimizer: Postgres query optimizer (5 rows) @@ -843,14 +844,14 @@ select * from generate_series(1, 5) g left join trep_join_gp on g = trep_join_gp g | c1 | c2 | c1 | c2 ---+----+----+----+---- 1 | 1 | 1 | 1 | 1 - 2 | 2 | 2 | 1 | 1 - 3 | | | 1 | 1 - 4 | | | 1 | 1 - 5 | | | 1 | 1 1 | 1 | 1 | 2 | 2 + 2 | 2 | 2 | 1 | 1 2 | 2 | 2 | 2 | 2 + 3 | | | 1 | 1 3 | | | 2 | 2 + 4 | | | 1 | 1 4 | | | 2 | 2 + 5 | | | 1 | 1 5 | | | 2 | 2 (10 rows) @@ -871,10 +872,10 @@ explain select * from generate_series(1, 5) g left join thash_join_gp on g = tha select * from generate_series(1, 5) g left join thash_join_gp on g = thash_join_gp.c1; g | c1 | c2 ---+----+---- + 1 | 1 | 1 2 | 2 | 2 3 | | 4 | | - 1 | 1 | 1 5 | | (5 rows) @@ -892,11 +893,11 @@ explain select * from generate_series(1, 5) g left join thash_join_gp on g = tha select * from generate_series(1, 5) g left join thash_join_gp on g = thash_join_gp.c2; g | c1 | c2 ---+----+---- - 5 | | + 1 | 1 | 1 2 | 2 | 2 3 | | 4 | | - 1 | 1 | 1 + 5 | | (5 rows) explain select * from generate_series(1, 5) g left join trand_join_gp on g = trand_join_gp.c1; @@ -913,10 +914,10 @@ explain select * from generate_series(1, 5) g left join trand_join_gp on g = tra select * from generate_series(1, 5) g left join trand_join_gp on g = trand_join_gp.c1; g | c1 | c2 ---+----+---- + 1 | | 2 | | 3 | | 4 | | - 1 | | 5 | | (5 rows) @@ -934,10 +935,10 @@ explain select * from generate_series(1, 5) g full join trand_join_gp on g = tra select * from generate_series(1, 5) g full join trand_join_gp on g = trand_join_gp.c1; g | c1 | c2 ---+----+---- + 1 | | 2 | | 3 | | 4 | | - 1 | | 5 | | (5 rows) @@ -977,8 +978,8 @@ explain select * from trep_join_gp left join trand_join_gp using (c1); select * from trep_join_gp left join trand_join_gp using (c1); c1 | c2 | c2 ----+----+---- - 2 | 2 | 1 | 1 | + 2 | 2 | (2 rows) explain select * from trep1_join_gp join thash_join_gp using (c1); @@ -1097,9 +1098,9 @@ explain select * from t1_lateral_limit as t1 cross join lateral (select ((c).x+t2.b) as n from t2_lateral_limit as t2 order by n limit 1)s; QUERY PLAN ------------------------------------------------------------------------------------------------ - Nested Loop (cost=10000000169.08..10000813417.08 rows=4810 width=44) + Nested Loop (cost=10000000169.08..10000813368.98 rows=4810 width=44) -> Seq Scan on t1_lateral_limit t1 (cost=0.00..58.10 rows=4810 width=40) - -> Materialize (cost=169.08..169.09 rows=1 width=4) + -> Materialize (cost=169.08..169.08 rows=1 width=4) -> Limit (cost=169.08..169.08 rows=1 width=4) -> Sort (cost=169.08..191.80 rows=9090 width=4) Sort Key: (((t1.c).x + t2.b)) @@ -1154,9 +1155,9 @@ explain select * from t1_lateral_limit t1 cross join lateral (select (c).x+t2.a, sum(t2.a+t2.b) from t2_lateral_limit t2 group by (c).x+t2.a)x; QUERY PLAN ------------------------------------------------------------------------------------------- - Nested Loop (cost=10000000191.80..10001078941.10 rows=4810000 width=52) + Nested Loop (cost=10000000191.80..10001030841.10 rows=4810000 width=52) -> Seq Scan on t1_lateral_limit t1 (cost=0.00..58.10 rows=4810 width=40) - -> Materialize (cost=191.80..219.30 rows=1000 width=12) + -> Materialize (cost=191.80..209.30 rows=1000 width=12) -> HashAggregate (cost=191.80..204.30 rows=1000 width=12) Group Key: ((t1.c).x + t2.a) -> Seq Scan on t2_lateral_limit t2 (cost=0.00..123.62 rows=9090 width=12) @@ -1167,8 +1168,8 @@ select * from t1_lateral_limit t1 cross join lateral (select (c).x+t2.a, sum(t2.a+t2.b) from t2_lateral_limit t2 group by (c).x+t2.a)x; a | b | c | ?column? | sum ---+---+-------+----------+----- - 1 | 1 | (1,1) | 4 | 6 1 | 1 | (1,1) | 3 | 4 + 1 | 1 | (1,1) | 4 | 6 1 | 2 | (2,2) | 5 | 6 1 | 2 | (2,2) | 4 | 4 (4 rows) @@ -1204,8 +1205,8 @@ inner join lateral on true; myid | first_date | next_date ------+------------------------------+------------------------------ - 2 | Sun Jan 02 01:04:00 2000 PST | Sun Jan 02 03:04:00 2000 PST 1 | Sun Jan 02 02:04:00 2000 PST | Sun Jan 02 03:04:00 2000 PST + 2 | Sun Jan 02 01:04:00 2000 PST | Sun Jan 02 03:04:00 2000 PST (2 rows) -- test prefetch join qual @@ -1346,27 +1347,27 @@ explain (costs off) select * from foo where exists (select 1 from bar where foo.a = bar.b); QUERY PLAN ------------------------------------- - Hash Semi Join - Hash Cond: (foo.a = bar.b) - -> Seq Scan on foo + Hash Right Semi Join + Hash Cond: (bar.b = foo.a) + -> Seq Scan on bar -> Hash - -> Seq Scan on bar + -> Seq Scan on foo Optimizer: Postgres query optimizer (6 rows) select * from foo where exists (select 1 from bar where foo.a = bar.b); a ---- - 10 - 9 + 1 + 2 3 - 7 4 5 - 8 - 1 - 2 6 + 7 + 8 + 9 + 10 (10 rows) set enable_hashagg to off; @@ -1374,11 +1375,11 @@ explain (costs off) select * from foo where exists (select 1 from bar where foo.a = bar.b); QUERY PLAN ------------------------------------- - Hash Semi Join - Hash Cond: (foo.a = bar.b) - -> Seq Scan on foo + Hash Right Semi Join + Hash Cond: (bar.b = foo.a) + -> Seq Scan on bar -> Hash - -> Seq Scan on bar + -> Seq Scan on foo Optimizer: Postgres query optimizer (6 rows) @@ -1481,20 +1482,20 @@ full join ( select r.id1, r.id2 from t_issue_10315 r group by r.id1, r.id2 ) tq_ on (coalesce(t.id1) = tq_all.id1 and t.id2 = tq_all.id2) ; id1 | id2 | id1 | id2 | id1 | id2 -----+-----+-----+-----+-----+----- + 1 | 1 | 1 | 1 | 1 | 1 + | 2 | | | | 2 | 2 | 2 | 2 | 2 | 2 + 1 | | | | | 2 | | | | | | 1 | | | | - | 2 | | | | + | | 1 | | | | | | 2 | | | | | 1 | | | | 2 | | | - | | 1 | | | + | | | | 1 | | | | | | 2 | | | | | 1 | | | | 2 | - 1 | 1 | 1 | 1 | 1 | 1 - 1 | | | | | - | | | | 1 | (14 rows) drop table t_issue_10315; diff --git a/src/test/singlenode_regress/expected/partition_join.out b/src/test/singlenode_regress/expected/partition_join.out index 6fe266d4140..22211eac90d 100644 --- a/src/test/singlenode_regress/expected/partition_join.out +++ b/src/test/singlenode_regress/expected/partition_join.out @@ -925,50 +925,46 @@ SELECT t1.a, t1.phv, t2.b, t2.phv, t3.a + t3.b, t3.phv FROM ((SELECT 50 phv, * F -- Semi-join EXPLAIN (COSTS OFF) SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1, prt1_e t2 WHERE t1.a = 0 AND t1.b = (t2.a + t2.b)/2) AND t1.b = 0 ORDER BY t1.a; - QUERY PLAN -------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------- Sort Sort Key: t1.a -> Append - -> Hash Semi Join - Hash Cond: (t1_2.a = t1_5.b) - -> Seq Scan on prt1_p1 t1_2 - Filter: (b = 0) + -> Hash Right Semi Join + Hash Cond: (t1_5.b = t1_2.a) + -> Hash Join + Hash Cond: (((t2_1.a + t2_1.b) / 2) = t1_5.b) + -> Seq Scan on prt1_e_p1 t2_1 + -> Hash + -> Seq Scan on prt2_p1 t1_5 + Filter: (a = 0) -> Hash - -> Hash Join - Hash Cond: (((t2_1.a + t2_1.b) / 2) = t1_5.b) - -> Seq Scan on prt1_e_p1 t2_1 - -> Hash - -> Seq Scan on prt2_p1 t1_5 - Filter: (a = 0) - -> Hash Join - Hash Cond: (t1_3.a = t1_6.b) - -> Seq Scan on prt1_p2 t1_3 - Filter: (b = 0) + -> Seq Scan on prt1_p1 t1_2 + Filter: (b = 0) + -> Hash Right Semi Join + Hash Cond: (t1_6.b = t1_3.a) + -> Hash Join + Hash Cond: (((t2_2.a + t2_2.b) / 2) = t1_6.b) + -> Seq Scan on prt1_e_p2 t2_2 + -> Hash + -> Seq Scan on prt2_p2 t1_6 + Filter: (a = 0) -> Hash - -> HashAggregate - Group Key: t1_6.b - -> Hash Join - Hash Cond: (((t2_2.a + t2_2.b) / 2) = t1_6.b) - -> Seq Scan on prt1_e_p2 t2_2 - -> Hash - -> Seq Scan on prt2_p2 t1_6 - Filter: (a = 0) - -> Hash Join - Hash Cond: (t1_4.a = t1_7.b) - -> Seq Scan on prt1_p3 t1_4 - Filter: (b = 0) + -> Seq Scan on prt1_p2 t1_3 + Filter: (b = 0) + -> Hash Right Semi Join + Hash Cond: (t1_7.b = t1_4.a) + -> Hash Join + Hash Cond: (((t2_3.a + t2_3.b) / 2) = t1_7.b) + -> Seq Scan on prt1_e_p3 t2_3 + -> Hash + -> Seq Scan on prt2_p3 t1_7 + Filter: (a = 0) -> Hash - -> HashAggregate - Group Key: t1_7.b - -> Hash Join - Hash Cond: (((t2_3.a + t2_3.b) / 2) = t1_7.b) - -> Seq Scan on prt1_e_p3 t2_3 - -> Hash - -> Seq Scan on prt2_p3 t1_7 - Filter: (a = 0) + -> Seq Scan on prt1_p3 t1_4 + Filter: (b = 0) Optimizer: Postgres query optimizer -(41 rows) +(37 rows) SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1, prt1_e t2 WHERE t1.a = 0 AND t1.b = (t2.a + t2.b)/2) AND t1.b = 0 ORDER BY t1.a; a | b | c @@ -2341,24 +2337,24 @@ SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a Sort Sort Key: t1.a -> Append - -> Hash Semi Join - Hash Cond: (t1_1.a = t2_1.b) - -> Seq Scan on prt1_adv_p1 t1_1 - Filter: (b = 0) + -> Hash Right Semi Join + Hash Cond: (t2_1.b = t1_1.a) + -> Seq Scan on prt2_adv_p1 t2_1 -> Hash - -> Seq Scan on prt2_adv_p1 t2_1 - -> Hash Semi Join - Hash Cond: (t1_2.a = t2_2.b) - -> Seq Scan on prt1_adv_p2 t1_2 - Filter: (b = 0) + -> Seq Scan on prt1_adv_p1 t1_1 + Filter: (b = 0) + -> Hash Right Semi Join + Hash Cond: (t2_2.b = t1_2.a) + -> Seq Scan on prt2_adv_p2 t2_2 -> Hash - -> Seq Scan on prt2_adv_p2 t2_2 - -> Hash Semi Join - Hash Cond: (t1_3.a = t2_3.b) - -> Seq Scan on prt1_adv_p3 t1_3 - Filter: (b = 0) + -> Seq Scan on prt1_adv_p2 t1_2 + Filter: (b = 0) + -> Hash Right Semi Join + Hash Cond: (t2_3.b = t1_3.a) + -> Seq Scan on prt2_adv_p3 t2_3 -> Hash - -> Seq Scan on prt2_adv_p3 t2_3 + -> Seq Scan on prt1_adv_p3 t1_3 + Filter: (b = 0) Optimizer: Postgres query optimizer (22 rows) @@ -2555,24 +2551,24 @@ SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a Sort Sort Key: t1.a -> Append - -> Hash Semi Join - Hash Cond: (t1_1.a = t2_1.b) - -> Seq Scan on prt1_adv_p1 t1_1 - Filter: (b = 0) + -> Hash Right Semi Join + Hash Cond: (t2_1.b = t1_1.a) + -> Seq Scan on prt2_adv_p1 t2_1 -> Hash - -> Seq Scan on prt2_adv_p1 t2_1 - -> Hash Semi Join - Hash Cond: (t1_2.a = t2_2.b) - -> Seq Scan on prt1_adv_p2 t1_2 - Filter: (b = 0) + -> Seq Scan on prt1_adv_p1 t1_1 + Filter: (b = 0) + -> Hash Right Semi Join + Hash Cond: (t2_2.b = t1_2.a) + -> Seq Scan on prt2_adv_p2 t2_2 -> Hash - -> Seq Scan on prt2_adv_p2 t2_2 - -> Hash Semi Join - Hash Cond: (t1_3.a = t2_3.b) - -> Seq Scan on prt1_adv_p3 t1_3 - Filter: (b = 0) + -> Seq Scan on prt1_adv_p2 t1_2 + Filter: (b = 0) + -> Hash Right Semi Join + Hash Cond: (t2_3.b = t1_3.a) + -> Seq Scan on prt2_adv_p3 t2_3 -> Hash - -> Seq Scan on prt2_adv_p3 t2_3 + -> Seq Scan on prt1_adv_p3 t1_3 + Filter: (b = 0) Optimizer: Postgres query optimizer (22 rows) @@ -2849,25 +2845,25 @@ SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_adv t1 INNER JOIN prt2_adv t2 ON (t1.a = -- semi join EXPLAIN (COSTS OFF) SELECT t1.* FROM prt1_adv t1 WHERE EXISTS (SELECT 1 FROM prt2_adv t2 WHERE t1.a = t2.b) AND t1.b = 0 ORDER BY t1.a; - QUERY PLAN --------------------------------------------------------- + QUERY PLAN +------------------------------------------------------ Sort Sort Key: t1.a - -> Hash Semi Join - Hash Cond: (t1.a = t2.b) + -> Hash Right Semi Join + Hash Cond: (t2.b = t1.a) -> Append - -> Seq Scan on prt1_adv_p1 t1_1 - Filter: (b = 0) - -> Seq Scan on prt1_adv_p2 t1_2 - Filter: (b = 0) - -> Seq Scan on prt1_adv_p3 t1_3 - Filter: (b = 0) + -> Seq Scan on prt2_adv_p1 t2_1 + -> Seq Scan on prt2_adv_p2 t2_2 + -> Seq Scan on prt2_adv_p3_1 t2_3 + -> Seq Scan on prt2_adv_p3_2 t2_4 -> Hash -> Append - -> Seq Scan on prt2_adv_p1 t2_1 - -> Seq Scan on prt2_adv_p2 t2_2 - -> Seq Scan on prt2_adv_p3_1 t2_3 - -> Seq Scan on prt2_adv_p3_2 t2_4 + -> Seq Scan on prt1_adv_p1 t1_1 + Filter: (b = 0) + -> Seq Scan on prt1_adv_p2 t1_2 + Filter: (b = 0) + -> Seq Scan on prt1_adv_p3 t1_3 + Filter: (b = 0) Optimizer: Postgres query optimizer (18 rows) @@ -3266,24 +3262,24 @@ SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a Sort Sort Key: t1.a -> Append - -> Hash Semi Join - Hash Cond: ((t1_1.a = t2_1.a) AND (t1_1.c = t2_1.c)) - -> Seq Scan on plt1_adv_p1 t1_1 - Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 -> Hash - -> Seq Scan on plt2_adv_p1 t2_1 - -> Hash Semi Join - Hash Cond: ((t1_2.a = t2_2.a) AND (t1_2.c = t2_2.c)) - -> Seq Scan on plt1_adv_p2 t1_2 - Filter: (b < 10) + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 -> Hash - -> Seq Scan on plt2_adv_p2 t2_2 - -> Hash Semi Join - Hash Cond: ((t1_3.a = t2_3.a) AND (t1_3.c = t2_3.c)) - -> Seq Scan on plt1_adv_p3 t1_3 - Filter: (b < 10) + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3 t2_3 -> Hash - -> Seq Scan on plt2_adv_p3 t2_3 + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) Optimizer: Postgres query optimizer (22 rows) @@ -3464,24 +3460,24 @@ SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a Sort Sort Key: t1.a -> Append - -> Hash Semi Join - Hash Cond: ((t1_1.a = t2_1.a) AND (t1_1.c = t2_1.c)) - -> Seq Scan on plt1_adv_p1 t1_1 - Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 -> Hash - -> Seq Scan on plt2_adv_p1 t2_1 - -> Hash Semi Join - Hash Cond: ((t1_2.a = t2_2.a) AND (t1_2.c = t2_2.c)) - -> Seq Scan on plt1_adv_p2 t1_2 - Filter: (b < 10) + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 -> Hash - -> Seq Scan on plt2_adv_p2 t2_2 - -> Hash Semi Join - Hash Cond: ((t1_3.a = t2_3.a) AND (t1_3.c = t2_3.c)) - -> Seq Scan on plt1_adv_p3 t1_3 - Filter: (b < 10) + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3 t2_3 -> Hash - -> Seq Scan on plt2_adv_p3 t2_3 + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) Optimizer: Postgres query optimizer (22 rows) @@ -3685,25 +3681,25 @@ SELECT t1.a, t1.c, t2.a, t2.c FROM plt1_adv t1 INNER JOIN plt2_adv t2 ON (t1.a = -- semi join EXPLAIN (COSTS OFF) SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a = t2.a AND t1.c = t2.c) AND t1.b < 10 ORDER BY t1.a; - QUERY PLAN --------------------------------------------------------- + QUERY PLAN +------------------------------------------------------ Sort Sort Key: t1.a - -> Hash Semi Join - Hash Cond: ((t1.a = t2.a) AND (t1.c = t2.c)) + -> Hash Right Semi Join + Hash Cond: ((t2.a = t1.a) AND (t2.c = t1.c)) -> Append - -> Seq Scan on plt1_adv_p1 t1_1 - Filter: (b < 10) - -> Seq Scan on plt1_adv_p2 t1_2 - Filter: (b < 10) - -> Seq Scan on plt1_adv_p3 t1_3 - Filter: (b < 10) + -> Seq Scan on plt2_adv_p1 t2_1 + -> Seq Scan on plt2_adv_p2_1 t2_2 + -> Seq Scan on plt2_adv_p2_2 t2_3 + -> Seq Scan on plt2_adv_p3 t2_4 -> Hash -> Append - -> Seq Scan on plt2_adv_p1 t2_1 - -> Seq Scan on plt2_adv_p2_1 t2_2 - -> Seq Scan on plt2_adv_p2_2 t2_3 - -> Seq Scan on plt2_adv_p3 t2_4 + -> Seq Scan on plt1_adv_p1 t1_1 + Filter: (b < 10) + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) Optimizer: Postgres query optimizer (18 rows) @@ -3843,24 +3839,24 @@ SELECT t1.* FROM plt1_adv t1 WHERE EXISTS (SELECT 1 FROM plt2_adv t2 WHERE t1.a Sort Sort Key: t1.a -> Append - -> Hash Semi Join - Hash Cond: ((t1_1.a = t2_1.a) AND (t1_1.c = t2_1.c)) - -> Seq Scan on plt1_adv_p1_null t1_1 - Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_1.a = t1_1.a) AND (t2_1.c = t1_1.c)) + -> Seq Scan on plt2_adv_p1 t2_1 -> Hash - -> Seq Scan on plt2_adv_p1 t2_1 - -> Hash Semi Join - Hash Cond: ((t1_2.a = t2_2.a) AND (t1_2.c = t2_2.c)) - -> Seq Scan on plt1_adv_p2 t1_2 - Filter: (b < 10) + -> Seq Scan on plt1_adv_p1_null t1_1 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_2.a = t1_2.a) AND (t2_2.c = t1_2.c)) + -> Seq Scan on plt2_adv_p2 t2_2 -> Hash - -> Seq Scan on plt2_adv_p2 t2_2 - -> Hash Semi Join - Hash Cond: ((t1_3.a = t2_3.a) AND (t1_3.c = t2_3.c)) - -> Seq Scan on plt1_adv_p3 t1_3 - Filter: (b < 10) + -> Seq Scan on plt1_adv_p2 t1_2 + Filter: (b < 10) + -> Hash Right Semi Join + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.c = t1_3.c)) + -> Seq Scan on plt2_adv_p3_null t2_3 -> Hash - -> Seq Scan on plt2_adv_p3_null t2_3 + -> Seq Scan on plt1_adv_p3 t1_3 + Filter: (b < 10) Optimizer: Postgres query optimizer (22 rows) diff --git a/src/test/singlenode_regress/expected/subselect.out b/src/test/singlenode_regress/expected/subselect.out index 8a8275735ce..ba957a090bd 100644 --- a/src/test/singlenode_regress/expected/subselect.out +++ b/src/test/singlenode_regress/expected/subselect.out @@ -1115,7 +1115,6 @@ where o.ten = 0; -> Seq Scan on public.int4_tbl Output: int4_tbl.f1 Filter: (int4_tbl.f1 <= o.hundred) - Settings: optimizer = 'off' Optimizer: Postgres query optimizer (17 rows) @@ -1341,24 +1340,24 @@ select * from int4_tbl where explain (verbose, costs off) select * from int4_tbl o where (f1, f1) in (select f1, generate_series(1,50) / 10 g from int4_tbl i group by f1); - QUERY PLAN -------------------------------------------------------------------- - Hash Semi Join + QUERY PLAN +------------------------------------------------------------- + Hash Right Semi Join Output: o.f1 - Hash Cond: (o.f1 = "ANY_subquery".f1) - -> Seq Scan on public.int4_tbl o - Output: o.f1 - -> Hash + Hash Cond: ("ANY_subquery".f1 = o.f1) + -> Subquery Scan on "ANY_subquery" Output: "ANY_subquery".f1, "ANY_subquery".g - -> Subquery Scan on "ANY_subquery" - Output: "ANY_subquery".f1, "ANY_subquery".g - Filter: ("ANY_subquery".f1 = "ANY_subquery".g) - -> Result - Output: i.f1, ((generate_series(1, 50)) / 10) - -> ProjectSet - Output: generate_series(1, 50), i.f1 - -> Seq Scan on public.int4_tbl i - Output: i.f1 + Filter: ("ANY_subquery".f1 = "ANY_subquery".g) + -> Result + Output: i.f1, ((generate_series(1, 50)) / 10) + -> ProjectSet + Output: generate_series(1, 50), i.f1 + -> Seq Scan on public.int4_tbl i + Output: i.f1 + -> Hash + Output: o.f1 + -> Seq Scan on public.int4_tbl o + Output: o.f1 Optimizer: Postgres query optimizer (17 rows) @@ -1671,8 +1670,9 @@ select * from x where f1 = 1; Seq Scan on public.subselect_tbl Output: subselect_tbl.f1 Filter: (subselect_tbl.f1 = 1) + Settings: gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(4 rows) +(5 rows) -- Explicitly request materialization explain (verbose, costs off) @@ -1687,8 +1687,9 @@ select * from x where f1 = 1; Output: share0_ref1.f1 -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1 + Settings: gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(8 rows) +(9 rows) -- Stable functions are safe to inline explain (verbose, costs off) @@ -1699,8 +1700,9 @@ select * from x where f1 = 1; Seq Scan on public.subselect_tbl Output: subselect_tbl.f1, 'regression'::name Filter: (subselect_tbl.f1 = 1) + Settings: gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(4 rows) +(5 rows) -- Volatile functions prevent inlining -- GPDB_12_MERGE_FIXME: inlining happens on GPDB: But the plan seems OK @@ -1719,8 +1721,9 @@ select * from x where f1 = 1; Output: share0_ref1.f1, share0_ref1.random -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1, random() + Settings: gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(4 rows) +(9 rows) -- SELECT FOR UPDATE cannot be inlined -- GPDB: select statement with locking clause is not easy to fully supported @@ -1737,8 +1740,9 @@ select * from x where f1 = 1; -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1, subselect_tbl.ctid Filter: (subselect_tbl.f1 = 1) + Settings: gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(6 rows) +(7 rows) -- Multiply-referenced CTEs are inlined only when requested explain (verbose, costs off) @@ -1757,8 +1761,9 @@ select * from x, x x2 where x.n = x2.n; Output: share0_ref1.f1, share0_ref1.n -> Seq Scan on public.subselect_tbl Output: subselect_tbl.f1, 'regression'::name + Settings: gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(12 rows) +(13 rows) explain (verbose, costs off) with x as not materialized (select * from (select f1, current_database() as n from subselect_tbl) ss) @@ -1774,8 +1779,9 @@ select * from x, x x2 where x.n = x2.n; Output: subselect_tbl_1.f1, ('regression'::name) -> Seq Scan on public.subselect_tbl subselect_tbl_1 Output: subselect_tbl_1.f1, 'regression'::name + Settings: gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(10 rows) +(11 rows) -- Multiply-referenced CTEs can't be inlined if they contain outer self-refs -- start_ignore @@ -1801,12 +1807,11 @@ select * from x; Join Filter: (length((x.a || x_1.a)) < 5) -> WorkTable Scan on x Output: x.a - -> Materialize + -> WorkTable Scan on x x_1 Output: x_1.a - -> WorkTable Scan on x x_1 - Output: x_1.a + Settings: gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(13 rows) +(12 rows) with recursive x(a) as ((values ('a'), ('b')) @@ -1815,11 +1820,31 @@ with recursive x(a) as select z.a || z1.a as a from z cross join z as z1 where length(z.a || z1.a) < 5)) select * from x; - a ---- + a +------ a b -(2 rows) + aa + ab + ba + bb + aaaa + aaab + aaba + aabb + abaa + abab + abba + abbb + baaa + baab + baba + babb + bbaa + bbab + bbba + bbbb +(22 rows) -- end_ignore explain (verbose, costs off) @@ -1840,8 +1865,9 @@ select * from x; -> WorkTable Scan on x Output: x.a Filter: (length((x.a || x.a)) < 5) + Settings: gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(9 rows) +(10 rows) with recursive x(a) as ((values ('a'), ('b')) @@ -1868,8 +1894,9 @@ select * from (with y as (select * from x) select * from y) ss; ------------------------------------- Seq Scan on public.int4_tbl Output: int4_tbl.f1 + Settings: gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(3 rows) +(4 rows) explain (verbose, costs off) with x as materialized (select * from int4_tbl) @@ -1880,8 +1907,9 @@ select * from (with y as (select * from x) select * from y) ss; Output: share0_ref1.f1 -> Seq Scan on public.int4_tbl Output: int4_tbl.f1 + Settings: gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(5 rows) +(6 rows) -- Ensure that we inline the currect CTE when there are -- multiple CTEs with the same name @@ -1892,8 +1920,9 @@ select * from (with x as (select 2 as y) select * from x) ss; ------------------------------------- Result Output: 2 + Settings: gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(3 rows) +(4 rows) -- Row marks are not pushed into CTEs explain (verbose, costs off) @@ -1903,7 +1932,8 @@ select * from x for update; ---------------------------------------------------------------- Seq Scan on public.subselect_tbl Output: subselect_tbl.f1, subselect_tbl.f2, subselect_tbl.f3 + Settings: gp_cte_sharing = 'on' Optimizer: Postgres query optimizer -(3 rows) +(4 rows) set gp_cte_sharing to off; diff --git a/src/test/singlenode_regress/expected/subselect_gp.out b/src/test/singlenode_regress/expected/subselect_gp.out index 1fad969939a..43ad6095b14 100644 --- a/src/test/singlenode_regress/expected/subselect_gp.out +++ b/src/test/singlenode_regress/expected/subselect_gp.out @@ -1,3 +1,7 @@ +-- start_ignore +create schema subselect_gp; +set search_path to subselect_gp, public; +-- end_ignore set optimizer_enable_master_only_queries = on; set optimizer_segments = 3; set optimizer_nestloop_factor = 1.0; @@ -794,8 +798,8 @@ explain select * from csq_pullup t0 where not exists (select 1 from csq_pullup t select * from csq_pullup t0 where not exists (select 1 from csq_pullup t1 where t0.t=t1.t and t1.i = 1); t | n | i | v -----+---+---+----- - abc | 1 | 2 | xyz xyz | 2 | 3 | def + abc | 1 | 2 | xyz (2 rows) -- @@ -832,11 +836,11 @@ analyze subselect_t2; explain select * from subselect_t1 where x in (select y from subselect_t2); QUERY PLAN ------------------------------------------------------------------------ - Hash Semi Join (cost=1.07..2.13 rows=3 width=4) - Hash Cond: (subselect_t1.x = subselect_t2.y) - -> Seq Scan on subselect_t1 (cost=0.00..1.02 rows=2 width=4) - -> Hash (cost=1.03..1.03 rows=3 width=4) - -> Seq Scan on subselect_t2 (cost=0.00..1.03 rows=3 width=4) + Hash Right Semi Join (cost=1.04..2.12 rows=3 width=4) + Hash Cond: (subselect_t2.y = subselect_t1.x) + -> Seq Scan on subselect_t2 (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.02..1.02 rows=2 width=4) + -> Seq Scan on subselect_t1 (cost=0.00..1.02 rows=2 width=4) Optimizer: Postgres query optimizer (6 rows) @@ -851,15 +855,15 @@ select * from subselect_t1 where x in (select y from subselect_t2); -- Known_opt_diff: MPP-21351 -- end_ignore explain select * from subselect_t1 where x in (select y from subselect_t2 union all select y from subselect_t2); - QUERY PLAN ---------------------------------------------------------------------------------------------- - Hash Semi Join (cost=2.17..3.23 rows=3 width=4) - Hash Cond: (subselect_t1.x = subselect_t2.y) - -> Seq Scan on subselect_t1 (cost=0.00..1.02 rows=2 width=4) - -> Hash (cost=2.09..2.09 rows=6 width=4) - -> Append (cost=0.00..2.09 rows=6 width=4) - -> Seq Scan on subselect_t2 (cost=0.00..1.03 rows=3 width=4) - -> Seq Scan on subselect_t2 subselect_t2_1 (cost=0.00..1.03 rows=3 width=4) + QUERY PLAN +--------------------------------------------------------------------------------------- + Hash Right Semi Join (cost=1.04..3.19 rows=3 width=4) + Hash Cond: (subselect_t2.y = subselect_t1.x) + -> Append (cost=0.00..2.09 rows=6 width=4) + -> Seq Scan on subselect_t2 (cost=0.00..1.03 rows=3 width=4) + -> Seq Scan on subselect_t2 subselect_t2_1 (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.02..1.02 rows=2 width=4) + -> Seq Scan on subselect_t1 (cost=0.00..1.02 rows=2 width=4) Optimizer: Postgres query optimizer (8 rows) @@ -873,12 +877,12 @@ select * from subselect_t1 where x in (select y from subselect_t2 union all sele explain select count(*) from subselect_t1 where x in (select y from subselect_t2); QUERY PLAN ------------------------------------------------------------------------------ - Aggregate (cost=2.14..2.15 rows=1 width=8) - -> Hash Semi Join (cost=1.07..2.13 rows=3 width=0) - Hash Cond: (subselect_t1.x = subselect_t2.y) - -> Seq Scan on subselect_t1 (cost=0.00..1.02 rows=2 width=4) - -> Hash (cost=1.03..1.03 rows=3 width=4) - -> Seq Scan on subselect_t2 (cost=0.00..1.03 rows=3 width=4) + Aggregate (cost=2.13..2.14 rows=1 width=8) + -> Hash Right Semi Join (cost=1.04..2.12 rows=3 width=0) + Hash Cond: (subselect_t2.y = subselect_t1.x) + -> Seq Scan on subselect_t2 (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.02..1.02 rows=2 width=4) + -> Seq Scan on subselect_t1 (cost=0.00..1.02 rows=2 width=4) Optimizer: Postgres query optimizer (7 rows) @@ -892,16 +896,16 @@ select count(*) from subselect_t1 where x in (select y from subselect_t2); -- Known_opt_diff: MPP-21351 -- end_ignore explain select count(*) from subselect_t1 where x in (select y from subselect_t2 union all select y from subselect_t2); - QUERY PLAN ---------------------------------------------------------------------------------------------------- - Aggregate (cost=3.23..3.24 rows=1 width=8) - -> Hash Semi Join (cost=2.17..3.23 rows=3 width=0) - Hash Cond: (subselect_t1.x = subselect_t2.y) - -> Seq Scan on subselect_t1 (cost=0.00..1.02 rows=2 width=4) - -> Hash (cost=2.09..2.09 rows=6 width=4) - -> Append (cost=0.00..2.09 rows=6 width=4) - -> Seq Scan on subselect_t2 (cost=0.00..1.03 rows=3 width=4) - -> Seq Scan on subselect_t2 subselect_t2_1 (cost=0.00..1.03 rows=3 width=4) + QUERY PLAN +--------------------------------------------------------------------------------------------- + Aggregate (cost=3.19..3.20 rows=1 width=8) + -> Hash Right Semi Join (cost=1.04..3.19 rows=3 width=0) + Hash Cond: (subselect_t2.y = subselect_t1.x) + -> Append (cost=0.00..2.09 rows=6 width=4) + -> Seq Scan on subselect_t2 (cost=0.00..1.03 rows=3 width=4) + -> Seq Scan on subselect_t2 subselect_t2_1 (cost=0.00..1.03 rows=3 width=4) + -> Hash (cost=1.02..1.02 rows=2 width=4) + -> Seq Scan on subselect_t1 (cost=0.00..1.02 rows=2 width=4) Optimizer: Postgres query optimizer (9 rows) @@ -924,9 +928,13 @@ select count(*) from -- Query was deadlocking because of not squelching subplans (MPP-18936) -- drop table if exists t1; +NOTICE: table "t1" does not exist, skipping drop table if exists t2; +NOTICE: table "t2" does not exist, skipping drop table if exists t3; +NOTICE: table "t3" does not exist, skipping drop table if exists t4; +NOTICE: table "t4" does not exist, skipping CREATE TABLE t1 AS (SELECT generate_series(1, 5000) AS i, generate_series(5001, 10000) AS j); CREATE TABLE t2 AS (SELECT * FROM t1 WHERE gp_segment_id = 0); CREATE TABLE t3 AS (SELECT * FROM t1 WHERE gp_segment_id = 1); @@ -1352,19 +1360,19 @@ EXPLAIN SELECT '' AS six, f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL EXPLAIN SELECT '' AS six, f1 AS "Uncorrelated Field" FROM SUBSELECT_TBL WHERE f1 IN (SELECT f2 FROM SUBSELECT_TBL WHERE f2 IN (SELECT f1 FROM SUBSELECT_TBL)) ORDER BY 2; - QUERY PLAN ------------------------------------------------------------------------------------------------------------ - Sort (cost=3.77..3.79 rows=8 width=36) + QUERY PLAN +----------------------------------------------------------------------------------------------------- + Sort (cost=3.78..3.80 rows=8 width=36) Sort Key: subselect_tbl.f1 - -> Hash Semi Join (cost=2.45..3.65 rows=8 width=36) - Hash Cond: (subselect_tbl.f1 = subselect_tbl_1.f2) - -> Seq Scan on subselect_tbl (cost=0.00..1.08 rows=8 width=4) - -> Hash (cost=2.36..2.36 rows=7 width=8) - -> Hash Semi Join (cost=1.18..2.36 rows=7 width=8) - Hash Cond: (subselect_tbl_1.f2 = subselect_tbl_2.f1) - -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..1.08 rows=8 width=4) - -> Hash (cost=1.08..1.08 rows=8 width=4) - -> Seq Scan on subselect_tbl subselect_tbl_2 (cost=0.00..1.08 rows=8 width=4) + -> Hash Right Semi Join (cost=2.36..3.66 rows=8 width=36) + Hash Cond: (subselect_tbl_1.f2 = subselect_tbl.f1) + -> Hash Semi Join (cost=1.18..2.36 rows=7 width=8) + Hash Cond: (subselect_tbl_1.f2 = subselect_tbl_2.f1) + -> Seq Scan on subselect_tbl subselect_tbl_1 (cost=0.00..1.08 rows=8 width=4) + -> Hash (cost=1.08..1.08 rows=8 width=4) + -> Seq Scan on subselect_tbl subselect_tbl_2 (cost=0.00..1.08 rows=8 width=4) + -> Hash (cost=1.08..1.08 rows=8 width=4) + -> Seq Scan on subselect_tbl (cost=0.00..1.08 rows=8 width=4) Optimizer: Postgres query optimizer (12 rows) @@ -1427,13 +1435,13 @@ EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f3 AS "Second Field" (SELECT f2 FROM SUBSELECT_TBL WHERE CAST(upper.f2 AS float) = f3) ORDER BY 2,3; QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Sort (cost=2.50..2.52 rows=6 width=44) + Sort (cost=2.49..2.50 rows=6 width=44) Sort Key: upper.f1, upper.f3 - -> Hash Semi Join (cost=1.20..2.43 rows=6 width=44) - Hash Cond: (((upper.f2)::double precision = subselect_tbl.f3) AND (upper.f1 = subselect_tbl.f2)) - -> Seq Scan on subselect_tbl upper (cost=0.00..1.08 rows=8 width=16) - -> Hash (cost=1.08..1.08 rows=8 width=12) - -> Seq Scan on subselect_tbl (cost=0.00..1.08 rows=8 width=12) + -> Hash Right Semi Join (cost=1.20..2.41 rows=6 width=44) + Hash Cond: ((subselect_tbl.f3 = (upper.f2)::double precision) AND (subselect_tbl.f2 = upper.f1)) + -> Seq Scan on subselect_tbl (cost=0.00..1.08 rows=8 width=12) + -> Hash (cost=1.08..1.08 rows=8 width=16) + -> Seq Scan on subselect_tbl upper (cost=0.00..1.08 rows=8 width=16) Optimizer: Postgres query optimizer (8 rows) @@ -1446,7 +1454,7 @@ EXPLAIN SELECT '' AS six, f1 AS "Correlated Field", f3 AS "Second Field" Sort (cost=10000000002.39..10000000002.40 rows=3 width=44) Sort Key: upper.f1, upper.f3 -> Nested Loop Semi Join (cost=10000000000.00..10000000002.36 rows=3 width=44) - Join Filter: (((upper.f1 + subselect_tbl.f2))::double precision = upper.f3) + Join Filter: (upper.f3 = ((upper.f1 + subselect_tbl.f2))::double precision) -> Seq Scan on subselect_tbl upper (cost=0.00..1.08 rows=8 width=12) -> Materialize (cost=0.00..1.12 rows=1 width=4) -> Seq Scan on subselect_tbl (cost=0.00..1.12 rows=1 width=4) @@ -1653,13 +1661,13 @@ analyze dedup_reptab; -- row otherwise. explain (costs off) select * from dedup_reptab r where r.a in (select t.a/10 from dedup_tab t); - QUERY PLAN -------------------------------------- - Hash Semi Join - Hash Cond: (r.a = (t.a / 10)) - -> Seq Scan on dedup_reptab r + QUERY PLAN +---------------------------------------- + Hash Right Semi Join + Hash Cond: ((t.a / 10) = r.a) + -> Seq Scan on dedup_tab t -> Hash - -> Seq Scan on dedup_tab t + -> Seq Scan on dedup_reptab r Optimizer: Postgres query optimizer (6 rows) @@ -1696,13 +1704,13 @@ create function dedup_srf_volatile() RETURNS SETOF int AS $$ $$ LANGUAGE plpgsql VOLATILE ROWS 3; explain (costs off) select * from dedup_srf() r(a) where r.a in (select t.a/10 from dedup_tab t); - QUERY PLAN -------------------------------------- - Hash Semi Join - Hash Cond: (r.a = (t.a / 10)) - -> Function Scan on dedup_srf r + QUERY PLAN +------------------------------------------ + Hash Right Semi Join + Hash Cond: ((t.a / 10) = r.a) + -> Seq Scan on dedup_tab t -> Hash - -> Seq Scan on dedup_tab t + -> Function Scan on dedup_srf r Optimizer: Postgres query optimizer (6 rows) @@ -1716,13 +1724,13 @@ select * from dedup_srf() r(a) where r.a in (select t.a/10 from dedup_tab t); explain (costs off) select * from dedup_srf_stable() r(a) where r.a in (select t.a/10 from dedup_tab t); - QUERY PLAN -------------------------------------------- - Hash Semi Join - Hash Cond: (r.a = (t.a / 10)) - -> Function Scan on dedup_srf_stable r + QUERY PLAN +------------------------------------------------- + Hash Right Semi Join + Hash Cond: ((t.a / 10) = r.a) + -> Seq Scan on dedup_tab t -> Hash - -> Seq Scan on dedup_tab t + -> Function Scan on dedup_srf_stable r Optimizer: Postgres query optimizer (6 rows) @@ -1736,13 +1744,13 @@ select * from dedup_srf_stable() r(a) where r.a in (select t.a/10 from dedup_tab explain (costs off) select * from dedup_srf_volatile() r(a) where r.a in (select t.a/10 from dedup_tab t); - QUERY PLAN ---------------------------------------------- - Hash Semi Join - Hash Cond: (r.a = (t.a / 10)) - -> Function Scan on dedup_srf_volatile r + QUERY PLAN +--------------------------------------------------- + Hash Right Semi Join + Hash Cond: ((t.a / 10) = r.a) + -> Seq Scan on dedup_tab t -> Hash - -> Seq Scan on dedup_tab t + -> Function Scan on dedup_srf_volatile r Optimizer: Postgres query optimizer (6 rows) @@ -1803,15 +1811,15 @@ select * from dedup_func_stable() r(a) where r.a in (select t.a/10 from dedup_ta explain (costs off) select * from dedup_func_volatile() r(a) where r.a in (select t.a/10 from dedup_tab t); - QUERY PLAN -------------------------------------- - Hash Semi Join - Hash Cond: (($0) = (t.a / 10)) - -> Result - InitPlan 1 (returns $0) - -> Result + QUERY PLAN +--------------------------------------- + Hash Right Semi Join + Hash Cond: ((t.a / 10) = ($0)) + -> Seq Scan on dedup_tab t -> Hash - -> Seq Scan on dedup_tab t + -> Result + InitPlan 1 (returns $0) + -> Result Optimizer: Postgres query optimizer (8 rows) @@ -2217,18 +2225,18 @@ select * from foo where (select b.i from baz b); QUERY PLAN --------------------------------------------------------------------------------------- - Hash Semi Join + Hash Right Semi Join Output: foo.i, foo.j - Hash Cond: (CASE WHEN ((hashed SubPlan 1)) THEN foo.i ELSE NULL::integer END = b.i) - -> Seq Scan on subselect_gp.foo - Output: foo.i, foo.j, (hashed SubPlan 1) - SubPlan 1 - -> Seq Scan on subselect_gp.baz a - Output: a.i + Hash Cond: (b.i = CASE WHEN ((hashed SubPlan 1)) THEN foo.i ELSE NULL::integer END) + -> Seq Scan on subselect_gp.baz b + Output: b.i, b.j -> Hash - Output: b.i - -> Seq Scan on subselect_gp.baz b - Output: b.i + Output: foo.i, foo.j, ((hashed SubPlan 1)) + -> Seq Scan on subselect_gp.foo + Output: foo.i, foo.j, (hashed SubPlan 1) + SubPlan 1 + -> Seq Scan on subselect_gp.baz a + Output: a.i Optimizer: Postgres query optimizer (13 rows) @@ -2284,7 +2292,7 @@ where dt < '2010-01-01'::date; -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b Optimizer: Postgres query optimizer -(18 rows) +(17 rows) with run_dt as ( select @@ -2332,7 +2340,7 @@ where dt < '2010-01-01'::date; -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b Optimizer: Postgres query optimizer -(17 rows) +(16 rows) with run_dt as ( select @@ -2380,7 +2388,7 @@ where dt < '2010-01-01'::date; -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b Optimizer: Postgres query optimizer -(19 rows) +(18 rows) with run_dt as ( select @@ -2433,7 +2441,7 @@ where dt < extra_flow_dist1.a; -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b Optimizer: Postgres query optimizer -(25 rows) +(24 rows) -- case 5 for subplan with outer entry locus without param in subplan (CTE and subquery) explain (verbose, costs off) with run_dt as ( @@ -2470,7 +2478,7 @@ where dt < extra_flow_dist1.a; -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b Optimizer: Postgres query optimizer -(25 rows) +(24 rows) -- case 6 without CTE, nested subquery should not add extral flow explain (verbose, costs off) select * from ( @@ -2525,7 +2533,7 @@ where dt < '2010-01-01'::date; -> Seq Scan on subselect_gp.extra_flow_dist1 Output: extra_flow_dist1.a, extra_flow_dist1.b Optimizer: Postgres query optimizer -(34 rows) +(33 rows) -- Check DISTINCT ON clause and ORDER BY clause in SubLink, See https://github.com/greenplum-db/gpdb/issues/12656. -- For EXISTS SubLink, we don’t need to care about the data deduplication problem, we can delete DISTINCT ON clause and @@ -2559,7 +2567,7 @@ select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issu -> Seq Scan on subselect_gp.issue_12656 issue_12656_1 Output: issue_12656_1.i, issue_12656_1.j Optimizer: Postgres query optimizer -(18 rows) +(17 rows) select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issue_12656); i | j @@ -2589,7 +2597,7 @@ select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issu -> Seq Scan on subselect_gp.issue_12656 issue_12656_1 Output: issue_12656_1.i, issue_12656_1.j Optimizer: Postgres query optimizer -(18 rows) +(17 rows) select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issue_12656 order by i, j asc); i | j @@ -2618,7 +2626,7 @@ select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issu -> Seq Scan on subselect_gp.issue_12656 issue_12656_1 Output: issue_12656_1.i, issue_12656_1.j Optimizer: Postgres query optimizer -(18 rows) +(17 rows) select * from issue_12656 where (i, j) in (select distinct on (i) i, j from issue_12656 order by i, j desc); i | j