blob: 42b4416c14e99bac95443868bfc46dfa8d1a9a2c [file] [log] [blame]
CREATE SCHEMA orca_static_pruning;
SET search_path TO orca_static_pruning;
CREATE TABLE rp (a int, b int, c int) DISTRIBUTED BY (a) PARTITION BY RANGE (b);
CREATE TABLE rp0 PARTITION OF rp FOR VALUES FROM (MINVALUE) TO (10);
NOTICE: table has parent, setting distribution columns to match parent table
CREATE TABLE rp1 PARTITION OF rp FOR VALUES FROM (10) TO (20);
NOTICE: table has parent, setting distribution columns to match parent table
CREATE TABLE rp2 PARTITION OF rp FOR VALUES FROM (4200) TO (4203);
NOTICE: table has parent, setting distribution columns to match parent table
INSERT INTO rp VALUES (0, 0, 0), (11, 11, 0), (4201, 4201, 0);
SELECT $query$
SELECT *
FROM rp
WHERE b > 4200
$query$ AS qry \gset
SET optimizer_trace_fallback TO on;
EXPLAIN (COSTS OFF, VERBOSE)
:qry ;
QUERY PLAN
----------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
Output: rp.a, rp.b, rp.c
-> Seq Scan on orca_static_pruning.rp2 rp
Output: rp.a, rp.b, rp.c
Filter: (rp.b > 4200)
Optimizer: Postgres query optimizer
(6 rows)
:qry ;
a | b | c
------+------+---
4201 | 4201 | 0
(1 row)
SELECT $query$
SELECT *
FROM rp
WHERE b = 4201
$query$ AS qry \gset
EXPLAIN (COSTS OFF, VERBOSE)
:qry ;
QUERY PLAN
----------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
Output: rp.a, rp.b, rp.c
-> Seq Scan on orca_static_pruning.rp2 rp
Output: rp.a, rp.b, rp.c
Filter: (rp.b = 4201)
Optimizer: Postgres query optimizer
(6 rows)
:qry ;
a | b | c
------+------+---
4201 | 4201 | 0
(1 row)
SELECT $query$
SELECT *
FROM rp
WHERE b IN (4201, 4200)
$query$ AS qry \gset
EXPLAIN (COSTS OFF, VERBOSE)
:qry ;
QUERY PLAN
---------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
Output: rp.a, rp.b, rp.c
-> Seq Scan on orca_static_pruning.rp2 rp
Output: rp.a, rp.b, rp.c
Filter: (rp.b = ANY ('{4201,4200}'::integer[]))
Optimizer: Postgres query optimizer
(6 rows)
:qry ;
a | b | c
------+------+---
4201 | 4201 | 0
(1 row)
RESET optimizer_trace_fallback;
CREATE TABLE lp (a int, b int) DISTRIBUTED BY (a) PARTITION BY LIST (b);
CREATE TABLE lp0 PARTITION OF lp FOR VALUES IN (0, 1);
NOTICE: table has parent, setting distribution columns to match parent table
CREATE TABLE lp1 PARTITION OF lp FOR VALUES IN (10, 11);
NOTICE: table has parent, setting distribution columns to match parent table
CREATE TABLE lp2 PARTITION OF lp FOR VALUES IN (42, 43);
NOTICE: table has parent, setting distribution columns to match parent table
INSERT INTO lp VALUES (0, 0), (10, 10), (42, 42);
SET optimizer_trace_fallback TO on;
SELECT $query$
SELECT *
FROM lp
WHERE b > 42
$query$ AS qry \gset
EXPLAIN (COSTS OFF, VERBOSE)
:qry ;
QUERY PLAN
----------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
Output: lp.a, lp.b
-> Seq Scan on orca_static_pruning.lp2 lp
Output: lp.a, lp.b
Filter: (lp.b > 42)
Optimizer: Postgres query optimizer
(6 rows)
:qry ;
a | b
---+---
(0 rows)
SELECT $query$
SELECT *
FROM lp
WHERE b = 42
$query$ AS qry \gset
EXPLAIN (COSTS OFF, VERBOSE)
:qry ;
QUERY PLAN
----------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
Output: lp.a, lp.b
-> Seq Scan on orca_static_pruning.lp2 lp
Output: lp.a, lp.b
Filter: (lp.b = 42)
Optimizer: Postgres query optimizer
(6 rows)
:qry ;
a | b
----+----
42 | 42
(1 row)
RESET optimizer_trace_fallback;
CREATE TABLE hp (a int, b int) PARTITION BY HASH (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 hp0 PARTITION OF hp FOR VALUES WITH (MODULUS 2, REMAINDER 0);
NOTICE: table has parent, setting distribution columns to match parent table
CREATE TABLE hp1 PARTITION OF hp FOR VALUES WITH (MODULUS 2, REMAINDER 1);
NOTICE: table has parent, setting distribution columns to match parent table
INSERT INTO hp VALUES (0, 1), (0, 3), (0, 4), (0, 42);
SET optimizer_trace_fallback TO on;
SELECT $query$
SELECT *
FROM hp
WHERE b = 42
$query$ AS qry \gset
EXPLAIN (COSTS OFF, VERBOSE)
:qry ;
QUERY PLAN
----------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
Output: hp.a, hp.b
-> Seq Scan on orca_static_pruning.hp0 hp
Output: hp.a, hp.b
Filter: (hp.b = 42)
Optimizer: Postgres query optimizer
(6 rows)
:qry ;
a | b
---+----
0 | 42
(1 row)
RESET optimizer_trace_fallback;
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);
-- 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;
SET optimizer_trace_fallback TO on;
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: rp_multi_inds.a, rp_multi_inds.b, rp_multi_inds.c
-> Bitmap Heap Scan on orca_static_pruning.rp_multi_inds_part2 rp_multi_inds
Output: rp_multi_inds.a, rp_multi_inds.b, rp_multi_inds.c
Recheck Cond: ((rp_multi_inds.b = 11) AND ((rp_multi_inds.c = 11) OR (rp_multi_inds.c = 4201)))
-> BitmapAnd
-> Bitmap Index Scan on rp_multi_inds_part2_b_idx
Index Cond: (rp_multi_inds.b = 11)
-> BitmapOr
-> Bitmap Index Scan on rp_multi_inds_part2_c_idx
Index Cond: (rp_multi_inds.c = 11)
-> Bitmap Index Scan on rp_multi_inds_part2_c_idx
Index Cond: (rp_multi_inds.c = 4201)
Optimizer: Postgres query optimizer
Settings: optimizer=off
(15 rows)
SELECT * FROM rp_multi_inds WHERE b = 11 AND (c = 11 OR c = 4201);
a | b | c
----+----+----
11 | 11 | 11
(1 row)
RESET optimizer_trace_fallback;
RESET optimizer_enable_dynamictablescan;
CREATE TABLE foo (a int, b int) DISTRIBUTED BY (a) PARTITION BY RANGE (b);
CREATE TABLE foo_part1 PARTITION OF foo FOR VALUES FROM (MINVALUE) TO (10);
NOTICE: table has parent, setting distribution columns to match parent table
CREATE TABLE foo_part2 PARTITION OF foo FOR VALUES FROM (10) TO (20);
NOTICE: table has parent, setting distribution columns to match parent table
CREATE TABLE foo_part3 PARTITION OF foo FOR VALUES FROM (4201) TO (4203);
NOTICE: table has parent, setting distribution columns to match parent table
CREATE INDEX foo_idx on foo(a);
CREATE TABLE bar (a int) DISTRIBUTED BY (a);
INSERT INTO foo VALUES (0, 0), (11, 11), (4201, 4201);
INSERT INTO bar VALUES (0), (11), (42);
SET optimizer_trace_fallback TO on;
-- Test ORCA index nested loop join has correct outer ref
-- Set below GUCs for planner just to keep parity
SET enable_hashjoin TO off;
SET enable_mergejoin TO off;
SET enable_nestloop TO on;
EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM foo JOIN bar on foo.a = bar.a AND foo.b = 11;
QUERY PLAN
-------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
Output: foo.a, foo.b, bar.a
-> Nested Loop
Output: foo.a, foo.b, bar.a
Join Filter: (foo.a = bar.a)
-> Seq Scan on orca_static_pruning.bar
Output: bar.a
-> Materialize
Output: foo.a, foo.b
-> Seq Scan on orca_static_pruning.foo_part2 foo
Output: foo.a, foo.b
Filter: (foo.b = 11)
Optimizer: Postgres query optimizer
Settings: enable_hashjoin = 'off', enable_mergejoin = 'off', enable_nestloop = 'on'
(14 rows)
SELECT * FROM foo JOIN bar on foo.a = bar.a AND foo.b = 11;
a | b | a
----+----+----
11 | 11 | 11
(1 row)
RESET enable_hashjoin;
RESET enable_mergejoin;
RESET enable_nestloop;
CREATE TABLE rp_insert (a int, b int) 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 rp_insert_part_1 PARTITION OF rp_insert FOR VALUES FROM (0) TO (3);
NOTICE: table has parent, setting distribution columns to match parent table
CREATE TABLE rp_insert_part_2 PARTITION OF rp_insert FOR VALUES FROM (3) TO (6);
NOTICE: table has parent, setting distribution columns to match parent table
-- The INSERT plans should no longer contain Partition Selector DMLs.
EXPLAIN (COSTS OFF, VERBOSE) INSERT INTO rp_insert VALUES (1, 1), (3, 3);
QUERY PLAN
--------------------------------------------------------------
Insert on orca_static_pruning.rp_insert
-> Redistribute Motion 1:3 (slice1; segments: 1)
Output: "*VALUES*".column1, "*VALUES*".column2
Hash Key: "*VALUES*".column1
-> Values Scan on "*VALUES*"
Output: "*VALUES*".column1, "*VALUES*".column2
Optimizer: Postgres query optimizer
Settings: optimizer=off
(8 rows)
INSERT INTO rp_insert VALUES (1, 1), (3, 3);
EXPLAIN (COSTS OFF, VERBOSE) INSERT INTO rp_insert SELECT * FROM rp_insert;
QUERY PLAN
--------------------------------------------------------------------------
Insert on orca_static_pruning.rp_insert
-> Append
-> Seq Scan on orca_static_pruning.rp_insert_part_1 rp_insert_2
Output: rp_insert_2.a, rp_insert_2.b
-> Seq Scan on orca_static_pruning.rp_insert_part_2 rp_insert_3
Output: rp_insert_3.a, rp_insert_3.b
Optimizer: Postgres query optimizer
Settings: optimizer=off
(8 rows)
INSERT INTO rp_insert SELECT * FROM rp_insert;
SELECT * FROM rp_insert;
a | b
---+---
3 | 3
3 | 3
1 | 1
1 | 1
(4 rows)