blob: 9fd86e7f228bba7618c29296de82846bb72c8be6 [file] [log] [blame]
-- Regression tests for prepareable statements
-- Force a generic plan to specifically test parameters
set plan_cache_mode=force_generic_plan;
SET optimizer_trace_fallback to on;
create schema qp_query_params;
set search_path=qp_query_params;
create table t1 (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.
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 from generate_series(1,4)i;
analyze t1;
create table t2(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.
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 t2 values (1,1);
analyze t2;
CREATE TABLE part (
a int ,
b int,
c text,
d numeric)
DISTRIBUTED BY (b)
partition by range(a) (
start(1) end(6) every(2),
default partition def);
insert into part select i,i,'abc',i*1.01 from generate_series(1,10)i;
analyze part;
-- Should simplify to false, Orca does not
PREPARE q1 as SELECT * from t1 where a=$1 and a!=$1;
explain (costs off) execute q1(3);
QUERY PLAN
------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Seq Scan on t1
Filter: ((a = $1) AND (a <> $1))
Optimizer: GPORCA
(4 rows)
execute q1(3);
a | b
---+---
(0 rows)
deallocate q1;
-- Should simplify to false, currently does not
PREPARE q1 as SELECT * from t1 where $1!=$1;
explain (costs off) execute q1(4);
QUERY PLAN
------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Seq Scan on t1
Filter: ($1 <> $1)
Optimizer: GPORCA
(4 rows)
execute q1(4);
a | b
---+---
(0 rows)
deallocate q1;
-- Should perform static elimination at execution time, Orca does not do this currently
PREPARE q1 as SELECT * from part where a=$1;
explain (costs off) EXECUTE q1(2);
QUERY PLAN
----------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Dynamic Seq Scan on part
Number of partitions to scan: 4 (out of 4)
Filter: (a = $1)
Optimizer: GPORCA
(5 rows)
execute q1(2);
a | b | c | d
---+---+-----+------
2 | 2 | abc | 2.02
(1 row)
-- Ensure default partition is scanned
explain (costs off) EXECUTE q1(9);
QUERY PLAN
----------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Dynamic Seq Scan on part
Number of partitions to scan: 4 (out of 4)
Filter: (a = $1)
Optimizer: GPORCA
(5 rows)
execute q1(9);
a | b | c | d
---+---+-----+------
9 | 9 | abc | 9.09
(1 row)
deallocate q1;
-- Test multiple query params
PREPARE q1 as SELECT * from t1 where a=$1 and b=$2;
explain (costs off) execute q1(4,4);
QUERY PLAN
------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Seq Scan on t1
Filter: ((a = $1) AND (b = $2))
Optimizer: GPORCA
(4 rows)
execute q1(4,4);
a | b
---+---
4 | 4
(1 row)
deallocate q1;
-- Test param op param
PREPARE q1 as SELECT * from t1 where $1=$2;
explain (costs off) execute q1(4,5);
QUERY PLAN
------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Seq Scan on t1
Filter: ($1 = $2)
Optimizer: GPORCA
(4 rows)
execute q1(4,5);
a | b
---+---
(0 rows)
deallocate q1;
-- Should NOT produce a direct dispatch plan!
PREPARE q1 as SELECT * from t1 where a=$1;
explain (costs off) execute q1(5);
QUERY PLAN
------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Seq Scan on t1
Filter: (a = $1)
Optimizer: GPORCA
(4 rows)
execute q1(5);
a | b
---+---
(0 rows)
deallocate q1;
-- Should NOT do direct dispatch with delete. Explain doesn't show this, so we must verify results
PREPARE q1 as DELETE from t1 where a=$1;
explain (costs off) execute q1(1);
QUERY PLAN
--------------------------
Delete on t1
-> Seq Scan on t1
Filter: (a = $1)
Optimizer: GPORCA
(4 rows)
execute q1(1);
deallocate q1;
select count(*) from t1;
count
-------
3
(1 row)
-- Should NOT do direct dispatch with insert. Explain doesn't show this, so we must verify results
PREPARE q1 as INSERT into t1 values ($1, $2);
explain (costs off) execute q1(1,3);
QUERY PLAN
--------------------------
Insert on t1
-> Result
-> Result
-> Result
Optimizer: GPORCA
(5 rows)
execute q1(1,3);
deallocate q1;
select count(*) from t1;
count
-------
4
(1 row)
-- Test index with parameter
CREATE INDEX idx on t1(b);
PREPARE q1 as select * from t1 where b=$1;
explain (costs off) execute q1(3);
QUERY PLAN
------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Index Scan using idx on t1
Index Cond: (b = $1)
Optimizer: GPORCA
(4 rows)
execute q1(3);
a | b
---+---
3 | 3
1 | 3
(2 rows)
deallocate q1;
drop index idx;
-- Test limit with parameter
PREPARE q1 as select * from t1 order by a limit $1;
explain (costs off) execute q1(4);
QUERY PLAN
------------------------------------------------
Limit
-> Gather Motion 3:1 (slice1; segments: 3)
Merge Key: a
-> Sort
Sort Key: a
-> Seq Scan on t1
Optimizer: GPORCA
(7 rows)
execute q1(4);
a | b
---+---
1 | 3
2 | 2
3 | 3
4 | 4
(4 rows)
deallocate q1;
-- Test normalization with params
PREPARE q1 as select count(*)+$1+$2 from t1 group by t1.a;
explain (verbose, costs off) execute q1(4,1);
QUERY PLAN
--------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
Output: (((count(*) + $1) + $2))
-> GroupAggregate
Output: ((count(*) + $1) + $2)
Group Key: t1.a
-> Sort
Output: a
Sort Key: t1.a
-> Seq Scan on qp_query_params.t1
Output: a
Optimizer: GPORCA
Settings: plan_cache_mode = 'force_generic_plan'
(12 rows)
execute q1(4,1);
?column?
----------
6
6
6
6
(4 rows)
deallocate q1;
PREPARE q1 as select count(*)+$1+$2 from t1 group by t1.a+$2;
explain (verbose, costs off) execute q1(3,2);
QUERY PLAN
------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
Output: (((count(*) + $1) + $2))
-> GroupAggregate
Output: ((count(*) + $1) + $2)
Group Key: ((t1.a + $2))
-> Sort
Output: ((a + $2))
Sort Key: ((t1.a + $2))
-> Redistribute Motion 3:3 (slice2; segments: 3)
Output: ((a + $2))
Hash Key: ((a + $2))
-> Seq Scan on qp_query_params.t1
Output: (a + $2)
Optimizer: GPORCA
Settings: plan_cache_mode = 'force_generic_plan'
(15 rows)
execute q1(3,2);
?column?
----------
6
6
6
6
(4 rows)
deallocate q1;
PREPARE q1 as select sum(b)+$1 from t1 group by(b) having count(*) > $2;
explain (verbose, costs off) execute q1(4,0);
QUERY PLAN
------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
Output: (((sum(b)) + $1))
-> Result
Output: ((sum(b)) + $1)
Filter: ((count(*)) > $2)
-> GroupAggregate
Output: sum(b), count(*), b
Group Key: t1.b
-> Sort
Output: b
Sort Key: t1.b
-> Redistribute Motion 3:3 (slice2; segments: 3)
Output: b
Hash Key: b
-> Seq Scan on qp_query_params.t1
Output: b
Optimizer: GPORCA
Settings: plan_cache_mode = 'force_generic_plan'
(18 rows)
execute q1(4,0);
?column?
----------
6
10
8
(3 rows)
deallocate q1;
-- Test subplans with params
PREPARE q1 as select $1::int, (select b from t2 where b=t1.a and b!=$1) from t1;
explain (verbose, costs off) execute q1(4);
QUERY PLAN
-----------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
Output: ($1), ((SubPlan 1))
-> Seq Scan on qp_query_params.t1
Output: $1, (SubPlan 1)
SubPlan 1
-> Result
Output: t2.b
Filter: (t2.b = t1.a)
-> Materialize
Output: t2.b
-> Broadcast Motion 3:3 (slice2; segments: 3)
Output: t2.b
-> Seq Scan on qp_query_params.t2
Output: t2.b
Filter: (t2.b <> $1)
Optimizer: GPORCA
Settings: plan_cache_mode = 'force_generic_plan'
(17 rows)
execute q1(4);
int4 | b
------+---
4 |
4 |
4 |
4 | 1
(4 rows)
deallocate q1;