blob: 6afe28abe77a236c346e1d07adbffc9f4e2aae16 [file] [log] [blame]
--
-- ORCA tests
--
-- show version
SELECT count(*) from gp_opt_version();
count
-------
1
(1 row)
-- Mask out Log & timestamp for orca message that has feature not supported.
-- start_matchsubs
-- m/^LOG.*\"Falling/
-- s/^LOG.*\"Falling/\"Falling/
-- end_matchsubs
-- TODO: incremental sort is turned off by default, because it may have
-- wrong result for some core case. Turn it on to run the existing tests
-- and minimize the difference from upstream.
set enable_incremental_sort=on;
-- fix the number of segments for Orca
set optimizer_segments = 3;
set optimizer_enable_master_only_queries = on;
-- master only tables
create schema orca;
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;
delete from gp_distribution_policy where localoid='orca.r'::regclass;
reset allow_system_table_mods;
alter table orca.r add column a int;
alter table orca.r add column b int;
insert into orca.r select i, i/3 from generate_series(1,20) i;
create table orca.s();
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;
delete from gp_distribution_policy where localoid='orca.s'::regclass;
reset allow_system_table_mods;
alter table orca.s add column c int;
alter table orca.s add column d int;
insert into orca.s select i, i/2 from generate_series(1,30) i;
set optimizer_log=on;
set optimizer_enable_indexjoin=on;
set optimizer_trace_fallback = on;
-- expected fall back to the planner
select sum(distinct a), count(distinct b) from orca.r;
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: Multiple Distinct Qualified Aggregates are disabled in the optimizer
sum | count
-----+-------
210 | 7
(1 row)
select * from orca.r;
a | b
----+---
1 | 0
2 | 0
3 | 1
4 | 1
5 | 1
6 | 2
7 | 2
8 | 2
9 | 3
10 | 3
11 | 3
12 | 4
13 | 4
14 | 4
15 | 5
16 | 5
17 | 5
18 | 6
19 | 6
20 | 6
(20 rows)
select * from orca.r, orca.s where r.a=s.c;
a | b | c | d
----+---+----+----
1 | 0 | 1 | 0
2 | 0 | 2 | 1
3 | 1 | 3 | 1
4 | 1 | 4 | 2
5 | 1 | 5 | 2
6 | 2 | 6 | 3
7 | 2 | 7 | 3
8 | 2 | 8 | 4
9 | 3 | 9 | 4
10 | 3 | 10 | 5
11 | 3 | 11 | 5
12 | 4 | 12 | 6
13 | 4 | 13 | 6
14 | 4 | 14 | 7
15 | 5 | 15 | 7
16 | 5 | 16 | 8
17 | 5 | 17 | 8
18 | 6 | 18 | 9
19 | 6 | 19 | 9
20 | 6 | 20 | 10
(20 rows)
select * from orca.r, orca.s where r.a<s.c+1 or r.a>s.c;
a | b | c | d
----+---+----+----
1 | 0 | 1 | 0
1 | 0 | 2 | 1
1 | 0 | 3 | 1
1 | 0 | 4 | 2
1 | 0 | 5 | 2
1 | 0 | 6 | 3
1 | 0 | 7 | 3
1 | 0 | 8 | 4
1 | 0 | 9 | 4
1 | 0 | 10 | 5
1 | 0 | 11 | 5
1 | 0 | 12 | 6
1 | 0 | 13 | 6
1 | 0 | 14 | 7
1 | 0 | 15 | 7
1 | 0 | 16 | 8
1 | 0 | 17 | 8
1 | 0 | 18 | 9
1 | 0 | 19 | 9
1 | 0 | 20 | 10
1 | 0 | 21 | 10
1 | 0 | 22 | 11
1 | 0 | 23 | 11
1 | 0 | 24 | 12
1 | 0 | 25 | 12
1 | 0 | 26 | 13
1 | 0 | 27 | 13
1 | 0 | 28 | 14
1 | 0 | 29 | 14
1 | 0 | 30 | 15
2 | 0 | 1 | 0
2 | 0 | 2 | 1
2 | 0 | 3 | 1
2 | 0 | 4 | 2
2 | 0 | 5 | 2
2 | 0 | 6 | 3
2 | 0 | 7 | 3
2 | 0 | 8 | 4
2 | 0 | 9 | 4
2 | 0 | 10 | 5
2 | 0 | 11 | 5
2 | 0 | 12 | 6
2 | 0 | 13 | 6
2 | 0 | 14 | 7
2 | 0 | 15 | 7
2 | 0 | 16 | 8
2 | 0 | 17 | 8
2 | 0 | 18 | 9
2 | 0 | 19 | 9
2 | 0 | 20 | 10
2 | 0 | 21 | 10
2 | 0 | 22 | 11
2 | 0 | 23 | 11
2 | 0 | 24 | 12
2 | 0 | 25 | 12
2 | 0 | 26 | 13
2 | 0 | 27 | 13
2 | 0 | 28 | 14
2 | 0 | 29 | 14
2 | 0 | 30 | 15
3 | 1 | 1 | 0
3 | 1 | 2 | 1
3 | 1 | 3 | 1
3 | 1 | 4 | 2
3 | 1 | 5 | 2
3 | 1 | 6 | 3
3 | 1 | 7 | 3
3 | 1 | 8 | 4
3 | 1 | 9 | 4
3 | 1 | 10 | 5
3 | 1 | 11 | 5
3 | 1 | 12 | 6
3 | 1 | 13 | 6
3 | 1 | 14 | 7
3 | 1 | 15 | 7
3 | 1 | 16 | 8
3 | 1 | 17 | 8
3 | 1 | 18 | 9
3 | 1 | 19 | 9
3 | 1 | 20 | 10
3 | 1 | 21 | 10
3 | 1 | 22 | 11
3 | 1 | 23 | 11
3 | 1 | 24 | 12
3 | 1 | 25 | 12
3 | 1 | 26 | 13
3 | 1 | 27 | 13
3 | 1 | 28 | 14
3 | 1 | 29 | 14
3 | 1 | 30 | 15
4 | 1 | 1 | 0
4 | 1 | 2 | 1
4 | 1 | 3 | 1
4 | 1 | 4 | 2
4 | 1 | 5 | 2
4 | 1 | 6 | 3
4 | 1 | 7 | 3
4 | 1 | 8 | 4
4 | 1 | 9 | 4
4 | 1 | 10 | 5
4 | 1 | 11 | 5
4 | 1 | 12 | 6
4 | 1 | 13 | 6
4 | 1 | 14 | 7
4 | 1 | 15 | 7
4 | 1 | 16 | 8
4 | 1 | 17 | 8
4 | 1 | 18 | 9
4 | 1 | 19 | 9
4 | 1 | 20 | 10
4 | 1 | 21 | 10
4 | 1 | 22 | 11
4 | 1 | 23 | 11
4 | 1 | 24 | 12
4 | 1 | 25 | 12
4 | 1 | 26 | 13
4 | 1 | 27 | 13
4 | 1 | 28 | 14
4 | 1 | 29 | 14
4 | 1 | 30 | 15
5 | 1 | 1 | 0
5 | 1 | 2 | 1
5 | 1 | 3 | 1
5 | 1 | 4 | 2
5 | 1 | 5 | 2
5 | 1 | 6 | 3
5 | 1 | 7 | 3
5 | 1 | 8 | 4
5 | 1 | 9 | 4
5 | 1 | 10 | 5
5 | 1 | 11 | 5
5 | 1 | 12 | 6
5 | 1 | 13 | 6
5 | 1 | 14 | 7
5 | 1 | 15 | 7
5 | 1 | 16 | 8
5 | 1 | 17 | 8
5 | 1 | 18 | 9
5 | 1 | 19 | 9
5 | 1 | 20 | 10
5 | 1 | 21 | 10
5 | 1 | 22 | 11
5 | 1 | 23 | 11
5 | 1 | 24 | 12
5 | 1 | 25 | 12
5 | 1 | 26 | 13
5 | 1 | 27 | 13
5 | 1 | 28 | 14
5 | 1 | 29 | 14
5 | 1 | 30 | 15
6 | 2 | 1 | 0
6 | 2 | 2 | 1
6 | 2 | 3 | 1
6 | 2 | 4 | 2
6 | 2 | 5 | 2
6 | 2 | 6 | 3
6 | 2 | 7 | 3
6 | 2 | 8 | 4
6 | 2 | 9 | 4
6 | 2 | 10 | 5
6 | 2 | 11 | 5
6 | 2 | 12 | 6
6 | 2 | 13 | 6
6 | 2 | 14 | 7
6 | 2 | 15 | 7
6 | 2 | 16 | 8
6 | 2 | 17 | 8
6 | 2 | 18 | 9
6 | 2 | 19 | 9
6 | 2 | 20 | 10
6 | 2 | 21 | 10
6 | 2 | 22 | 11
6 | 2 | 23 | 11
6 | 2 | 24 | 12
6 | 2 | 25 | 12
6 | 2 | 26 | 13
6 | 2 | 27 | 13
6 | 2 | 28 | 14
6 | 2 | 29 | 14
6 | 2 | 30 | 15
7 | 2 | 1 | 0
7 | 2 | 2 | 1
7 | 2 | 3 | 1
7 | 2 | 4 | 2
7 | 2 | 5 | 2
7 | 2 | 6 | 3
7 | 2 | 7 | 3
7 | 2 | 8 | 4
7 | 2 | 9 | 4
7 | 2 | 10 | 5
7 | 2 | 11 | 5
7 | 2 | 12 | 6
7 | 2 | 13 | 6
7 | 2 | 14 | 7
7 | 2 | 15 | 7
7 | 2 | 16 | 8
7 | 2 | 17 | 8
7 | 2 | 18 | 9
7 | 2 | 19 | 9
7 | 2 | 20 | 10
7 | 2 | 21 | 10
7 | 2 | 22 | 11
7 | 2 | 23 | 11
7 | 2 | 24 | 12
7 | 2 | 25 | 12
7 | 2 | 26 | 13
7 | 2 | 27 | 13
7 | 2 | 28 | 14
7 | 2 | 29 | 14
7 | 2 | 30 | 15
8 | 2 | 1 | 0
8 | 2 | 2 | 1
8 | 2 | 3 | 1
8 | 2 | 4 | 2
8 | 2 | 5 | 2
8 | 2 | 6 | 3
8 | 2 | 7 | 3
8 | 2 | 8 | 4
8 | 2 | 9 | 4
8 | 2 | 10 | 5
8 | 2 | 11 | 5
8 | 2 | 12 | 6
8 | 2 | 13 | 6
8 | 2 | 14 | 7
8 | 2 | 15 | 7
8 | 2 | 16 | 8
8 | 2 | 17 | 8
8 | 2 | 18 | 9
8 | 2 | 19 | 9
8 | 2 | 20 | 10
8 | 2 | 21 | 10
8 | 2 | 22 | 11
8 | 2 | 23 | 11
8 | 2 | 24 | 12
8 | 2 | 25 | 12
8 | 2 | 26 | 13
8 | 2 | 27 | 13
8 | 2 | 28 | 14
8 | 2 | 29 | 14
8 | 2 | 30 | 15
9 | 3 | 1 | 0
9 | 3 | 2 | 1
9 | 3 | 3 | 1
9 | 3 | 4 | 2
9 | 3 | 5 | 2
9 | 3 | 6 | 3
9 | 3 | 7 | 3
9 | 3 | 8 | 4
9 | 3 | 9 | 4
9 | 3 | 10 | 5
9 | 3 | 11 | 5
9 | 3 | 12 | 6
9 | 3 | 13 | 6
9 | 3 | 14 | 7
9 | 3 | 15 | 7
9 | 3 | 16 | 8
9 | 3 | 17 | 8
9 | 3 | 18 | 9
9 | 3 | 19 | 9
9 | 3 | 20 | 10
9 | 3 | 21 | 10
9 | 3 | 22 | 11
9 | 3 | 23 | 11
9 | 3 | 24 | 12
9 | 3 | 25 | 12
9 | 3 | 26 | 13
9 | 3 | 27 | 13
9 | 3 | 28 | 14
9 | 3 | 29 | 14
9 | 3 | 30 | 15
10 | 3 | 1 | 0
10 | 3 | 2 | 1
10 | 3 | 3 | 1
10 | 3 | 4 | 2
10 | 3 | 5 | 2
10 | 3 | 6 | 3
10 | 3 | 7 | 3
10 | 3 | 8 | 4
10 | 3 | 9 | 4
10 | 3 | 10 | 5
10 | 3 | 11 | 5
10 | 3 | 12 | 6
10 | 3 | 13 | 6
10 | 3 | 14 | 7
10 | 3 | 15 | 7
10 | 3 | 16 | 8
10 | 3 | 17 | 8
10 | 3 | 18 | 9
10 | 3 | 19 | 9
10 | 3 | 20 | 10
10 | 3 | 21 | 10
10 | 3 | 22 | 11
10 | 3 | 23 | 11
10 | 3 | 24 | 12
10 | 3 | 25 | 12
10 | 3 | 26 | 13
10 | 3 | 27 | 13
10 | 3 | 28 | 14
10 | 3 | 29 | 14
10 | 3 | 30 | 15
11 | 3 | 1 | 0
11 | 3 | 2 | 1
11 | 3 | 3 | 1
11 | 3 | 4 | 2
11 | 3 | 5 | 2
11 | 3 | 6 | 3
11 | 3 | 7 | 3
11 | 3 | 8 | 4
11 | 3 | 9 | 4
11 | 3 | 10 | 5
11 | 3 | 11 | 5
11 | 3 | 12 | 6
11 | 3 | 13 | 6
11 | 3 | 14 | 7
11 | 3 | 15 | 7
11 | 3 | 16 | 8
11 | 3 | 17 | 8
11 | 3 | 18 | 9
11 | 3 | 19 | 9
11 | 3 | 20 | 10
11 | 3 | 21 | 10
11 | 3 | 22 | 11
11 | 3 | 23 | 11
11 | 3 | 24 | 12
11 | 3 | 25 | 12
11 | 3 | 26 | 13
11 | 3 | 27 | 13
11 | 3 | 28 | 14
11 | 3 | 29 | 14
11 | 3 | 30 | 15
12 | 4 | 1 | 0
12 | 4 | 2 | 1
12 | 4 | 3 | 1
12 | 4 | 4 | 2
12 | 4 | 5 | 2
12 | 4 | 6 | 3
12 | 4 | 7 | 3
12 | 4 | 8 | 4
12 | 4 | 9 | 4
12 | 4 | 10 | 5
12 | 4 | 11 | 5
12 | 4 | 12 | 6
12 | 4 | 13 | 6
12 | 4 | 14 | 7
12 | 4 | 15 | 7
12 | 4 | 16 | 8
12 | 4 | 17 | 8
12 | 4 | 18 | 9
12 | 4 | 19 | 9
12 | 4 | 20 | 10
12 | 4 | 21 | 10
12 | 4 | 22 | 11
12 | 4 | 23 | 11
12 | 4 | 24 | 12
12 | 4 | 25 | 12
12 | 4 | 26 | 13
12 | 4 | 27 | 13
12 | 4 | 28 | 14
12 | 4 | 29 | 14
12 | 4 | 30 | 15
13 | 4 | 1 | 0
13 | 4 | 2 | 1
13 | 4 | 3 | 1
13 | 4 | 4 | 2
13 | 4 | 5 | 2
13 | 4 | 6 | 3
13 | 4 | 7 | 3
13 | 4 | 8 | 4
13 | 4 | 9 | 4
13 | 4 | 10 | 5
13 | 4 | 11 | 5
13 | 4 | 12 | 6
13 | 4 | 13 | 6
13 | 4 | 14 | 7
13 | 4 | 15 | 7
13 | 4 | 16 | 8
13 | 4 | 17 | 8
13 | 4 | 18 | 9
13 | 4 | 19 | 9
13 | 4 | 20 | 10
13 | 4 | 21 | 10
13 | 4 | 22 | 11
13 | 4 | 23 | 11
13 | 4 | 24 | 12
13 | 4 | 25 | 12
13 | 4 | 26 | 13
13 | 4 | 27 | 13
13 | 4 | 28 | 14
13 | 4 | 29 | 14
13 | 4 | 30 | 15
14 | 4 | 1 | 0
14 | 4 | 2 | 1
14 | 4 | 3 | 1
14 | 4 | 4 | 2
14 | 4 | 5 | 2
14 | 4 | 6 | 3
14 | 4 | 7 | 3
14 | 4 | 8 | 4
14 | 4 | 9 | 4
14 | 4 | 10 | 5
14 | 4 | 11 | 5
14 | 4 | 12 | 6
14 | 4 | 13 | 6
14 | 4 | 14 | 7
14 | 4 | 15 | 7
14 | 4 | 16 | 8
14 | 4 | 17 | 8
14 | 4 | 18 | 9
14 | 4 | 19 | 9
14 | 4 | 20 | 10
14 | 4 | 21 | 10
14 | 4 | 22 | 11
14 | 4 | 23 | 11
14 | 4 | 24 | 12
14 | 4 | 25 | 12
14 | 4 | 26 | 13
14 | 4 | 27 | 13
14 | 4 | 28 | 14
14 | 4 | 29 | 14
14 | 4 | 30 | 15
15 | 5 | 1 | 0
15 | 5 | 2 | 1
15 | 5 | 3 | 1
15 | 5 | 4 | 2
15 | 5 | 5 | 2
15 | 5 | 6 | 3
15 | 5 | 7 | 3
15 | 5 | 8 | 4
15 | 5 | 9 | 4
15 | 5 | 10 | 5
15 | 5 | 11 | 5
15 | 5 | 12 | 6
15 | 5 | 13 | 6
15 | 5 | 14 | 7
15 | 5 | 15 | 7
15 | 5 | 16 | 8
15 | 5 | 17 | 8
15 | 5 | 18 | 9
15 | 5 | 19 | 9
15 | 5 | 20 | 10
15 | 5 | 21 | 10
15 | 5 | 22 | 11
15 | 5 | 23 | 11
15 | 5 | 24 | 12
15 | 5 | 25 | 12
15 | 5 | 26 | 13
15 | 5 | 27 | 13
15 | 5 | 28 | 14
15 | 5 | 29 | 14
15 | 5 | 30 | 15
16 | 5 | 1 | 0
16 | 5 | 2 | 1
16 | 5 | 3 | 1
16 | 5 | 4 | 2
16 | 5 | 5 | 2
16 | 5 | 6 | 3
16 | 5 | 7 | 3
16 | 5 | 8 | 4
16 | 5 | 9 | 4
16 | 5 | 10 | 5
16 | 5 | 11 | 5
16 | 5 | 12 | 6
16 | 5 | 13 | 6
16 | 5 | 14 | 7
16 | 5 | 15 | 7
16 | 5 | 16 | 8
16 | 5 | 17 | 8
16 | 5 | 18 | 9
16 | 5 | 19 | 9
16 | 5 | 20 | 10
16 | 5 | 21 | 10
16 | 5 | 22 | 11
16 | 5 | 23 | 11
16 | 5 | 24 | 12
16 | 5 | 25 | 12
16 | 5 | 26 | 13
16 | 5 | 27 | 13
16 | 5 | 28 | 14
16 | 5 | 29 | 14
16 | 5 | 30 | 15
17 | 5 | 1 | 0
17 | 5 | 2 | 1
17 | 5 | 3 | 1
17 | 5 | 4 | 2
17 | 5 | 5 | 2
17 | 5 | 6 | 3
17 | 5 | 7 | 3
17 | 5 | 8 | 4
17 | 5 | 9 | 4
17 | 5 | 10 | 5
17 | 5 | 11 | 5
17 | 5 | 12 | 6
17 | 5 | 13 | 6
17 | 5 | 14 | 7
17 | 5 | 15 | 7
17 | 5 | 16 | 8
17 | 5 | 17 | 8
17 | 5 | 18 | 9
17 | 5 | 19 | 9
17 | 5 | 20 | 10
17 | 5 | 21 | 10
17 | 5 | 22 | 11
17 | 5 | 23 | 11
17 | 5 | 24 | 12
17 | 5 | 25 | 12
17 | 5 | 26 | 13
17 | 5 | 27 | 13
17 | 5 | 28 | 14
17 | 5 | 29 | 14
17 | 5 | 30 | 15
18 | 6 | 1 | 0
18 | 6 | 2 | 1
18 | 6 | 3 | 1
18 | 6 | 4 | 2
18 | 6 | 5 | 2
18 | 6 | 6 | 3
18 | 6 | 7 | 3
18 | 6 | 8 | 4
18 | 6 | 9 | 4
18 | 6 | 10 | 5
18 | 6 | 11 | 5
18 | 6 | 12 | 6
18 | 6 | 13 | 6
18 | 6 | 14 | 7
18 | 6 | 15 | 7
18 | 6 | 16 | 8
18 | 6 | 17 | 8
18 | 6 | 18 | 9
18 | 6 | 19 | 9
18 | 6 | 20 | 10
18 | 6 | 21 | 10
18 | 6 | 22 | 11
18 | 6 | 23 | 11
18 | 6 | 24 | 12
18 | 6 | 25 | 12
18 | 6 | 26 | 13
18 | 6 | 27 | 13
18 | 6 | 28 | 14
18 | 6 | 29 | 14
18 | 6 | 30 | 15
19 | 6 | 1 | 0
19 | 6 | 2 | 1
19 | 6 | 3 | 1
19 | 6 | 4 | 2
19 | 6 | 5 | 2
19 | 6 | 6 | 3
19 | 6 | 7 | 3
19 | 6 | 8 | 4
19 | 6 | 9 | 4
19 | 6 | 10 | 5
19 | 6 | 11 | 5
19 | 6 | 12 | 6
19 | 6 | 13 | 6
19 | 6 | 14 | 7
19 | 6 | 15 | 7
19 | 6 | 16 | 8
19 | 6 | 17 | 8
19 | 6 | 18 | 9
19 | 6 | 19 | 9
19 | 6 | 20 | 10
19 | 6 | 21 | 10
19 | 6 | 22 | 11
19 | 6 | 23 | 11
19 | 6 | 24 | 12
19 | 6 | 25 | 12
19 | 6 | 26 | 13
19 | 6 | 27 | 13
19 | 6 | 28 | 14
19 | 6 | 29 | 14
19 | 6 | 30 | 15
20 | 6 | 1 | 0
20 | 6 | 2 | 1
20 | 6 | 3 | 1
20 | 6 | 4 | 2
20 | 6 | 5 | 2
20 | 6 | 6 | 3
20 | 6 | 7 | 3
20 | 6 | 8 | 4
20 | 6 | 9 | 4
20 | 6 | 10 | 5
20 | 6 | 11 | 5
20 | 6 | 12 | 6
20 | 6 | 13 | 6
20 | 6 | 14 | 7
20 | 6 | 15 | 7
20 | 6 | 16 | 8
20 | 6 | 17 | 8
20 | 6 | 18 | 9
20 | 6 | 19 | 9
20 | 6 | 20 | 10
20 | 6 | 21 | 10
20 | 6 | 22 | 11
20 | 6 | 23 | 11
20 | 6 | 24 | 12
20 | 6 | 25 | 12
20 | 6 | 26 | 13
20 | 6 | 27 | 13
20 | 6 | 28 | 14
20 | 6 | 29 | 14
20 | 6 | 30 | 15
(600 rows)
select sum(r.a) from orca.r;
sum
-----
210
(1 row)
select count(*) from orca.r;
count
-------
20
(1 row)
select a, b from orca.r, orca.s group by a,b;
a | b
----+---
1 | 0
2 | 0
3 | 1
4 | 1
5 | 1
6 | 2
7 | 2
8 | 2
9 | 3
10 | 3
11 | 3
12 | 4
13 | 4
14 | 4
15 | 5
16 | 5
17 | 5
18 | 6
19 | 6
20 | 6
(20 rows)
select r.a+1 from orca.r;
?column?
----------
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
(20 rows)
select * from orca.r, orca.s where r.a<s.c or (r.b<s.d and r.b>s.c);
a | b | c | d
----+---+----+----
1 | 0 | 2 | 1
1 | 0 | 3 | 1
1 | 0 | 4 | 2
1 | 0 | 5 | 2
1 | 0 | 6 | 3
1 | 0 | 7 | 3
1 | 0 | 8 | 4
1 | 0 | 9 | 4
1 | 0 | 10 | 5
1 | 0 | 11 | 5
1 | 0 | 12 | 6
1 | 0 | 13 | 6
1 | 0 | 14 | 7
1 | 0 | 15 | 7
1 | 0 | 16 | 8
1 | 0 | 17 | 8
1 | 0 | 18 | 9
1 | 0 | 19 | 9
1 | 0 | 20 | 10
1 | 0 | 21 | 10
1 | 0 | 22 | 11
1 | 0 | 23 | 11
1 | 0 | 24 | 12
1 | 0 | 25 | 12
1 | 0 | 26 | 13
1 | 0 | 27 | 13
1 | 0 | 28 | 14
1 | 0 | 29 | 14
1 | 0 | 30 | 15
2 | 0 | 3 | 1
2 | 0 | 4 | 2
2 | 0 | 5 | 2
2 | 0 | 6 | 3
2 | 0 | 7 | 3
2 | 0 | 8 | 4
2 | 0 | 9 | 4
2 | 0 | 10 | 5
2 | 0 | 11 | 5
2 | 0 | 12 | 6
2 | 0 | 13 | 6
2 | 0 | 14 | 7
2 | 0 | 15 | 7
2 | 0 | 16 | 8
2 | 0 | 17 | 8
2 | 0 | 18 | 9
2 | 0 | 19 | 9
2 | 0 | 20 | 10
2 | 0 | 21 | 10
2 | 0 | 22 | 11
2 | 0 | 23 | 11
2 | 0 | 24 | 12
2 | 0 | 25 | 12
2 | 0 | 26 | 13
2 | 0 | 27 | 13
2 | 0 | 28 | 14
2 | 0 | 29 | 14
2 | 0 | 30 | 15
3 | 1 | 4 | 2
3 | 1 | 5 | 2
3 | 1 | 6 | 3
3 | 1 | 7 | 3
3 | 1 | 8 | 4
3 | 1 | 9 | 4
3 | 1 | 10 | 5
3 | 1 | 11 | 5
3 | 1 | 12 | 6
3 | 1 | 13 | 6
3 | 1 | 14 | 7
3 | 1 | 15 | 7
3 | 1 | 16 | 8
3 | 1 | 17 | 8
3 | 1 | 18 | 9
3 | 1 | 19 | 9
3 | 1 | 20 | 10
3 | 1 | 21 | 10
3 | 1 | 22 | 11
3 | 1 | 23 | 11
3 | 1 | 24 | 12
3 | 1 | 25 | 12
3 | 1 | 26 | 13
3 | 1 | 27 | 13
3 | 1 | 28 | 14
3 | 1 | 29 | 14
3 | 1 | 30 | 15
4 | 1 | 5 | 2
4 | 1 | 6 | 3
4 | 1 | 7 | 3
4 | 1 | 8 | 4
4 | 1 | 9 | 4
4 | 1 | 10 | 5
4 | 1 | 11 | 5
4 | 1 | 12 | 6
4 | 1 | 13 | 6
4 | 1 | 14 | 7
4 | 1 | 15 | 7
4 | 1 | 16 | 8
4 | 1 | 17 | 8
4 | 1 | 18 | 9
4 | 1 | 19 | 9
4 | 1 | 20 | 10
4 | 1 | 21 | 10
4 | 1 | 22 | 11
4 | 1 | 23 | 11
4 | 1 | 24 | 12
4 | 1 | 25 | 12
4 | 1 | 26 | 13
4 | 1 | 27 | 13
4 | 1 | 28 | 14
4 | 1 | 29 | 14
4 | 1 | 30 | 15
5 | 1 | 6 | 3
5 | 1 | 7 | 3
5 | 1 | 8 | 4
5 | 1 | 9 | 4
5 | 1 | 10 | 5
5 | 1 | 11 | 5
5 | 1 | 12 | 6
5 | 1 | 13 | 6
5 | 1 | 14 | 7
5 | 1 | 15 | 7
5 | 1 | 16 | 8
5 | 1 | 17 | 8
5 | 1 | 18 | 9
5 | 1 | 19 | 9
5 | 1 | 20 | 10
5 | 1 | 21 | 10
5 | 1 | 22 | 11
5 | 1 | 23 | 11
5 | 1 | 24 | 12
5 | 1 | 25 | 12
5 | 1 | 26 | 13
5 | 1 | 27 | 13
5 | 1 | 28 | 14
5 | 1 | 29 | 14
5 | 1 | 30 | 15
6 | 2 | 7 | 3
6 | 2 | 8 | 4
6 | 2 | 9 | 4
6 | 2 | 10 | 5
6 | 2 | 11 | 5
6 | 2 | 12 | 6
6 | 2 | 13 | 6
6 | 2 | 14 | 7
6 | 2 | 15 | 7
6 | 2 | 16 | 8
6 | 2 | 17 | 8
6 | 2 | 18 | 9
6 | 2 | 19 | 9
6 | 2 | 20 | 10
6 | 2 | 21 | 10
6 | 2 | 22 | 11
6 | 2 | 23 | 11
6 | 2 | 24 | 12
6 | 2 | 25 | 12
6 | 2 | 26 | 13
6 | 2 | 27 | 13
6 | 2 | 28 | 14
6 | 2 | 29 | 14
6 | 2 | 30 | 15
7 | 2 | 8 | 4
7 | 2 | 9 | 4
7 | 2 | 10 | 5
7 | 2 | 11 | 5
7 | 2 | 12 | 6
7 | 2 | 13 | 6
7 | 2 | 14 | 7
7 | 2 | 15 | 7
7 | 2 | 16 | 8
7 | 2 | 17 | 8
7 | 2 | 18 | 9
7 | 2 | 19 | 9
7 | 2 | 20 | 10
7 | 2 | 21 | 10
7 | 2 | 22 | 11
7 | 2 | 23 | 11
7 | 2 | 24 | 12
7 | 2 | 25 | 12
7 | 2 | 26 | 13
7 | 2 | 27 | 13
7 | 2 | 28 | 14
7 | 2 | 29 | 14
7 | 2 | 30 | 15
8 | 2 | 9 | 4
8 | 2 | 10 | 5
8 | 2 | 11 | 5
8 | 2 | 12 | 6
8 | 2 | 13 | 6
8 | 2 | 14 | 7
8 | 2 | 15 | 7
8 | 2 | 16 | 8
8 | 2 | 17 | 8
8 | 2 | 18 | 9
8 | 2 | 19 | 9
8 | 2 | 20 | 10
8 | 2 | 21 | 10
8 | 2 | 22 | 11
8 | 2 | 23 | 11
8 | 2 | 24 | 12
8 | 2 | 25 | 12
8 | 2 | 26 | 13
8 | 2 | 27 | 13
8 | 2 | 28 | 14
8 | 2 | 29 | 14
8 | 2 | 30 | 15
9 | 3 | 10 | 5
9 | 3 | 11 | 5
9 | 3 | 12 | 6
9 | 3 | 13 | 6
9 | 3 | 14 | 7
9 | 3 | 15 | 7
9 | 3 | 16 | 8
9 | 3 | 17 | 8
9 | 3 | 18 | 9
9 | 3 | 19 | 9
9 | 3 | 20 | 10
9 | 3 | 21 | 10
9 | 3 | 22 | 11
9 | 3 | 23 | 11
9 | 3 | 24 | 12
9 | 3 | 25 | 12
9 | 3 | 26 | 13
9 | 3 | 27 | 13
9 | 3 | 28 | 14
9 | 3 | 29 | 14
9 | 3 | 30 | 15
10 | 3 | 11 | 5
10 | 3 | 12 | 6
10 | 3 | 13 | 6
10 | 3 | 14 | 7
10 | 3 | 15 | 7
10 | 3 | 16 | 8
10 | 3 | 17 | 8
10 | 3 | 18 | 9
10 | 3 | 19 | 9
10 | 3 | 20 | 10
10 | 3 | 21 | 10
10 | 3 | 22 | 11
10 | 3 | 23 | 11
10 | 3 | 24 | 12
10 | 3 | 25 | 12
10 | 3 | 26 | 13
10 | 3 | 27 | 13
10 | 3 | 28 | 14
10 | 3 | 29 | 14
10 | 3 | 30 | 15
11 | 3 | 12 | 6
11 | 3 | 13 | 6
11 | 3 | 14 | 7
11 | 3 | 15 | 7
11 | 3 | 16 | 8
11 | 3 | 17 | 8
11 | 3 | 18 | 9
11 | 3 | 19 | 9
11 | 3 | 20 | 10
11 | 3 | 21 | 10
11 | 3 | 22 | 11
11 | 3 | 23 | 11
11 | 3 | 24 | 12
11 | 3 | 25 | 12
11 | 3 | 26 | 13
11 | 3 | 27 | 13
11 | 3 | 28 | 14
11 | 3 | 29 | 14
11 | 3 | 30 | 15
12 | 4 | 13 | 6
12 | 4 | 14 | 7
12 | 4 | 15 | 7
12 | 4 | 16 | 8
12 | 4 | 17 | 8
12 | 4 | 18 | 9
12 | 4 | 19 | 9
12 | 4 | 20 | 10
12 | 4 | 21 | 10
12 | 4 | 22 | 11
12 | 4 | 23 | 11
12 | 4 | 24 | 12
12 | 4 | 25 | 12
12 | 4 | 26 | 13
12 | 4 | 27 | 13
12 | 4 | 28 | 14
12 | 4 | 29 | 14
12 | 4 | 30 | 15
13 | 4 | 14 | 7
13 | 4 | 15 | 7
13 | 4 | 16 | 8
13 | 4 | 17 | 8
13 | 4 | 18 | 9
13 | 4 | 19 | 9
13 | 4 | 20 | 10
13 | 4 | 21 | 10
13 | 4 | 22 | 11
13 | 4 | 23 | 11
13 | 4 | 24 | 12
13 | 4 | 25 | 12
13 | 4 | 26 | 13
13 | 4 | 27 | 13
13 | 4 | 28 | 14
13 | 4 | 29 | 14
13 | 4 | 30 | 15
14 | 4 | 15 | 7
14 | 4 | 16 | 8
14 | 4 | 17 | 8
14 | 4 | 18 | 9
14 | 4 | 19 | 9
14 | 4 | 20 | 10
14 | 4 | 21 | 10
14 | 4 | 22 | 11
14 | 4 | 23 | 11
14 | 4 | 24 | 12
14 | 4 | 25 | 12
14 | 4 | 26 | 13
14 | 4 | 27 | 13
14 | 4 | 28 | 14
14 | 4 | 29 | 14
14 | 4 | 30 | 15
15 | 5 | 16 | 8
15 | 5 | 17 | 8
15 | 5 | 18 | 9
15 | 5 | 19 | 9
15 | 5 | 20 | 10
15 | 5 | 21 | 10
15 | 5 | 22 | 11
15 | 5 | 23 | 11
15 | 5 | 24 | 12
15 | 5 | 25 | 12
15 | 5 | 26 | 13
15 | 5 | 27 | 13
15 | 5 | 28 | 14
15 | 5 | 29 | 14
15 | 5 | 30 | 15
16 | 5 | 17 | 8
16 | 5 | 18 | 9
16 | 5 | 19 | 9
16 | 5 | 20 | 10
16 | 5 | 21 | 10
16 | 5 | 22 | 11
16 | 5 | 23 | 11
16 | 5 | 24 | 12
16 | 5 | 25 | 12
16 | 5 | 26 | 13
16 | 5 | 27 | 13
16 | 5 | 28 | 14
16 | 5 | 29 | 14
16 | 5 | 30 | 15
17 | 5 | 18 | 9
17 | 5 | 19 | 9
17 | 5 | 20 | 10
17 | 5 | 21 | 10
17 | 5 | 22 | 11
17 | 5 | 23 | 11
17 | 5 | 24 | 12
17 | 5 | 25 | 12
17 | 5 | 26 | 13
17 | 5 | 27 | 13
17 | 5 | 28 | 14
17 | 5 | 29 | 14
17 | 5 | 30 | 15
18 | 6 | 19 | 9
18 | 6 | 20 | 10
18 | 6 | 21 | 10
18 | 6 | 22 | 11
18 | 6 | 23 | 11
18 | 6 | 24 | 12
18 | 6 | 25 | 12
18 | 6 | 26 | 13
18 | 6 | 27 | 13
18 | 6 | 28 | 14
18 | 6 | 29 | 14
18 | 6 | 30 | 15
19 | 6 | 20 | 10
19 | 6 | 21 | 10
19 | 6 | 22 | 11
19 | 6 | 23 | 11
19 | 6 | 24 | 12
19 | 6 | 25 | 12
19 | 6 | 26 | 13
19 | 6 | 27 | 13
19 | 6 | 28 | 14
19 | 6 | 29 | 14
19 | 6 | 30 | 15
20 | 6 | 21 | 10
20 | 6 | 22 | 11
20 | 6 | 23 | 11
20 | 6 | 24 | 12
20 | 6 | 25 | 12
20 | 6 | 26 | 13
20 | 6 | 27 | 13
20 | 6 | 28 | 14
20 | 6 | 29 | 14
20 | 6 | 30 | 15
(390 rows)
select case when r.a<s.c then r.a<s.c else r.a<s.c end from orca.r, orca.s;
case
------
f
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
f
f
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
f
f
f
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
f
f
f
f
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
f
f
f
f
f
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
f
f
f
f
f
f
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
f
f
f
f
f
f
f
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
f
f
f
f
f
f
f
f
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
f
f
f
f
f
f
f
f
f
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
f
f
f
f
f
f
f
f
f
f
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
f
f
f
f
f
f
f
f
f
f
f
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
f
f
f
f
f
f
f
f
f
f
f
f
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
f
f
f
f
f
f
f
f
f
f
f
f
f
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
f
f
f
f
f
f
f
f
f
f
f
f
f
f
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
t
t
t
t
t
t
t
t
t
t
t
t
t
t
t
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
t
t
t
t
t
t
t
t
t
t
t
t
t
t
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
t
t
t
t
t
t
t
t
t
t
t
t
t
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
t
t
t
t
t
t
t
t
t
t
t
t
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
t
t
t
t
t
t
t
t
t
t
t
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
f
t
t
t
t
t
t
t
t
t
t
(600 rows)
select case r.b<s.c when true then r.b else s.c end from orca.r, orca.s where r.a = s.d;
c
---
0
0
0
0
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
(29 rows)
select * from orca.r limit 100;
a | b
----+---
1 | 0
2 | 0
3 | 1
4 | 1
5 | 1
6 | 2
7 | 2
8 | 2
9 | 3
10 | 3
11 | 3
12 | 4
13 | 4
14 | 4
15 | 5
16 | 5
17 | 5
18 | 6
19 | 6
20 | 6
(20 rows)
select * from orca.r limit 10 offset 9;
a | b
----+---
10 | 3
11 | 3
12 | 4
13 | 4
14 | 4
15 | 5
16 | 5
17 | 5
18 | 6
19 | 6
(10 rows)
select * from orca.r offset 10;
a | b
----+---
11 | 3
12 | 4
13 | 4
14 | 4
15 | 5
16 | 5
17 | 5
18 | 6
19 | 6
20 | 6
(10 rows)
select sqrt(r.a) from orca.r;
sqrt
--------------------
1
1.4142135623730951
1.7320508075688772
2
2.23606797749979
2.449489742783178
2.6457513110645907
2.8284271247461903
3
3.1622776601683795
3.3166247903554
3.4641016151377544
3.605551275463989
3.7416573867739413
3.872983346207417
4
4.123105625617661
4.242640687119285
4.358898943540674
4.47213595499958
(20 rows)
select pow(r.b,r.a) from orca.r;
pow
-----------------------
0
0
1
1
1
64
128
256
19683
59049
177147
16777216
67108864
268435456
30517578125
152587890625
762939453125
101559956668416
609359740010496
3.656158440062976e+15
(20 rows)
select b from orca.r group by b having count(*) > 2;
b
---
1
2
3
4
5
6
(6 rows)
select b from orca.r group by b having count(*) <= avg(a) + (select count(*) from orca.s where s.c = r.b);
b
---
3
2
5
6
1
4
(6 rows)
select sum(a) from orca.r group by b having count(*) > 2 order by b+1;
sum
-----
12
21
30
39
48
57
(6 rows)
select sum(a) from orca.r group by b having count(*) > 2 order by b+1;
sum
-----
12
21
30
39
48
57
(6 rows)
-- constants
select 0.001::numeric from orca.r;
numeric
---------
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
(20 rows)
select NULL::text, NULL::int from orca.r;
text | int4
------+------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(20 rows)
select 'helloworld'::text, 'helloworld2'::varchar from orca.r;
text | varchar
------------+-------------
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
(20 rows)
select 129::bigint, 5623::int, 45::smallint from orca.r;
int8 | int4 | int2
------+------+------
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
(20 rows)
select 0.001::numeric from orca.r;
numeric
---------
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
0.001
(20 rows)
select NULL::text, NULL::int from orca.r;
text | int4
------+------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(20 rows)
select 'helloworld'::text, 'helloworld2'::varchar from orca.r;
text | varchar
------------+-------------
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
helloworld | helloworld2
(20 rows)
select 129::bigint, 5623::int, 45::smallint from orca.r;
int8 | int4 | int2
------+------+------
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
129 | 5623 | 45
(20 rows)
-- distributed tables
create table orca.foo (x1 int, x2 int, x3 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.
create table orca.bar1 (x1 int, x2 int, x3 int) distributed randomly;
create table orca.bar2 (x1 int, x2 int, x3 int) distributed randomly;
insert into orca.foo select i,i+1,i+2 from generate_series(1,10) i;
insert into orca.bar1 select i,i+1,i+2 from generate_series(1,20) i;
insert into orca.bar2 select i,i+1,i+2 from generate_series(1,30) i;
analyze orca.foo;
analyze orca.bar1;
analyze orca.bar2;
-- produces result node
select x2 from orca.foo where x1 in (select x2 from orca.bar1);
x2
----
4
6
8
10
3
5
7
9
11
(9 rows)
select 1;
?column?
----------
1
(1 row)
SELECT 1 AS one FROM orca.foo having 1 < 2;
one
-----
1
(1 row)
SELECT generate_series(1,5) AS one FROM orca.foo having 1 < 2;
one
-----
1
2
3
4
5
(5 rows)
SELECT 1 AS one FROM orca.foo group by x1 having 1 < 2;
one
-----
1
1
1
1
1
1
1
1
1
1
(10 rows)
SELECT x1 AS one FROM orca.foo having 1 < 2;
ERROR: column "foo.x1" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT x1 AS one FROM orca.foo having 1 < 2;
^
-- distinct clause
select distinct 1, null;
?column? | ?column?
----------+----------
1 |
(1 row)
select distinct 1, null from orca.foo;
?column? | ?column?
----------+----------
1 |
(1 row)
select distinct 1, sum(x1) from orca.foo;
?column? | sum
----------+-----
1 | 55
(1 row)
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
8 | 8
9 | 9
10 | 10
(10 rows)
select distinct x1, sum(x3) from orca.foo group by x1,x2;
x1 | sum
----+-----
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
4
6
8
10
(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);
x1 | x2 | x3
----+----+----
2 | 3 | 4
(1 row)
select distinct a.x1 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) order by 1;
x1
----
1
2
(2 rows)
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
4 | 5 | 6
6 | 7 | 8
8 | 9 | 10
10 | 11 | 12
(10 rows)
-- with clause
with cte1 as (select * from orca.foo) select a.x1+1 from (select * from cte1) a group by a.x1;
?column?
----------
3
5
7
9
11
2
4
6
8
10
(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);
?column?
----------
11
(1 row)
select count(*)+1 from orca.bar1 b where b.x1 < any (with cte1 as (select * from orca.foo) select a.x1 from (select * from cte1) a group by a.x1);
?column?
----------
10
(1 row)
select count(*)+1 from orca.bar1 b where b.x1 < any (with cte1 as (select * from orca.foo) select a.x1 from cte1 a group by a.x1);
?column?
----------
10
(1 row)
with cte1 as (select * from orca.foo) select count(*)+1 from cte1 a where a.x1 < any (with cte2 as (select * from cte1 b where b.x1 > 10) select c.x1 from (select * from cte2) c group by c.x1);
?column?
----------
1
(1 row)
with cte1 as (select * from orca.foo) select count(*)+1 from cte1 a where a.x1 < any (with cte2 as (select * from cte1 b where b.x1 > 10) select c.x1+1 from (select * from cte2) c group by c.x1);
?column?
----------
1
(1 row)
with x as (select * from orca.foo) select count(*) from (select * from x) y where y.x1 <= (select count(*) from x);
count
-------
10
(1 row)
with x as (select * from orca.foo) select count(*)+1 from (select * from x) y where y.x1 <= (select count(*) from x);
?column?
----------
11
(1 row)
with x as (select * from orca.foo) select count(*) from (select * from x) y where y.x1 < (with z as (select * from x) select count(*) from z);
count
-------
9
(1 row)
-- outer references
select count(*)+1 from orca.foo x where x.x1 > (select count(*)+1 from orca.bar1 y where y.x1 = x.x2);
?column?
----------
9
(1 row)
select count(*)+1 from orca.foo x where x.x1 > (select count(*) from orca.bar1 y where y.x1 = x.x2);
?column?
----------
10
(1 row)
select count(*) from orca.foo x where x.x1 > (select count(*)+1 from orca.bar1 y where y.x1 = x.x2);
count
-------
8
(1 row)
-- result node with one time filter and filter
explain 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
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 Key: bar1.x1
-> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1765423.13 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)
Hash Key: bar1.x2
-> Seq Scan on bar1 (cost=0.00..431.00 rows=7 width=8)
-> Hash (cost=431.00..431.00 rows=10 width=4)
-> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..431.00 rows=10 width=4)
Hash Key: bar2.x2
-> Seq Scan on bar2 (cost=0.00..431.00 rows=10 width=4)
SubPlan 1
-> Result (cost=0.00..431.02 rows=1 width=4)
-> Result (cost=0.00..431.02 rows=1 width=1)
One-Time Filter: (bar1.x2 = bar2.x2)
Filter: (((bar1.x2)::double precision = random()) AND (foo.x2 = bar2.x2))
-> 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)
(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
from orca.bar1 inner join orca.bar2 on (bar1.x2 = bar2.x2) order by bar1.x1;
col1 | x1
------+----
0 | 1
0 | 2
0 | 3
0 | 4
0 | 5
0 | 6
0 | 7
0 | 8
0 | 9
0 | 10
0 | 11
0 | 12
0 | 13
0 | 14
0 | 15
0 | 16
0 | 17
0 | 18
0 | 19
0 | 20
(20 rows)
drop table orca.r cascade;
create table orca.r(a int, b int) distributed by (a);
create unique index r_a on orca.r(a);
create index r_b on orca.r(b);
insert into orca.r select i, i%3 from generate_series(1,20) i;
drop table orca.s;
create table orca.s(c int, d int) distributed by (c);
insert into orca.s select i%7, i%2 from generate_series(1,30) i;
analyze orca.r;
analyze orca.s;
select * from orca.r, orca.s where r.a=s.c;
a | b | c | d
---+---+---+---
2 | 2 | 2 | 0
4 | 1 | 4 | 0
6 | 0 | 6 | 0
2 | 2 | 2 | 1
4 | 1 | 4 | 1
6 | 0 | 6 | 1
2 | 2 | 2 | 0
4 | 1 | 4 | 0
6 | 0 | 6 | 0
2 | 2 | 2 | 1
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)
-- Materialize node
select * from orca.r, orca.s where r.a<s.c+1 or r.a>s.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
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
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
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 | 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
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
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 | 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 | 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 | 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
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 | 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
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 | 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
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 | 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
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
(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
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
16 | 1
16 | 1
18 | 0
18 | 0
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
5 | 2
5 | 2
5 | 2
5 | 2
5 | 2
7 | 1
7 | 1
7 | 1
7 | 1
7 | 1
9 | 0
9 | 0
9 | 0
9 | 0
9 | 0
11 | 2
11 | 2
11 | 2
11 | 2
11 | 2
13 | 1
13 | 1
13 | 1
13 | 1
13 | 1
15 | 0
15 | 0
15 | 0
15 | 0
15 | 0
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();
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause, and no column type is suitable for a distribution key. Creating a NULL policy entry.
alter table orca.m add column a int;
alter table orca.m add column b int;
create table orca.m1();
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause, and no column type is suitable for a distribution key. Creating a NULL policy entry.
alter table orca.m1 add column a int;
alter table orca.m1 add column b int;
insert into orca.m select i-1, i%2 from generate_series(1,35) i;
insert into orca.m1 select i-2, i%3 from generate_series(1,25) i;
insert into orca.r values (null, 1);
-- join types
select r.a, s.c from orca.r left outer join orca.s on(r.a=s.c);
a | c
----+---
2 | 2
2 | 2
2 | 2
2 | 2
2 | 2
4 | 4
4 | 4
4 | 4
4 | 4
6 | 6
6 | 6
6 | 6
6 | 6
8 |
10 |
12 |
14 |
16 |
18 |
20 |
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 |
15 |
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;
a | c
----+---
1 | 1
1 | 1
1 | 1
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
|
(23 rows)
select r.a, s.c from orca.r left outer join orca.s on(r.a=s.c) where s.d > 2 or s.d is null order by r.a;
a | c
----+---
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
|
(15 rows)
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
1 | 1
3 | 3
5 | 5
1 | 1
3 | 3
5 | 5
1 | 1
3 | 3
5 | 5
1 | 1
2 | 2
4 | 4
6 | 6
| 0
2 | 2
4 | 4
6 | 6
| 0
2 | 2
4 | 4
6 | 6
| 0
2 | 2
4 | 4
6 | 6
| 0
2 | 2
(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 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
5 | 2
| 1
19 | 1
13 | 1
7 | 1
1 | 1
16 | 1
10 | 1
4 | 1
18 | 0
12 | 0
6 | 0
20 | 2
14 | 2
8 | 2
2 | 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
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
(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
(2 rows)
-- enable_hashjoin=off; enable_mergejoin=on
select 1 from orca.m, orca.m1 where m.a = m1.a and m.b!=m1.b;
?column?
----------
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
(16 rows)
-- plan.qual vs hashclauses/join quals:
select * from orca.r left outer join orca.s on (r.a=s.c and r.b<s.d) where s.d is null;
a | b | c | d
----+---+---+---
1 | 1 | |
5 | 2 | |
7 | 1 | |
9 | 0 | |
11 | 2 | |
13 | 1 | |
15 | 0 | |
17 | 2 | |
19 | 1 | |
| 1 | |
2 | 2 | |
4 | 1 | |
8 | 2 | |
10 | 1 | |
12 | 0 | |
14 | 2 | |
16 | 1 | |
18 | 0 | |
20 | 2 | |
(19 rows)
-- select * from orca.r m full outer join orca.r m1 on (m.a=m1.a) where m.a is null;
-- explain Hash Join with 'IS NOT DISTINCT FROM' join condition
-- force_explain
explain select * from orca.r, orca.s where r.a is not distinct from s.c;
QUERY PLAN
--------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.01 rows=30 width=16)
-> Hash Join (cost=0.00..862.00 rows=10 width=16)
Hash Cond: (NOT (s.c IS DISTINCT FROM r.a))
-> 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)
(7 rows)
-- explain Hash Join with equality join condition
-- force_explain
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)
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)
(7 rows)
-- sort
select * from orca.r join orca.s on(r.a=s.c) order by r.a, s.d;
a | b | c | d
---+---+---+---
1 | 1 | 1 | 0
1 | 1 | 1 | 0
1 | 1 | 1 | 1
1 | 1 | 1 | 1
1 | 1 | 1 | 1
2 | 2 | 2 | 0
2 | 2 | 2 | 0
2 | 2 | 2 | 0
2 | 2 | 2 | 1
2 | 2 | 2 | 1
3 | 0 | 3 | 0
3 | 0 | 3 | 0
3 | 0 | 3 | 1
3 | 0 | 3 | 1
4 | 1 | 4 | 0
4 | 1 | 4 | 0
4 | 1 | 4 | 1
4 | 1 | 4 | 1
5 | 2 | 5 | 0
5 | 2 | 5 | 0
5 | 2 | 5 | 1
5 | 2 | 5 | 1
6 | 0 | 6 | 0
6 | 0 | 6 | 0
6 | 0 | 6 | 1
6 | 0 | 6 | 1
(26 rows)
select * from orca.r join orca.s on(r.a=s.c) order by r.a, s.d limit 10;
a | b | c | d
---+---+---+---
1 | 1 | 1 | 0
1 | 1 | 1 | 0
1 | 1 | 1 | 1
1 | 1 | 1 | 1
1 | 1 | 1 | 1
2 | 2 | 2 | 0
2 | 2 | 2 | 0
2 | 2 | 2 | 0
2 | 2 | 2 | 1
2 | 2 | 2 | 1
(10 rows)
select * from orca.r join orca.s on(r.a=s.c) order by r.a + 5, s.d limit 10;
a | b | c | d
---+---+---+---
1 | 1 | 1 | 0
1 | 1 | 1 | 0
1 | 1 | 1 | 1
1 | 1 | 1 | 1
1 | 1 | 1 | 1
2 | 2 | 2 | 0
2 | 2 | 2 | 0
2 | 2 | 2 | 0
2 | 2 | 2 | 1
2 | 2 | 2 | 1
(10 rows)
-- group by
select 1 from orca.m group by a+b;
?column?
----------
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
(18 rows)
-- join with const table
select * from orca.r where a = (select 1);
a | b
---+---
1 | 1
(1 row)
-- union with const table
select * from ((select a as x from orca.r) union (select 1 as x )) as foo order by x;
x
----
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(21 rows)
insert into orca.m values (1,-1), (1,2), (1,1);
-- computed columns
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
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
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
1 | 0 | 0
1 | 3 | 3
1 | 2 | 2
(38 rows)
-- func expr
select * from orca.m where a=abs(b);
a | b
---+----
1 | -1
1 | 1
(2 rows)
-- grouping sets
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
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 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
| 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
(73 rows)
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
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
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
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;
a | b | count
----+----+-------
0 | 1 | 1
0 | | 1
1 | -1 | 1
1 | 0 | 1
1 | 1 | 1
1 | 2 | 1
1 | | 4
2 | 1 | 1
2 | | 1
3 | 0 | 1
3 | | 1
4 | 1 | 1
4 | | 1
5 | 0 | 1
5 | | 1
6 | 1 | 1
6 | | 1
7 | 0 | 1
7 | | 1
8 | 1 | 1
8 | | 1
9 | 0 | 1
9 | | 1
10 | 1 | 1
10 | | 1
11 | 0 | 1
11 | | 1
12 | 1 | 1
12 | | 1
13 | 0 | 1
13 | | 1
14 | 1 | 1
14 | | 1
15 | 0 | 1
15 | | 1
16 | 1 | 1
16 | | 1
17 | 0 | 1
17 | | 1
18 | 1 | 1
18 | | 1
19 | 0 | 1
19 | | 1
20 | 1 | 1
20 | | 1
21 | 0 | 1
21 | | 1
22 | 1 | 1
22 | | 1
23 | 0 | 1
23 | | 1
24 | 1 | 1
24 | | 1
25 | 0 | 1
25 | | 1
26 | 1 | 1
26 | | 1
27 | 0 | 1
27 | | 1
28 | 1 | 1
28 | | 1
29 | 0 | 1
29 | | 1
30 | 1 | 1
30 | | 1
31 | 0 | 1
31 | | 1
32 | 1 | 1
32 | | 1
33 | 0 | 1
33 | | 1
34 | 1 | 1
34 | | 1
| | 38
(74 rows)
select count(*) from orca.m group by ();
count
-------
38
(1 row)
select a, count(*) from orca.r group by (), a;
a | count
----+-------
1 | 1
3 | 1
5 | 1
7 | 1
9 | 1
11 | 1
13 | 1
15 | 1
17 | 1
19 | 1
| 1
2 | 1
4 | 1
6 | 1
8 | 1
10 | 1
12 | 1
14 | 1
16 | 1
18 | 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
9 | 1
11 | 1
13 | 1
15 | 1
17 | 1
19 | 1
| 1
(22 rows)
select a, b, count(*) c from orca.r group by grouping sets ((),(a), (a,b)) order by b,a,c;
a | b | c
----+---+----
3 | 0 | 1
6 | 0 | 1
9 | 0 | 1
12 | 0 | 1
15 | 0 | 1
18 | 0 | 1
1 | 1 | 1
4 | 1 | 1
7 | 1 | 1
10 | 1 | 1
13 | 1 | 1
16 | 1 | 1
19 | 1 | 1
| 1 | 1
2 | 2 | 1
5 | 2 | 1
8 | 2 | 1
11 | 2 | 1
14 | 2 | 1
17 | 2 | 1
20 | 2 | 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
| | 1
| | 21
(43 rows)
select a, count(*) c from orca.r group by grouping sets ((),(a), (a,b)) order by b,a,c;
a | c
----+----
3 | 1
6 | 1
9 | 1
12 | 1
15 | 1
18 | 1
1 | 1
4 | 1
7 | 1
10 | 1
13 | 1
16 | 1
19 | 1
| 1
2 | 1
5 | 1
8 | 1
11 | 1
14 | 1
17 | 1
20 | 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
| 1
| 21
(43 rows)
select 1 from orca.r group by ();
?column?
----------
1
(1 row)
select a,1 from orca.r group by rollup(a);
a | ?column?
----+----------
1 | 1
3 | 1
5 | 1
7 | 1
9 | 1
11 | 1
13 | 1
15 | 1
17 | 1
19 | 1
| 1
| 1
2 | 1
4 | 1
6 | 1
8 | 1
10 | 1
12 | 1
14 | 1
16 | 1
18 | 1
20 | 1
(22 rows)
select distinct grouping(a) + grouping(b) from orca.m group by rollup(a,b);
?column?
----------
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}
{{12,0}} | {0}
{{14,2}} | {2}
{{16,1}} | {1}
{{18,0}} | {0}
{{20,2}} | {2}
{{1,1}} | {1}
{{3,0}} | {0}
{{5,2}} | {2}
{{7,1}} | {1}
{{9,0}} | {0}
{{11,2}} | {2}
{{13,1}} | {1}
{{15,0}} | {0}
{{17,2}} | {2}
{{19,1}} | {1}
{{NULL,1}} | {1}
(21 rows)
-- setops
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 | 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
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
----
0
0
0
0
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
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;
create table orca.foo(a int, b int, c int, d 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.
drop table if exists orca.bar;
NOTICE: table "bar" does not exist, skipping
create table orca.bar(a int, b 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.
insert into orca.foo select i, i%2, i%4, i-1 from generate_series(1,40)i;
insert into orca.bar select i, i%3, i%2 from generate_series(1,30)i;
-- distinct operation
SELECT distinct a, b from orca.foo;
a | b
----+---
2 | 0
4 | 0
6 | 0
8 | 0
10 | 0
12 | 0
14 | 0
16 | 0
18 | 0
20 | 0
22 | 0
24 | 0
26 | 0
28 | 0
30 | 0
32 | 0
34 | 0
36 | 0
38 | 0
40 | 0
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
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
31 | 1
33 | 1
35 | 1
37 | 1
39 | 1
(20 rows)
SELECT distinct a, b from orca.foo;
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
37 | 1
39 | 1
2 | 0
4 | 0
6 | 0
8 | 0
10 | 0
12 | 0
14 | 0
16 | 0
18 | 0
20 | 0
22 | 0
24 | 0
26 | 0
28 | 0
30 | 0
32 | 0
34 | 0
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
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
35 | 1
36 | 1
37 | 1
38 | 1
39 | 1
40 | 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
37 | 1 | 2
39 | 1 | 4
(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
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
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
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
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
37 | 1 | 2
39 | 1 | 4
(20 rows)
SELECT distinct a, b from orca.foo;
a | b
----+---
2 | 0
4 | 0
6 | 0
8 | 0
10 | 0
12 | 0
14 | 0
16 | 0
18 | 0
20 | 0
22 | 0
24 | 0
26 | 0
28 | 0
30 | 0
32 | 0
34 | 0
36 | 0
38 | 0
40 | 0
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
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
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
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
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
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
37 | 1 | 2
39 | 1 | 4
(20 rows)
-- window operations
select row_number() over() from orca.foo order by 1;
row_number
------------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
(40 rows)
select rank() over(partition by b order by count(*)/sum(a)) from orca.foo group by a, b order by 1;
rank
------
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
20
(40 rows)
select row_number() over(order by foo.a) from orca.foo inner join orca.bar using(b) group by foo.a, bar.b, bar.a;
row_number
------------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
(400 rows)
select 1+row_number() over(order by foo.a+bar.a) from orca.foo inner join orca.bar using(b);
?column?
----------
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
(400 rows)
select row_number() over(order by foo.a+ bar.a)/count(*) from orca.foo inner join orca.bar using(b) group by foo.a, bar.a, bar.b;
?column?
----------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
(400 rows)
select count(*) over(partition by b order by a range between 1 preceding and (select count(*) from orca.bar) following) from orca.foo;
count
-------
16
16
16
16
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
16
16
16
16
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
(40 rows)
select a+1, rank() over(partition by b+1 order by a+1) from orca.foo order by 1, 2;
?column? | rank
----------+------
2 | 1
3 | 1
4 | 2
5 | 2
6 | 3
7 | 3
8 | 4
9 | 4
10 | 5
11 | 5
12 | 6
13 | 6
14 | 7
15 | 7
16 | 8
17 | 8
18 | 9
19 | 9
20 | 10
21 | 10
22 | 11
23 | 11
24 | 12
25 | 12
26 | 13
27 | 13
28 | 14
29 | 14
30 | 15
31 | 15
32 | 16
33 | 16
34 | 17
35 | 17
36 | 18
37 | 18
38 | 19
39 | 19
40 | 20
41 | 20
(40 rows)
select a , sum(a) over (order by a range 1 preceding) from orca.r order by 1,2;
a | sum
----+-----
1 | 1
2 | 3
3 | 5
4 | 7
5 | 9
6 | 11
7 | 13
8 | 15
9 | 17
10 | 19
11 | 21
12 | 23
13 | 25
14 | 27
15 | 29
16 | 31
17 | 33
18 | 35
19 | 37
20 | 39
|
(21 rows)
select a, b, floor(avg(b) over(order by a desc, b desc rows between unbounded preceding and unbounded following)) as avg, dense_rank() over (order by a) from orca.r order by 1,2,3,4;
a | b | avg | dense_rank
----+---+-----+------------
1 | 1 | 1 | 1
2 | 2 | 1 | 2
3 | 0 | 1 | 3
4 | 1 | 1 | 4
5 | 2 | 1 | 5
6 | 0 | 1 | 6
7 | 1 | 1 | 7
8 | 2 | 1 | 8
9 | 0 | 1 | 9
10 | 1 | 1 | 10
11 | 2 | 1 | 11
12 | 0 | 1 | 12
13 | 1 | 1 | 13
14 | 2 | 1 | 14
15 | 0 | 1 | 15
16 | 1 | 1 | 16
17 | 2 | 1 | 17
18 | 0 | 1 | 18
19 | 1 | 1 | 19
20 | 2 | 1 | 20
| 1 | 1 | 21
(21 rows)
select lead(a) over(order by a) from orca.r order by 1;
lead
------
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(21 rows)
select lag(c,d) over(order by c,d) from orca.s order by 1;
lag
-----
0
0
0
0
1
1
1
1
1
2
2
2
2
2
3
3
3
3
4
4
4
4
5
5
5
5
6
6
6
6
(30 rows)
select lead(c,c+d,1000) over(order by c,d) from orca.s order by 1;
lead
------
0
0
0
1
1
1
1
2
2
2
2
2
3
3
3
4
4
4
5
5
5
6
6
6
1000
1000
1000
1000
1000
1000
(30 rows)
-- test normalization of window functions
create table orca_w1(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 orca_w2(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 orca_w3(a int, b text);
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 orca_w1 select i, i from generate_series(1, 3) i;
insert into orca_w2 select i, i from generate_series(2, 4) i;
insert into orca_w3 select i, i from generate_series(3, 5) i;
-- outer ref in subquery in target list and window func in target list
select (select b from orca_w3 where a = orca_w1.a) as one, row_number() over(partition by orca_w1.a) as two from orca_w2, orca_w1;
one | two
-----+-----
| 1
| 2
| 3
| 1
| 2
| 3
3 | 1
3 | 2
3 | 3
(9 rows)
-- aggref in subquery with window func in target list
select orca_w1.a, (select sum(orca_w2.a) from orca_w2 where orca_w1.b = orca_w2.b), count(*), rank() over (order by orca_w1.b) from orca_w1 group by orca_w1.a, orca_w1.b order by orca_w1.a;
a | sum | count | rank
---+-----+-------+------
1 | | 1 | 1
2 | 2 | 1 | 2
3 | 3 | 1 | 3
(3 rows)
-- window function inside subquery inside target list with outer ref
select orca_w1.a, (select rank() over (order by orca_w1.b) from orca_w2 where orca_w1.b = orca_w2.b), count(*) from orca_w1 group by orca_w1.a, orca_w1.b order by orca_w1.a;
a | rank | count
---+------+-------
1 | | 1
2 | 1 | 1
3 | 1 | 1
(3 rows)
-- window function with empty partition clause inside subquery inside target list with outer ref
select (select rank() over() from orca_w3 where a = orca_w1.a) as one, row_number() over(partition by orca_w1.a) as two from orca_w1, orca_w2;
one | two
-----+-----
| 1
| 2
| 3
| 1
| 2
| 3
1 | 1
1 | 2
1 | 3
(9 rows)
-- window function in IN clause
select (select a from orca_w3 where a = orca_w1.a) as one from orca_w1 where orca_w1.a IN (select rank() over(partition by orca_w1.a) + 1 from orca_w1, orca_w2);
one
-----
(1 row)
-- window function in subquery inside target list with outer ref in partition clause
select (select rank() over(partition by orca_w2.a) from orca_w3 where a = orca_w1.a) as one, row_number() over(partition by orca_w1.a) as two from orca_w1, orca_w2 order by orca_w1.a;
one | two
-----+-----
| 1
| 2
| 3
| 1
| 2
| 3
1 | 1
1 | 2
1 | 3
(9 rows)
-- correlated subquery in target list
select (select a+1 from (select a from orca_w2 where orca_w1.a=orca_w2.a) sq(a)) as one, row_number() over(partition by orca_w1.a) as two from orca_w1;
one | two
-----+-----
3 | 1
4 | 1
| 1
(3 rows)
-- correlated subquery in target list, mismatching varattnos
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
(3 rows)
-- cte in scalar subquery
with x as (select a, b from orca_w1)
select (select count(*) from x) as one, rank() over(partition by a) as rank_within_parent from x order by a desc;
one | rank_within_parent
-----+--------------------
3 | 1
3 | 1
3 | 1
(3 rows)
-- window function in subquery inside target list with outer ref in order clause
select (select rank() over(order by orca_w2.a) from orca_w3 where a = orca_w1.a) as one, row_number() over(partition by orca_w1.a) as two from orca_w1, orca_w2 order by orca_w1.a;
one | two
-----+-----
| 1
| 2
| 3
| 1
| 2
| 3
1 | 1
1 | 2
1 | 3
(9 rows)
-- window function with outer ref in arguments
select (select sum(orca_w1.a + a) over(order by b) + 1 from orca_w2 where orca_w1.a = orca_w2.a) from orca_w1 order by orca_w1.a;
?column?
----------
5
7
(3 rows)
-- window function with outer ref in window clause and arguments
select (select sum(orca_w1.a + a) over(order by b + orca_w1.a) + 1 from orca_w2 where orca_w1.a = orca_w2.a) from orca_w1 order by orca_w1.a;
?column?
----------
5
7
(3 rows)
-- cte
with x as (select a, b from orca.r)
select rank() over(partition by a, case when b = 0 then a+b end order by b asc) as rank_within_parent from x order by a desc ,case when a+b = 0 then a end ,b;
rank_within_parent
--------------------
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
(21 rows)
-- alias
select foo.d from orca.foo full join orca.bar on (foo.d = bar.a) group by d;
d
----
1
3
5
7
9
11
13
15
17
19
21
23
25
27
29
31
33
35
37
39
0
2
4
6
8
10
12
14
16
18
20
22
24
26
28
30
32
34
36
38
(40 rows)
select 1 as v from orca.foo full join orca.bar on (foo.d = bar.a) group by d;
v
---
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
(40 rows)
select * from orca.r where a in (select count(*)+1 as v from orca.foo full join orca.bar on (foo.d = bar.a) group by d+r.b);
a | b
---+---
2 | 2
(1 row)
select * from orca.r where r.a in (select d+r.b+1 as v from orca.foo full join orca.bar on (foo.d = bar.a) group by d+r.b) order by r.a, r.b;
INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner
DETAIL: Query-to-DXL Translation: No attribute entry found due to incorrect normalization of query
a | b
----+---
3 | 0
4 | 1
5 | 2
6 | 0
7 | 1
8 | 2
9 | 0
10 | 1
11 | 2
12 | 0
13 | 1
14 | 2
15 | 0
16 | 1
17 | 2
18 | 0
19 | 1
20 | 2
(18 rows)
drop table if exists orca.rcte;
NOTICE: table "rcte" does not exist, skipping
create table orca.rcte(a int, b 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.
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 | 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 | 7 | 1 | 1
4 | 0 | 1 | 7 | 1 | 1
6 | 0 | 0 | 7 | 1 | 1
8 | 0 | 2 | 7 | 1 | 1
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
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 | 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 | 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
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 | 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 | 9 | 1 | 0
9 | 1 | 0 | 9 | 1 | 0
1 | 1 | 1 | 2 | 0 | 2
3 | 1 | 0 | 2 | 0 | 2
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 | 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 | 8 | 0 | 2
7 | 1 | 1 | 8 | 0 | 2
9 | 1 | 0 | 8 | 0 | 2
(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
(5 rows)
with x as (select * from orca.rcte where a < 10) select a from x union all select b from x;
a
---
2
4
6
8
0
0
0
0
1
3
5
7
9
1
1
1
1
1
(18 rows)
with x as (select * from orca.rcte where a < 10) select * from x x1 where x1.b = any (select x2.a from x x2 group by x2.a);
a | b | c
---+---+---
1 | 1 | 1
3 | 1 | 0
5 | 1 | 2
7 | 1 | 1
9 | 1 | 0
(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);
a | b | c
---+---+---
(0 rows)
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
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 | 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
---+---+---
2 | 0 | 2
4 | 0 | 1
6 | 0 | 0
8 | 0 | 2
(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;
a | a
---+---
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 | 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
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 | 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
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 | 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
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 | 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
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
(225 rows)
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 | 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 | 2
3 | 2
5 | 2
1 | 2
3 | 2
5 | 2
1 | 2
3 | 2
5 | 2
1 | 2
3 | 2
5 | 2
1 | 2
1 | 4
3 | 4
5 | 4
1 | 4
3 | 4
5 | 4
1 | 4
3 | 4
5 | 4
1 | 4
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
3 | 2
5 | 2
1 | 2
3 | 2
5 | 2
1 | 2
1 | 4
3 | 4
5 | 4
1 | 4
3 | 4
5 | 4
1 | 4
3 | 4
5 | 4
1 | 4
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
3 | 2
5 | 2
1 | 2
3 | 2
5 | 2
1 | 2
1 | 4
3 | 4
5 | 4
1 | 4
3 | 4
5 | 4
1 | 4
3 | 4
5 | 4
1 | 4
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
3 | 2
5 | 2
1 | 2
3 | 2
5 | 2
1 | 2
1 | 4
3 | 4
5 | 4
1 | 4
3 | 4
5 | 4
1 | 4
3 | 4
5 | 4
1 | 4
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
3 | 2
5 | 2
1 | 2
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 | 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
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
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
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
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 | 6
6 | 6
2 | 6
4 | 6
6 | 6
2 | 6
4 | 6
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 | 6
2 | 6
4 | 6
6 | 6
2 | 6
4 | 6
6 | 6
2 | 6
4 | 6
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 | 6
2 | 6
4 | 6
6 | 6
2 | 6
4 | 6
6 | 6
2 | 6
4 | 6
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 | 6
2 | 6
4 | 6
6 | 6
2 | 6
4 | 6
6 | 6
2 | 6
4 | 6
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
---
2
4
6
8
1
3
5
7
9
9
(10 rows)
with x as (select * from orca.r) select * from x order by a;
a | b
----+---
1 | 1
2 | 2
3 | 0
4 | 1
5 | 2
6 | 0
7 | 1
8 | 2
9 | 0
10 | 1
11 | 2
12 | 0
13 | 1
14 | 2
15 | 0
16 | 1
17 | 2
18 | 0
19 | 1
20 | 2
| 1
(21 rows)
-- with x as (select * from orca.rcte where a < 10) select * from x x1, x x2 where x2.a = x1.b limit 1;
-- correlated execution
select (select 1 union select 2);
ERROR: one or more assertions failed
DETAIL: Expected no more than one row to be returned by expression
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
select (select generate_series(1,1)) as series;
series
--------
1
(1 row)
select generate_series(1,5);
generate_series
-----------------
1
2
3
4
5
(5 rows)
select a, c from orca.r, orca.s where a = any (select c) order by a, c limit 10;
a | c
---+---
1 | 1
1 | 1
1 | 1
1 | 1
1 | 1
2 | 2
2 | 2
2 | 2
2 | 2
2 | 2
(10 rows)
select a, c from orca.r, orca.s where a = (select c) order by a, c limit 10;
a | c
---+---
1 | 1
1 | 1
1 | 1
1 | 1
1 | 1
2 | 2
2 | 2
2 | 2
2 | 2
2 | 2
(10 rows)
select a, c from orca.r, orca.s where a not in (select c) order by a, c limit 10;
a | c
---+---
1 | 0
1 | 0
1 | 0
1 | 0
1 | 2
1 | 2
1 | 2
1 | 2
1 | 2
1 | 3
(10 rows)
select a, c from orca.r, orca.s where a = any (select c from orca.r) order by a, c limit 10;
a | c
---+---
1 | 1
1 | 1
1 | 1
1 | 1
1 | 1
2 | 2
2 | 2
2 | 2
2 | 2
2 | 2
(10 rows)
select a, c from orca.r, orca.s where a <> all (select c) order by a, c limit 10;
a | c
---+---
1 | 0
1 | 0
1 | 0
1 | 0
1 | 2
1 | 2
1 | 2
1 | 2
1 | 2
1 | 3
(10 rows)
select a, (select (select (select c from orca.s where a=c group by c))) as subq from orca.r order by a;
a | subq
----+------
1 | 1
2 | 2
3 | 3
4 | 4
5 | 5
6 | 6
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
|
(21 rows)
with v as (select a,b from orca.r, orca.s where a=c) select c from orca.s group by c having count(*) not in (select b from v where a=c) order by c;
c
---
0
1
2
3
4
5
6
(7 rows)
CREATE TABLE orca.onek (
unique1 int4,
unique2 int4,
two int4,
four int4,
ten int4,
twenty int4,
hundred int4,
thousand int4,
twothousand int4,
fivethous int4,
tenthous int4,
odd int4,
even int4,
stringu1 name,
stringu2 name,
string4 name
);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column 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.
insert into orca.onek values (931,1,1,3,1,11,1,31,131,431,931,2,3,'VJAAAA','BAAAAA','HHHHxx');
insert into orca.onek values (714,2,0,2,4,14,4,14,114,214,714,8,9,'MBAAAA','CAAAAA','OOOOxx');
insert into orca.onek values (711,3,1,3,1,11,1,11,111,211,711,2,3,'JBAAAA','DAAAAA','VVVVxx');
insert into orca.onek values (883,4,1,3,3,3,3,83,83,383,883,6,7,'ZHAAAA','EAAAAA','AAAAxx');
insert into orca.onek values (439,5,1,3,9,19,9,39,39,439,439,18,19,'XQAAAA','FAAAAA','HHHHxx');
insert into orca.onek values (670,6,0,2,0,10,0,70,70,170,670,0,1,'UZAAAA','GAAAAA','OOOOxx');
insert into orca.onek values (543,7,1,3,3,3,3,43,143,43,543,6,7,'XUAAAA','HAAAAA','VVVVxx');
select ten, sum(distinct four) from orca.onek a
group by ten
having exists (select 1 from orca.onek b where sum(distinct a.four) = b.four);
ten | sum
-----+-----
0 | 2
1 | 3
3 | 3
4 | 2
9 | 3
(5 rows)
-- indexes on partitioned tables
create table orca.pp(a int) partition by range(a)(partition pp1 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.
create index pp_a on orca.pp(a);
-- list partition tests
-- test homogeneous partitions
drop table if exists orca.t;
NOTICE: table "t" does not exist, skipping
create table orca.t ( a int, b char(2), to_be_drop int, c int, d char(2), e int)
distributed by (a)
partition by list(d) (partition part1 values('a'), partition part2 values('b'));
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;
a | b | to_be_drop | c | d | e
---+----+------------+---+----+---
1 | 1 | 1 | 1 | b | 1
2 | 2 | 2 | 2 | a | 2
3 | 3 | 3 | 3 | b | 3
4 | 4 | 4 | 4 | a | 4
(4 rows)
alter table orca.t drop column to_be_drop;
select * from orca.t order by 1, 2, 3, 4, 5 limit 4;
a | b | c | d | e
---+----+---+----+---
1 | 1 | 1 | b | 1
2 | 2 | 2 | a | 2
3 | 3 | 3 | b | 3
4 | 4 | 4 | a | 4
(4 rows)
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;
a | b | c | d | e
---+----+---+----+---
0 | | | a |
0 | | | b |
1 | 1 | 1 | b | 1
2 | 2 | 2 | a | 2
(4 rows)
create table orca.multilevel_p (a int, b int)
partition by range(a)
subpartition by range(a)
subpartition template
(
subpartition sp1 start(0) end(10) every (5),
subpartition sp2 start(10) end(200) every(50)
)
(partition aa start(0) end (100) every (50),
partition bb start(100) end(200) every (50) );
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 orca.multilevel_p values (1,1), (100,200);
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
select * from orca.multilevel_p;
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
(2 rows)
-- test appendonly
drop table if exists orca.t;
create table orca.t ( a int, b char(2), to_be_drop int, c int, d char(2), e int)
distributed by (a)
partition by list(d) (partition part1 values('a') with (appendonly=true, compresslevel=5, orientation=column), partition part2 values('b') with (appendonly=true, compresslevel=5, orientation=column));
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;
a | b | to_be_drop | c | d | e
---+----+------------+---+----+---
1 | 1 | 1 | 1 | b | 1
2 | 2 | 2 | 2 | a | 2
3 | 3 | 3 | 3 | b | 3
4 | 4 | 4 | 4 | a | 4
(4 rows)
alter table orca.t drop column to_be_drop;
select * from orca.t order by 1, 2, 3, 4, 5 limit 4;
a | b | c | d | e
---+----+---+----+---
1 | 1 | 1 | b | 1
2 | 2 | 2 | a | 2
3 | 3 | 3 | b | 3
4 | 4 | 4 | a | 4
(4 rows)
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;
a | b | c | d | e
---+----+---+----+---
1 | 1 | 1 | b | 1
1 | 1 | 1 | b | 1
2 | 2 | 2 | a | 2
2 | 2 | 2 | a | 2
(4 rows)
-- test heterogeneous partitions
drop table if exists orca.t;
create table orca.t ( timest character varying(6), user_id numeric(16,0) not null, to_be_drop char(5), tag1 char(5), tag2 char(5))
distributed by (user_id)
partition by list (timest) (partition part201203 values('201203') with (appendonly=true, compresslevel=5, orientation=column), partition part201204 values('201204') with (appendonly=true, compresslevel=5, orientation=row), partition part201205 values('201205'));
insert into orca.t values('201203',0,'drop', 'tag1','tag2');
alter table orca.t drop column to_be_drop;
alter table orca.t add partition part201206 values('201206') with (appendonly=true, compresslevel=5, orientation=column);
alter table orca.t add partition part201207 values('201207') with (appendonly=true, compresslevel=5, orientation=row);
alter table orca.t add partition part201208 values('201208');
insert into orca.t values('201203',1,'tag1','tag2');
insert into orca.t values('201204',2,'tag1','tag2');
insert into orca.t values('201205',1,'tag1','tag2');
insert into orca.t values('201206',2,'tag1','tag2');
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;
timest | user_id | tag1 | tag2
--------+---------+-------+-------
201203 | 0 | tag1 | tag2
201203 | 1 | tag1 | tag2
201204 | 2 | tag1 | tag2
201205 | 1 | tag1 | tag2
201206 | 2 | tag1 | tag2
201207 | 1 | tag1 | tag2
201208 | 2 | tag1 | tag2
(7 rows)
-- test EXPLAIN support of partition selection nodes, while we're at it.
explain select * from orca.t order by 1,2;
QUERY PLAN
-------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=24)
Merge Key: timest, user_id
-> Sort (cost=0.00..431.00 rows=1 width=24)
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)
(7 rows)
select tag2, tag1 from orca.t order by 1, 2;;
tag2 | tag1
-------+-------
tag2 | tag1
tag2 | tag1
tag2 | tag1
tag2 | tag1
tag2 | tag1
tag2 | tag1
tag2 | tag1
(7 rows)
select tag1, user_id from orca.t order by 1, 2;
tag1 | user_id
-------+---------
tag1 | 0
tag1 | 1
tag1 | 1
tag1 | 1
tag1 | 2
tag1 | 2
tag1 | 2
(7 rows)
insert into orca.t(user_id, timest, tag2) values(3, '201208','tag2');
select * from orca.t order by 1, 2;
timest | user_id | tag1 | tag2
--------+---------+-------+-------
201203 | 0 | tag1 | tag2
201203 | 1 | tag1 | tag2
201204 | 2 | tag1 | tag2
201205 | 1 | tag1 | tag2
201206 | 2 | tag1 | tag2
201207 | 1 | tag1 | tag2
201208 | 2 | tag1 | tag2
201208 | 3 | | tag2
(8 rows)
-- test heterogeneous indexes with constant expression evaluation
drop table if exists orca.t_date;
NOTICE: table "t_date" does not exist, skipping
create table orca.t_date ( timest date, user_id numeric(16,0) not null, tag1 char(5), tag2 char(5))
distributed by (user_id)
partition by list (timest) (partition part201203 values('01-03-2012'::date), partition part201204 values('01-04-2012'::date), partition part201205 values('01-05-2012'::date));
create index user_id_idx on orca.t_date_1_prt_part201203(user_id);
alter table orca.t_date add partition part201206 values('01-06-2012'::date);
alter table orca.t_date add partition part201207 values('01-07-2012'::date);
alter table orca.t_date add partition part201208 values('01-08-2012'::date);
insert into orca.t_date values('01-03-2012'::date,0,'tag1','tag2');
insert into orca.t_date values('01-03-2012'::date,1,'tag1','tag2');
insert into orca.t_date values('01-04-2012'::date,2,'tag1','tag2');
insert into orca.t_date values('01-05-2012'::date,1,'tag1','tag2');
insert into orca.t_date values('01-06-2012'::date,2,'tag1','tag2');
insert into orca.t_date values('01-07-2012'::date,1,'tag1','tag2');
insert into orca.t_date values('01-08-2012'::date,2,'tag1','tag2');
insert into orca.t_date values('01-03-2012'::date,2,'tag1','tag2');
insert into orca.t_date values('01-03-2012'::date,3,'tag1','tag2');
insert into orca.t_date values('01-03-2012'::date,4,'tag1','tag2');
insert into orca.t_date values('01-03-2012'::date,5,'tag1','tag2');
insert into orca.t_date values('01-03-2012'::date,6,'tag1','tag2');
insert into orca.t_date values('01-03-2012'::date,7,'tag1','tag2');
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;
explain select * from orca.t_date where user_id=9;
QUERY PLAN
-------------------------------------------------------------------------------
Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..431.00 rows=2 width=20)
-> 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)
(5 rows)
select * from orca.t_date where user_id=9;
timest | user_id | tag1 | tag2
------------+---------+-------+-------
01-03-2012 | 9 | tag1 | tag2
(1 row)
reset optimizer_enable_space_pruning;
set optimizer_enumerate_plans=off;
set optimizer_enable_constant_expression_evaluation=off;
drop table if exists orca.t_text;
NOTICE: table "t_text" does not exist, skipping
drop index if exists orca.user_id_idx;
create table orca.t_text ( timest date, user_id numeric(16,0) not null, tag1 char(5), tag2 char(5))
distributed by (user_id)
partition by list(tag1) (partition partgood values('good'::text), partition partbad values('bad'::text), partition partugly values('ugly'::text));
create index user_id_idx on orca.t_text_1_prt_partgood(user_id);
insert into orca.t_text values('01-03-2012'::date,0,'good','tag2');
insert into orca.t_text values('01-03-2012'::date,1,'bad','tag2');
insert into orca.t_text values('01-04-2012'::date,2,'ugly','tag2');
insert into orca.t_text values('01-05-2012'::date,1,'good','tag2');
insert into orca.t_text values('01-06-2012'::date,2,'bad','tag2');
insert into orca.t_text values('01-07-2012'::date,1,'ugly','tag2');
insert into orca.t_text values('01-08-2012'::date,2,'good','tag2');
insert into orca.t_text values('01-03-2012'::date,2,'bad','tag2');
insert into orca.t_text values('01-03-2012'::date,3,'ugly','tag2');
insert into orca.t_text values('01-03-2012'::date,4,'good','tag2');
insert into orca.t_text values('01-03-2012'::date,5,'bad','tag2');
insert into orca.t_text values('01-03-2012'::date,6,'ugly','tag2');
insert into orca.t_text values('01-03-2012'::date,7,'good','tag2');
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;
explain select * from orca.t_text where user_id=9;
QUERY PLAN
-------------------------------------------------------------------------------
Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..431.00 rows=2 width=20)
-> 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)
(5 rows)
select * from orca.t_text where user_id=9;
timest | user_id | tag1 | tag2
------------+---------+-------+-------
01-03-2012 | 9 | ugly | tag2
(1 row)
reset optimizer_enable_space_pruning;
set optimizer_enumerate_plans=off;
reset optimizer_enable_constant_expression_evaluation;
-- test that constant expression evaluation works with integers
drop table if exists orca.t_ceeval_ints;
NOTICE: table "t_ceeval_ints" does not exist, skipping
create table orca.t_ceeval_ints(user_id numeric(16,0), category_id int, tag1 char(5), tag2 char(5))
distributed by (user_id)
partition by list (category_id)
(partition part100 values('100') , partition part101 values('101'), partition part103 values('102'));
create index user_id_ceeval_ints on orca.t_ceeval_ints_1_prt_part101(user_id);
insert into orca.t_ceeval_ints values(1, 100, 'tag1', 'tag2');
insert into orca.t_ceeval_ints values(2, 100, 'tag1', 'tag2');
insert into orca.t_ceeval_ints values(3, 100, 'tag1', 'tag2');
insert into orca.t_ceeval_ints values(4, 101, 'tag1', 'tag2');
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;
explain select * from orca.t_ceeval_ints where user_id=4;
QUERY PLAN
-------------------------------------------------------------------------------
Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..431.00 rows=1 width=21)
-> 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)
(5 rows)
select * from orca.t_ceeval_ints where user_id=4;
user_id | category_id | tag1 | tag2
---------+-------------+-------+-------
4 | 101 | tag1 | tag2
(1 row)
reset optimizer_enable_space_pruning;
reset optimizer_enumerate_plans;
reset optimizer_use_external_constant_expression_evaluation_for_ints;
reset optimizer_enable_constant_expression_evaluation;
-- test project elements in TVF
CREATE FUNCTION orca.csq_f(a int) RETURNS int AS $$ select $1 $$ LANGUAGE SQL;
CREATE TABLE orca.csq_r(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 orca.csq_r VALUES (1);
SELECT * FROM orca.csq_r WHERE a IN (SELECT * FROM orca.csq_f(orca.csq_r.a));
a
---
1
(1 row)
-- test algebrization of having clause
drop table if exists orca.tab1;
NOTICE: table "tab1" does not exist, skipping
create table orca.tab1(a int, b int, c int, d int, e 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 orca.tab1 values (1,2,3,4,5);
insert into orca.tab1 values (1,2,3,4,5);
insert into orca.tab1 values (1,2,3,4,5);
select b,d from orca.tab1 group by b,d having min(distinct d)>3;
b | d
---+---
2 | 4
(1 row)
select b,d from orca.tab1 group by b,d having d>3;
b | d
---+---
2 | 4
(1 row)
select b,d from orca.tab1 group by b,d having min(distinct d)>b;
b | d
---+---
2 | 4
(1 row)
create table orca.fooh1 (a int, b 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.
create table orca.fooh2 (a int, b 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.
insert into orca.fooh1 select i%4, i%3, i from generate_series(1,20) i;
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
(4 rows)
select f1.a + 1 from fooh1 f1 group by f1.a+1 having sum(f1.a+1) + 1 > 20;
?column?
----------
4
(1 row)
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
(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;
a | one
---+-----
2 | 1
3 | 1
(2 rows)
select 1 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;
?column?
----------
1
1
(2 rows)
select f1.a, 1 as one from orca.fooh1 f1 group by f1.a having 10 > (select 1 from orca.fooh2 f2 group by f2.a having sum(f1.b) > count(*) order by f2.a limit 1) order by f1.a;
a | one
---+-----
(0 rows)
select 1 from orca.fooh1 f1 group by f1.a having 10 > (select 1 from orca.fooh2 f2 group by f2.a having sum(f1.b) > count(*) order by f2.a limit 1) order by f1.a;
?column?
----------
(0 rows)
select f1.a, 1 as one from orca.fooh1 f1 group by f1.a having 0 = (select f2.a from orca.fooh2 f2 group by f2.a having sum(f2.b) > 1 order by f2.a limit 1) order by f1.a;
a | one
---+-----
0 | 1
1 | 1
2 | 1
3 | 1
(4 rows)
select 1 as one from orca.fooh1 f1 group by f1.a having 0 = (select f2.a from orca.fooh2 f2 group by f2.a having sum(f2.b) > 1 order by f2.a limit 1) order by f1.a;
one
-----
1
1
1
1
(4 rows)
select f1.a, 1 as one from orca.fooh1 f1 group by f1.a having 0 = (select f2.a from orca.fooh2 f2 group by f2.a having sum(f2.b) > 1 order by f2.a limit 1) order by f1.a;
a | one
---+-----
0 | 1
1 | 1
2 | 1
3 | 1
(4 rows)
select f1.a, 1 as one from orca.fooh1 f1 group by f1.a having 0 = (select f2.a from orca.fooh2 f2 group by f2.a having sum(f2.b + f1.a) > 1 order by f2.a limit 1) order by f1.a;
a | one
---+-----
0 | 1
1 | 1
2 | 1
3 | 1
(4 rows)
select f1.a, 1 as one from orca.fooh1 f1 group by f1.a having 0 = (select f2.a from orca.fooh2 f2 group by f2.a having sum(f2.b + sum(f1.b)) > 1 order by f2.a limit 1) order by f1.a;
a | one
---+-----
0 | 1
1 | 1
2 | 1
3 | 1
(4 rows)
select f1.a, 1 as one from orca.fooh1 f1 group by f1.a having f1.a < (select f2.a from orca.fooh2 f2 group by f2.a having sum(f2.b + 1) > f1.a order by f2.a desc limit 1) order by f1.a;
a | one
---+-----
0 | 1
1 | 1
(2 rows)
select f1.a, 1 as one from orca.fooh1 f1 group by f1.a having f1.a = (select f2.a from orca.fooh2 f2 group by f2.a having sum(f2.b) + 1 > f1.a order by f2.a desc limit 1);
a | one
---+-----
2 | 1
(1 row)
select f1.a, 1 as one from orca.fooh1 f1 group by f1.a having f1.a = (select f2.a from orca.fooh2 f2 group by f2.a having sum(f2.b) > 1 order by f2.a limit 1);
a | one
---+-----
0 | 1
(1 row)
select sum(f1.a+1)+1 from orca.fooh1 f1 group by f1.a+1;
?column?
----------
11
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
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
24.0000000000000000 | 15 | 20
6.00000000000000000000 | 0 | 5
18.0000000000000000 | 10 | 15
(4 rows)
--
-- test algebrization of group by clause with subqueries
--
drop table if exists foo, bar, jazz;
NOTICE: table "jazz" does not exist, skipping
create table foo (a int, b 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.
create table bar (d int, e int, f int);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'd' as the Apache Cloudberry data distribution key for this table.
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 jazz (g int, h int, j int);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'g' as the Apache Cloudberry data distribution key for this table.
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, 1, 1), (2, 2, 2), (3, 3, 3);
insert into bar values (1, 1, 1), (2, 2, 2), (3, 3, 3);
insert into jazz values (2, 2, 2);
-- subquery with outer reference with aggfunc in target list
select a, (select sum(e) from bar where foo.b = bar.f), b, count(*) from foo, jazz where foo.c = jazz.g group by b, a, h;
a | sum | b | count
---+-----+---+-------
2 | 2 | 2 | 1
(1 row)
-- complex agg expr in subquery
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 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
(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
(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
-----
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
(3 rows)
-- nested group by
select (select max(f) from bar where d = 1 group by a, e) from foo group by a;
max
-----
1
1
1
(3 rows)
-- cte with an aggfunc of outer ref
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
(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?
---+-------+----------
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
-----
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
(2 rows)
-- group by inside groupby inside group by
select max(a) from foo group by (select min(g) from jazz where foo.a = (select max(g) from jazz group by h) group by h);
max
-----
2
3
(2 rows)
-- cte subquery in group by
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 rows)
-- group by subquery in order by
select * from foo order by ((select min(bar.e + 1) * 2 from bar group by foo.a) - foo.a);
a | b | c
---+---+---
3 | 3 | 3
2 | 2 | 2
1 | 1 | 1
(3 rows)
-- everything in the kitchen sink
select max(b), (select foo.a * count(bar.e) from bar), (with cte as (select e, min(d) as dd from bar group by e) select max(a) * sum(dd) from cte), count(*) from foo group by foo.a, (select min(g) from jazz where foo.a = (select max(g) from jazz group by h) group by h), (with cte as (select min(g) from jazz group by h) select a from cte) order by ((select min(bar.e + 1) * 2 from bar group by foo.a) - foo.a);
max | ?column? | ?column? | count
-----+----------+----------+-------
3 | 9 | 18 | 1
2 | 6 | 12 | 1
1 | 3 | 6 | 1
(3 rows)
-- complex expression in group by & targetlist
select b + (a+1) from foo group by b, a+1;
?column?
----------
3
5
7
(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
(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 |
(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;
?column? | t
----------+---
2 |
3 | 1
4 |
(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
----------+---
3 | 1
4 |
2 |
(3 rows)
drop table foo, bar, jazz;
create table orca.t77(C952 text) WITH (compresstype=zlib,compresslevel=2,appendonly=true,blocksize=393216,checksum=true);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c952' as the Apache Cloudberry data distribution key for this table.
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.t77 select 'text'::text;
insert into orca.t77 select 'mine'::text;
insert into orca.t77 select 'apple'::text;
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
------------------+-----
5.0000000 | 5
4.0000000 | 4
6.0000000 | 6
(3 rows)
create table orca.prod9 (sale integer, prodnm varchar,price integer);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'sale' as the Apache Cloudberry data distribution key for this table.
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.prod9 values (100, 'shirts', 500);
insert into orca.prod9 values (200, 'pants',800);
insert into orca.prod9 values (300, 't-shirts', 300);
-- returning product and price using Having and Group by clause
select prodnm, price from orca.prod9 GROUP BY prodnm, price HAVING price !=300;
prodnm | price
--------+-------
shirts | 500
pants | 800
(2 rows)
-- analyze on tables with dropped attributes
create table orca.toanalyze(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 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
analyze orca.toanalyze;
-- union
create table orca.ur (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 orca.us (c int, d int);
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.
create table orca.ut(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 table orca.uu(c int, d bigint);
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.
insert into orca.ur values (1,1);
insert into orca.ur values (1,2);
insert into orca.ur values (2,1);
insert into orca.us values (1,3);
insert into orca.ut values (3);
insert into orca.uu values (1,3);
select * from (select a, a from orca.ur union select c, d from orca.us) x(g,h);
g | h
---+---
2 | 2
1 | 1
1 | 3
(3 rows)
select * from (select a, a from orca.ur union select c, d from orca.us) x(g,h), orca.ut t where t.a = x.h;
g | h | a
---+---+---
1 | 3 | 3
(1 row)
select * from (select a, a from orca.ur union select c, d from orca.uu) x(g,h), orca.ut t where t.a = x.h;
g | h | a
---+---+---
1 | 3 | 3
(1 row)
select 1 AS two UNION select 2.2;
two
-----
1
2.2
(2 rows)
select 2.2 AS two UNION select 1;
two
-----
1
2.2
(2 rows)
select * from (select 2.2 AS two UNION select 1) x(a), (select 1.0 AS two UNION ALL select 1) y(a) where y.a = x.a;
a | a
---+-----
1 | 1.0
1 | 1
(2 rows)
-- window functions inside inline CTE
CREATE TABLE orca.twf1 AS SELECT i as a, i+1 as b from generate_series(1,10)i;
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause. Creating a NULL policy entry.
CREATE TABLE orca.twf2 AS SELECT i as c, i+1 as d from generate_series(1,10)i;
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause. Creating a NULL policy entry.
SET optimizer_cte_inlining_bound=1000;
SET optimizer_cte_inlining = on;
WITH CTE(a,b) AS
(SELECT a,d FROM orca.twf1, orca.twf2 WHERE a = d),
CTE1(e,f) AS
( SELECT f1.a, rank() OVER (PARTITION BY f1.b ORDER BY CTE.a) FROM orca.twf1 f1, CTE )
SELECT * FROM CTE1,CTE WHERE CTE.a = CTE1.f and CTE.a = 2 ORDER BY 1;
e | f | a | b
----+---+---+---
1 | 2 | 2 | 2
2 | 2 | 2 | 2
3 | 2 | 2 | 2
4 | 2 | 2 | 2
5 | 2 | 2 | 2
6 | 2 | 2 | 2
7 | 2 | 2 | 2
8 | 2 | 2 | 2
9 | 2 | 2 | 2
10 | 2 | 2 | 2
(10 rows)
RESET optimizer_cte_inlining;
RESET optimizer_cte_inlining_bound;
-- catalog queries
select 1 from pg_class c group by c.oid limit 1;
?column?
----------
1
(1 row)
-- CSQs
drop table if exists orca.tab1;
drop table if exists orca.tab2;
NOTICE: table "tab2" does not exist, skipping
create table orca.tab1 (i, j) as select i,i%2 from generate_series(1,10) i;
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause. Creating a NULL policy entry.
create table orca.tab2 (a, b) as select 1, 2;
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause. Creating a NULL policy entry.
select * from orca.tab1 where 0 < (select count(*) from generate_series(1,i)) order by 1;
i | j
----+---
1 | 1
2 | 0
3 | 1
4 | 0
5 | 1
6 | 0
7 | 1
8 | 0
9 | 1
10 | 0
(10 rows)
select * from orca.tab1 where i > (select b from orca.tab2);
i | j
----+---
4 | 0
6 | 0
8 | 0
10 | 0
3 | 1
5 | 1
7 | 1
9 | 1
(8 rows)
-- subqueries
select NULL in (select 1);
?column?
----------
(1 row)
select 1 in (select 1);
?column?
----------
t
(1 row)
select 1 in (select 2);
?column?
----------
f
(1 row)
select NULL in (select 1/0);
ERROR: division by zero
select 1 where 22 in (SELECT unnest(array[1,2]));
?column?
----------
(0 rows)
select 1 where 22 not in (SELECT unnest(array[1,2]));
?column?
----------
1
(1 row)
select 1 where 22 in (SELECT generate_series(1,10));
?column?
----------
(0 rows)
select 1 where 22 not in (SELECT generate_series(1,10));
?column?
----------
1
(1 row)
-- UDAs
CREATE FUNCTION sum_sfunc(anyelement,anyelement) returns anyelement AS 'select $1+$2' LANGUAGE SQL STRICT;
CREATE FUNCTION sum_combinefunc(anyelement,anyelement) returns anyelement AS 'select $1+$2' LANGUAGE SQL STRICT;
CREATE AGGREGATE myagg1(anyelement) (SFUNC = sum_sfunc, COMBINEFUNC = sum_combinefunc, STYPE = anyelement, INITCOND = '0');
SELECT myagg1(i) FROM orca.tab1;
myagg1
--------
55
(1 row)
CREATE FUNCTION sum_sfunc2(anyelement,anyelement,anyelement) returns anyelement AS 'select $1+$2+$3' LANGUAGE SQL STRICT;
CREATE AGGREGATE myagg2(anyelement,anyelement) (SFUNC = sum_sfunc2, STYPE = anyelement, INITCOND = '0');
SELECT myagg2(i,j) FROM orca.tab1;
myagg2
--------
60
(1 row)
CREATE FUNCTION gptfp(anyarray,anyelement) RETURNS anyarray AS 'select $1 || $2' LANGUAGE SQL;
CREATE FUNCTION gpffp(anyarray) RETURNS anyarray AS 'select $1' LANGUAGE SQL;
CREATE AGGREGATE myagg3(BASETYPE = anyelement, SFUNC = gptfp, STYPE = anyarray, FINALFUNC = gpffp, INITCOND = '{}');
CREATE TABLE array_table(f1 int, f2 int[], f3 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 array_table values(1,array[1],'a');
INSERT INTO array_table values(2,array[11],'b');
INSERT INTO array_table values(3,array[111],'c');
INSERT INTO array_table values(4,array[2],'a');
INSERT INTO array_table values(5,array[22],'b');
INSERT INTO array_table values(6,array[222],'c');
INSERT INTO array_table values(7,array[3],'a');
INSERT INTO array_table values(8,array[3],'b');
SELECT f3, myagg3(f1) from (select * from array_table order by f1 limit 10) as foo GROUP BY f3 ORDER BY f3;
f3 | myagg3
----+---------
a | {4,1,7}
b | {8,2,5}
c | {6,3}
(3 rows)
-- MPP-22453: wrong result in indexscan when the indexqual compares different data types
create table mpp22453(a int, d date);
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 mpp22453 values (1, '2012-01-01'), (2, '2012-01-02'), (3, '2012-12-31');
create index mpp22453_idx on mpp22453(d);
set optimizer_enable_tablescan = off;
select * from mpp22453 where d > date '2012-01-31' + interval '1 day' ;
a | d
---+------------
3 | 12-31-2012
(1 row)
select * from mpp22453 where d > '2012-02-01';
a | d
---+------------
3 | 12-31-2012
(1 row)
reset optimizer_enable_tablescan;
-- MPP-22791: SIGSEGV when querying a table with default partition only
create table mpp22791(a int, b int) partition by range(b) (default partition d);
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 mpp22791 values (1, 1), (2, 2), (3, 3);
select * from mpp22791 where b > 1;
a | b
---+---
2 | 2
3 | 3
(2 rows)
select * from mpp22791 where b <= 3;
a | b
---+---
1 | 1
3 | 3
2 | 2
(3 rows)
-- MPP-20713, MPP-20714, MPP-20738: Const table get with a filter
select 1 as x where 1 in (2, 3);
x
---
(0 rows)
-- MPP-23081: keys of partitioned tables
create table orca.p1(a int) partition by range(a)(partition pp1 start(1) end(10), partition pp2 start(10) end(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.
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;
count
-------
14
(1 row)
-- MPP-25194: histograms on text columns are dropped in ORCA. NDVs of these histograms should be added to NDVRemain
CREATE TABLE orca.tmp_verd_s_pp_provtabs_agt_0015_extract1 (
uid136 character(16),
tab_nr smallint,
prdgrp character(5),
bg smallint,
typ142 smallint,
ad_gsch smallint,
guelt_ab date,
guelt_bis date,
guelt_stat text,
verarb_ab timestamp(5) without time zone,
u_erzeugen integer,
grenze integer,
erstellt_am_122 timestamp(5) without time zone,
erstellt_am_135 timestamp(5) without time zone,
erstellt_am_134 timestamp(5) without time zone
)
WITH (appendonly=true, compresstype=zlib) DISTRIBUTED BY (uid136);
set allow_system_table_mods=true;
UPDATE pg_class
SET
relpages = 30915::int, reltuples = 7.28661e+07::real WHERE relname = 'tmp_verd_s_pp_provtabs_agt_0015_extract1' AND relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'xvclin');
insert into pg_statistic
values (
'orca.tmp_verd_s_pp_provtabs_agt_0015_extract1'::regclass,
1::smallint,
'f',
0::real,
17::integer,
264682::real,
1::smallint,
2::smallint,
0::smallint,
0::smallint,
0::smallint,
1054::oid,
1058::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
'{0.000161451,0.000107634,0.000107634,0.000107634,0.000107634,0.000107634,0.000107634,0.000107634,0.000107634,0.000107634,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05}'::real[],
NULL::real[],
NULL::real[],
NULL::real[],
NULL::real[],
'{8X8#1F8V92A2025G,YFAXQ§UBF210PA0P,2IIVIE8V92A2025G,9§BP8F8V92A2025G,35A9EE8V92A2025G,§AJ2Z§9MA210PA0P,3NUQ3E8V92A2025G,F7ZD4F8V92A2025G,$WHHEO§§E210PA0P,Z6EATH2BE210PA0P,N7I28E8V92A2025G,YU0K$E$§9210PA0P,3TAI1ANIF210PA0P,P#H8BF8V92A2025G,VTQ$N$D§92A201SC,N7ZD4F8V92A2025G,77BP8F8V92A2025G,39XOXY78H210PA01,#2#OX6NHH210PA01,2DG1J#XZH210PA01,MFEG$E8V92A2025G,M0HKWNGND210PA0P,FSXI67NSA210PA0P,C1L77E8V92A2025G,01#21E8V92A2025G}'::bpchar[],
'{§00§1HKZC210PA0P,1D90GE8V92A2025G,2ULZI6L0O210PA01,489G7L8$I210PA01,5RE8FF8V92A2025G,76NIRFNIF210PA0P,8KOMKE8V92A2025G,#9Y#GPSHB210PA0P,BDAJ#D8V92A2025G,CV9Z7IYVK210PA01,#EC5FE8V92A2025G,FQWY§O1XC210PA0P,H8HL4E8V92A2025G,INC5FE8V92A2025G,K4MX0XHCF210PA0P,LKE8FF8V92A2025G,N03G9UM2F210PA0P,OHJ$#GFZ9210PA0P,PXU3T1OTB210PA0P,RCUA45F1H210PA01,SU§FRY#QI210PA01,UABHMLSLK210PA01,VRBP8F8V92A2025G,X65#KZIDC210PA0P,YLFG§#A2G210PA0P,ZZG8H29OC210PA0P,ZZZDBCEVA210PA0P}'::bpchar[],
NULL::bpchar[],
NULL::bpchar[],
NULL::bpchar[]
),
(
'orca.tmp_verd_s_pp_provtabs_agt_0015_extract1'::regclass,
2::smallint,
'f',
0::real,
2::integer,
205.116::real,
1::smallint,
2::smallint,
0::smallint,
0::smallint,
0::smallint,
94::oid,
95::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
'{0.278637,0.272448,0.0303797,0.0301106,0.0249442,0.0234373,0.0231682,0.0191319,0.0169793,0.0162527,0.0142884,0.0141539,0.0125394,0.0103329,0.0098216,0.00944488,0.00850308,0.00715766,0.0066464,0.00656567,0.00591987,0.0050588,0.00454753,0.00449372,0.0044399}'::real[],
NULL::real[],
NULL::real[],
NULL::real[],
NULL::real[],
'{199,12,14,5,197,11,198,8,152,299,201,153,9,13,74,179,24,202,2,213,17,195,215,16,200}'::int2[],
'{1,5,9,12,14,24,58,80,152,195,198,199,207,302,402}'::int2[],
NULL::int2[],
NULL::int2[],
NULL::int2[]
),
(
'orca.tmp_verd_s_pp_provtabs_agt_0015_extract1'::regclass,
3::smallint,
'f',
0::real,
6::integer,
201.005::real,
1::smallint,
2::smallint,
0::smallint,
0::smallint,
0::smallint,
1054::oid,
1058::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
'{0.0478164,0.0439146,0.0406856,0.0239755,0.0154186,0.0149073,0.0148804,0.0143422,0.0141808,0.0139386,0.0138848,0.0138848,0.0137502,0.0134812,0.0134004,0.0133197,0.0133197,0.013239,0.0131852,0.0130775,0.0130775,0.0130237,0.0129699,0.0129699,0.012943}'::real[],
NULL::real[],
NULL::real[],
NULL::real[],
NULL::real[],
'{AG023,AG032,AG999,AG022,AG--B,AG-VB,AG--C,AG-VC,AG014,AG-VA,AG036,AGT4C,AG--A,AG037,AG009,AG015,AG003,AG002,AGT3C,AG025,AG019,AGT2C,AGT1C,AG005,AG031}'::bpchar[],
'{AG001,AG004,AG007,AG010,AG013,AG017,AG020,AG022,AG023,AG026,AG030,AG032,AG034,AG037,AG040,AG045,AG122,AG999,AG--B,AGT1C,AGT4C,AG-VB,MA017,MA--A,MK081,MKRKV}'::bpchar[],
NULL::bpchar[],
NULL::bpchar[],
NULL::bpchar[]
),
(
'orca.tmp_verd_s_pp_provtabs_agt_0015_extract1'::regclass,
4::smallint,
'f',
0::real,
2::integer,
34::real,
1::smallint,
2::smallint,
0::smallint,
0::smallint,
0::smallint,
94::oid,
95::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
'{0.1135,0.112881,0.111778,0.100288,0.0895245,0.0851384,0.0821785,0.0723569,0.0565616,0.0368646,0.0309986,0.0160375,0.00621586,0.00594677,0.0050588,0.00489734,0.00487044,0.00487044,0.00468208,0.00462826,0.00460135,0.00441299,0.00438608,0.00417081,0.00414391}'::real[],
NULL::real[],
NULL::real[],
NULL::real[],
NULL::real[],
'{1,3,2,7,9,4,5,16,10,6,8,77,12,11,14,13,22,23,64,61,24,51,53,15,54}'::int2[],
'{1,2,3,4,5,6,7,9,10,14,16,17,53,98}'::int2[],
NULL::int2[],
NULL::int2[],
NULL::int2[]
),
(
'orca.tmp_verd_s_pp_provtabs_agt_0015_extract1'::regclass,
5::smallint,
'f',
0::real,
2::integer,
1::real,
1::smallint,
2::smallint,
0::smallint,
0::smallint,
0::smallint,
94::oid,
95::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
'{1}'::real[],
NULL::real[],
NULL::real[],
NULL::real[],
NULL::real[],
'{1}'::int2[],
'{1}'::int2[],
NULL::int2[],
NULL::int2[],
NULL::int2[]
),
(
'orca.tmp_verd_s_pp_provtabs_agt_0015_extract1'::regclass,
6::smallint,
'f',
0::real,
2::integer,
2::real,
1::smallint,
2::smallint,
0::smallint,
0::smallint,
0::smallint,
94::oid,
95::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
'{0.850227,0.149773}'::real[],
NULL::real[],
NULL::real[],
NULL::real[],
NULL::real[],
'{1,2}'::int2[],
'{1,2}'::int2[],
NULL::int2[],
NULL::int2[],
NULL::int2[]
),
(
'orca.tmp_verd_s_pp_provtabs_agt_0015_extract1'::regclass,
7::smallint,
'f',
0::real,
4::integer,
591.134::real,
1::smallint,
2::smallint,
0::smallint,
0::smallint,
0::smallint,
1093::oid,
1095::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
'{0.26042,0.0859995,0.0709308,0.0616473,0.0567231,0.0303797,0.0109787,0.0106289,0.00990232,0.00987541,0.00979469,0.00944488,0.00820709,0.00718457,0.00626968,0.00621586,0.00616204,0.00600059,0.00586605,0.00557006,0.00516643,0.00511261,0.0050857,0.0050857,0.0047628}'::real[],
NULL::real[],
NULL::real[],
NULL::real[],
NULL::real[],
'{1994-01-01,1997-01-01,2005-07-01,1999-01-01,2003-09-01,2000-01-01,2001-01-01,1998-10-01,2001-05-01,1999-03-01,2013-01-01,2003-01-01,2008-01-01,2004-01-01,2009-01-01,2003-02-01,1998-09-01,2000-12-01,2007-04-01,1998-08-01,1998-01-01,2003-07-01,1998-11-01,2005-02-01,1999-04-01}'::date[],
'{1900-01-01,1994-01-01,1997-01-01,1998-05-07,1999-01-01,1999-05-01,2000-01-01,2001-03-22,2002-10-01,2003-09-01,2004-08-01,2005-07-01,2007-01-01,2008-06-01,2010-04-01,2012-07-01,2014-12-01,2015-01-01}'::date[],
NULL::date[],
NULL::date[],
NULL::date[]
),
(
'orca.tmp_verd_s_pp_provtabs_agt_0015_extract1'::regclass,
8::smallint,
'f',
0::real,
4::integer,
474.232::real,
1::smallint,
2::smallint,
0::smallint,
0::smallint,
0::smallint,
1093::oid,
1095::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
'{0.52111,0.0709308,0.0591987,0.0587412,0.0148804,0.010279,0.00990232,0.00931034,0.00791109,0.00718457,0.00688857,0.00608132,0.00557006,0.0053817,0.00503189,0.00500498,0.00457444,0.004117,0.00395555,0.00390173,0.00357883,0.00352501,0.00352501,0.00344429,0.00333665}'::real[],
NULL::real[],
NULL::real[],
NULL::real[],
NULL::real[],
'{9999-12-31,2005-07-01,1999-01-01,2003-09-01,2004-02-01,2001-05-01,2005-02-01,1999-03-01,1998-10-01,2000-01-01,2003-01-01,1998-09-01,1998-08-01,2008-01-01,2007-04-01,2000-12-01,1999-04-01,1998-11-01,2003-02-01,1994-01-01,2002-09-01,1999-02-01,2004-01-01,1998-07-01,2003-07-01}'::date[],
'{1994-01-01,1998-11-01,1999-01-01,1999-04-01,2001-05-01,2003-07-01,2003-09-01,2004-02-01,2005-07-01,2007-02-01,2010-03-01,9999-12-31}'::date[],
NULL::date[],
NULL::date[],
NULL::date[]
),
(
'orca.tmp_verd_s_pp_provtabs_agt_0015_extract1'::regclass,
9::smallint,
'f',
0::real,
2::integer,
1::real,
1::smallint,
2::smallint,
0::smallint,
0::smallint,
0::smallint,
98::oid,
664::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
'{1}'::real[],
NULL::real[],
NULL::real[],
NULL::real[],
NULL::real[],
'{H}'::text[],
'{H}'::text[],
NULL::text[],
NULL::text[],
NULL::text[]
),
(
'orca.tmp_verd_s_pp_provtabs_agt_0015_extract1'::regclass,
10::smallint,
'f',
0::real,
8::integer,
1::real,
1::smallint,
2::smallint,
0::smallint,
0::smallint,
0::smallint,
2060::oid,
2062::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
'{1}'::real[],
NULL::real[],
NULL::real[],
NULL::real[],
NULL::real[],
'{1900-01-01 00:00:00}'::timestamp[],
'{1900-01-01 00:00:00}'::timestamp[],
NULL::timestamp[],
NULL::timestamp[],
NULL::timestamp[]
),
(
'orca.tmp_verd_s_pp_provtabs_agt_0015_extract1'::regclass,
11::smallint,
'f',
1::real,
0::integer,
-1::real,
0::smallint,
0::smallint,
0::smallint,
0::smallint,
0::smallint,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
NULL::real[],
NULL::real[],
NULL::real[],
NULL::real[],
NULL::real[],
NULL::int4[],
NULL::int4[],
NULL::int4[],
NULL::int4[],
NULL::int4[]
),
(
'orca.tmp_verd_s_pp_provtabs_agt_0015_extract1'::regclass,
12::smallint,
'f',
0::real,
4::integer,
1::real,
1::smallint,
2::smallint,
0::smallint,
0::smallint,
0::smallint,
96::oid,
97::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
'{1}'::real[],
NULL::real[],
NULL::real[],
NULL::real[],
NULL::real[],
'{1}'::int4[],
'{1}'::int4[],
NULL::int4[],
NULL::int4[],
NULL::int4[]
),
(
'orca.tmp_verd_s_pp_provtabs_agt_0015_extract1'::regclass,
13::smallint,
'f',
0.991927::real,
8::integer,
301.416::real,
1::smallint,
2::smallint,
0::smallint,
0::smallint,
0::smallint,
2060::oid,
2062::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
'{8.07255e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05,2.69085e-05}'::real[],
NULL::real[],
NULL::real[],
NULL::real[],
NULL::real[],
'{2004-01-05 13:45:06.18894,2007-03-20 12:02:33.73888,2009-12-15 12:33:55.32684,2012-09-21 09:58:09.70321,2012-02-13 14:56:03.11625,2000-10-02 09:56:01.24836,1998-01-14 10:11:29.43055,2014-01-08 14:41:44.85935,2012-06-21 12:46:37.48899,2013-07-23 14:27:52.27322,2011-10-27 16:17:10.01694,2005-07-13 16:55:30.7964,2003-06-05 14:53:13.71932,2002-07-22 10:22:31.0967,2011-12-27 16:12:54.85765,2001-01-12 11:40:09.16207,2005-12-30 08:46:31.30943,2007-03-01 08:29:36.765,2011-06-16 09:09:43.8651,2000-12-15 14:33:29.20083,2006-04-25 13:46:46.09684,2011-06-20 16:26:23.65135,2004-01-23 12:37:06.92535,2002-03-04 10:02:08.92547,2003-08-01 10:33:57.33683}'::timestamp[],
'{1997-12-05 10:59:43.94611,2014-11-18 08:48:18.32773}'::timestamp[],
NULL::timestamp[],
NULL::timestamp[],
NULL::timestamp[]
),
(
'orca.tmp_verd_s_pp_provtabs_agt_0015_extract1'::regclass,
14::smallint,
'f',
0.329817::real,
8::integer,
38109.5::real,
1::smallint,
2::smallint,
0::smallint,
0::smallint,
0::smallint,
2060::oid,
2062::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
'{0.0715766,0.0621317,0.00546242,0.0044399,0.000134542,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05,8.07255e-05}'::real[],
NULL::real[],
NULL::real[],
NULL::real[],
NULL::real[],
'{1997-11-25 19:05:00.83798,1998-12-29 16:19:18.50226,1998-01-28 23:01:18.41289,2000-12-21 18:03:30.34549,2003-08-28 11:14:33.26306,2003-08-28 11:14:33.2622,1999-03-20 13:04:33.24015,2003-08-28 11:14:33.22312,2003-08-28 11:14:33.21933,2003-08-28 11:14:33.22082,2003-08-28 11:14:33.21425,2003-08-28 11:14:33.22336,2003-08-28 11:14:33.2092,2003-08-28 11:14:33.20251,2003-08-28 11:14:33.22145,2003-08-28 11:14:33.26235,2003-08-28 11:14:33.26525,2003-08-28 11:14:33.23714,2003-08-28 11:14:33.26667,2003-08-28 11:14:33.23978,2003-08-28 11:14:33.21527,2003-08-28 11:14:33.2227,1999-04-16 09:01:42.92689,2003-08-28 11:14:33.21846,2003-08-28 11:14:33.24725}'::timestamp[],
'{1997-11-25 19:05:00.83798,1998-01-05 11:57:12.19545,1998-10-14 09:06:01.87217,1998-12-29 16:19:18.50226,1999-01-18 15:01:52.77062,1999-12-28 07:57:37.93632,2001-05-16 10:55:44.78317,2003-05-23 10:32:40.1846,2003-08-28 11:14:33.23985,2004-02-04 14:01:57.60942,2005-07-26 17:01:10.98951,2005-07-26 18:41:33.09864,2006-04-25 16:52:03.49003,2008-02-18 14:17:08.58924,2010-04-19 10:16:19.03194,2012-07-23 10:47:40.65789,2014-12-05 10:59:02.25493}'::timestamp[],
NULL::timestamp[],
NULL::timestamp[],
NULL::timestamp[]
),
(
'orca.tmp_verd_s_pp_provtabs_agt_0015_extract1'::regclass,
15::smallint,
'f',
0.678255::real,
8::integer,
7167.15::real,
1::smallint,
2::smallint,
0::smallint,
0::smallint,
0::smallint,
2060::oid,
2062::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
'{0.000376719,0.00034981,0.00034981,0.00034981,0.00034981,0.00034981,0.00034981,0.000322902,0.000322902,0.000322902,0.000295993,0.000295993,0.000295993,0.000295993,0.000295993,0.000295993,0.000295993,0.000295993,0.000295993,0.000295993,0.000295993,0.000295993,0.000295993,0.000269085,0.000269085}'::real[],
NULL::real[],
NULL::real[],
NULL::real[],
NULL::real[],
'{2012-09-07 14:14:23.95552,2012-09-07 14:14:36.8171,2008-12-02 09:02:19.06415,2012-03-16 15:57:15.10939,1999-06-08 13:59:56.59862,1998-10-29 14:57:47.93588,1997-07-10 09:55:34.68999,2003-03-26 11:18:44.43314,2002-02-27 15:07:42.12004,2002-02-27 15:07:13.65666,2003-03-26 11:22:07.7484,2013-11-29 13:16:25.79261,2007-09-06 09:14:10.7907,1998-10-29 14:54:04.23854,2003-04-11 07:54:56.90542,2006-03-09 15:42:27.40086,2000-05-31 10:27:52.92485,2006-01-23 17:12:44.80256,2003-01-28 10:44:17.44046,2007-11-01 15:11:21.99194,2006-03-09 15:42:56.14013,2004-03-31 10:58:47.12524,1999-06-08 14:02:11.91465,1997-07-11 14:52:47.95918,1999-06-08 13:58:15.07927}'::timestamp[],
'{1997-07-09 10:42:54.69421,1997-09-16 10:30:42.71499,1999-06-08 14:32:08.31914,2002-02-27 15:07:13.67355,2003-04-08 16:31:58.80724,2004-05-05 10:18:01.33179,2006-03-13 16:19:59.61215,2007-09-06 09:13:41.71774,2013-11-29 13:16:37.17591,2014-12-03 09:24:25.20945}'::timestamp[],
NULL::timestamp[],
NULL::timestamp[],
NULL::timestamp[]
);
set optimizer_segments = 256;
select a.*, b.guelt_ab as guelt_ab_b, b.guelt_bis as guelt_bis_b
from orca.tmp_verd_s_pp_provtabs_agt_0015_extract1 a
left outer join orca.tmp_verd_s_pp_provtabs_agt_0015_extract1 b
ON a.uid136=b.uid136 and a.tab_nr=b.tab_nr and a.prdgrp=b.prdgrp and a.bg=b.bg and a.typ142=b.typ142 and a.ad_gsch=b.ad_gsch
AND a.guelt_ab <= b.guelt_ab AND a.guelt_bis > b.guelt_ab
;
uid136 | tab_nr | prdgrp | bg | typ142 | ad_gsch | guelt_ab | guelt_bis | guelt_stat | verarb_ab | u_erzeugen | grenze | erstellt_am_122 | erstellt_am_135 | erstellt_am_134 | guelt_ab_b | guelt_bis_b
--------+--------+--------+----+--------+---------+----------+-----------+------------+-----------+------------+--------+-----------------+-----------------+-----------------+------------+-------------
(0 rows)
set optimizer_segments = 3;
set allow_system_table_mods=false;
-- Arrayref
drop table if exists orca.arrtest;
NOTICE: table "arrtest" does not exist, skipping
create table orca.arrtest (
a int2[],
b int4[][][],
c name[],
d text[][]
) DISTRIBUTED RANDOMLY;
insert into orca.arrtest (a[1:5], b[1:1][1:2][1:2], c, d)
values ('{1,2,3,4,5}', '{{{0,0},{1,2}}}', '{}', '{}');
select a[1:3], b[1][2][1], c[1], d[1][1] FROM orca.arrtest order by 1,2,3,4;
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-default collation
a | b | c | d
---------+---+---+---
{1,2,3} | 1 | |
(1 row)
select a[b[1][2][2]] from orca.arrtest;
a
---
2
(1 row)
-- MPP-20713, MPP-20714, MPP-20738: Const table get with a filter
select 1 as x where 1 in (2, 3);
x
---
(0 rows)
-- MPP-22918: join inner child with universal distribution
SELECT generate_series(1,10) EXCEPT SELECT 1;
generate_series
-----------------
2
3
4
5
6
7
8
9
10
(9 rows)
-- MPP-23932: SetOp of const table and volatile function
SELECT generate_series(1,10) INTERSECT SELECT 1;
generate_series
-----------------
1
(1 row)
SELECT generate_series(1,10) UNION SELECT 1;
generate_series
-----------------
1
2
3
4
5
6
7
8
9
10
(10 rows)
-- warning messages for missing stats
create table foo_missing_stats(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 foo_missing_stats select i, i%5 from generate_series(1,20) i;
create table bar_missing_stats(c int, d int);
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.
insert into bar_missing_stats select i, i%8 from generate_series(1,30) i;
analyze foo_missing_stats;
analyze bar_missing_stats;
select count(*) from foo_missing_stats where a = 10;
count
-------
1
(1 row)
with x as (select * from foo_missing_stats) select count(*) from x x1, x x2 where x1.a = x2.a;
count
-------
20
(1 row)
with x as (select * from foo_missing_stats) select count(*) from x x1, x x2 where x1.a = x2.b;
count
-------
16
(1 row)
set allow_system_table_mods=true;
delete from pg_statistic where starelid='foo_missing_stats'::regclass;
NOTICE: One or more columns in the following table(s) do not have statistics: pg_statistic
HINT: For non-partitioned tables, run analyze <table_name>(<column_list>). For partitioned tables, run analyze rootpartition <table_name>(<column_list>). See log for columns missing statistics.
delete from pg_statistic where starelid='bar_missing_stats'::regclass;
NOTICE: One or more columns in the following table(s) do not have statistics: pg_statistic
HINT: For non-partitioned tables, run analyze <table_name>(<column_list>). For partitioned tables, run analyze rootpartition <table_name>(<column_list>). See log for columns missing statistics.
set allow_system_table_mods=false;
select count(*) from foo_missing_stats where a = 10;
NOTICE: One or more columns in the following table(s) do not have statistics: foo_missing_stats
HINT: For non-partitioned tables, run analyze <table_name>(<column_list>). For partitioned tables, run analyze rootpartition <table_name>(<column_list>). See log for columns missing statistics.
count
-------
1
(1 row)
with x as (select * from foo_missing_stats) select count(*) from x x1, x x2 where x1.a = x2.a;
NOTICE: One or more columns in the following table(s) do not have statistics: foo_missing_stats
HINT: For non-partitioned tables, run analyze <table_name>(<column_list>). For partitioned tables, run analyze rootpartition <table_name>(<column_list>). See log for columns missing statistics.
count
-------
20
(1 row)
with x as (select * from foo_missing_stats) select count(*) from x x1, x x2 where x1.a = x2.b;
NOTICE: One or more columns in the following table(s) do not have statistics: foo_missing_stats
HINT: For non-partitioned tables, run analyze <table_name>(<column_list>). For partitioned tables, run analyze rootpartition <table_name>(<column_list>). See log for columns missing statistics.
count
-------
16
(1 row)
set optimizer_print_missing_stats = off;
DROP TABLE IF EXISTS orca.table_with_small_statistic_precision_diff;
NOTICE: table "table_with_small_statistic_precision_diff" does not exist, skipping
CREATE TABLE orca.table_with_small_statistic_precision_diff (
col1 double precision
);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'col1' as the Apache Cloudberry data distribution key for this table.
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 allow_system_table_mods=true;
DELETE FROM pg_statistic WHERE starelid='table_with_small_statistic_precision_diff'::regclass;
INSERT INTO pg_statistic VALUES (
'table_with_small_statistic_precision_diff'::regclass,
1::smallint,
True::boolean,
0::real,
8::integer,
0::real,
1::smallint,
2::smallint,
0::smallint,
0::smallint,
0::smallint,
670::oid,
672::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
0::oid,
E'{0.002}'::real[],
NULL::real[],
NULL::real[],
NULL::real[],
NULL::real[],
E'{-0.25475}'::float8[],
E'{-0.3,-0.2547399}'::float8[],
NULL::float8[],
NULL::float8[],
NULL::float8[]);
SET allow_system_table_mods=false;
SELECT *
FROM (
SELECT
*
FROM orca.table_with_small_statistic_precision_diff
UNION ALL
SELECT
*
FROM orca.table_with_small_statistic_precision_diff
) x;
col1
------
(0 rows)
-- Push components of disjunctive predicates
create table cust(cid integer, firstname text, lastname text) distributed by (cid);
create table datedim(date_sk integer, year integer, moy integer) distributed by (date_sk);
create table sales(item_sk integer, ticket_number integer, cid integer, date_sk integer, type text)
distributed by (item_sk, ticket_number);
-- create a volatile function which should not be pushed
CREATE FUNCTION plusone(integer) RETURNS integer AS $$
BEGIN
SELECT $1 + 1;
END;
$$ LANGUAGE plpgsql volatile;
explain
select c.cid cid,
c.firstname firstname,
c.lastname lastname,
d.year dyear
from cust c, sales s, datedim d
where c.cid = s.cid and s.date_sk = d.date_sk and
((d.year = 2001 and lower(s.type) = 't1' and plusone(d.moy) = 5) or (d.moy = 4 and upper(s.type) = 'T2'));
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1293.00 rows=1 width=24)
-> Hash Join (cost=0.00..1293.00 rows=1 width=24)
Hash Cond: (c.cid = s.cid)
-> Seq Scan on cust c (cost=0.00..431.00 rows=1 width=20)
-> Hash (cost=862.00..862.00 rows=1 width=8)
-> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..862.00 rows=1 width=8)
Hash Key: s.cid
-> Hash Join (cost=0.00..862.00 rows=1 width=8)
Hash Cond: (s.date_sk = d.date_sk)
Join Filter: (((d.year = 2001) AND (lower(s.type) = 't1'::text) AND (plusone(d.moy) = 5)) OR ((d.moy = 4) AND (upper(s.type) = 'T2'::text)))
-> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=16)
Hash Key: s.date_sk
-> Seq Scan on sales s (cost=0.00..431.00 rows=1 width=16)
Filter: ((lower(type) = 't1'::text) OR (upper(type) = 'T2'::text))
-> 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)
(18 rows)
-- Bitmap indexes
drop table if exists orca.bm_test;
NOTICE: table "bm_test" does not exist, skipping
create table orca.bm_test (i int, 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.
insert into orca.bm_test select i % 10, (i % 10)::text from generate_series(1, 100) i;
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
--------------------------------------------------------------------------------
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)
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)
(7 rows)
select * from orca.bm_test where i=2 and t='2';
i | t
---+---
2 | 2
2 | 2
2 | 2
2 | 2
2 | 2
2 | 2
2 | 2
2 | 2
2 | 2
2 | 2
(10 rows)
reset optimizer_enable_bitmapscan;
-- Dynamic bitmap indexes
drop table if exists orca.bm_dyn_test;
NOTICE: table "bm_dyn_test" does not exist, skipping
create table orca.bm_dyn_test (i int, to_be_dropped char(5), j int, t text) distributed by (i) partition by list(j)
(partition part0 values(0) with (appendonly=true, compresslevel=5, orientation=column),
partition part1 values(1),
partition part2 values(2) with (appendonly=true, compresslevel=5, orientation=row),
partition part3 values(3), partition part4 values(4));
insert into orca.bm_dyn_test select i % 10, 'drop', i % 5, (i % 10)::text from generate_series(1, 100) i;
create index bm_dyn_test_idx on orca.bm_dyn_test using bitmap (i);
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;
-- gather on 1 segment because of direct dispatch
explain select * from orca.bm_dyn_test where i=2 and t='2';
QUERY PLAN
--------------------------------------------------------------------------------------------
Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..398.03 rows=2 width=10)
-> Dynamic Bitmap Heap Scan on bm_dyn_test (cost=0.00..398.03 rows=1 width=10)
Number of partitions to scan: 6 (out of 6)
Recheck Cond: (i = 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)
(8 rows)
select * from orca.bm_dyn_test where i=2 and t='2';
i | j | t
---+---+---
2 | 2 | 2
2 | 2 | 2
2 | 2 | 2
2 | 2 | 2
2 | 2 | 2
2 | 2 | 2
2 | 2 | 2
2 | 2 | 2
2 | 2 | 2
2 | 2 | 2
2 | 5 | 2
(11 rows)
reset optimizer_enable_bitmapscan;
-- Now, create a partial index
drop table if exists orca.bm_dyn_test_onepart;
NOTICE: table "bm_dyn_test_onepart" does not exist, skipping
create table orca.bm_dyn_test_onepart (i int, to_be_dropped char(5), j int, t text)
distributed by (i) partition by list(j)
(partition part0 values(0) with (appendonly=true, compresslevel=5, orientation=column),
partition part1 values(1),
partition part2 values(2) with (appendonly=true, compresslevel=5, orientation=row),
partition part3 values(3), partition part4 values(4));
insert into orca.bm_dyn_test_onepart select i % 10, 'drop', i % 5, (i % 10)::text from generate_series(1, 100) i;
create index bm_test_idx_part on orca.bm_dyn_test_onepart_1_prt_part2 using bitmap (i);
alter table orca.bm_dyn_test_onepart drop column to_be_dropped;
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;
-- 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
DETAIL: Falling back to Postgres-based planner because no plan has been computed for required properties in GPORCA
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)
-> Seq Scan on bm_dyn_test_onepart_1_prt_part0 bm_dyn_test_onepart_1 (cost=0.00..1.10 rows=1 width=10)
Filter: ((i = 2) AND (t = '2'::text))
-> Seq Scan on bm_dyn_test_onepart_1_prt_part1 bm_dyn_test_onepart_2 (cost=0.00..1.10 rows=1 width=10)
Filter: ((i = 2) AND (t = '2'::text))
-> Seq Scan on bm_dyn_test_onepart_1_prt_part2 bm_dyn_test_onepart_3 (cost=0.00..1.10 rows=2 width=10)
Filter: ((i = 2) AND (t = '2'::text))
-> Seq Scan on bm_dyn_test_onepart_1_prt_part3 bm_dyn_test_onepart_4 (cost=0.00..1.10 rows=1 width=10)
Filter: ((i = 2) AND (t = '2'::text))
-> Seq Scan on bm_dyn_test_onepart_1_prt_part4 bm_dyn_test_onepart_5 (cost=0.00..1.10 rows=1 width=10)
Filter: ((i = 2) AND (t = '2'::text))
-> Seq Scan on bm_dyn_test_onepart_1_prt_part5 bm_dyn_test_onepart_6 (cost=0.00..1.01 rows=1 width=10)
Filter: ((i = 2) AND (t = '2'::text))
Optimizer: Postgres query optimizer
(15 rows)
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
i | j | t
---+---+---
2 | 2 | 2
2 | 2 | 2
2 | 2 | 2
2 | 2 | 2
2 | 2 | 2
2 | 2 | 2
2 | 2 | 2
2 | 2 | 2
2 | 2 | 2
2 | 2 | 2
2 | 5 | 2
(11 rows)
reset optimizer_enable_dynamictablescan;
reset optimizer_enable_bitmapscan;
-- Multi-level partition with dynamic bitmap indexes
create table orca.bm_dyn_test_multilvl_part (id int, year int, quarter int, region text)
distributed by (id) partition by range (year)
subpartition by range (quarter)
subpartition template (
start (1) end (3) every (1) )
subpartition by list (region)
subpartition template (
subpartition usa values ('usa'),
default subpartition other_regions )
( start (2018) end (2020) every (1) );
insert into orca.bm_dyn_test_multilvl_part select i, 2018 + (i%2), i%2 + 1, 'usa' from generate_series(1,100)i;
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 bm_multi_test_idx_part on orca.bm_dyn_test_multilvl_part using bitmap(year);
analyze orca.bm_dyn_test_multilvl_part;
-- print name of parent index
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)
-> 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)
Filter: (year = 2019)
-> Seq Scan on bm_dyn_test_multilvl_part_1_prt_2_2_prt_2_3_prt_usa bm_dyn_test_multilvl_part_3 (cost=0.00..1.21 rows=17 width=16)
Filter: (year = 2019)
-> Seq Scan on bm_dyn_test_multilvl_part_1_prt_2_2_prt_2_3_prt_other_regions bm_dyn_test_multilvl_part_4 (cost=0.00..1.01 rows=1 width=44)
Filter: (year = 2019)
Optimizer: Postgres query optimizer
(11 rows)
select count(*) 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
count
-------
50
(1 row)
-- More BitmapTableScan & BitmapIndexScan tests
set optimizer_enable_bitmapscan=on;
create schema bm;
-- Bitmap index scan on Heterogeneous parts with dropped columns
drop table if exists bm.het_bm;
NOTICE: table "het_bm" does not exist, skipping
create table bm.het_bm (i int, to_be_dropped char(5), j int, t text) distributed by (i) partition by list(j)
(partition part0 values(0) with (appendonly=true, compresslevel=5, orientation=column),
partition part1 values(1),
partition part2 values(2) with (appendonly=true, compresslevel=5, orientation=row),
partition part3 values(3), partition part4 values(4));
insert into bm.het_bm select i % 10, 'drop', i % 5, (i % 10)::text from generate_series(1, 100) i;
create index het_bm_idx on bm.het_bm using bitmap (i);
alter table bm.het_bm drop column to_be_dropped;
alter table bm.het_bm add partition part5 values(5);
insert into bm.het_bm values(2, 5, '2');
select sum(i) i_sum, sum(j) j_sum, sum(t::integer) t_sum from bm.het_bm where i=2 and t='2';
i_sum | j_sum | t_sum
-------+-------+-------
22 | 25 | 22
(1 row)
-- Bitmap index scan on heap parts with dropped columns
drop table if exists bm.hom_bm_heap;
NOTICE: table "hom_bm_heap" does not exist, skipping
create table bm.hom_bm_heap (i int, to_be_dropped char(5), j int, t text) distributed by (i) partition by list(j)
(partition part0 values(0),
partition part1 values(1),
partition part2 values(2),
partition part3 values(3),
partition part4 values(4));
insert into bm.hom_bm_heap select i % 10, 'drop', i % 5, (i % 10)::text from generate_series(1, 100) i;
create index hom_bm_heap_idx on bm.hom_bm_heap using bitmap (i);
alter table bm.hom_bm_heap drop column to_be_dropped;
alter table bm.hom_bm_heap add partition part5 values(5);
insert into bm.hom_bm_heap values(2, 5, '2');
select sum(i) i_sum, sum(j) j_sum, sum(t::integer) t_sum from bm.hom_bm_heap where i=2 and t='2';
i_sum | j_sum | t_sum
-------+-------+-------
22 | 25 | 22
(1 row)
-- Bitmap index scan on AO parts with dropped columns
drop table if exists bm.hom_bm_ao;
NOTICE: table "hom_bm_ao" does not exist, skipping
create table bm.hom_bm_ao (i int, to_be_dropped char(5), j int, t text)
with (appendonly=true, compresslevel=5, orientation=row)
distributed by (i) partition by list(j)
(partition part0 values(0),
partition part1 values(1),
partition part2 values(2),
partition part3 values(3),
partition part4 values(4));
insert into bm.hom_bm_ao select i % 10, 'drop', i % 5, (i % 10)::text from generate_series(1, 100) i;
create index hom_bm_ao_idx on bm.hom_bm_ao using bitmap (i);
alter table bm.hom_bm_ao drop column to_be_dropped;
alter table bm.hom_bm_ao add partition part5 values(5);
insert into bm.hom_bm_ao values(2, 5, '2');
select sum(i) i_sum, sum(j) j_sum, sum(t::integer) t_sum from bm.hom_bm_ao where i=2 and t='2';
i_sum | j_sum | t_sum
-------+-------+-------
22 | 25 | 22
(1 row)
-- Bitmap index scan on AOCO parts with dropped columns
drop table if exists bm.hom_bm_aoco;
NOTICE: table "hom_bm_aoco" does not exist, skipping
create table bm.hom_bm_aoco (i int, to_be_dropped char(5), j int, t text)
with (appendonly=true, compresslevel=5, orientation=column)
distributed by (i) partition by list(j)
(partition part0 values(0),
partition part1 values(1),
partition part2 values(2),
partition part3 values(3),
partition part4 values(4));
insert into bm.hom_bm_aoco select i % 10, 'drop', i % 5, (i % 10)::text from generate_series(1, 100) i;
create index hom_bm_aoco_idx on bm.hom_bm_aoco using bitmap (i);
alter table bm.hom_bm_aoco drop column to_be_dropped;
alter table bm.hom_bm_aoco add partition part5 values(5);
insert into bm.hom_bm_aoco values(2, 5, '2');
select sum(i) i_sum, sum(j) j_sum, sum(t::integer) t_sum from bm.hom_bm_aoco where i=2 and t='2';
i_sum | j_sum | t_sum
-------+-------+-------
22 | 25 | 22
(1 row)
-- Create index before dropped column
drop table if exists bm.het_bm;
create table bm.het_bm (i int, to_be_dropped char(5), j int, t text) distributed by (i) partition by list(j)
(partition part0 values(0) with (appendonly=true, compresslevel=5, orientation=column),
partition part1 values(1),
partition part2 values(2) with (appendonly=true, compresslevel=5, orientation=row),
partition part3 values(3), partition part4 values(4));
insert into bm.het_bm select i % 10, 'drop', i % 5, (i % 10)::text from generate_series(1, 100) i;
-- Create index before dropping a column
create index het_bm_i_idx on bm.het_bm using bitmap (i);
create index het_bm_j_idx on bm.het_bm using bitmap (j);
alter table bm.het_bm drop column to_be_dropped;
alter table bm.het_bm add partition part5 values(5);
insert into bm.het_bm values(2, 5, '2');
select sum(i) i_sum, sum(j) j_sum, sum(t::integer) t_sum from bm.het_bm where i=2 and j=2;
i_sum | j_sum | t_sum
-------+-------+-------
20 | 20 | 20
(1 row)
select sum(i) i_sum, sum(j) j_sum, sum(t::integer) t_sum from bm.het_bm where i=2 and t='2';
i_sum | j_sum | t_sum
-------+-------+-------
22 | 25 | 22
(1 row)
-- Drop and recreate index after we dropped column
drop index bm.het_bm_i_idx;
drop index bm.het_bm_j_idx;
create index het_bm_i_idx on bm.het_bm using bitmap (i);
create index het_bm_j_idx on bm.het_bm using bitmap (j);
select sum(i) i_sum, sum(j) j_sum, sum(t::integer) t_sum from bm.het_bm where j=2 or j=3;
i_sum | j_sum | t_sum
-------+-------+-------
200 | 100 | 200
(1 row)
-- Create index after dropped column
drop table if exists bm.het_bm;
create table bm.het_bm (i int, to_be_dropped char(5), j int, t text) distributed by (i) partition by list(j)
(partition part0 values(0) with (appendonly=true, compresslevel=5, orientation=column),
partition part1 values(1),
partition part2 values(2) with (appendonly=true, compresslevel=5, orientation=row),
partition part3 values(3), partition part4 values(4));
insert into bm.het_bm select i % 10, 'drop', i % 5, (i % 10)::text from generate_series(1, 100) i;
alter table bm.het_bm drop column to_be_dropped;
alter table bm.het_bm add partition part5 values(5);
-- Create index after dropping a column but before we insert into newly created part
create index het_bm_i_idx on bm.het_bm using bitmap (i);
create index het_bm_j_idx on bm.het_bm using bitmap (j);
insert into bm.het_bm values(2, 5, '2');
select sum(i) i_sum, sum(j) j_sum, sum(t::integer) t_sum from bm.het_bm where j=2 or j=3;
i_sum | j_sum | t_sum
-------+-------+-------
200 | 100 | 200
(1 row)
-- Rescan bitmap index
drop table if exists bm.outer_tab;
NOTICE: table "outer_tab" does not exist, skipping
create table bm.outer_tab
(
id serial,
code character varying(25),
name character varying(40)
);
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 bm.outer_tab select i % 10, i % 5, i % 2 from generate_series(1, 100) i;
set optimizer_enable_hashjoin = off;
select count(1) from bm.outer_tab;
count
-------
100
(1 row)
select count(1) from bm.het_bm;
count
-------
101
(1 row)
select sum(id) id_sum, sum(i) i_sum, sum(j) j_sum from bm.outer_tab as ot join bm.het_bm as het_bm on ot.id = het_bm.j
where het_bm.i between 2 and 5;
id_sum | i_sum | j_sum
--------+-------+-------
950 | 1420 | 950
(1 row)
drop schema bm cascade;
NOTICE: drop cascades to 5 other objects
DETAIL: drop cascades to table bm.hom_bm_heap
drop cascades to table bm.hom_bm_ao
drop cascades to table bm.hom_bm_aoco
drop cascades to table bm.het_bm
drop cascades to table bm.outer_tab
reset optimizer_enable_hashjoin;
reset optimizer_enable_bitmapscan;
-- End of BitmapTableScan & BitmapIndexScan tests
set optimizer_enable_constant_expression_evaluation=on;
CREATE TABLE my_tt_agg_opt (
symbol character(16),
event_ts bigint,
trade_price numeric,
trade_volume bigint
) DISTRIBUTED BY (symbol);
CREATE TABLE my_tq_agg_opt_part (
ets bigint,
sym character varying(16),
bid_price numeric,
ask_price numeric,
end_ts bigint
) DISTRIBUTED BY (ets)
PARTITION BY RANGE(bid_price)(PARTITION p1 START(0) END(200000),
PARTITION p2 START(200000) END(900000));
CREATE INDEX my_tq_agg_opt_part_ets_end_ts_ix_1 ON my_tq_agg_opt_part_1_prt_p1 USING btree (ets, end_ts);
CREATE INDEX my_tq_agg_opt_part_ets_end_ts_ix_2 ON my_tq_agg_opt_part_1_prt_p2 USING btree (ets);
CREATE FUNCTION plusone(numeric) RETURNS numeric AS $$
BEGIN
SELECT $1 + 1;
END;
$$ LANGUAGE plpgsql volatile;
-- force_explain
set optimizer_segments = 3;
EXPLAIN
SELECT (tt.event_ts / 100000) / 5 * 5 as fivemin, COUNT(*)
FROM my_tt_agg_opt tt, my_tq_agg_opt_part tq
WHERE tq.sym = tt.symbol AND
plusone(tq.bid_price) < tt.trade_price AND
tt.event_ts >= tq.ets AND
tt.event_ts < tq.end_ts
GROUP BY 1
ORDER BY 1 asc ;
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)
Sort Key: ((((tt.event_ts / 100000) / 5) * 5))
-> 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: ((tq.sym)::bpchar = tt.symbol)
Join Filter: ((plusone(tq.bid_price) < tt.trade_price) AND (tt.event_ts >= tq.ets) AND (tt.event_ts < tq.end_ts))
-> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=32)
Hash Key: tq.sym
-> Dynamic Seq Scan on my_tq_agg_opt_part tq (cost=0.00..431.00 rows=1 width=32)
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)
(15 rows)
-- MPP-25661: IndexScan crashing for qual with reference to outer tuple
drop table if exists idxscan_outer;
NOTICE: table "idxscan_outer" does not exist, skipping
create table idxscan_outer
(
id serial,
code character varying(25),
name character varying(40)
);
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.
drop table if exists idxscan_inner;
NOTICE: table "idxscan_inner" does not exist, skipping
create table idxscan_inner
(
ordernum int unique,
productid int,
comment character varying(40)
);
-- Have more rows in one table, so that the planner will
-- choose to make that the outer side of the join.
insert into idxscan_outer values (1, 'a', 'aaa');
insert into idxscan_outer values (2, 'b', 'bbb');
insert into idxscan_outer values (3, 'c', 'ccc');
insert into idxscan_outer values (4, 'd', 'ddd');
insert into idxscan_outer values (5, 'e', 'eee');
insert into idxscan_outer values (6, 'f', 'fff');
insert into idxscan_outer values (7, 'g', 'ggg');
insert into idxscan_outer values (8, 'h', 'hhh');
insert into idxscan_outer values (9, 'i', 'iii');
insert into idxscan_inner values (11, 1, 'xxxx');
insert into idxscan_inner values (24, 2, 'yyyy');
insert into idxscan_inner values (13, 3, 'zzzz');
analyze idxscan_outer;
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)
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)
-> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..6.00 rows=1 width=9)
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)
(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
(2 rows)
reset optimizer_enable_hashjoin;
drop table idxscan_outer;
drop table idxscan_inner;
drop table if exists ggg;
NOTICE: table "ggg" does not exist, skipping
create table ggg (a char(1), b char(2), d char(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.
insert into ggg values ('x', 'a', 'c');
insert into ggg values ('x', 'a');
insert into ggg values ('x');
-- MPP-25700 Fix to TO_DATE on hybrid datums during constant expression evaluation
drop table if exists orca.t3;
NOTICE: table "t3" does not exist, skipping
create table orca.t3 (c1 timestamp without time zone);
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 orca.t3 values ('2015-07-03 00:00:00'::timestamp without time zone);
select to_char(c1, 'YYYY-MM-DD HH24:MI:SS') from orca.t3 where c1 = TO_DATE('2015-07-03','YYYY-MM-DD');
to_char
---------------------
2015-07-03 00:00:00
(1 row)
select to_char(c1, 'YYYY-MM-DD HH24:MI:SS') from orca.t3 where c1 = '2015-07-03'::date;
to_char
---------------------
2015-07-03 00:00:00
(1 row)
-- MPP-25806: multi-column index
create table orca.index_test (a int, b int, c int, d int, e int, constraint index_test_pkey PRIMARY KEY (a, b, c, d));
insert into orca.index_test select i,i%2,i%3,i%4,i%5 from generate_series(1,100) i;
analyze orca.index_test;
-- force_explain
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)
-> 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)
(4 rows)
-- force_explain
explain select * from orca.index_test where c = 5;
QUERY PLAN
-----------------------------------------------------------------------------------------
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)
(4 rows)
-- force_explain
explain select * from orca.index_test where a = 5 and c = 5;
QUERY PLAN
-----------------------------------------------------------------------------------------
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)
(4 rows)
-- renaming columns
select * from (values (2),(null)) v(k);
k
---
2
(2 rows)
-- Checking if ORCA correctly populates canSetTag in PlannedStmt for multiple statements because of rules
drop table if exists can_set_tag_target;
NOTICE: table "can_set_tag_target" does not exist, skipping
create table can_set_tag_target
(
x int,
y int,
z char
);
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.
drop table if exists can_set_tag_audit;
NOTICE: table "can_set_tag_audit" does not exist, skipping
create table can_set_tag_audit
(
t timestamp without time zone,
x int,
y int,
z char
);
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.
create rule can_set_tag_audit_update AS
ON UPDATE TO can_set_tag_target DO INSERT INTO can_set_tag_audit (t, x, y, z)
VALUES (now(), old.x, old.y, old.z);
insert into can_set_tag_target select i, i + 1, i + 2 from generate_series(1,2) as i;
create role unpriv;
NOTICE: resource queue required -- using default resource queue "pg_default"
grant all on can_set_tag_target to unpriv;
grant all on can_set_tag_audit to unpriv;
set role unpriv;
show optimizer;
optimizer
-----------
on
(1 row)
update can_set_tag_target set y = y + 1;
select count(1) from can_set_tag_audit;
count
-------
2
(1 row)
reset role;
revoke all on can_set_tag_target from unpriv;
revoke all on can_set_tag_audit from unpriv;
drop role unpriv;
drop table can_set_tag_target;
drop table can_set_tag_audit;
-- start_ignore
create language plpython3u;
-- 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 $$
if (x is None):
return 0
else:
return x * 3
$$ language plpython3u;
create table canSetTag_input_data (domain integer, class integer, attr text, value integer)
distributed by (domain);
insert into canSetTag_input_data values(1, 1, 'A', 1);
insert into canSetTag_input_data values(2, 1, 'A', 0);
insert into canSetTag_input_data values(3, 0, 'B', 1);
create table canSetTag_bug_table as
SELECT attr, class, (select canSetTag_Func(count(distinct class)::int) from canSetTag_input_data)
as dclass FROM canSetTag_input_data GROUP BY attr, class distributed by (attr);
drop function canSetTag_Func(x int);
drop table canSetTag_bug_table;
drop table canSetTag_input_data;
-- Test B-Tree index scan with in list
CREATE TABLE btree_test as SELECT i a, i b FROM generate_series(1,100) i distributed randomly;
ANALYZE btree_test;
CREATE INDEX btree_test_index ON btree_test(a);
set optimizer_enable_tablescan = off;
-- start_ignore
select disable_xform('CXformSelect2IndexGet');
disable_xform
-----------------------------------
CXformSelect2IndexGet 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)
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)
(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)
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)
(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)
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)
(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)
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)
(6 rows)
SELECT * FROM btree_test WHERE a in ('1', '2', 47);
a | b
----+----
1 | 1
2 | 2
47 | 47
(3 rows)
CREATE INDEX btree_test_index_ab ON btree_test using btree(a,b);
EXPLAIN SELECT * FROM btree_test WHERE a in (1, 2, 47) AND b > 1;
QUERY PLAN
----------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.06 rows=4 width=8)
-> Bitmap Heap Scan on btree_test (cost=0.00..431.06 rows=2 width=8)
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)
(6 rows)
SELECT * FROM btree_test WHERE a in (1, 2, 47) AND b > 1;
a | b
----+----
2 | 2
47 | 47
(2 rows)
-- start_ignore
select enable_xform('CXformSelect2IndexGet');
enable_xform
----------------------------------
CXformSelect2IndexGet is enabled
(1 row)
-- end_ignore
reset optimizer_enable_tablescan;
-- Test Bitmap index scan with in list
CREATE TABLE bitmap_test as SELECT * FROM generate_series(1,100) as a distributed randomly;
ANALYZE bitmap_test;
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)
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)
(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)
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)
(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)
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)
(6 rows)
EXPLAIN SELECT * FROM bitmap_test WHERE a in ('1', '2');
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)
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)
(6 rows)
EXPLAIN SELECT * FROM bitmap_test WHERE a in ('1', '2', 47);
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)
(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
-- difference in the output will make the test fail. Disable log_statement
-- and log_min_duration_statement, they are the most obvious ones.
set log_statement='none';
set log_min_duration_statement=-1;
set client_min_messages='log';
explain select count(*) from foo group by cube(a,b);
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2155.00 rows=1 width=8)
-> Sequence (cost=0.00..2155.00 rows=1 width=8)
-> Shared Scan (share slice:id 1:0) (cost=0.00..431.00 rows=1 width=1)
-> Seq Scan on foo (cost=0.00..431.00 rows=1 width=8)
-> Append (cost=0.00..1724.00 rows=1 width=8)
-> GroupAggregate (cost=0.00..431.00 rows=1 width=8)
Group Key: share0_ref2.a, share0_ref2.b
-> Sort (cost=0.00..431.00 rows=1 width=8)
Sort Key: share0_ref2.a, share0_ref2.b
-> Shared Scan (share slice:id 1:0) (cost=0.00..431.00 rows=1 width=8)
-> GroupAggregate (cost=0.00..431.00 rows=1 width=8)
Group Key: share0_ref3.b
-> Sort (cost=0.00..431.00 rows=1 width=4)
Sort Key: share0_ref3.b
-> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=4)
Hash Key: share0_ref3.b
-> Result (cost=0.00..431.00 rows=1 width=4)
-> Shared Scan (share slice:id 2:0) (cost=0.00..431.00 rows=1 width=4)
-> GroupAggregate (cost=0.00..431.00 rows=1 width=8)
Group Key: share0_ref4.a
-> Sort (cost=0.00..431.00 rows=1 width=4)
Sort Key: share0_ref4.a
-> Shared Scan (share slice:id 1:0) (cost=0.00..431.00 rows=1 width=4)
-> Result (cost=0.00..431.00 rows=1 width=8)
-> Redistribute Motion 1:3 (slice3) (cost=0.00..431.00 rows=1 width=8)
-> Aggregate (cost=0.00..431.00 rows=1 width=8)
-> Gather Motion 3:1 (slice4; segments: 3) (cost=0.00..431.00 rows=1 width=1)
-> Result (cost=0.00..431.00 rows=1 width=1)
-> Shared Scan (share slice:id 4:0) (cost=0.00..431.00 rows=1 width=1)
Optimizer: GPORCA
(30 rows)
reset client_min_messages;
reset log_statement;
reset log_min_duration_statement;
-- TVF accepts ANYENUM, ANYELEMENT returns ANYENUM, ANYARRAY
CREATE TYPE rainbow AS ENUM('red','yellow','blue');
CREATE FUNCTION func_enum_element(ANYENUM, ANYELEMENT) RETURNS TABLE(a ANYENUM, b ANYARRAY)
AS $$ SELECT $1, ARRAY[$2] $$ LANGUAGE SQL STABLE;
SELECT * FROM func_enum_element('red'::rainbow, 'blue'::rainbow::anyelement);
a | b
-----+--------
red | {blue}
(1 row)
DROP FUNCTION IF EXISTS func_enum_element(ANYENUM, ANYELEMENT);
-- TVF accepts ANYELEMENT, ANYARRAY returns ANYELEMENT, ANYENUM
CREATE FUNCTION func_element_array(ANYELEMENT, ANYARRAY) RETURNS TABLE(a ANYELEMENT, b ANYENUM)
AS $$ SELECT $1, $2[1]$$ LANGUAGE SQL STABLE;
SELECT * FROM func_element_array('red'::rainbow, ARRAY['blue'::rainbow]);
a | b
-----+------
red | blue
(1 row)
DROP FUNCTION IF EXISTS func_element_array(ANYELEMENT, ANYARRAY);
-- TVF accepts ANYARRAY, ANYENUM returns ANYELEMENT
CREATE FUNCTION func_element_array(ANYARRAY, ANYENUM) RETURNS TABLE(a ANYELEMENT, b ANYELEMENT)
AS $$ SELECT $1[1], $2 $$ LANGUAGE SQL STABLE;
SELECT * FROM func_element_array(ARRAY['blue'::rainbow], 'blue'::rainbow);
a | b
------+------
blue | blue
(1 row)
DROP FUNCTION IF EXISTS func_element_array(ANYARRAY, ANYENUM);
-- TVF accepts ANYARRAY argument returns ANYELEMENT, ANYENUM
CREATE FUNCTION func_array(ANYARRAY) RETURNS TABLE(a ANYELEMENT, b ANYENUM)
AS $$ SELECT $1[1], $1[2] $$ LANGUAGE SQL STABLE;
SELECT * FROM func_array(ARRAY['blue'::rainbow, 'yellow'::rainbow]);
a | b
------+--------
blue | yellow
(1 row)
DROP FUNCTION IF EXISTS func_array(ANYARRAY);
-- TVF accepts ANYELEMENT, VARIADIC ARRAY returns ANYARRAY
CREATE FUNCTION func_element_variadic(ANYELEMENT, VARIADIC ANYARRAY) RETURNS TABLE(a ANYARRAY)
AS $$ SELECT array_prepend($1, $2); $$ LANGUAGE SQL STABLE;
SELECT * FROM func_element_variadic(1.1, 1.1, 2.2, 3.3);
a
-------------------
{1.1,1.1,2.2,3.3}
(1 row)
DROP FUNCTION IF EXISTS func_element_variadic(ANYELEMENT, VARIADIC ANYARRAY);
-- TVF accepts ANYNONARRAY returns ANYNONARRAY
CREATE FUNCTION func_nonarray(ANYNONARRAY) RETURNS TABLE(a ANYNONARRAY)
AS $$ SELECT $1; $$ LANGUAGE SQL STABLE;
SELECT * FROM func_nonarray(5);
a
---
5
(1 row)
DROP FUNCTION IF EXISTS func_nonarray(ANYNONARRAY);
-- TVF accepts ANYNONARRAY, ANYENUM returns ANYARRAY
CREATE FUNCTION func_nonarray_enum(ANYNONARRAY, ANYENUM) RETURNS TABLE(a ANYARRAY)
AS $$ SELECT ARRAY[$1, $2]; $$ LANGUAGE SQL STABLE;
SELECT * FROM func_nonarray_enum('blue'::rainbow, 'red'::rainbow);
a
------------
{blue,red}
(1 row)
DROP FUNCTION IF EXISTS func_nonarray_enum(ANYNONARRAY, ANYENUM);
-- TVF accepts ANYARRAY, ANYNONARRAY, ANYENUM returns ANYNONARRAY
CREATE FUNCTION func_array_nonarray_enum(ANYARRAY, ANYNONARRAY, ANYENUM) RETURNS TABLE(a ANYNONARRAY)
AS $$ SELECT $1[1]; $$ LANGUAGE SQL STABLE;
SELECT * FROM func_array_nonarray_enum(ARRAY['blue'::rainbow, 'red'::rainbow], 'red'::rainbow, 'yellow'::rainbow);
a
------
blue
(1 row)
DROP FUNCTION IF EXISTS func_array_nonarray_enum(ANYARRAY, ANYNONARRAY, ANYENUM);
--TVF accepts ANYENUM, ANYELEMENT, ANYELEMENT return ANYENUM, ANYARRAY
CREATE FUNCTION return_enum_as_array(ANYENUM, ANYELEMENT, ANYELEMENT) RETURNS TABLE (ae ANYENUM, aa ANYARRAY)
AS $$ SELECT $1, array[$2, $3] $$ LANGUAGE SQL STABLE;
SELECT * FROM return_enum_as_array('red'::rainbow, 'yellow'::rainbow, 'blue'::rainbow);
ae | aa
-----+---------------
red | {yellow,blue}
(1 row)
DROP FUNCTION IF EXISTS return_enum_as_array(ANYENUM, ANYELEMENT, ANYELEMENT);
-- start_ignore
drop table foo;
-- end_ignore
-- Test GPDB Expr (T_ArrayCoerceExpr) conversion to Scalar Array Coerce Expr
-- start_ignore
create table foo (a int, b character varying(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.
-- end_ignore
-- Query should not fallback to planner
explain select * from foo where b in ('1', '2');
QUERY PLAN
-------------------------------------------------------------------------------
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)
(4 rows)
set optimizer_enable_ctas = off;
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",
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;
reset log_min_duration_statement;
reset log_statement;
reset optimizer_enable_ctas;
-- Test to ensure that ORCA produces correct results for a query with an Agg on top of LOJ
-- start_ignore
create table input_tab1 (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 input_tab2 (c int, d int);
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.
insert into input_tab1 values (1, 1);
analyze input_tab1;
insert into input_tab1 values (NULL, NULL);
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
--------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> GroupAggregate
Group Key: t2.c
-> Sort
Sort Key: t2.c
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: t2.c
-> Hash Left Join
Hash Cond: (t1.a = t2.c)
-> Seq Scan on input_tab1 t1
-> Hash
-> Seq Scan on input_tab2 t2
Optimizer: Pivotal 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;
count | c
-------+---
2 |
(1 row)
-- start_ignore
reset optimizer_force_multistage_agg;
reset optimizer_force_three_stage_scalar_dqa;
-- end_ignore
--
-- Test to ensure orca produces correct equivalence class for an alias projected by a LOJ and thus producing correct results.
-- Previously, orca produced an incorrect filter (cd2 = cd) on top of LOJ which led to incorrect results as column 'cd' is
-- produced by a nullable side of LOJ (tab2).
--
-- start_ignore
CREATE TABLE tab_1 (id VARCHAR(32)) DISTRIBUTED RANDOMLY;
INSERT INTO tab_1 VALUES('qwert'), ('vbn');
ANALYZE tab_1;
CREATE TABLE tab_2(key VARCHAR(200) NOT NULL, id VARCHAR(32) NOT NULL, cd VARCHAR(2) NOT NULL) DISTRIBUTED BY(key);
INSERT INTO tab_2 VALUES('abc', 'rew', 'dr');
ANALYZE tab_2;
INSERT INTO tab_2 VALUES('tyu', 'rer', 'fd');
CREATE TABLE tab_3 (region TEXT, code TEXT) DISTRIBUTED RANDOMLY;
INSERT INTO tab_3 VALUES('cvb' ,'tyu');
ANALYZE tab_3;
INSERT INTO tab_3 VALUES('hjj' ,'xyz');
-- end_ignore
EXPLAIN SELECT Count(*)
FROM (SELECT *
FROM (SELECT tab_2.cd AS CD1,
tab_2.cd AS CD2
FROM tab_1
LEFT JOIN tab_2
ON tab_1.id = tab_2.id) f
UNION ALL
SELECT region,
code
FROM tab_3)a;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------
Aggregate (cost=0.00..1293.00 rows=1 width=8)
-> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1293.00 rows=4 width=1)
-> Append (cost=0.00..1293.00 rows=2 width=1)
-> Hash Left Join (cost=0.00..862.00 rows=1 width=3)
Hash Cond: ((tab_1.id)::text = (tab_2.id)::text)
-> Seq Scan on tab_1 (cost=0.00..431.00 rows=1 width=5)
-> Hash (cost=431.00..431.00 rows=1 width=7)
-> 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)
(11 rows)
SELECT Count(*)
FROM (SELECT *
FROM (SELECT tab_2.cd AS CD1,
tab_2.cd AS CD2
FROM tab_1
LEFT JOIN tab_2
ON tab_1.id = tab_2.id) f
UNION ALL
SELECT region,
code
FROM tab_3)a;
count
-------
4
(1 row)
--
-- Test to ensure that ORCA produces correct results with both blocking and
-- streaming materialze as controlled by optimizer_enable_streaming_material
-- GUC.
--
-- start_ignore
create table t_outer (c1 integer);
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 table t_inner (c2 integer);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'c2' as the Apache Cloudberry data distribution key for this table.
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_outer values (generate_series (1,10));
insert into t_inner values (generate_series (1,300));
-- end_ignore
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
9
10
(10 rows)
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
5
6
7
(10 rows)
reset optimizer_enable_streaming_material;
-- Ensure that ORCA rescans the subquery in case of skip-level correlation with
-- materialization
drop table if exists wst0, wst1, wst2;
NOTICE: table "wst0" does not exist, skipping
NOTICE: table "wst1" does not exist, skipping
NOTICE: table "wst2" does not exist, skipping
create table wst0(a0 int, b0 int);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a0' as the Apache Cloudberry data distribution key for this table.
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 wst1(a1 int, b1 int);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a1' as the Apache Cloudberry data distribution key for this table.
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 wst2(a2 int, b2 int);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a2' as the Apache Cloudberry data distribution key for this table.
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 wst0 select i, i from generate_series(1,10) i;
insert into wst1 select i, i from generate_series(1,10) i;
insert into wst2 select i, i from generate_series(1,10) i;
-- NB: the rank() is need to force materialization (via Sort) in the subplan
select count(*) from wst0 where exists (select 1, rank() over (order by wst1.a1) from wst1 where a1 = (select b2 from wst2 where a0=a2+5));
count
-------
5
(1 row)
--
-- Test to ensure sane behavior when DML queries are optimized by ORCA by
-- enforcing a non-master gather motion, controlled by
-- optimizer_enable_gather_on_segment_for_DML GUC
--
--
-- CTAS with global-local aggregation
--
-- start_ignore
create table test1 (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 test1 select generate_series(1,100),generate_series(1,100);
-- end_ignore
create table t_new as select avg(a) from test1 join (select i from unnest(array[1,2,3]) i) t on (test1.a = t.i);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause. Creating a NULL policy entry.
select * from t_new;
avg
--------------------
2.0000000000000000
(1 row)
-- start_ignore
drop table t_new;
set optimizer_enable_gather_on_segment_for_DML=off;
-- end_ignore
create table t_new as select avg(a) from test1 join (select i from unnest(array[1,2,3]) i) t on (test1.a = t.i);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause. Creating a NULL policy entry.
select * from t_new;
avg
--------------------
2.0000000000000000
(1 row)
-- start_ignore
reset optimizer_enable_gather_on_segment_for_DML;
-- end_ignore
--
-- Insert with outer references in the subquery
--
-- start_ignore
create table x_tab(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 table y_tab(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 table z_tab(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 x_tab values(1);
insert into y_tab values(0);
insert into z_tab values(1);
-- end_ignore
insert into x_tab select * from x_tab where exists (select * from x_tab where x_tab.a = (select x_tab.a + y_tab.a from y_tab));
select * from x_tab;
a
---
1
1
(2 rows)
--
-- Insert with Union All with an universal child
--
insert into y_tab select 1 union all select a from x_tab limit 10;
select * from y_tab;
a
---
0
1
1
1
(4 rows)
--
-- Insert with a function containing a SQL
--
create or replace function test_func_pg_stats()
returns integer
as $$ declare cnt int; begin execute 'select count(*) from pg_statistic' into cnt; return cnt; end $$
language plpgsql volatile READS SQL DATA;
insert into y_tab select test_func_pg_stats() from x_tab limit 2;
select count(*) from y_tab;
count
-------
6
(1 row)
--
-- Delete with Hash Join with a universal child
--
delete from x_tab where exists (select z_tab.a from z_tab join (select 1 as g) as tab on z_tab.a = tab.g);
select * from x_tab;
a
---
(0 rows)
-- 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);
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 bar values('person');
select * from unnest((select string_to_array(name, ',') from bar)) as a;
a
--------
person
(1 row)
-- Query should not fall back to planner and handle implicit cast properly
CREATE TYPE myint;
CREATE FUNCTION myintout(myint) RETURNS cstring AS 'int4out' LANGUAGE INTERNAL STRICT IMMUTABLE;
NOTICE: argument type myint is only a shell
CREATE FUNCTION myintin(cstring) RETURNS myint AS 'int4in' LANGUAGE INTERNAL STRICT IMMUTABLE;
NOTICE: return type myint is only a shell
CREATE TYPE myint
(
INPUT=myintin,
OUTPUT=myintout,
INTERNALLENGTH=4,
PASSEDBYVALUE
);
CREATE FUNCTION myint_int8(myint) RETURNS int8 AS 'int48' LANGUAGE INTERNAL STRICT IMMUTABLE;
CREATE CAST (myint AS int8) WITH FUNCTION myint_int8(myint) AS IMPLICIT;
CREATE TABLE csq_cast_param_outer (a int, b myint);
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 csq_cast_param_outer VALUES
(1, '42'),
(2, '12');
CREATE TABLE csq_cast_param_inner (c int, d myint);
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.
INSERT INTO csq_cast_param_inner VALUES
(11, '11'),
(101, '12');
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)
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)
-> Seq Scan on csq_cast_param_inner (cost=0.00..431.00 rows=1 width=4)
Optimizer: Pivotal 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);
a
---
1
2
(2 rows)
DROP CAST (myint as int8);
CREATE FUNCTION myint_numeric(myint) RETURNS numeric AS 'int4_numeric' LANGUAGE INTERNAL STRICT IMMUTABLE;
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)
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)
-> Seq Scan on csq_cast_param_inner (cost=0.00..431.00 rows=1 width=4)
Optimizer: Pivotal 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);
a
---
1
2
(2 rows)
SELECT a FROM ggg WHERE a IN (NULL, 'x');
a
---
x
x
x
(3 rows)
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)
Filter: (a <> ALL ('{NULL,""}'::bpchar[]))
Optimizer: Pivotal 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)
Filter: (a = ANY ('{NULL,x}'::bpchar[]))
Optimizer: Pivotal Optimizer (GPORCA)
(4 rows)
-- result node with one time filter and filter
CREATE TABLE onetimefilter1 (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 onetimefilter2 (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 onetimefilter1 SELECT i, i FROM generate_series(1,10)i;
INSERT INTO onetimefilter2 SELECT i, i FROM generate_series(1,10)i;
ANALYZE onetimefilter1;
ANALYZE onetimefilter2;
EXPLAIN (COSTS OFF) 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;
QUERY PLAN
------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Sequence
-> Shared Scan (share slice:id 1:0)
-> Hash Join
Hash Cond: (onetimefilter1.a = onetimefilter2.a)
-> Seq Scan on onetimefilter1
-> Hash
-> Seq Scan on onetimefilter2
-> Hash Join
Hash Cond: (f1.b = f2.b)
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: f1.b
-> Seq Scan on onetimefilter1 f1
-> Hash
-> Redistribute Motion 3:3 (slice3; segments: 3)
Hash Key: f2.b
-> Seq Scan on onetimefilter2 f2
SubPlan 1
-> Result
-> Limit
-> Result
One-Time Filter: (f1.b = f2.b)
-> Materialize
-> Broadcast Motion 3:3 (slice4; segments: 3)
-> Result
-> Shared Scan (share slice:id 4:0)
SubPlan 2
-> Result
-> Result
One-Time Filter: (f1.a = 2)
Filter: ((f1.a)::double precision = random())
-> Materialize
-> Broadcast Motion 3:3 (slice5; segments: 3)
-> Result
-> Shared Scan (share slice:id 5:0)
SubPlan 3
-> Result
Filter: (share0_ref3.b = f1.b)
-> Materialize
-> Broadcast Motion 3:3 (slice6; segments: 3)
-> Result
-> Shared Scan (share slice:id 6:0)
Optimizer: GPORCA
(43 rows)
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 | 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
(10 rows)
-- full joins with predicates
DROP TABLE IF EXISTS ffoo, fbar;
NOTICE: table "ffoo" does not exist, skipping
NOTICE: table "fbar" does not exist, skipping
CREATE TABLE ffoo (a, b) AS (VALUES (1, 2), (2, 3), (4, 5), (5, 6), (6, 7)) DISTRIBUTED BY (a);
CREATE TABLE fbar (c, d) AS (VALUES (1, 42), (2, 43), (4, 45), (5, 46)) DISTRIBUTED BY (c);
SELECT d FROM ffoo FULL OUTER JOIN fbar ON a = c WHERE b BETWEEN 5 and 9;
d
----
46
45
(3 rows)
-- test index left outer joins on bitmap and btree indexes on partitioned tables with and without select clause
DROP TABLE IF EXISTS touter, tinner;
NOTICE: table "touter" does not exist, skipping
NOTICE: table "tinner" does not exist, skipping
CREATE TABLE touter(a int, b int) DISTRIBUTED BY (a);
CREATE TABLE tinnerbitmap(a int, b int) DISTRIBUTED BY (a) PARTITION BY range(b) (start (0) end (6) every (3));
CREATE TABLE tinnerbtree(a int, b int) DISTRIBUTED BY (a) PARTITION BY range(b) (start (0) end (6) every (3));
INSERT INTO touter SELECT i, i%6 FROM generate_series(1,10) i;
INSERT INTO tinnerbitmap select i, i%6 FROM generate_series(1,1000) i;
INSERT INTO tinnerbtree select i, i%6 FROM generate_series(1,1000) i;
CREATE INDEX tinnerbitmap_ix ON tinnerbitmap USING bitmap(a);
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
(10 rows)
SELECT * FROM touter LEFT JOIN tinnerbitmap ON touter.a = tinnerbitmap.a AND tinnerbitmap.b=10;
a | b | a | b
----+---+---+---
2 | 2 | |
3 | 3 | |
4 | 4 | |
7 | 1 | |
8 | 2 | |
1 | 1 | |
5 | 5 | |
6 | 0 | |
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
2 | 2 | 2 | 2
7 | 1 | 7 | 1
8 | 2 | 8 | 2
3 | 3 | 3 | 3
4 | 4 | 4 | 4
(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 | |
(10 rows)
-- test subplan in a qual under dynamic scan
CREATE TABLE ds_part ( a INT, b INT, c INT) PARTITION BY RANGE(c)( START(1) END (10) EVERY (2), DEFAULT PARTITION deflt);
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 non_part1 (c INT);
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.
CREATE TABLE non_part2 (e INT, f INT);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'e' as the Apache Cloudberry data distribution key for this table.
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 ds_part SELECT i, i, i FROM generate_series (1, 1000)i;
INSERT INTO non_part1 SELECT i FROM generate_series(1, 100)i;
INSERT INTO non_part2 SELECT i, i FROM generate_series(1, 100)i;
SET optimizer_enforce_subplans TO ON;
analyze ds_part;
analyze non_part1;
analyze non_part2;
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);
a | b | c | e | 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)
Hash Cond: (ds_part.c = non_part2.e)
-> Dynamic Seq Scan on ds_part (cost=0.00..1324050.11 rows=334 width=12)
Number of partitions to scan: 6 (out of 6)
Filter: ((a = (b + 1)) AND (SubPlan 1))
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)
Filter: (f = 10)
Optimizer: Pivotal Optimizer (GPORCA)
(19 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?
----+----+----+----+----+----------
10 | 10 | 10 | 10 | 10 | f
(1 row)
CREATE INDEX ds_idx ON ds_part(a);
analyze ds_part;
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?
----+----+----+----+----+----------
10 | 10 | 10 | 10 | 10 | f
(1 row)
RESET optimizer_enforce_subplans;
-- implied predicate must be generated for the type cast(ident) scalar array cmp const array
CREATE TABLE varchar_sc_array_cmp(a 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 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
---------------------------------------------------------------------------------------------------------------
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)
-> Seq Scan on varchar_sc_array_cmp t1 (cost=0.00..431.00 rows=1 width=8)
Filter: (((a)::text = ANY ('{b,c}'::text[])) AND (a = ANY ('{b,c}'::character varying[])))
-> 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)
(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');
a | a
---+---
b | b
c | c
(2 rows)
SET optimizer_array_constraints=on;
EXPLAIN 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');
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)
-> Seq Scan on varchar_sc_array_cmp t1 (cost=0.00..431.00 rows=1 width=8)
Filter: ((((a)::text = ANY ('{b,c}'::text[])) OR ((a)::text = 'a'::text)) AND (a = ANY ('{a,b,c}'::character varying[])))
-> 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
(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
---+---
a | a
c | c
b | b
(3 rows)
DROP TABLE varchar_sc_array_cmp;
-- table constraints on nullable columns
-- start_ignore
DROP TABLE IF EXISTS tc0, tc1, tc2, tc3, tc4;
NOTICE: table "tc0" does not exist, skipping
NOTICE: table "tc1" does not exist, skipping
NOTICE: table "tc2" does not exist, skipping
NOTICE: table "tc3" does not exist, skipping
NOTICE: table "tc4" does not exist, skipping
-- end_ignore
CREATE TABLE tc0 (a int check (a = 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.
INSERT INTO tc0 VALUES (NULL);
-- FIXME: Planner gives wrong result
SELECT * from tc0 where a IS NULL;
a
---
(1 row)
CREATE TABLE tc1 (a int check (a between 1 and 2 or a != 3 and a > 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.
INSERT INTO tc1 VALUES (NULL);
SELECT * from tc1 where a IS NULL;
a
---
(1 row)
CREATE TABLE tc2 (a int check (a in (1,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.
INSERT INTO tc2 VALUES (NULL);
SELECT * from tc2 where a IS NULL;
a
---
(1 row)
set optimizer_array_constraints = on;
CREATE TABLE tc3 (a int check (a = ANY (ARRAY[1,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.
INSERT INTO tc3 VALUES (NULL);
SELECT * from tc3 where a IS NULL;
a
---
(1 row)
reset optimizer_array_constraints;
CREATE TABLE tc4 (a int, b int, check(a + b > 1 and a = 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.
INSERT INTO tc4 VALUES(NULL, NULL);
SELECT * from tc4 where a IS NULL;
a | b
---+---
|
(1 row)
CREATE EXTENSION IF NOT EXISTS citext;
drop table if exists tt, tc;
NOTICE: table "tt" does not exist, skipping
NOTICE: table "tc" does not exist, skipping
create table tc (a int, c citext) distributed by (a);
create table tt (b int, v varchar) distributed by (v);
insert into tc values (1, 'a'), (1, 'A');
insert into tt values (1, 'a'), (1, 'A');
insert into tc values (1, 'b'), (1, 'B');
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
(4 rows)
-- bitmap scan on bitmap index
create index tc_idx on tc using bitmap(c);
select * from tc where c='a';
a | c
---+---
1 | a
1 | A
(2 rows)
explain select * from tc where c='a';
QUERY PLAN
-------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..391.30 rows=1 width=12)
-> Bitmap Heap Scan on tc (cost=0.00..391.30 rows=1 width=12)
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)
(6 rows)
-- test gpexpand phase 1
-- right now, these will fall back to planner
drop table if exists noexp_hash, gpexp_hash, gpexp_rand, gpexp_repl;
NOTICE: table "noexp_hash" does not exist, skipping
NOTICE: table "gpexp_hash" does not exist, skipping
NOTICE: table "gpexp_rand" does not exist, skipping
NOTICE: table "gpexp_repl" does not exist, skipping
create table noexp_hash(a int, b int) distributed by (a);
insert into noexp_hash select i, i from generate_series(1,50) i;
analyze noexp_hash;
-- three tables that will be expanded (simulated)
create table gpexp_hash(a int, b int) distributed by (a);
create table gpexp_rand(a int, b int) distributed randomly;
create table gpexp_repl(a int, b int) distributed replicated;
-- simulate a cluster with one segment less than we have now
set allow_system_table_mods = true;
update gp_distribution_policy set numsegments = numsegments-1 where localoid = 'gpexp_hash'::regclass and numsegments > 1;
update gp_distribution_policy set numsegments = numsegments-1 where localoid = 'gpexp_rand'::regclass and numsegments > 1;
update gp_distribution_policy set numsegments = numsegments-1 where localoid = 'gpexp_repl'::regclass and numsegments > 1;
reset allow_system_table_mods;
-- populate the tables on this smaller cluster
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)
Hash Key: i.i
-> Function Scan on generate_series i (cost=0.00..10.00 rows=500 width=8)
Optimizer: Postgres query optimizer
(5 rows)
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
insert into gpexp_rand 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
insert into gpexp_repl 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
analyze gpexp_hash;
analyze gpexp_rand;
analyze gpexp_repl;
-- the segment ids in the unmodified table should have one extra number
select max(noexp_hash.gp_segment_id) - max(gpexp_hash.gp_segment_id) as expect_one
from noexp_hash, gpexp_hash;
INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner
DETAIL: Unknown error: Partially Distributed Data
expect_one
------------
1
(1 row)
-- join should have a redistribute motion for gpexp_hash
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
-----------------------------------------------------------------------------------------------------------
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)
-> Partial Aggregate (cost=3.55..3.56 rows=1 width=8)
-> Hash Join (cost=1.56..3.49 rows=25 width=0)
Hash Cond: (n.a = x.a)
-> Redistribute Motion 3:2 (slice2; segments: 3) (cost=0.00..1.58 rows=25 width=4)
Hash Key: n.a
-> Seq Scan on noexp_hash n (cost=0.00..1.17 rows=17 width=4)
-> Hash (cost=1.25..1.25 rows=25 width=4)
-> Seq Scan on gpexp_hash x (cost=0.00..1.25 rows=25 width=4)
Optimizer: Postgres query optimizer
(11 rows)
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
count
-------
50
(1 row)
delete from gpexp_hash where b between 21 and 50;
INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner
DETAIL: Unknown error: Partially Distributed Data
select count(*) from gpexp_hash;
INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner
DETAIL: Unknown error: Partially Distributed Data
count
-------
20
(1 row)
update gpexp_hash set b=-1 where b between 11 and 100;
INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner
DETAIL: Unknown error: Partially Distributed Data
select b, count(*) from gpexp_hash group by b order by b;
INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner
DETAIL: Unknown error: Partially Distributed Data
b | count
----+-------
-1 | 10
1 | 1
2 | 1
3 | 1
4 | 1
5 | 1
6 | 1
7 | 1
8 | 1
9 | 1
10 | 1
(11 rows)
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
----------------------------------------------------------------------------------------------------------
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)
SubPlan 1
-> Result (cost=0.00..4.25 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)
Optimizer: Postgres query optimizer
(9 rows)
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
select b, count(*) from gpexp_rand group by b order by b;
INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner
DETAIL: Unknown error: Partially Distributed Data
b | count
----+-------
-1 | 10
1 | 1
2 | 1
3 | 1
4 | 1
5 | 1
6 | 1
7 | 1
8 | 1
9 | 1
10 | 1
| 30
(12 rows)
delete from gpexp_repl where b >= 20;
INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner
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
--------------------------------------------------------
Insert on gpexp_repl (cost=0.00..0.01 rows=1 width=8)
-> Result (cost=0.00..0.01 rows=1 width=8)
Optimizer: Postgres query optimizer
(3 rows)
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
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
-------------------------------------------------------------------------------------------
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)
-> Partial Aggregate (cost=3.56..3.57 rows=1 width=8)
-> Hash Join (cost=1.56..3.50 rows=25 width=0)
Hash Cond: (r.a = h.a)
-> Seq Scan on gpexp_repl r (cost=0.00..1.50 rows=50 width=4)
-> Hash (cost=1.25..1.25 rows=25 width=4)
-> Seq Scan on gpexp_hash h (cost=0.00..1.25 rows=25 width=4)
Optimizer: Postgres query optimizer
(9 rows)
select count(*) as expect_20 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
expect_20
-----------
20
(1 row)
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
-----------------------------------------------------------------------------------------------------------
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)
-> Partial Aggregate (cost=3.81..3.82 rows=1 width=8)
-> Hash Join (cost=1.38..3.77 rows=17 width=0)
Hash Cond: (r.a = h.a)
-> Redistribute Motion 1:3 (slice2; segments: 1) (cost=0.00..2.17 rows=17 width=4)
Hash Key: r.a
-> Seq Scan on gpexp_repl r (cost=0.00..1.50 rows=50 width=4)
-> Hash (cost=1.17..1.17 rows=17 width=4)
-> Seq Scan on noexp_hash h (cost=0.00..1.17 rows=17 width=4)
Optimizer: Postgres query optimizer
(11 rows)
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
expect_20
-----------
20
(1 row)
create table part1(a int, b int) partition by range(b) (start(1) end(5) 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.
create table part2(a int, b int) partition by range(b) (start(1) end(5) 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.
insert into part1 select i, (i % 2) + 1 from generate_series(1, 1000) i;
insert into part2 select i, (i % 2) + 1 from generate_series(1, 100) i;
-- make sure some child partitions have not been analyzed. This just means that
-- stats are missing for some child partition but not necessarily that the relation
-- is empty. So we should not flag this as an empty relation
analyze part1_1_prt_1;
analyze part1_1_prt_2;
analyze part2_1_prt_1;
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)
-> 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 Cond: (part1.b = part2.b)
-> Dynamic Seq Scan on part1 (cost=0.00..431.01 rows=334 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)
Number of partitions to scan: 4 (out of 4)
Optimizer: Pivotal Optimizer (GPORCA)
(13 rows)
-- test opfamily handling in ORCA
CREATE FUNCTION abseq(int, int) RETURNS BOOL AS
$$
begin return abs($1) = abs($2); end;
$$ LANGUAGE plpgsql STRICT IMMUTABLE;
CREATE OPERATOR |=| (
PROCEDURE = abseq,
LEFTARG = int,
RIGHTARG = int,
COMMUTATOR = |=|,
hashes, merges);
CREATE FUNCTION abshashfunc(int) RETURNS int AS
$$
begin return hashint4(abs($1)); end;
$$ LANGUAGE plpgsql STRICT IMMUTABLE;
CREATE FUNCTION abslt(int, int) RETURNS BOOL AS
$$
begin return abs($1) < abs($2); end;
$$ LANGUAGE plpgsql STRICT IMMUTABLE;
CREATE OPERATOR |<| (
PROCEDURE = abslt,
LEFTARG = int,
RIGHTARG = int);
CREATE FUNCTION absgt(int, int) RETURNS BOOL AS
$$
begin return abs($1) > abs($2); end;
$$ LANGUAGE plpgsql STRICT IMMUTABLE;
CREATE OPERATOR |>| (
PROCEDURE = absgt,
LEFTARG = int,
RIGHTARG = int);
CREATE FUNCTION abscmp(int, int) RETURNS int AS
$$
begin return btint4cmp(abs($1),abs($2)); end;
$$ LANGUAGE plpgsql STRICT IMMUTABLE;
DROP TABLE IF EXISTS atab_old_hash;
NOTICE: table "atab_old_hash" does not exist, skipping
DROP TABLE IF EXISTS btab_old_hash;
NOTICE: table "btab_old_hash" does not exist, skipping
CREATE TABLE atab_old_hash (a int) DISTRIBUTED BY (a);
CREATE TABLE btab_old_hash (b int) DISTRIBUTED BY (b);
INSERT INTO atab_old_hash VALUES (-1), (0), (1);
INSERT INTO btab_old_hash VALUES (-1), (0), (1), (2);
ANALYZE atab_old_hash;
ANALYZE btab_old_hash;
-- Test simple join using the new operator(s) before creating the opclass/opfamily
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)
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)
-> Seq Scan on atab_old_hash (cost=0.00..431.00 rows=1 width=4)
Optimizer: Pivotal Optimizer (GPORCA) version 3.93.0
(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
(5 rows)
CREATE OPERATOR CLASS abs_int_hash_ops FOR TYPE int4
USING hash AS
OPERATOR 1 |=|,
FUNCTION 1 abshashfunc(int);
CREATE OPERATOR CLASS abs_int_btree_ops FOR TYPE int4
USING btree AS
OPERATOR 1 |<|,
OPERATOR 3 |=|,
OPERATOR 5 |>|,
FUNCTION 1 abscmp(int, int);
-- OK test different kinds of joins
EXPLAIN SELECT a, b FROM atab_old_hash INNER JOIN btab_old_hash ON a |=| b;
QUERY PLAN
------------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=5 width=8)
-> Hash Join (cost=0.00..862.00 rows=2 width=8)
Hash Cond: (btab_old_hash.b |=| atab_old_hash.a)
-> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=2 width=4)
Hash Key: btab_old_hash.b
-> Seq Scan on btab_old_hash (cost=0.00..431.00 rows=2 width=4)
-> Hash (cost=431.00..431.00 rows=1 width=4)
-> 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)
(11 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
(5 rows)
EXPLAIN SELECT a, b FROM btab_old_hash LEFT OUTER JOIN atab_old_hash ON a |=| b;
QUERY PLAN
------------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.00 rows=7 width=8)
-> Hash Left Join (cost=0.00..862.00 rows=3 width=8)
Hash Cond: (btab_old_hash.b |=| atab_old_hash.a)
-> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=2 width=4)
Hash Key: btab_old_hash.b
-> Seq Scan on btab_old_hash (cost=0.00..431.00 rows=2 width=4)
-> Hash (cost=431.00..431.00 rows=1 width=4)
-> 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)
(11 rows)
SELECT a, b FROM btab_old_hash LEFT OUTER JOIN atab_old_hash ON a |=| b;
a | b
----+----
| 2
0 | 0
-1 | 1
1 | 1
-1 | -1
1 | -1
(6 rows)
set optimizer_expand_fulljoin = on;
select disable_xform('CXformFullOuterJoin2HashJoin');
disable_xform
------------------------------------------
CXformFullOuterJoin2HashJoin is disabled
(1 row)
EXPLAIN SELECT a, b FROM atab_old_hash FULL JOIN btab_old_hash ON a |=| b;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..2586.00 rows=10 width=8)
-> Result (cost=0.00..2586.00 rows=4 width=8)
-> Sequence (cost=0.00..2586.00 rows=4 width=8)
-> Shared Scan (share slice:id 1:2) (cost=0.00..431.00 rows=2 width=1)
-> Seq Scan on btab_old_hash (cost=0.00..431.00 rows=2 width=34)
-> Sequence (cost=0.00..2155.00 rows=4 width=8)
-> Shared Scan (share slice:id 1:3) (cost=0.00..431.00 rows=1 width=1)
-> Seq Scan on atab_old_hash (cost=0.00..431.00 rows=1 width=34)
-> Append (cost=0.00..1724.00 rows=4 width=8)
-> Hash Left Join (cost=0.00..862.00 rows=3 width=8)
Hash Cond: (share2_ref2.b |=| share3_ref2.a)
-> Redistribute Motion 3:3 (slice2; segments: 3) (cost=0.00..431.00 rows=2 width=4)
Hash Key: share2_ref2.b
-> Result (cost=0.00..431.00 rows=2 width=4)
-> Shared Scan (share slice:id 2:2) (cost=0.00..431.00 rows=2 width=4)
-> Hash (cost=431.00..431.00 rows=1 width=4)
-> Redistribute Motion 3:3 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=4)
Hash Key: share3_ref2.a
-> Result (cost=0.00..431.00 rows=1 width=4)
-> 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 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
-> Result (cost=0.00..431.00 rows=1 width=4)
-> 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
-> Result (cost=0.00..431.00 rows=2 width=4)
-> Shared Scan (share slice:id 5:2) (cost=0.00..431.00 rows=2 width=4)
Optimizer: GPORCA
(32 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
(6 rows)
reset optimizer_expand_fulljoin;
-- Test rescanned materialize that is not directly above a motion
DROP TABLE IF EXISTS foo1 CASCADE;
NOTICE: table "foo1" does not exist, skipping
DROP TABLE IF EXISTS foo2 CASCADE;
NOTICE: table "foo2" does not exist, skipping
DROP TABLE IF EXISTS foo3 CASCADE;
NOTICE: table "foo3" does not exist, skipping
CREATE table foo1(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 table foo2(a int, b 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.
CREATE table foo3(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 f2c on foo2 using bitmap(c);
INSERT INTO foo1 values (1), (2);
INSERT INTO foo2 values (1,1,1), (2,2,2);
INSERT INTO foo3 values (1,1), (2,2);
ANALYZE foo1;
ANALYZE foo2;
ANALYZE foo3;
set optimizer_join_order=query;
-- we ignore enable/disable_xform statements as their output will differ if the server is compiled without Orca (the xform won't exist)
-- start_ignore
select disable_xform('CXformLeftOuterJoin2HashJoin');
disable_xform
------------------------------------------
CXformLeftOuterJoin2HashJoin is disabled
(1 row)
select disable_xform('CXformImplementInnerJoin');
disable_xform
--------------------------------------
CXformImplementInnerJoin is disabled
(1 row)
-- end_ignore
EXPLAIN SELECT 1 FROM foo1 left join foo2 on foo1.a = foo2.a AND foo2.c = 3 AND foo2.b IN (SELECT b FROM foo3);
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------
Result (cost=0.00..1721310.84 rows=2 width=4)
-> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1721310.84 rows=2 width=1)
-> Nested Loop Left Join (cost=0.00..1721310.84 rows=1 width=1)
Join Filter: (foo1.a = foo2.a)
-> Seq Scan on foo1 (cost=0.00..431.00 rows=1 width=4)
-> Materialize (cost=0.00..818.97 rows=1 width=4)
-> Hash Semi Join (cost=0.00..818.97 rows=1 width=4)
Hash Cond: (foo2.b = foo3.b)
-> Bitmap Heap Scan on foo2 (cost=0.00..387.97 rows=1 width=8)
Recheck Cond: (c = 3)
-> Bitmap Index Scan on f2c (cost=0.00..0.00 rows=0 width=0)
Index Cond: (c = 3)
-> 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)
(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);
?column?
----------
1
1
(2 rows)
reset optimizer_join_order;
-- start_ignore
select enable_xform('CXformLeftOuterJoin2HashJoin');
enable_xform
-----------------------------------------
CXformLeftOuterJoin2HashJoin is enabled
(1 row)
select enable_xform('CXformImplementInnerJoin');
enable_xform
-------------------------------------
CXformImplementInnerJoin is enabled
(1 row)
-- end_ignore
-- Test that duplicate sensitive redistributes don't have invalid projection (eg: element that can't be hashed)
drop table if exists t55;
NOTICE: table "t55" does not exist, skipping
drop table if exists tp;
NOTICE: table "tp" does not exist, skipping
create table t55 (c int, lid int);
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.
insert into t55 select i, i from generate_series(1, 1000) i;
analyze t55;
set optimizer_join_order = query;
-- force_explain
explain verbose
CREATE TABLE TP AS
WITH META AS (SELECT '2020-01-01' AS VALID_DT, '99' AS LOAD_ID)
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
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
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)
Output: c, lid
-> GroupAggregate (cost=0.00..431.07 rows=1 width=8)
Output: c, lid
Group Key: l1.c, l1.lid
-> Sort (cost=0.00..431.07 rows=1 width=8)
Output: c, lid
Sort Key: l1.c, l1.lid
-> Hash Join (cost=0.00..431.07 rows=1 width=8)
Output: c, lid
Hash Cond: (l1.lid = int4in(textout(('99'::text))))
-> Seq Scan on orca.t55 l1 (cost=0.00..431.01 rows=334 width=8)
Output: c, lid
-> Hash (cost=0.00..0.00 rows=1 width=8)
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)
CREATE TABLE TP AS
WITH META AS (SELECT '2020-01-01' AS VALID_DT, '99' AS LOAD_ID)
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.
reset optimizer_join_order;
SELECT * from tp;
c | lid
----+-----
99 | 99
(1 row)
-- Test partition selection for lossy casts
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
-----------------------------------------------------------------------------------
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)
(5 rows)
select * from lossycastrangepart where b::int = 10;
a | b
------+------
10.1 | 10.1
9.9 | 9.9
(2 rows)
explain select * from lossycastrangepart where b::int = 11;
QUERY PLAN
-----------------------------------------------------------------------------------
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)
(5 rows)
select * from lossycastrangepart where b::int = 11;
a | b
------+------
10.9 | 10.9
11.1 | 11.1
(2 rows)
explain select * from lossycastrangepart where b::int < 10;
QUERY PLAN
-----------------------------------------------------------------------------------
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)
(5 rows)
select * from lossycastrangepart where b::int < 10;
a | b
-----+-----
9.1 | 9.1
5.1 | 5.1
(2 rows)
explain select * from lossycastrangepart where b::int < 11;
QUERY PLAN
-----------------------------------------------------------------------------------
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)
(5 rows)
select * from lossycastrangepart where b::int < 11;
a | b
------+------
9.1 | 9.1
10.1 | 10.1
5.1 | 5.1
9.9 | 9.9
(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
----------------------------------------------------------------------------------
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)
(5 rows)
select * from lossycastlistpart where b::int < 2;
a | b
---+-----
1 | 1.3
(1 row)
explain select * from lossycastlistpart where b::int = 2;
QUERY PLAN
----------------------------------------------------------------------------------
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)
(5 rows)
select * from lossycastlistpart where b::int = 2;
a | b
----+-----
11 | 1.8
10 | 2.1
21 | 1.7
1 | 2.1
(4 rows)
--Test lossy casted NEQ on range partitioned table
drop table if exists sales;
create table sales(id int, prod_id int, cust_id int, sales_ts timestamp)
partition by range(sales_ts) (start (timestamp '2010-01-01 00:00:00') end(timestamp '2010-02-02 23:59:59')
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
----+---------+---------+--------------------------
1 | 1 | 1 | Sat Jan 02 00:00:00 2010
2 | 2 | 2 | Sun Jan 03 00:00:00 2010
3 | 3 | 3 | Mon Jan 04 00:00:00 2010
5 | 5 | 5 | Wed Jan 06 00:00:00 2010
6 | 6 | 6 | Thu Jan 07 00:00:00 2010
7 | 7 | 7 | Fri Jan 08 00:00:00 2010
8 | 8 | 8 | Sat Jan 09 00:00:00 2010
9 | 9 | 9 | Sun Jan 10 00:00:00 2010
10 | 10 | 10 | Mon Jan 11 00:00:00 2010
11 | 11 | 11 | Tue Jan 12 00:00:00 2010
12 | 12 | 12 | Wed Jan 13 00:00:00 2010
13 | 13 | 13 | Thu Jan 14 00:00:00 2010
14 | 14 | 14 | Fri Jan 15 00:00:00 2010
15 | 15 | 15 | Sat Jan 16 00:00:00 2010
16 | 16 | 16 | Sun Jan 17 00:00:00 2010
17 | 17 | 17 | Mon Jan 18 00:00:00 2010
18 | 18 | 18 | Tue Jan 19 00:00:00 2010
19 | 19 | 19 | Wed Jan 20 00:00:00 2010
20 | 20 | 20 | Thu Jan 21 00:00:00 2010
(19 rows)
-- validate lossy cast logic can handle BCCs
drop table if exists part_tbl_varchar;
NOTICE: table "part_tbl_varchar" does not exist, skipping
CREATE TABLE part_tbl_varchar(a varchar(15) NOT NULL, b varchar(8) NOT NULL)
DISTRIBUTED BY (a)
PARTITION BY RANGE(b) (start('v1') end('v5'), start('v5') end('v9'), default partition def);
insert into part_tbl_varchar values ('v3','v3'), ('v5','v5');
select * from part_tbl_varchar where b between 'v3' and 'v4';
a | b
----+----
v3 | v3
(1 row)
-- test n-ary inner and left joins with outer references
drop table if exists tcorr1, tcorr2;
NOTICE: table "tcorr1" does not exist, skipping
NOTICE: table "tcorr2" does not exist, skipping
create table tcorr1(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 tcorr2(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 tcorr1 values (1,99);
insert into tcorr2 values (1,1);
analyze tcorr1;
analyze tcorr2;
explain
select *
from tcorr1 out
where out.b in (select coalesce(tcorr2.a, 99)
from tcorr1 left outer join tcorr2 on tcorr1.a=tcorr2.a+out.a);
QUERY PLAN
--------------------------------------------------------------------------------------------------
Result (cost=0.00..1356692031.36 rows=1 width=8)
Filter: (SubPlan 1)
-> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=8)
-> Seq Scan on tcorr1 "out" (cost=0.00..431.00 rows=1 width=8)
SubPlan 1
-> Nested Loop Left Join (cost=0.00..1324032.56 rows=2 width=4)
Join Filter: (tcorr1.a = (tcorr2.a + "out".a))
-> Materialize (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)
-> Seq Scan on tcorr1 (cost=0.00..431.00 rows=1 width=4)
-> 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)
(14 rows)
-- expect 1 row
select *
from tcorr1 out
where out.b in (select coalesce(tcorr2.a, 99)
from tcorr1 left outer join tcorr2 on tcorr1.a=tcorr2.a+out.a);
a | b
---+----
1 | 99
(1 row)
explain
select *
from tcorr1 out
where out.b in (select max(tcorr2.b + out.b - 1)
from tcorr2
where tcorr2.a=out.a);
QUERY PLAN
--------------------------------------------------------------------------------------------------------
Result (cost=0.00..1324032.63 rows=1 width=8)
Filter: (SubPlan 1)
-> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=8)
-> Seq Scan on tcorr1 "out" (cost=0.00..431.00 rows=1 width=8)
SubPlan 1
-> Aggregate (cost=0.00..431.00 rows=1 width=4)
-> Result (cost=0.00..431.00 rows=1 width=4)
Filter: (tcorr2.a = "out".a)
-> 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)
(12 rows)
-- expect 1 row
select *
from tcorr1 out
where out.b in (select max(tcorr2.b + out.b - 1)
from tcorr2
where tcorr2.a=out.a);
a | b
---+----
1 | 99
(1 row)
explain
select *
from tcorr1 out
where out.b in (select coalesce(tcorr2_d.c, 99)
from tcorr1 left outer join (select a, count(*) as c
from tcorr2
where tcorr2.b = out.b
group by a) tcorr2_d on tcorr1.a=tcorr2_d.a);
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------
Result (cost=0.00..1356692228.44 rows=1 width=8)
Filter: (SubPlan 1)
-> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=8)
-> Seq Scan on tcorr1 "out" (cost=0.00..431.00 rows=1 width=8)
SubPlan 1
-> Nested Loop Left Join (cost=0.00..1324032.75 rows=3 width=8)
Join Filter: (tcorr1.a = tcorr2.a)
-> Materialize (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)
-> Seq Scan on tcorr1 (cost=0.00..431.00 rows=1 width=4)
-> GroupAggregate (cost=0.00..431.00 rows=1 width=12)
Group Key: tcorr2.a
-> Sort (cost=0.00..431.00 rows=1 width=4)
Sort Key: tcorr2.a
-> Result (cost=0.00..431.00 rows=1 width=4)
Filter: (tcorr2.b = "out".b)
-> 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)
(20 rows)
-- expect 1 row
select *
from tcorr1 out
where out.b in (select coalesce(tcorr2_d.c, 99)
from tcorr1 left outer join (select a, count(*) as c
from tcorr2
where tcorr2.b = out.b
group by a) tcorr2_d on tcorr1.a=tcorr2_d.a);
a | b
---+----
1 | 99
(1 row)
-- expect 1 row
select *
from tcorr1 out
where out.b in (select coalesce(tcorr2.a, 99)
from tcorr1 full outer join tcorr2 on tcorr1.a=tcorr2.a+out.a);
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
a | b
---+----
1 | 99
(1 row)
set optimizer_join_order to exhaustive2;
explain
select *
from tcorr1 out
where out.b in (select coalesce(tcorr2.a, 99)
from tcorr1 left outer join tcorr2 on tcorr1.a=tcorr2.a+out.a);
QUERY PLAN
--------------------------------------------------------------------------------------------------
Result (cost=0.00..1356692031.36 rows=1 width=8)
Filter: (SubPlan 1)
-> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=8)
-> Seq Scan on tcorr1 "out" (cost=0.00..431.00 rows=1 width=8)
SubPlan 1
-> Nested Loop Left Join (cost=0.00..1324032.56 rows=2 width=4)
Join Filter: (tcorr1.a = (tcorr2.a + "out".a))
-> Materialize (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)
-> Seq Scan on tcorr1 (cost=0.00..431.00 rows=1 width=4)
-> 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)
(14 rows)
-- expect 1 row
select *
from tcorr1 out
where out.b in (select coalesce(tcorr2.a, 99)
from tcorr1 left outer join tcorr2 on tcorr1.a=tcorr2.a+out.a);
a | b
---+----
1 | 99
(1 row)
explain
select *
from tcorr1 out
where out.b in (select max(tcorr2.b + out.b - 1)
from tcorr2
where tcorr2.a=out.a);
QUERY PLAN
--------------------------------------------------------------------------------------------------------
Result (cost=0.00..1324032.63 rows=1 width=8)
Filter: (SubPlan 1)
-> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=8)
-> Seq Scan on tcorr1 "out" (cost=0.00..431.00 rows=1 width=8)
SubPlan 1
-> Aggregate (cost=0.00..431.00 rows=1 width=4)
-> Result (cost=0.00..431.00 rows=1 width=4)
Filter: (tcorr2.a = "out".a)
-> 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)
(12 rows)
-- expect 1 row
select *
from tcorr1 out
where out.b in (select max(tcorr2.b + out.b - 1)
from tcorr2
where tcorr2.a=out.a);
a | b
---+----
1 | 99
(1 row)
explain
select *
from tcorr1 out
where out.b in (select coalesce(tcorr2_d.c, 99)
from tcorr1 left outer join (select a, count(*) as c
from tcorr2
where tcorr2.b = out.b
group by a) tcorr2_d on tcorr1.a=tcorr2_d.a);
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------
Result (cost=0.00..1356692228.44 rows=1 width=8)
Filter: (SubPlan 1)
-> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=8)
-> Seq Scan on tcorr1 "out" (cost=0.00..431.00 rows=1 width=8)
SubPlan 1
-> Nested Loop Left Join (cost=0.00..1324032.75 rows=3 width=8)
Join Filter: (tcorr1.a = tcorr2.a)
-> Materialize (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)
-> Seq Scan on tcorr1 (cost=0.00..431.00 rows=1 width=4)
-> GroupAggregate (cost=0.00..431.00 rows=1 width=12)
Group Key: tcorr2.a
-> Sort (cost=0.00..431.00 rows=1 width=4)
Sort Key: tcorr2.a
-> Result (cost=0.00..431.00 rows=1 width=4)
Filter: (tcorr2.b = "out".b)
-> 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)
(20 rows)
-- expect 1 row
select *
from tcorr1 out
where out.b in (select coalesce(tcorr2_d.c, 99)
from tcorr1 left outer join (select a, count(*) as c
from tcorr2
where tcorr2.b = out.b
group by a) tcorr2_d on tcorr1.a=tcorr2_d.a);
a | b
---+----
1 | 99
(1 row)
-- expect 1 row
select *
from tcorr1 out
where out.b in (select coalesce(tcorr2.a, 99)
from tcorr1 full outer join tcorr2 on tcorr1.a=tcorr2.a+out.a);
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
a | b
---+----
1 | 99
(1 row)
reset optimizer_join_order;
-- test selecting an outer ref from a scalar subquery
-- expect 0 rows
SELECT 1
FROM tcorr1
WHERE tcorr1.a IS NULL OR
tcorr1.a = (SELECT tcorr1.a
FROM (SELECT rtrim(tcorr1.a::text) AS userid,
rtrim(tcorr1.b::text) AS part_pls
FROM tcorr2) al
WHERE 3 = tcorr1.a
);
?column?
----------
(0 rows)
-- expect 1 row, subquery returns a row
select * from tcorr1 where b = (select tcorr1.b from tcorr2);
a | b
---+----
1 | 99
(1 row)
-- expect 0 rows, subquery returns no rows
select * from tcorr1 where b = (select tcorr1.b from tcorr2 where b=33);
a | b
---+---
(0 rows)
-- expect 1 row, subquery returns nothing, so a < 22 is true
select * from tcorr1 where a < coalesce((select tcorr1.a from tcorr2 where a = 11), 22);
a | b
---+----
1 | 99
(1 row)
-- test join to index get apply xform
drop table if exists foo, tbtree, tbitmap;
NOTICE: table "tbtree" does not exist, skipping
NOTICE: table "tbitmap" does not exist, skipping
create table foo(a int, b int, c int) distributed by(a);
create table tbtree(a int, b int, c int) distributed by(a);
create table tbitmap(a int, b int, c int) distributed by(a);
insert into foo select i*1000,i*1000,i*1000 from generate_series(1,10) i;
insert into tbtree select i,i,i from generate_series(1,100000) i;
insert into tbitmap select i,i,i from generate_series(1,100000) i;
-- insert a duplicate value for a=2000
insert into tbtree values (2000,-1,-1);
insert into tbitmap values (2000,-1,-1);
create index tbtreexa on tbtree using btree(a);
create index tbitmapxa on tbitmap using bitmap(a);
analyze foo;
analyze tbtree;
analyze tbitmap;
set optimizer_join_order = query;
set optimizer_enable_hashjoin = off;
set optimizer_enable_groupagg = off;
set enable_sort = off;
-- 1 simple btree
explain (costs off)
select * from foo join tbtree on foo.a=tbtree.a;
QUERY PLAN
-------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop
Join Filter: true
-> Seq Scan on foo
-> Index Scan using tbtreexa on tbtree
Index Cond: (a = foo.a)
Optimizer: Pivotal Optimizer (GPORCA)
(7 rows)
select * from foo join tbtree on foo.a=tbtree.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
(11 rows)
-- 2 simple bitmap
explain (costs off)
select * from foo join tbitmap on foo.a=tbitmap.a;
QUERY PLAN
--------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop
Join Filter: true
-> Seq Scan on foo
-> Bitmap Heap Scan on tbitmap
Recheck Cond: (a = foo.a)
-> Bitmap Index Scan on tbitmapxa
Index Cond: (a = foo.a)
Optimizer: Pivotal Optimizer (GPORCA)
(9 rows)
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
(11 rows)
-- 3 btree with select pred
explain (costs off)
select * from foo join tbtree on foo.a=tbtree.a where tbtree.a < 5000;
QUERY PLAN
--------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop
Join Filter: true
-> Seq Scan on foo
Filter: (a < 5000)
-> Index Scan using tbtreexa on tbtree
Index Cond: ((a = foo.a) AND (a < 5000))
Optimizer: Pivotal 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
(5 rows)
-- 4 bitmap with select pred
explain (costs off)
select * from foo join tbitmap on foo.a=tbitmap.a where tbitmap.a < 5000;
QUERY PLAN
--------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop
Join Filter: true
-> Seq Scan on foo
Filter: (a < 5000)
-> Bitmap Heap Scan on 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)
(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
(5 rows)
-- 5 btree with project
explain (costs off)
select * from foo join (select a, b+c as bc from tbtree) proj on foo.a=proj.a;
QUERY PLAN
-------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop
Join Filter: true
-> Seq Scan on foo
-> Index Scan using tbtreexa on tbtree
Index Cond: (a = foo.a)
Optimizer: Pivotal Optimizer (GPORCA)
(7 rows)
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
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
(11 rows)
-- 6 bitmap with project
explain (costs off)
select * from foo join (select a, b+c as bc from tbitmap) proj on foo.a=proj.a;
QUERY PLAN
--------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop
Join Filter: true
-> Seq Scan on foo
-> Bitmap Heap Scan on tbitmap
Recheck Cond: (a = foo.a)
-> Bitmap Index Scan on tbitmapxa
Index Cond: (a = foo.a)
Optimizer: Pivotal 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
(11 rows)
-- 7 btree with grby
explain (costs off)
select * from foo join (select a, count(*) as cnt from tbtree group by a,b) grby on foo.a=grby.a;
QUERY PLAN
-------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop
Join Filter: true
-> Seq Scan on foo
-> HashAggregate
Group Key: tbtree.a, tbtree.b
-> Index Scan using tbtreexa on tbtree
Index Cond: (a = foo.a)
Optimizer: Pivotal 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;
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
(11 rows)
-- 8 bitmap with grby
explain (costs off)
select * from foo join (select a, count(*) as cnt from tbitmap group by a) grby on foo.a=grby.a;
QUERY PLAN
--------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop
Join Filter: true
-> Seq Scan on foo
-> HashAggregate
Group Key: tbitmap.a
-> Bitmap Heap Scan on tbitmap
Recheck Cond: (a = foo.a)
-> Bitmap Index Scan on tbitmapxa
Index Cond: (a = foo.a)
Optimizer: Pivotal 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
3000 | 3000 | 3000 | 3000 | 1
4000 | 4000 | 4000 | 4000 | 1
9000 | 9000 | 9000 | 9000 | 1
10000 | 10000 | 10000 | 10000 | 1
(10 rows)
-- 9 btree with proj select grby select
explain (costs off)
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;
QUERY PLAN
--------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop
Join Filter: true
-> Seq Scan on foo
Filter: (a < 5000)
-> Result
Filter: ((count(*)) < 2)
-> HashAggregate
Group Key: tbtree.a
-> Index Scan using tbtreexa on tbtree
Index Cond: ((a = foo.a) AND (a < 5000))
Optimizer: Pivotal 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
(3 rows)
-- 10 bitmap with proj select grby select
explain (costs off)
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;
QUERY PLAN
--------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop
Join Filter: true
-> Seq Scan on foo
Filter: (a < 5000)
-> Result
Filter: ((count(*)) < 2)
-> HashAggregate
Group Key: tbitmap.a
-> Bitmap Heap Scan on 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)
(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;
a | b | c | a | cnt
------+------+------+------+-----
1000 | 1000 | 1000 | 1000 | 6
3000 | 3000 | 3000 | 3000 | 6
4000 | 4000 | 4000 | 4000 | 6
(3 rows)
-- 11 bitmap with two groupbys
explain (costs off)
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;
QUERY PLAN
--------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop
Join Filter: true
-> Seq Scan on foo
-> HashAggregate
Group Key: tbitmap.a
-> HashAggregate
Group Key: tbitmap.a, tbitmap.b
-> Bitmap Heap Scan on tbitmap
Recheck Cond: (a = foo.a)
-> Bitmap Index Scan on tbitmapxa
Index Cond: (a = foo.a)
Optimizer: Pivotal 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
(10 rows)
-- 12 btree with proj select 2*grby select
explain (costs off)
select * from foo join (select a, count(*) + cnt1 as cnt2 from (select a, count(*) as cnt1 from tbtree group by a) grby1
where grby1.a < 5000 group by a, cnt1 having count(*) < 2) proj_sel_grby_sel
on foo.a=proj_sel_grby_sel.a;
QUERY PLAN
--------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop
Join Filter: true
-> Seq Scan on foo
Filter: (a < 5000)
-> Result
Filter: ((count(*)) < 2)
-> HashAggregate
Group Key: tbtree.a, count(*)
-> HashAggregate
Group Key: tbtree.a
-> Index Scan using tbtreexa on tbtree
Index Cond: ((a = foo.a) AND (a < 5000))
Optimizer: Pivotal 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
where grby1.a < 5000 group by a, cnt1 having count(*) < 2) proj_sel_grby_sel
on foo.a=proj_sel_grby_sel.a;
a | b | c | a | cnt2
------+------+------+------+------
1000 | 1000 | 1000 | 1000 | 2
2000 | 2000 | 2000 | 2000 | 3
3000 | 3000 | 3000 | 3000 | 2
4000 | 4000 | 4000 | 4000 | 2
(4 rows)
-- 13 join pred accesses a projected column - no index scan
explain (costs off)
select * from foo join (select a, a::bigint*a::bigint as aa from tbtree) proj on foo.a=proj.a and foo.b=proj.aa;
QUERY PLAN
-----------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop
Join Filter: ((foo.a = tbtree.a) AND (foo.b = (((tbtree.a)::bigint * (tbtree.a)::bigint))))
-> Seq Scan on foo
-> Materialize
-> Seq Scan on tbtree
Optimizer: Pivotal Optimizer (GPORCA)
(6 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
--------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop
Join Filter: ((foo.a = tbitmap.a) AND (foo.b = (count(*))))
-> Seq Scan on foo
-> HashAggregate
Group Key: tbitmap.a
-> Seq Scan on tbitmap
Optimizer: Pivotal Optimizer (GPORCA)
(8 rows)
-- 15 the potential index join itself contains outer refs - no index scan
explain (costs off)
select *
from foo l1 where b in (select ab
from foo l2 join (select *, l1.a+tbtree.b as ab from tbtree) tbtree_derived
on l2.a=tbtree_derived.a and l2.b=tbtree_derived.b
where l2.c = 1
);
QUERY PLAN
--------------------------------------------------------------------------
Result
Filter: (SubPlan 1)
-> Gather Motion 3:1 (slice1; segments: 3)
-> Seq Scan on foo l1
SubPlan 1
-> Nested Loop
Join Filter: ((l2.a = tbtree.a) AND (l2.b = tbtree.b))
-> Materialize
-> Gather Motion 3:1 (slice3; segments: 3)
-> Seq Scan on foo l2
Filter: (c = 1)
-> Materialize
-> Result
-> Materialize
-> Gather Motion 3:1 (slice2; segments: 3)
-> Seq Scan on tbtree
Optimizer: Pivotal Optimizer (GPORCA)
(17 rows)
-- 16 group by columns are not a superset of the distribution columns - no index scan
explain (costs off)
select * from foo join (select b, count(*) as cnt from tbtree group by b) grby on foo.a=grby.cnt;
QUERY PLAN
------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop
Join Filter: (foo.a = (count(*)))
-> Broadcast Motion 3:3 (slice3; segments: 3)
-> Seq Scan on foo
-> Materialize
-> HashAggregate
Group Key: tbtree.b
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: tbtree.b
-> Seq Scan on tbtree
Optimizer: Pivotal Optimizer (GPORCA)
(12 rows)
-- 17 group by columns don't intersect - no index scan
explain (costs off)
select * from foo join (select min_a, count(*) as cnt from (select min(a) as min_a, b from tbitmap group by b) grby1 group by min_a) grby2 on foo.a=grby2.min_a;
QUERY PLAN
------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop
Join Filter: (foo.a = (min(tbitmap.a)))
-> Seq Scan on foo
-> Materialize
-> Finalize HashAggregate
Group Key: (min(tbitmap.a))
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: (min(tbitmap.a))
-> Streaming Partial HashAggregate
Group Key: min(tbitmap.a)
-> HashAggregate
Group Key: tbitmap.b
-> Redistribute Motion 3:3 (slice3; segments: 3)
Hash Key: tbitmap.b
-> Seq Scan on tbitmap
Optimizer: Pivotal Optimizer (GPORCA)
(17 rows)
reset optimizer_join_order;
reset optimizer_enable_hashjoin;
reset optimizer_enable_groupagg;
-- ROJ must use the hash side for deriving the distribution spec. Force a non-redistribute plan to ensure we get some motion (gather)
create table roj1 (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 roj2 (c int, d int) ;
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.
insert into roj1 values (1, 1);
insert into roj1 values (2, 2);
insert into roj2 select null,null from generate_series(1,10) ;
analyze roj1;
analyze roj2;
set optimizer_enable_motion_redistribute=off;
select count(*), t2.c from roj1 t1 left join roj2 t2 on t1.a = t2.c group by t2.c;
count | c
-------+---
2 |
(1 row)
explain (costs off) select count(*), t2.c from roj1 t1 left join roj2 t2 on t1.a = t2.c group by t2.c;
QUERY PLAN
------------------------------------------------------------------
GroupAggregate
Group Key: t2.c
-> Sort
Sort Key: t2.c
-> Hash Right Join
Hash Cond: (t2.c = t1.a)
-> Gather Motion 3:1 (slice1; segments: 3)
-> Seq Scan on roj2 t2
-> Hash
-> Gather Motion 3:1 (slice2; segments: 3)
-> Seq Scan on roj1 t1
Optimizer: Pivotal Optimizer (GPORCA)
(12 rows)
-- check that ROJ can be disabled via GUC
set optimizer_enable_right_outer_join=off;
explain (costs off) select count(*), t2.c from roj1 t1 left join roj2 t2 on t1.a = t2.c group by t2.c;
QUERY PLAN
------------------------------------------------------------------
GroupAggregate
Group Key: t2.c
-> Sort
Sort Key: t2.c
-> Hash Left Join
Hash Cond: (t1.a = t2.c)
-> Gather Motion 3:1 (slice1; segments: 3)
-> Seq Scan on roj1 t1
-> Hash
-> Gather Motion 3:1 (slice2; segments: 3)
-> Seq Scan on roj2 t2
Optimizer: GPORCA
(12 rows)
reset optimizer_enable_right_outer_join;
reset optimizer_enable_motion_redistribute;
reset enable_sort;
-- simple check for btree indexes on AO tables
create table t_ao_btree(a int, b int)
with (appendonly=true, orientation=row)
distributed by(a);
create table tpart_ao_btree(a int, b int)
with (appendonly=true, orientation=row)
distributed by(a)
partition by range(b) (start(0) end(50000) with(appendonly=true, orientation=row),
start(50000) end(100000) with(appendonly=true, orientation=row));
create table tpart_dim(a int, b int)
distributed by(a);
insert into t_ao_btree select i, i%100000 from generate_series(1,100000) i;
insert into tpart_ao_btree select i, i%100000 from generate_series(1,100000) i;
insert into tpart_dim select i, i from generate_series(1,100) i;
create index tpart_ao_btree_ix on tpart_ao_btree using btree(a,b);
create index t_ao_btree_ix on t_ao_btree using btree(a,b);
analyze t_ao_btree;
analyze tpart_ao_btree;
analyze tpart_dim;
set optimizer_enable_hashjoin to off;
-- this should use a bitmap scan on the btree index
select * from t_ao_btree where a = 3 and b = 3;
a | b
---+---
3 | 3
(1 row)
select * from tpart_ao_btree where a = 3 and b = 3;
a | b
---+---
3 | 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
---------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop
Join Filter: true
-> Seq Scan on tpart_dim d
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)
explain (costs off) select * from tpart_dim d join tpart_ao_btree f on d.a=f.a where d.b=1;
QUERY PLAN
----------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop
Join Filter: true
-> Seq Scan on tpart_dim d
Filter: (b = 1)
-> 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)
(9 rows)
-- negative test, make sure we don't use a btree scan on an AO table
-- start_ignore
select disable_xform('CXformSelect2BitmapBoolOp');
disable_xform
---------------------------------------
CXformSelect2BitmapBoolOp is disabled
(1 row)
select disable_xform('CXformSelect2DynamicBitmapBoolOp');
disable_xform
----------------------------------------------
CXformSelect2DynamicBitmapBoolOp is disabled
(1 row)
select disable_xform('CXformJoin2BitmapIndexGetApply');
disable_xform
--------------------------------------------
CXformJoin2BitmapIndexGetApply is disabled
(1 row)
set optimizer_enable_nljoin=off;
-- end_ignore
-- Make sure we don't allow a regular (btree) index scan or index join for an AO table
-- We disabled hash join, and bitmap index joins, NLJs, so this should leave ORCA no other choices
-- expect a sequential scan, not an index scan, from these two queries
explain (costs off) select * from t_ao_btree where a = 3 and b = 3;
QUERY PLAN
---------------------------------------------------------
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)
(4 rows)
explain (costs off) select * from tpart_ao_btree where a = 3 and b = 3;
QUERY PLAN
----------------------------------------------------------------------
Gather Motion 1:1 (slice1; segments: 1)
-> 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)
(5 rows)
select * from tpart_dim d join t_ao_btree f on d.a=f.a where d.b=1;
a | b | a | b
---+---+---+---
1 | 1 | 1 | 1
(1 row)
select * from tpart_dim d join tpart_ao_btree f on d.a=f.a where d.b=1;
a | b | a | b
---+---+---+---
1 | 1 | 1 | 1
(1 row)
-- start_ignore
select enable_xform('CXformSelect2BitmapBoolOp');
enable_xform
--------------------------------------
CXformSelect2BitmapBoolOp is enabled
(1 row)
select enable_xform('CXformSelect2DynamicBitmapBoolOp');
enable_xform
---------------------------------------------
CXformSelect2DynamicBitmapBoolOp is enabled
(1 row)
select enable_xform('CXformJoin2BitmapIndexGetApply');
enable_xform
-------------------------------------------
CXformJoin2BitmapIndexGetApply is enabled
(1 row)
reset optimizer_enable_nljoin;
-- end_ignore
reset optimizer_enable_hashjoin;
-- Tests converted from MDPs that use tables partitioned on text columns and similar types,
-- which can't be handled in ORCA MDPs, since they would require calling the GPDB executor
-- GroupingOnSameTblCol-2.mdp
-- from dxl
create table asset_records(
uid varchar,
hostname varchar,
active boolean,
os varchar,
vendor varchar,
asset_type varchar,
create_ts timestamp
)
with (appendonly=true)
distributed by (hostname)
partition by range(create_ts) (start('2000-01-01') end('2005-01-01') every(interval '1' year));
create table coverage(
date timestamp,
hostname varchar,
vendor_sla int
)
with (appendonly=true)
distributed by (hostname);
insert into asset_records
select 'u', 'h'||i::text, false, 'o', 'v', 'a', timestamp '2000-03-01 00:00:00' + i * interval '1' minute
from generate_series(1,100000) i;
analyze asset_records;
explain (costs off)
select asset_records.uid, asset_records.hostname, asset_records.asset_type, asset_records.os, asset_records.create_ts, 1
from asset_records left join coverage
on upper(asset_records.hostname::text) = upper(coverage.hostname::text)
and asset_records.create_ts = coverage.date
and (asset_type::text = 'xx' or asset_type::text = 'yy')
and asset_records.active
where upper(coalesce(vendor, 'none')::text) <> 'some_vendor' and vendor_sla is not null
group by asset_records.uid, asset_records.hostname, asset_records.asset_type, asset_records.os, asset_records.create_ts;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Result
-> Gather Motion 3:1 (slice1; segments: 3)
-> GroupAggregate
Group Key: asset_records.uid, asset_records.hostname, asset_records.asset_type, asset_records.os, asset_records.create_ts
-> Sort
Sort Key: asset_records.uid, asset_records.hostname, asset_records.asset_type, asset_records.os, asset_records.create_ts
-> Hash Join
Hash Cond: ((upper((asset_records.hostname)::text) = upper((coverage.hostname)::text)) AND (asset_records.create_ts = coverage.date))
-> Dynamic Seq Scan on asset_records
Number of partitions to scan: 5 (out of 5)
Filter: ((upper((COALESCE(vendor, 'none'::character varying))::text) <> 'some_vendor'::text) AND (((asset_type)::text = 'xx'::text) OR ((asset_type)::text = 'yy'::text)) AND active)
-> Hash
-> Partition Selector (selector id: $0)
-> Broadcast Motion 3:3 (slice2; segments: 3)
-> Seq Scan on coverage
Filter: (NOT (vendor_sla IS NULL))
Optimizer: Pivotal Optimizer (GPORCA)
(17 rows)
-- IndexApply-PartResolverExpand.mdp
-- from comment
create table x ( i text, j text, k text, m text) distributed by (i) ;
create table y ( i text, j text, k text, m text) distributed by (j)
PARTITION BY RANGE(i)
( partition p0 end('a') exclusive,
partition p1 start('a') inclusive end('i') exclusive,
partition p2 start('i') inclusive end('q') exclusive,
partition p3 start('q') inclusive end('x'),
default partition def);
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
---------------------------------------------------------------
Aggregate
-> Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop
Join Filter: true
-> Broadcast Motion 3:3 (slice2; segments: 3)
-> Seq Scan on x
-> Dynamic Index Scan on y_idx on y
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)
(11 rows)
reset optimizer_enable_indexjoin;
-- InferPredicatesBCC-vcpart-txt.mdp
-- from comment
create table infer_txt (a text);
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 infer_txt select * from generate_series(1,1000);
analyze infer_txt;
CREATE TABLE infer_part_vc (id int, gender varchar(1))
DISTRIBUTED BY (id)
PARTITION BY LIST (gender)
( PARTITION girls VALUES ('F'),
PARTITION boys VALUES ('M'),
DEFAULT PARTITION other );
insert into infer_part_vc select i, substring(i::varchar, 1, 1) from generate_series(1, 1000) i;
analyze infer_part_vc;
explain (costs off) select * from infer_part_vc inner join infer_txt on (infer_part_vc.gender = infer_txt.a) and infer_txt.a = 'M';
QUERY PLAN
---------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Hash Join
Hash Cond: ((infer_part_vc.gender)::text = infer_txt.a)
-> Dynamic Seq Scan on infer_part_vc
Number of partitions to scan: 1 (out of 3)
Filter: ((gender)::text = 'M'::text)
-> Hash
-> Partition Selector (selector id: $0)
-> Broadcast Motion 3:3 (slice2; segments: 3)
-> Seq Scan on infer_txt
Filter: (a = 'M'::text)
Optimizer: Pivotal Optimizer (GPORCA)
(12 rows)
-- NewBtreeIndexScanCost.mdp
-- from comment
CREATE TABLE oip (
id bigint NOT NULL,
oid bigint,
cidr inet NOT NULL,
state smallint,
asn text,
cc text,
expire timestamp without time zone NOT NULL,
ts timestamp without time zone NOT NULL,
metadata json
) DISTRIBUTED BY (id);
CREATE TABLE ria (
id bigint NOT NULL,
ip inet,
file_id bigint DEFAULT (-1),
auth_filter_id bigint,
oid bigint,
event_id bigint,
ip_source inet,
arecord inet,
subdomain text,
asn character varying,
cc character varying,
ts timestamp without time zone,
filter_match smallint,
filter_match_id bigint
) DISTRIBUTED BY (id);
explain (costs off) select * from oip oip join ria a on ip=cidr and oip.oid=194073;
QUERY PLAN
------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Hash Join
Hash Cond: (a.ip = oip.cidr)
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: a.ip
-> Seq Scan on ria a
-> Hash
-> Redistribute Motion 3:3 (slice3; segments: 3)
Hash Key: oip.cidr
-> Seq Scan on oip
Filter: (oid = 194073)
Optimizer: Pivotal Optimizer (GPORCA)
(12 rows)
-- PartTbl-ArrayCoerce.mdp
-- from comment
CREATE TABLE pt (id int, gender varchar(2))
DISTRIBUTED BY (id)
PARTITION BY LIST (gender)
( PARTITION girls VALUES ('F', NULL),
PARTITION boys VALUES ('M'),
DEFAULT PARTITION other );
explain (costs off) select * from pt where gender in ( 'F', 'FM');
QUERY PLAN
-----------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> 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)
(5 rows)
-- PartTbl-List-DPE-Varchar-Predicates.mdp
-- from comment
-- reuse DDL from previous test case
explain (costs off)
select * from pt where gender = 'F' union all
select * from pt where gender <= 'M' union all
select * from pt where gender in ('F', 'FM') union all
select * from pt where gender is null;
QUERY PLAN
-----------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Append
-> Dynamic Seq Scan on pt
Number of partitions to scan: 1 (out of 3)
Filter: ((gender)::text = 'F'::text)
-> Dynamic Seq Scan on pt pt_1
Number of partitions to scan: 3 (out of 3)
Filter: ((gender)::text <= 'M'::text)
-> Dynamic Seq Scan on pt pt_2
Number of partitions to scan: 2 (out of 3)
Filter: ((gender)::text = ANY ('{F,FM}'::text[]))
-> Dynamic Seq Scan on pt pt_3
Number of partitions to scan: 1 (out of 3)
Filter: (gender IS NULL)
Optimizer: Pivotal Optimizer (GPORCA)
(15 rows)
-- PartTbl-RangeJoinPred.mdp
-- from comment (query) and dxl (ddl)
create table stg_xdr_crce_cdr(
id bigint,
sessioncreationtimestamp timestamptz,
subscriberaddress varchar
)
with (appendonly=true)
distributed by (id)
partition by range(sessioncreationtimestamp) (start('2010-01-01 00:00:00') end ('2011-01-01 00:00:00'),
start('2011-01-01 00:00:00') end ('2012-01-01 00:00:00'));
create table dim_customer_device(
imei varchar,
msisdn varchar,
start_dtm timestamptz,
end_dtm timestamptz,
mkt_model varchar
)
with (appendonly=true)
distributed by(imei);
explain (costs off)
select *
from (select subscriberaddress,sessioncreationtimestamp from stg_xdr_crce_cdr) f,
dim_customer_device d
where d.msisdn=f.subscriberaddress and
f.sessioncreationtimestamp >= d.start_dtm and
f.sessioncreationtimestamp <d.end_dtm and
(mkt_model like '%IPHONE%');
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Hash Join
Hash Cond: ((d.msisdn)::text = (stg_xdr_crce_cdr.subscriberaddress)::text)
Join Filter: ((stg_xdr_crce_cdr.sessioncreationtimestamp >= d.start_dtm) AND (stg_xdr_crce_cdr.sessioncreationtimestamp < d.end_dtm))
-> Seq Scan on dim_customer_device d
Filter: ((mkt_model)::text ~~ '%IPHONE%'::text)
-> Hash
-> 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)
(11 rows)
-- PartTbl-Relabel-Equality.mdp
-- from dxl
create table ds_4(
month_id varchar,
cust_group_acc numeric(5,2),
mobile_no varchar
)
distributed by(cust_group_acc, mobile_no)
partition by list(month_id) (values('Jan', 'Feb', 'Mar'), values('Apr', 'May', 'Jun'));
explain (costs off)
select month_id, cust_group_acc, mobile_no
from ds_4
where month_id::text = 'Apr';
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)
(5 rows)
-- PartTbl-Relabel-Range.mdp
-- from dxl
-- reuse DDL from previous example
-- currently falls back, "non-trivial part filter not supported"
explain (costs off)
select month_id, cust_group_acc, mobile_no
from ds_4
where month_id::text >= 'Feb' and month_id::text < 'Mar';
QUERY PLAN
------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> 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)
(5 rows)
-- retail_28.mdp
-- from comment (query) and dxl (ddl)
create table order_lineitems(
order_id varchar,
item_shipment_status_code varchar,
order_datetime timestamp
)
with(appendonly=true)
distributed by(order_id)
partition by range(order_datetime) (start('2010-01-01'::timestamp) end('2011-01-01'::timestamp) every(interval '1' month));
-- currently falls back, "non-trivial part filter not supported"
explain (costs off)
SELECT to_char(order_datetime,'YYYY-Q') as ship_month
, item_shipment_status_code
, COUNT(DISTINCT order_id) AS num_orders
FROM order_lineitems
WHERE order_datetime BETWEEN timestamp '2010-04-01' AND date '2010-06-30'
GROUP BY to_char(order_datetime,'YYYY-Q')
, item_shipment_status_code
ORDER BY to_char(order_datetime,'YYYY-Q')
, item_shipment_status_code
;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
Merge Key: (to_char(order_datetime, 'YYYY-Q'::text)), item_shipment_status_code
-> GroupAggregate
Group Key: (to_char(order_datetime, 'YYYY-Q'::text)), item_shipment_status_code
-> Sort
Sort Key: (to_char(order_datetime, 'YYYY-Q'::text)), item_shipment_status_code
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: (to_char(order_datetime, 'YYYY-Q'::text)), item_shipment_status_code
-> 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)
(12 rows)
-- test partioned table with no partitions
create table no_part (a int, b int) partition by list (a) distributed by (b);
select * from no_part;
a | b
---+---
(0 rows)
-- test casting with setops
with v(year) as (
select 2019::float8 + dx from (VALUES (-1), (0), (0), (1), (1)) t(dx)
except
select 2019::int)
select * from v where year > 1;
year
------
2018
2020
(2 rows)
with v(year) as (
select 2019::float8 + dx from (VALUES (-1), (0), (0), (1), (1)) t(dx)
except all
select 2019::int)
select * from v where year > 1;
year
------
2018
2019
2020
2020
(4 rows)
with v(year) as (
select 2019::float8 + dx from (VALUES (-1), (0), (0), (1), (1)) t(dx)
intersect
select 2019::int)
select * from v where year > 1;
year
------
2019
(1 row)
with v(year) as (
select 2019::float8 + dx from (VALUES (-1), (0), (0), (1), (1)) t(dx)
intersect all
select 2019::int)
select * from v where year > 1;
year
------
2019
(1 row)
create table sqall_t1(a int) distributed by (a);
insert into sqall_t1 values (1), (2), (3);
set optimizer_join_order='query';
select * from sqall_t1 where a not in (
select b.a from sqall_t1 a left join sqall_t1 b on false);
a
---
(0 rows)
reset optimizer_join_order;
create table tt_varchar(
data character varying
) distributed by (data);
insert into tt_varchar values('test');
create table tt_int(
id integer
) distributed by (id);
insert into tt_int values(1);
set optimizer_enforce_subplans = 1;
-- test collation in subplan testexpr
select data from tt_varchar where data > any(select id::text from tt_int);
data
------
test
(1 row)
-- test implicit coerce via io
CREATE CAST (integer AS text) WITH INOUT AS IMPLICIT;
select data from tt_varchar where data > any(select id from tt_int);
data
------
test
(1 row)
DROP CAST (integer AS text);
reset optimizer_enforce_subplans;
create table left_outer_index_nl_foo (a integer, b integer, c integer) distributed randomly;
create table left_outer_index_nl_bar (a integer, b integer, c integer) distributed randomly;
create index left_outer_index_nl_bar_idx on left_outer_index_nl_bar using btree (b);
insert into left_outer_index_nl_foo select i, i, i from generate_series(1, 4)i;
insert into left_outer_index_nl_bar select i, i, i from generate_series(2, 6)i;
analyze left_outer_index_nl_foo;
analyze left_outer_index_nl_bar;
set optimizer_enable_hashjoin=off;
set enable_nestloop=on;
set enable_hashjoin=off;
--- verify that the inner half of a left outer nested loop join is non-randomly distributed
explain 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;
QUERY PLAN
---------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324033.80 rows=7 width=16)
-> Nested Loop Left Join (cost=0.00..1324033.80 rows=3 width=16)
Join Filter: (r.b = l.b)
-> Seq Scan on left_outer_index_nl_foo r (cost=0.00..431.00 rows=2 width=12)
-> 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)
(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
1 | 1 | 1 |
2 | 2 | 2 | 2
3 | 3 | 3 | 3
(4 rows)
create table left_outer_index_nl_foo_hash (a integer, b integer, c text);
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 left_outer_index_nl_bar_hash (a integer, b integer, c text);
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 left_outer_index_nl_bar_hash_idx on left_outer_index_nl_bar_hash using btree (b);
insert into left_outer_index_nl_foo_hash select i, i, i from generate_series(1, 4)i;
insert into left_outer_index_nl_bar_hash select i, i, i from generate_series(2, 6)i;
analyze left_outer_index_nl_foo_hash;
analyze left_outer_index_nl_bar_hash;
--- verify that the inner half of a left outer nested loop join is non-randomly distributed
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)
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)
(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;
a | b | c | c
---+---+---+---
2 | 2 | 2 | 2
3 | 3 | 3 | 3
4 | 4 | 4 | 4
1 | 1 | 1 |
(4 rows)
--- 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
------------------------------------------------------------------------------------------------------
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)
-> 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=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)
(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
(4 rows)
create table left_outer_index_nl_foo_repl (a integer, b integer, c integer) distributed replicated;
create table left_outer_index_nl_bar_repl (a integer, b integer, c integer) distributed replicated;
create index left_outer_index_nl_bar_repl_idx on left_outer_index_nl_bar_repl using btree (b);
insert into left_outer_index_nl_foo_repl select i, i, i from generate_series(1, 4)i;
insert into left_outer_index_nl_bar_repl select i, i, i from generate_series(2, 6)i;
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
----------------------------------------------------------------------------------------------------------------------------------
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)
(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;
a | b | c | c
---+---+---+---
1 | 1 | 1 |
2 | 2 | 2 | 2
3 | 3 | 3 | 3
4 | 4 | 4 | 4
(4 rows)
--- 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)
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)
(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;
a | b | c | c
---+---+---+---
1 | 1 | 1 |
2 | 2 | 2 | 2
3 | 3 | 3 | 3
4 | 4 | 4 | 4
(4 rows)
reset optimizer_enable_hashjoin;
reset enable_nestloop;
reset enable_hashjoin;
--- IS DISTINCT FROM FALSE previously simplified to IS TRUE, returning incorrect results for some hash anti joins
--- the following tests were added to verify the behavior is correct
CREATE TABLE tt1 (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 tt2 (c int, d int);
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.
INSERT INTO tt1 VALUES (1, NULL), (2, 2), (3, 4), (NULL, 5);
INSERT INTO tt2 VALUES (1, 1), (2, NULL), (4, 4), (NULL, 2);
ANALYZE tt1;
ANALYZE tt2;
EXPLAIN SELECT b FROM tt1 WHERE NOT EXISTS (SELECT * FROM tt2 WHERE (tt2.d = tt1.b) IS DISTINCT FROM false);
QUERY PLAN
---------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324033.03 rows=4 width=4)
-> Nested Loop Anti Join (cost=0.00..1324033.03 rows=2 width=4)
Join Filter: ((tt2.d = tt1.b) IS DISTINCT FROM false)
-> Seq Scan on tt1 (cost=0.00..431.00 rows=2 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 tt2 (cost=0.00..431.00 rows=2 width=4)
Optimizer: Pivotal Optimizer (GPORCA)
(8 rows)
SELECT b FROM tt1 WHERE NOT EXISTS (SELECT * FROM tt2 WHERE (tt2.d = tt1.b) IS DISTINCT FROM false);
b
---
(0 rows)
EXPLAIN SELECT b FROM tt1 WHERE NOT EXISTS (SELECT * FROM tt2 WHERE (tt2.d = tt1.b) IS DISTINCT FROM true);
QUERY PLAN
---------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324033.03 rows=4 width=4)
-> Nested Loop Anti Join (cost=0.00..1324033.03 rows=2 width=4)
Join Filter: ((tt2.d = tt1.b) IS DISTINCT FROM true)
-> Seq Scan on tt1 (cost=0.00..431.00 rows=2 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 tt2 (cost=0.00..431.00 rows=2 width=4)
Optimizer: Pivotal Optimizer (GPORCA)
(8 rows)
SELECT b FROM tt1 WHERE NOT EXISTS (SELECT * FROM tt2 WHERE (tt2.d = tt1.b) IS DISTINCT FROM true);
b
---
(0 rows)
EXPLAIN SELECT b FROM tt1 WHERE NOT EXISTS (SELECT * FROM tt2 WHERE (tt1.b = tt2.d) IS DISTINCT FROM NULL);
QUERY PLAN
---------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..1324033.03 rows=4 width=4)
-> Nested Loop Anti Join (cost=0.00..1324033.03 rows=2 width=4)
Join Filter: (NOT ((tt1.b = tt2.d) IS NULL))
-> Seq Scan on tt1 (cost=0.00..431.00 rows=2 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 tt2 (cost=0.00..431.00 rows=2 width=4)
Optimizer: Pivotal Optimizer (GPORCA)
(8 rows)
SELECT b FROM tt1 WHERE NOT EXISTS (SELECT * FROM tt2 WHERE (tt1.b = tt2.d) IS DISTINCT FROM NULL);
b
---
(1 row)
--- optimizer_xform_bind_threshold should limit the search space and quickly
--- generate a plan (<100ms, but if this GUC is not set it will take minutes to
--- optimize)
create table binding (a int) distributed by (a);
set optimizer_xform_bind_threshold=100;
set statement_timeout = '15s';
select a in (
select a from binding as t1 where a in (
select a from binding as t2 where a in (
select a from binding as t3 where a in (
select a from binding as t4 join binding as t5 using(a) group by t4.a
union
select a from binding as t4 join binding as t5 using(a) group by t4.a
union
select a from binding as t4 join binding as t5 using(a) group by t4.a
)
)
)
) from binding;
?column?
----------
(0 rows)
reset optimizer_xform_bind_threshold;
reset statement_timeout;
-- an agg of a non-SRF with a nested SRF should be treated as a SRF, the
-- optimizer must not eliminate the SRF or it can produce incorrect results
create table nested_srf(a text);
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 nested_srf values ('abc,def,ghi');
select * from (select regexp_split_to_table((a)::text, ','::text) from nested_srf)a;
regexp_split_to_table
-----------------------
abc
def
ghi
(3 rows)
select count(*) from (select regexp_split_to_table((a)::text, ','::text) from nested_srf)a;
count
-------
3
(1 row)
select * from (select trim(regexp_split_to_table((a)::text, ','::text)) from nested_srf)a;
btrim
-------
abc
def
ghi
(3 rows)
select count(*) from (select trim(regexp_split_to_table((a)::text, ','::text)) from nested_srf)a;
count
-------
3
(1 row)
select count(*) from (select trim( case when a!='abc' then (regexp_split_to_table((a)::text, ','::text)) else ' ' end) from nested_srf)a;
ERROR: set-returning functions are not allowed in CASE
LINE 1: ...t(*) from (select trim( case when a!='abc' then (regexp_spl...
^
HINT: You might be able to move the set-returning function into a LATERAL FROM item.
select count(*) from (select trim(coalesce(regexp_split_to_table((a)::text, ','::text),'')) from nested_srf)a;
ERROR: set-returning functions are not allowed in COALESCE
LINE 1: select count(*) from (select trim(coalesce(regexp_split_to_t...
^
HINT: You might be able to move the set-returning function into a LATERAL FROM item.
select count(regexp_split_to_table((a)::text, ','::text)) from nested_srf;
ERROR: aggregate function calls cannot contain set-returning function calls
LINE 1: select count(regexp_split_to_table((a)::text, ','::text)) fr...
^
HINT: You might be able to move the set-returning function into a LATERAL FROM item.
truncate nested_srf;
insert into nested_srf values (NULL);
select * from (select trim(regexp_split_to_table((a)::text, ','::text)) from nested_srf)a;
btrim
-------
(0 rows)
select count(*) from (select trim(regexp_split_to_table((a)::text, ','::text)) from nested_srf)a;
count
-------
0
(1 row)
--- if the inner child is already distributed on the join column, orca should
--- not place any motion on the inner child
CREATE TABLE tone (a int, b 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.
insert into tone select i,i,i from generate_series(1, 10) i;
ANALYZE tone;
SET optimizer_enable_hashjoin=off;
EXPLAIN (COSTS OFF) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.a;
QUERY PLAN
------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop Left Join
Join Filter: (t1.a = t2.a)
-> Seq Scan on tone t1
-> Seq Scan on tone t2
Optimizer: Pivotal 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
(10 rows)
--- if the inner child is not distributed on the join column, orca should
--- redistribute the inner child
EXPLAIN (COSTS OFF) SELECT * FROM tone t1 LEFT OUTER JOIN tone 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)
-> Seq Scan on tone t1
-> Materialize
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: t2.b
-> Seq Scan on tone t2
Optimizer: Pivotal 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
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;
QUERY PLAN
------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop Left Join
Join Filter: (t1.a = ((1 + t2.b)))
-> Seq Scan on tone t1
-> Materialize
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: ((1 + t2.b))
-> Seq Scan on tone t2
Optimizer: Pivotal 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 |
(10 rows)
--- if the join condition does not involve a simple scalar ident, orca must
--- broadcast the inner child
EXPLAIN (COSTS OFF) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.b-t1.a;
QUERY PLAN
---------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop Left Join
Join Filter: (t1.a = (t2.b - t1.a))
-> Seq Scan on tone t1
-> Materialize
-> Broadcast Motion 3:3 (slice2; segments: 3)
-> Seq Scan on tone t2
Optimizer: Pivotal 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 | | |
(10 rows)
--- orca should broadcast the inner child if the guc is set off
SET optimizer_enable_redistribute_nestloop_loj_inner_child=off;
EXPLAIN (COSTS OFF) SELECT * FROM tone t1 LEFT OUTER JOIN tone 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)
-> Seq Scan on tone t1
-> Materialize
-> Broadcast Motion 3:3 (slice2; segments: 3)
-> Seq Scan on tone t2
Optimizer: Pivotal 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
(10 rows)
EXPLAIN (COSTS OFF) SELECT * FROM tone t1 LEFT OUTER JOIN tone t2 ON t1.a = t2.a;
QUERY PLAN
---------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop Left Join
Join Filter: (t1.a = t2.a)
-> Seq Scan on tone t1
-> Materialize
-> Broadcast Motion 3:3 (slice2; segments: 3)
-> Seq Scan on tone t2
Optimizer: Pivotal 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
1 | 1 | 1 | 1 | 1 | 1
(10 rows)
RESET optimizer_enable_redistribute_nestloop_loj_inner_child;
RESET optimizer_enable_hashjoin;
--- Test if orca can produce the correct plan for CTAS
CREATE TABLE dist_tab_a (a varchar(15)) DISTRIBUTED BY(a);
INSERT INTO dist_tab_a VALUES('1 '), ('2 '), ('3 ');
CREATE TABLE dist_tab_b (a char(15), b bigint) DISTRIBUTED BY(a);
INSERT INTO dist_tab_b VALUES('1 ', 1), ('2 ', 2), ('3 ', 3);
EXPLAIN(COSTS OFF) CREATE TABLE result_tab AS
(SELECT a.a, b.b FROM dist_tab_a a LEFT JOIN dist_tab_b b ON a.a=b.a) DISTRIBUTED BY(a);
QUERY PLAN
------------------------------------------------------------------
Result
-> Redistribute Motion 3:3 (slice1; segments: 3)
Hash Key: a.a
-> Hash Left Join
Hash Cond: ((a.a)::bpchar = b.a)
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: a.a
-> Seq Scan on dist_tab_a a
-> Hash
-> Seq Scan on dist_tab_b b
Optimizer: GPORCA
(11 rows)
CREATE TABLE result_tab AS
(SELECT a.a, b.b FROM dist_tab_a a LEFT JOIN dist_tab_b b ON a.a=b.a) DISTRIBUTED BY(a);
SELECT gp_segment_id, * FROM result_tab;
gp_segment_id | a | b
---------------+-------+---
0 | 3 | 3
1 | 2 | 2
2 | 1 | 1
(3 rows)
DROP TABLE IF EXISTS dist_tab_a;
DROP TABLE IF EXISTS dist_tab_b;
DROP TABLE IF EXISTS result_tab;
--- Test if orca can produce correct plan for inner index nl join
CREATE TABLE t_clientinstrumentind2 (
tradingday text,
client_id INT,
instrumentid text,
PRIMARY KEY (tradingday, client_id, instrumentid)
)
DISTRIBUTED BY (tradingday, client_id, instrumentid)
PARTITION BY RANGE (tradingday)
(
PARTITION p2019 START ('20190101'::character varying(8)) END ('20200101'::character varying(8)) WITH (tablename='t_clientinstrumentind_2_prt_p2019', appendonly=false),
PARTITION p2020 START ('20200101'::character varying(8)) END ('20210101'::character varying(8)) WITH (tablename='t_clientinstrumentind_2_prt_p2020', appendonly=false)
);
CREATE TABLE t_clientproductind2 (
tradingday character varying(8),
productid TEXT,
clientid INT,
exchangegroup TEXT,
customertype INT ,
PRIMARY KEY (tradingday, productid, clientid, exchangegroup, customertype)
)
DISTRIBUTED BY (tradingday, productid, clientid, exchangegroup, customertype)
PARTITION BY RANGE (tradingday)
(
PARTITION p2019 START ('20190101'::character varying(8)) END ('20200101'::character varying(8)) WITH (tablename='t_clientproductind_2_prt_p2019', appendonly=false),
PARTITION p2020 START ('20200101'::character varying(8)) END ('20210101'::character varying(8)) WITH (tablename='t_clientproductind_2_prt_p2020', appendonly=false)
);
INSERT INTO t_clientinstrumentind2 (tradingday, client_id, instrumentid) VALUES
('20190715', 54982370, 'al1908'),
('20190715', 54982370, 'rb2001'),
('20190715', 54982370, 'cu1909'),
('20190715', 54982370, 'cu1908'),
('20190715', 54982370, 'zn1908'),
('20190715', 54982370, 'pb1908');
INSERT INTO t_clientproductind2 (tradingday, productid, clientid, exchangegroup, customertype) VALUES
('20190715', 'cu_f', 54982370, 'SHFE', 1),
('20190715', 'rb_f', 54982370, 'SHFE', 1),
('20190715', 'al_f', 54982370, 'SHFE', 1),
('20190715', 'zn_f', 54982370, 'SHFE', 1),
('20190715', 'pb_f', 54982370, 'SHFE', 1);
SET optimizer_enable_hashjoin = OFF;
EXPLAIN (COSTS OFF)
SELECT * FROM(
SELECT tradingday, 1 AS ins_SpanInsArbitrageRatio
FROM t_clientinstrumentind2 t
WHERE t.tradingday BETWEEN '20190715'AND'20190715'
GROUP BY t.tradingday
)t1
INNER JOIN (
SELECT t.tradingday, 0.9233716475 AS prod_SpanInsArbitrageRatio
FROM t_clientproductind2 t
WHERE t.tradingday BETWEEN'20190715'AND '20190715'
GROUP BY t.tradingday)t2
ON t1.tradingday = t2.tradingday;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Nested Loop
Join Filter: (t.tradingday = (t_1.tradingday)::text)
-> GroupAggregate
Group Key: t_1.tradingday
-> Sort
Sort Key: t_1.tradingday
-> Redistribute Motion 3:3 (slice3; segments: 3)
Hash Key: t_1.tradingday
-> Dynamic Index Scan on t_clientproductind2_pkey on t_clientproductind2 t_1
Index Cond: (((tradingday)::text >= '20190715'::text) AND ((tradingday)::text <= '20190715'::text) AND ((tradingday)::text = '20190715'::text))
Number of partitions to scan: 1 (out of 2)
-> Materialize
-> GroupAggregate
Group Key: t.tradingday
-> Sort
Sort Key: t.tradingday
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: t.tradingday
-> Dynamic Index Scan on t_clientinstrumentind2_pkey on t_clientinstrumentind2 t
Index Cond: ((tradingday >= '20190715'::text) AND (tradingday <= '20190715'::text) AND (tradingday = '20190715'::text))
Number of partitions to scan: 1 (out of 2)
Optimizer: GPORCA
(23 rows)
RESET optimizer_enable_hashjoin;
SELECT * FROM(
SELECT tradingday, 1 AS ins_SpanInsArbitrageRatio
FROM t_clientinstrumentind2 t
WHERE t.tradingday BETWEEN '20190715'AND'20190715'
GROUP BY t.tradingday
)t1
INNER JOIN (
SELECT t.tradingday, 0.9233716475 AS prod_SpanInsArbitrageRatio
FROM t_clientproductind2 t
WHERE t.tradingday BETWEEN'20190715'AND '20190715'
GROUP BY t.tradingday)t2
ON t1.tradingday = t2.tradingday;
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
tradingday | ins_spaninsarbitrageratio | tradingday | prod_spaninsarbitrageratio
------------+---------------------------+------------+----------------------------
20190715 | 1 | 20190715 | 0.9233716475
(1 row)
DROP TABLE t_clientinstrumentind2, t_clientproductind2;
-- Test ORCA not falling back to Postgres planner during
-- SimplifySelectOnOuterJoin stage. Previously, we could get assertion error
-- trying to EberEvaluate() strict function with zero arguments.
-- Postgres planner will fold our function, because it has additional
-- 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);
CREATE TABLE join_null_rej2(i int);
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 $$
BEGIN
RETURN 5;
END;
$$ LANGUAGE plpgsql STABLE STRICT;
EXPLAIN (COSTS OFF) SELECT (
SELECT count(*) cnt
FROM join_null_rej1 t1
LEFT JOIN join_null_rej2 t2 ON t1.i = t2.i
WHERE t2.i < join_null_rej_func()
);
QUERY PLAN
----------------------------------------------------------------------------
Nested Loop Left Join
Join Filter: true
-> Result
-> Materialize
-> Aggregate
-> Gather Motion 3:1 (slice1; segments: 3)
-> Hash Join
Hash Cond: (t1.i = t2.i)
-> Seq Scan on join_null_rej1 t1
-> Hash
-> Seq Scan on join_null_rej2 t2
Filter: (i < join_null_rej_func())
Optimizer: Pivotal Optimizer (GPORCA)
(13 rows)
-- Optional, but let's check we get same result for both, folded and
-- not folded join_null_rej_func() function.
SELECT (
SELECT count(*) cnt
FROM join_null_rej1 t1
LEFT JOIN join_null_rej2 t2 ON t1.i = t2.i
WHERE t2.i < join_null_rej_func()
);
cnt
-----
3
(1 row)
-- Check Sort node placed under GatherMerge in case we use Update from Select
-- with window function. Placing Sort node upper and executing it on one
-- segment can lead to slow query execution and can consume all spills for
-- heavy datasets. Sort node should be on it's place for both, Postgres
-- optimizer and ORCA.
create table window_agg_test(i int, j int) distributed randomly;
explain
update window_agg_test t
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;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------
Update on window_agg_test t (cost=0.00..862.02 rows=1 width=1)
-> Result (cost=0.00..0.00 rows=0 width=0)
-> Explicit Redistribute Motion 1:3 (slice1; segments: 1) (cost=0.00..862.00 rows=1 width=18)
-> Hash Join (cost=0.00..862.00 rows=1 width=18)
Hash Cond: (t.j = window_agg_test.j)
-> Gather Motion 3:1 (slice2; segments: 3) (cost=0.00..431.00 rows=1 width=14)
-> Seq Scan on window_agg_test t (cost=0.00..431.00 rows=1 width=14)
-> Hash (cost=431.00..431.00 rows=1 width=8)
-> WindowAgg (cost=0.00..431.00 rows=1 width=8)
Order By: window_agg_test.j
-> Gather Motion 3:1 (slice3; segments: 3) (cost=0.00..431.00 rows=1 width=8)
Merge Key: window_agg_test.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)
(16 rows)
----------------------------------
-- Test ORCA support for const TVF
----------------------------------
create type complex_t as (r float8, i float8);
-- Nested composite
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
-------------------------------------------------------------------
Function Scan on quad_func_cast (cost=0.00..0.00 rows=1 width=8)
Optimizer: Pivotal Optimizer (GPORCA)
(2 rows)
explain select c2 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)
(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)
(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)
(2 rows)
select c1 from quad_func_cast();
c1
--------
(1.1,)
(1 row)
select c2 from quad_func_cast();
c2
--------
(2.2,)
(1 row)
select (c1).r from quad_func_cast();
r
-----
1.1
(1 row)
select (c2).i from quad_func_cast();
i
---
(1 row)
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
------------------------------------------------------------------
Function Scan on mix_func_cast (cost=0.00..0.00 rows=1 width=8)
Optimizer: Pivotal Optimizer (GPORCA)
(2 rows)
explain select b from mix_func_cast();
QUERY PLAN
------------------------------------------------------------------
Function Scan on mix_func_cast (cost=0.00..0.00 rows=1 width=4)
Optimizer: Pivotal Optimizer (GPORCA)
(2 rows)
explain select c from mix_func_cast();
QUERY PLAN
------------------------------------------------------------------
Function Scan on mix_func_cast (cost=0.00..0.00 rows=1 width=1)
Optimizer: Pivotal Optimizer (GPORCA)
(2 rows)
select a from mix_func_cast();
a
---------
column1
(1 row)
select b from mix_func_cast();
b
---
1
(1 row)
select c from mix_func_cast();
c
---
t
(1 row)
----------------------------------
-- Test ORCA support for FIELDSELECT
----------------------------------
create type comp_type as ( a text, b numeric, c int, d float, e int);
create table comp_table(id int, item comp_type) distributed by (id);
create table comp_part (id int, item comp_type) distributed by (id) partition by range(id) (start(1) end(4) every(1));
insert into comp_table values (1, ROW('GP', 10.5, 10, 10.5, 20)), (2, ROW('VM',20.5, 20, 10.5, 20)), (3, ROW('DB',10.5, 10, 10.5, 10));
insert into comp_part values (1, ROW('GP', 10.5, 10, 10.5, 20)), (2, ROW('VM',20.5, 20, 10.5, 20)), (3, ROW('DB',10.5, 10, 10.5, 10));
analyze comp_table;
analyze comp_part;
select sum((item).b) from comp_table where (item).c=20;
sum
------
20.5
(1 row)
explain (costs off) select sum((item).b) from comp_table where (item).c=20;
QUERY PLAN
------------------------------------------------
Finalize Aggregate
-> Gather Motion 3:1 (slice1; segments: 3)
-> Partial Aggregate
-> Seq Scan on comp_table
Filter: ((item).c = 20)
Optimizer: GPORCA
(6 rows)
select distinct (item).b from comp_table where (item).c=20;
b
------
20.5
(1 row)
explain (costs off) select distinct (item).b from comp_table where (item).c=20;
QUERY PLAN
------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> GroupAggregate
Group Key: ((item).b)
-> Sort
Sort Key: ((item).b)
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: ((item).b)
-> Seq Scan on comp_table
Filter: ((item).c = 20)
Optimizer: GPORCA
(10 rows)
-- verify the query output using predicate with the same composite type
select (item).a from comp_table where (item).c=20 and (item).e >10;
a
----
VM
(1 row)
explain (costs off) select (item).a from comp_table where (item).c=20 and (item).e >10;
QUERY PLAN
-------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Seq Scan on comp_table
Filter: (((item).c = 20) AND ((item).e > 10))
Optimizer: GPORCA
(4 rows)
-- verify the query output using predicate with the different composite type
select * from comp_table where (item).c>(item).d;
id | item
----+----------------------
2 | (VM,20.5,20,10.5,20)
(1 row)
explain (costs off) select * from comp_table where (item).c>(item).d ;
QUERY PLAN
-----------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Seq Scan on comp_table
Filter: (((item).c)::double precision > (item).d)
Optimizer: GPORCA
(4 rows)
-- verify the query output by using a composite type in a join query
select (x.item).a from comp_table x join comp_table y on (x.item).c=(y.item).c;
a
----
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;
QUERY PLAN
------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Hash Join
Hash Cond: ((x.item).c = (y.item).c)
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: (x.item).c
-> Seq Scan on comp_table x
-> Hash
-> Redistribute Motion 3:3 (slice3; segments: 3)
Hash Key: (y.item).c
-> Seq Scan on comp_table y
Optimizer: GPORCA
(11 rows)
-- verify the query output by using a composite type in a TVF query
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
(3 rows)
explain (costs off) select (x.item).a, (select count(*) from generate_series(1, (x.item).c)) from comp_table x;
QUERY PLAN
------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Seq Scan on comp_table x
SubPlan 1
-> Aggregate
-> Function Scan on generate_series
Optimizer: GPORCA
(6 rows)
-- verify the query output by using a composite type in a cte query
with cte1 as (select * from comp_table where (item).c>10) select id, (item).a, (item).b, (item).c, (item).e from cte1;
id | a | b | c | e
----+----+------+----+----
2 | VM | 20.5 | 20 | 20
(1 row)
explain (costs off) with cte1 as (select * from comp_table where (item).c>10) select id, (item).a, (item).b, (item).c, (item).e from cte1;
QUERY PLAN
------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Seq Scan on comp_table
Filter: ((item).c > 10)
Optimizer: GPORCA
(4 rows)
-- verify the query output by using a composite type in a subquery
select (item).a from comp_table where (item).c=10 and (item).e IN (SELECT (item).e FROM comp_table WHERE (item).c = 10);
a
----
DB
GP
(2 rows)
explain (costs off) select (item).a from comp_table where (item).c=10 and (item).e IN (SELECT (item).e FROM comp_table WHERE (item).c = 10);
QUERY PLAN
--------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Hash Semi Join
Hash Cond: ((comp_table.item).e = ((comp_table_1.item).e))
-> Seq Scan on comp_table
Filter: ((item).c = 10)
-> Hash
-> Broadcast Motion 3:3 (slice2; segments: 3)
-> Seq Scan on comp_table comp_table_1
Filter: ((item).c = 10)
Optimizer: GPORCA
(10 rows)
-- verify the query output by using a composite type in a partition table query
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
(5 rows)
explain (costs off) select (x.item).a from comp_part x join comp_part y on (X.item).c=(Y.item).c;
QUERY PLAN
----------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Hash Join
Hash Cond: ((x.item).c = (y.item).c)
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: (x.item).c
-> Dynamic Seq Scan on comp_part x
Number of partitions to scan: 3 (out of 3)
-> Hash
-> Redistribute Motion 3:3 (slice3; segments: 3)
Hash Key: (y.item).c
-> Dynamic Seq Scan on comp_part y
Number of partitions to scan: 3 (out of 3)
Optimizer: GPORCA
(13 rows)
-- clean up
drop table comp_table;
drop table comp_part;
drop type comp_type;
-- the query with empty CTE producer target list should fall back to Postgres
-- optimizer without any error on build without asserts
drop table if exists empty_cte_tl_test;
NOTICE: table "empty_cte_tl_test" does not exist, skipping
create table empty_cte_tl_test(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.
with cte as (
select from empty_cte_tl_test
)
select *
from empty_cte_tl_test
where id in(select id from cte);
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: Empty target list
id
----
(0 rows)
-- test that we use default cardinality estimate (40) for non-comparable types
create table ts_tbl (ts timestamp);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'ts' as the Apache Cloudberry data distribution key for this table.
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 ts_tbl_idx on ts_tbl(ts);
insert into ts_tbl select to_timestamp('99991231'::text, 'YYYYMMDD'::text) from generate_series(1,100);
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)
Index Cond: (ts = 'Fri Dec 31 00:00:00 9999 PST'::timestamp with time zone)
Optimizer: Pivotal Optimizer (GPORCA)
(4 rows)
-- Test ORCA support for implicit array coerce cast
-- ORCA should generate a valid plan passing along the cast function as part of ArrayCoerceExpr
-- While execution thin insert query fails due to the mismatch of column length.
create table array_coerce_foo (a int, b varchar(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 array_coerce_bar (a int, b varchar(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.
insert into array_coerce_bar values (1, ARRAY['abcde']);
explain insert into array_coerce_foo select * from array_coerce_bar;
QUERY PLAN
-------------------------------------------------------------------------
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)
(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)
WITH conf AS (
SELECT setting
FROM pg_catalog.pg_config
WHERE name = 'LDFLAGS_EX')
select * from conf;
setting
---------
(1 row)
reset optimizer_trace_fallback;
-- These testcases will fallback to postgres when "PexprConvert2In" is enabled if
-- underlying issues are not fixed
create table baz (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 select baz.* from baz where
baz.a=1 OR
baz.b = 1 OR baz.b = 2 OR baz.b = 3 OR baz.b = 4 OR baz.b = 5 OR baz.b = 6 OR baz.b = 7 OR baz.b = 8 OR baz.b = 9 OR baz.b = 10 OR
baz.b = 11 OR baz.b = 12 OR baz.b = 13 OR baz.b = 14 OR baz.b = 15 OR baz.b = 16 OR baz.b = 17 OR baz.b = 18 OR baz.b = 19 OR baz.b = 20;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
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)
(4 rows)
drop table baz;
create table baz ( a 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.
explain select * from baz where baz.a::bpchar='b' or baz.a='c';
QUERY PLAN
------------------------------------------------------------------------------
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)
(4 rows)
drop table baz;
-- ensure shared scan producer returns 0 rows
create table cte_test(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 cte_test select i from generate_series(1,10)i;
analyze cte_test;
explain (analyze, costs off, summary off, timing off) with cte as (select * from cte_test) select * from cte union all select * from cte;
QUERY PLAN
----------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (actual rows=20 loops=1)
-> Sequence (actual rows=10 loops=1)
-> Shared Scan (share slice:id 1:0) (actual rows=0 loops=1)
-> Seq Scan on cte_test (actual rows=5 loops=1)
-> 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)
(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;
-- end_ignore
create or replace function check_col_width(query text, operator text, width text) returns int as
$$
rv = plpy.execute('EXPLAIN '+ query)
search_text_1 = operator
search_text_2 = width
result = 0
for i in range(len(rv)):
cur_line = rv[i]['QUERY PLAN']
if search_text_1 in cur_line and search_text_2 in cur_line:
result = result+1
return result
$$
language plpython3u;
create table testPartWidth (a numeric(7,2), b numeric(7,2)) distributed by (a)
partition by range(a) (start(0.0) end(4.0) every(2.0));
insert into testPartWidth values (0.001,0.001),(2.123,2.123);
analyze testPartWidth;
--------------------------------------------------------------------------------
-- The below query shows the column width of 'a' and 'b'
-- select attname,avg_width from pg_stats where tablename='testPartWidth';
-- attname | avg_width
-- ---------+-----------
-- a | 5
-- b | 5
--------------------------------------------------------------------------------
select check_col_width('select a from testPartWidth;','Dynamic Seq Scan','width=5') = 1;
?column?
----------
t
(1 row)
select check_col_width('select b from testPartWidth;','Dynamic Seq Scan','width=5') = 1;
?column?
----------
t
(1 row)
select check_col_width('select a from testPartWidth;','Append','width=5') = 1;
?column?
----------
f
(1 row)
select check_col_width('select a from testPartWidth;','Append','width=5') = 1;
?column?
----------
f
(1 row)
drop function check_col_width(query text, operator text, width text);
---------------------------------------------------------------------------------
-- Test cast from INT[] to TEXT[]
CREATE TABLE array_coerceviaio(a INT[]) distributed randomly;
INSERT INTO array_coerceviaio values(ARRAY[1, 2, 3]);
EXPLAIN SELECT CAST(a AS TEXT[]) FROM array_coerceviaio;
QUERY PLAN
------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=8)
-> Seq Scan on array_coerceviaio (cost=0.00..431.00 rows=1 width=8)
Optimizer: GPORCA
(3 rows)
SELECT CAST(a AS TEXT[]) FROM array_coerceviaio;
a
---------
{1,2,3}
(1 row)
---------------------------------------------------------------------------------
DROP TABLE IF EXISTS schema_test_table;
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
-----------------------------------------------------------------------------------------------------------------------------------
Result
Output: NULL::numeric, NULL::numeric(5,2), NULL::character(10)
One-Time Filter: false
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
-------------------------------------------
Result (cost=0.00..0.00 rows=0 width=12)
One-Time Filter: false
Optimizer: GPORCA
(3 rows)
---------------------------------------------------------------------------------
-- Test fill argtypes of PopAggFunc
-- start_ignore
drop table if exists foo;
drop table if exists bar;
-- end_ignore
set optimizer_enable_eageragg = on;
create table foo (j1 int, g1 int, s1 int);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'j1' as the Apache Cloudberry data distribution key for this table.
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 select i%10, i %10, i from generate_series(1,100) i;
create table bar (j2 int, g2 int, s2 int);
NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'j2' as the Apache Cloudberry data distribution key for this table.
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 select i%1, i %10, i from generate_series(1,10) i;
analyze foo;
analyze bar;
explain (costs off) select max(s1) from foo inner join bar on j1 = j2 group by g1;
QUERY PLAN
------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3)
-> Finalize GroupAggregate
Group Key: foo.g1
-> Sort
Sort Key: foo.g1
-> Redistribute Motion 3:3 (slice2; segments: 3)
Hash Key: foo.g1
-> Streaming Partial HashAggregate
Group Key: foo.g1
-> Hash Join
Hash Cond: (foo.j1 = bar.j2)
-> Seq Scan on foo
-> Hash
-> Seq Scan on bar
Optimizer: GPORCA
(15 rows)
drop table foo;
drop table bar;
reset optimizer_enable_eageragg;