mirror of https://github.com/citusdata/citus.git
841 lines
28 KiB
Plaintext
841 lines
28 KiB
Plaintext
SET citus.next_shard_id TO 1260000;
|
|
SET citus.log_multi_join_order to true;
|
|
SET client_min_messages TO LOG;
|
|
SET citus.shard_count TO 4;
|
|
CREATE TABLE multi_outer_join_left_hash
|
|
(
|
|
l_custkey integer not null,
|
|
l_name varchar(25) not null,
|
|
l_address varchar(40) not null,
|
|
l_nationkey integer not null,
|
|
l_phone char(15) not null,
|
|
l_acctbal decimal(15,2) not null,
|
|
l_mktsegment char(10) not null,
|
|
l_comment varchar(117) not null
|
|
);
|
|
SELECT create_distributed_table('multi_outer_join_left_hash', 'l_custkey');
|
|
create_distributed_table
|
|
--------------------------
|
|
|
|
(1 row)
|
|
|
|
CREATE TABLE multi_outer_join_right_reference
|
|
(
|
|
r_custkey integer not null,
|
|
r_name varchar(25) not null,
|
|
r_address varchar(40) not null,
|
|
r_nationkey integer not null,
|
|
r_phone char(15) not null,
|
|
r_acctbal decimal(15,2) not null,
|
|
r_mktsegment char(10) not null,
|
|
r_comment varchar(117) not null
|
|
);
|
|
SELECT create_reference_table('multi_outer_join_right_reference');
|
|
create_reference_table
|
|
------------------------
|
|
|
|
(1 row)
|
|
|
|
CREATE TABLE multi_outer_join_third_reference
|
|
(
|
|
t_custkey integer not null,
|
|
t_name varchar(25) not null,
|
|
t_address varchar(40) not null,
|
|
t_nationkey integer not null,
|
|
t_phone char(15) not null,
|
|
t_acctbal decimal(15,2) not null,
|
|
t_mktsegment char(10) not null,
|
|
t_comment varchar(117) not null
|
|
);
|
|
SELECT create_reference_table('multi_outer_join_third_reference');
|
|
create_reference_table
|
|
------------------------
|
|
|
|
(1 row)
|
|
|
|
CREATE TABLE multi_outer_join_right_hash
|
|
(
|
|
r_custkey integer not null,
|
|
r_name varchar(25) not null,
|
|
r_address varchar(40) not null,
|
|
r_nationkey integer not null,
|
|
r_phone char(15) not null,
|
|
r_acctbal decimal(15,2) not null,
|
|
r_mktsegment char(10) not null,
|
|
r_comment varchar(117) not null
|
|
);
|
|
SELECT create_distributed_table('multi_outer_join_right_hash', 'r_custkey');
|
|
create_distributed_table
|
|
--------------------------
|
|
|
|
(1 row)
|
|
|
|
-- Make sure we do not crash if both tables are emmpty
|
|
SELECT
|
|
min(l_custkey), max(l_custkey)
|
|
FROM
|
|
multi_outer_join_left_hash a LEFT JOIN multi_outer_join_third_reference b ON (l_custkey = t_custkey);
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ reference join "multi_outer_join_third_reference" ]
|
|
min | max
|
|
-----+-----
|
|
|
|
|
(1 row)
|
|
|
|
-- Left table is a large table
|
|
\copy multi_outer_join_left_hash FROM '@abs_srcdir@/data/customer-1-10.data' with delimiter '|'
|
|
\copy multi_outer_join_left_hash FROM '@abs_srcdir@/data/customer-11-20.data' with delimiter '|'
|
|
-- Right table is a small table
|
|
\copy multi_outer_join_right_reference FROM '@abs_srcdir@/data/customer-1-15.data' with delimiter '|'
|
|
\copy multi_outer_join_right_hash FROM '@abs_srcdir@/data/customer-1-15.data' with delimiter '|'
|
|
-- Make sure we do not crash if one table has data
|
|
SELECT
|
|
min(l_custkey), max(l_custkey)
|
|
FROM
|
|
multi_outer_join_left_hash a LEFT JOIN multi_outer_join_third_reference b ON (l_custkey = t_custkey);
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ reference join "multi_outer_join_third_reference" ]
|
|
min | max
|
|
-----+-----
|
|
1 | 20
|
|
(1 row)
|
|
|
|
SELECT
|
|
min(t_custkey), max(t_custkey)
|
|
FROM
|
|
multi_outer_join_third_reference a LEFT JOIN multi_outer_join_right_reference b ON (r_custkey = t_custkey);
|
|
min | max
|
|
-----+-----
|
|
|
|
|
(1 row)
|
|
|
|
-- Third table is a single shard table with all data
|
|
\copy multi_outer_join_third_reference FROM '@abs_srcdir@/data/customer-1-30.data' with delimiter '|'
|
|
\copy multi_outer_join_right_hash FROM '@abs_srcdir@/data/customer-1-30.data' with delimiter '|'
|
|
-- Regular outer join should return results for all rows
|
|
SELECT
|
|
min(l_custkey), max(l_custkey)
|
|
FROM
|
|
multi_outer_join_left_hash a LEFT JOIN multi_outer_join_right_reference b ON (l_custkey = r_custkey);
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ reference join "multi_outer_join_right_reference" ]
|
|
min | max
|
|
-----+-----
|
|
1 | 20
|
|
(1 row)
|
|
|
|
-- Since this is a broadcast join, we should be able to join on any key
|
|
SELECT
|
|
count(*)
|
|
FROM
|
|
multi_outer_join_left_hash a LEFT JOIN multi_outer_join_right_reference b ON (l_nationkey = r_nationkey);
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ reference join "multi_outer_join_right_reference" ]
|
|
count
|
|
-------
|
|
28
|
|
(1 row)
|
|
|
|
-- Anti-join should return customers for which there is no row in the right table
|
|
SELECT
|
|
min(l_custkey), max(l_custkey)
|
|
FROM
|
|
multi_outer_join_left_hash a LEFT JOIN multi_outer_join_right_reference b ON (l_custkey = r_custkey)
|
|
WHERE
|
|
r_custkey IS NULL;
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ reference join "multi_outer_join_right_reference" ]
|
|
min | max
|
|
-----+-----
|
|
16 | 20
|
|
(1 row)
|
|
|
|
-- Partial anti-join with specific value
|
|
SELECT
|
|
min(l_custkey), max(l_custkey)
|
|
FROM
|
|
multi_outer_join_left_hash a LEFT JOIN multi_outer_join_right_reference b ON (l_custkey = r_custkey)
|
|
WHERE
|
|
r_custkey IS NULL OR r_custkey = 5;
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ reference join "multi_outer_join_right_reference" ]
|
|
min | max
|
|
-----+-----
|
|
5 | 20
|
|
(1 row)
|
|
|
|
-- This query is an INNER JOIN in disguise since there cannot be NULL results
|
|
-- Added extra filter to make query not router plannable
|
|
SELECT
|
|
min(l_custkey), max(l_custkey)
|
|
FROM
|
|
multi_outer_join_left_hash a LEFT JOIN multi_outer_join_right_reference b ON (l_custkey = r_custkey)
|
|
WHERE
|
|
r_custkey = 5 or r_custkey > 15;
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ reference join "multi_outer_join_right_reference" ]
|
|
min | max
|
|
-----+-----
|
|
5 | 5
|
|
(1 row)
|
|
|
|
-- Apply a filter before the join
|
|
SELECT
|
|
count(l_custkey), count(r_custkey)
|
|
FROM
|
|
multi_outer_join_left_hash a LEFT JOIN multi_outer_join_right_reference b
|
|
ON (l_custkey = r_custkey AND r_custkey = 5);
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ reference join "multi_outer_join_right_reference" ]
|
|
count | count
|
|
-------+-------
|
|
20 | 1
|
|
(1 row)
|
|
|
|
-- Apply a filter before the join (no matches right)
|
|
SELECT
|
|
count(l_custkey), count(r_custkey)
|
|
FROM
|
|
multi_outer_join_left_hash a LEFT JOIN multi_outer_join_right_reference b
|
|
ON (l_custkey = r_custkey AND r_custkey = -1 /* nonexistant */);
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ reference join "multi_outer_join_right_reference" ]
|
|
count | count
|
|
-------+-------
|
|
20 | 0
|
|
(1 row)
|
|
|
|
-- Apply a filter before the join (no matches left)
|
|
SELECT
|
|
count(l_custkey), count(r_custkey)
|
|
FROM
|
|
multi_outer_join_left_hash a LEFT JOIN multi_outer_join_right_reference b
|
|
ON (l_custkey = r_custkey AND l_custkey = -1 /* nonexistant */);
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ reference join "multi_outer_join_right_reference" ]
|
|
count | count
|
|
-------+-------
|
|
20 | 0
|
|
(1 row)
|
|
|
|
-- Right join should be disallowed in this case
|
|
SELECT
|
|
min(r_custkey), max(r_custkey)
|
|
FROM
|
|
multi_outer_join_left_hash a RIGHT JOIN multi_outer_join_right_reference b ON (l_custkey = r_custkey);
|
|
ERROR: cannot run outer join query if join is not on the partition column
|
|
DETAIL: Outer joins requiring repartitioning are not supported.
|
|
-- Reverse right join should be same as left join
|
|
SELECT
|
|
min(l_custkey), max(l_custkey)
|
|
FROM
|
|
multi_outer_join_right_reference a RIGHT JOIN multi_outer_join_left_hash b ON (l_custkey = r_custkey);
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ reference join "multi_outer_join_right_reference" ]
|
|
min | max
|
|
-----+-----
|
|
1 | 20
|
|
(1 row)
|
|
|
|
-- load some more data
|
|
\copy multi_outer_join_right_reference FROM '@abs_srcdir@/data/customer-21-30.data' with delimiter '|'
|
|
-- Update shards so that they do not have 1-1 matching, triggering an error.
|
|
UPDATE pg_dist_shard SET shardminvalue = '2147483646' WHERE shardid = 1260006;
|
|
UPDATE pg_dist_shard SET shardmaxvalue = '2147483647' WHERE shardid = 1260006;
|
|
SELECT
|
|
min(l_custkey), max(l_custkey)
|
|
FROM
|
|
multi_outer_join_left_hash a LEFT JOIN multi_outer_join_right_hash b ON (l_custkey = r_custkey);
|
|
ERROR: hash partitioned table has overlapping shards
|
|
UPDATE pg_dist_shard SET shardminvalue = '-2147483648' WHERE shardid = 1260006;
|
|
UPDATE pg_dist_shard SET shardmaxvalue = '-1073741825' WHERE shardid = 1260006;
|
|
-- empty tables
|
|
SELECT master_modify_multiple_shards('DELETE FROM multi_outer_join_left_hash');
|
|
master_modify_multiple_shards
|
|
-------------------------------
|
|
20
|
|
(1 row)
|
|
|
|
SELECT master_modify_multiple_shards('DELETE FROM multi_outer_join_right_hash');
|
|
master_modify_multiple_shards
|
|
-------------------------------
|
|
45
|
|
(1 row)
|
|
|
|
DELETE FROM multi_outer_join_right_reference;
|
|
-- reload shards with 1-1 matching
|
|
\copy multi_outer_join_left_hash FROM '@abs_srcdir@/data/customer-1-15.data' with delimiter '|'
|
|
\copy multi_outer_join_left_hash FROM '@abs_srcdir@/data/customer-21-30.data' with delimiter '|'
|
|
\copy multi_outer_join_right_reference FROM '@abs_srcdir@/data/customer-11-20.data' with delimiter '|'
|
|
\copy multi_outer_join_right_reference FROM '@abs_srcdir@/data/customer-21-30.data' with delimiter '|'
|
|
\copy multi_outer_join_right_hash FROM '@abs_srcdir@/data/customer-11-20.data' with delimiter '|'
|
|
\copy multi_outer_join_right_hash FROM '@abs_srcdir@/data/customer-21-30.data' with delimiter '|'
|
|
-- multi_outer_join_third_reference is a single shard table
|
|
-- Regular left join should work as expected
|
|
SELECT
|
|
min(l_custkey), max(l_custkey)
|
|
FROM
|
|
multi_outer_join_left_hash a LEFT JOIN multi_outer_join_right_hash b ON (l_custkey = r_custkey);
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ local partition join "multi_outer_join_right_hash" ]
|
|
min | max
|
|
-----+-----
|
|
1 | 30
|
|
(1 row)
|
|
|
|
-- Citus can use broadcast join here
|
|
SELECT
|
|
count(*)
|
|
FROM
|
|
multi_outer_join_left_hash a LEFT JOIN multi_outer_join_right_hash b ON (l_nationkey = r_nationkey);
|
|
ERROR: cannot run outer join query if join is not on the partition column
|
|
DETAIL: Outer joins requiring repartitioning are not supported.
|
|
-- Anti-join should return customers for which there is no row in the right table
|
|
SELECT
|
|
min(l_custkey), max(l_custkey)
|
|
FROM
|
|
multi_outer_join_left_hash a LEFT JOIN multi_outer_join_right_reference b ON (l_custkey = r_custkey)
|
|
WHERE
|
|
r_custkey IS NULL;
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ reference join "multi_outer_join_right_reference" ]
|
|
min | max
|
|
-----+-----
|
|
1 | 10
|
|
(1 row)
|
|
|
|
-- Partial anti-join with specific value (5, 11-15)
|
|
SELECT
|
|
min(l_custkey), max(l_custkey)
|
|
FROM
|
|
multi_outer_join_left_hash a LEFT JOIN multi_outer_join_right_reference b ON (l_custkey = r_custkey)
|
|
WHERE
|
|
r_custkey IS NULL OR r_custkey = 15;
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ reference join "multi_outer_join_right_reference" ]
|
|
min | max
|
|
-----+-----
|
|
1 | 15
|
|
(1 row)
|
|
|
|
-- This query is an INNER JOIN in disguise since there cannot be NULL results (21)
|
|
-- Added extra filter to make query not router plannable
|
|
SELECT
|
|
min(l_custkey), max(l_custkey)
|
|
FROM
|
|
multi_outer_join_left_hash a LEFT JOIN multi_outer_join_right_reference b ON (l_custkey = r_custkey)
|
|
WHERE
|
|
r_custkey = 21 or r_custkey < 10;
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ reference join "multi_outer_join_right_reference" ]
|
|
min | max
|
|
-----+-----
|
|
21 | 21
|
|
(1 row)
|
|
|
|
-- Apply a filter before the join
|
|
SELECT
|
|
count(l_custkey), count(r_custkey)
|
|
FROM
|
|
multi_outer_join_left_hash a LEFT JOIN multi_outer_join_right_reference b
|
|
ON (l_custkey = r_custkey AND r_custkey = 21);
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ reference join "multi_outer_join_right_reference" ]
|
|
count | count
|
|
-------+-------
|
|
25 | 1
|
|
(1 row)
|
|
|
|
-- Right join should not be allowed in this case
|
|
SELECT
|
|
min(r_custkey), max(r_custkey)
|
|
FROM
|
|
multi_outer_join_left_hash a RIGHT JOIN multi_outer_join_right_reference b ON (l_custkey = r_custkey);
|
|
ERROR: cannot run outer join query if join is not on the partition column
|
|
DETAIL: Outer joins requiring repartitioning are not supported.
|
|
-- Reverse right join should be same as left join
|
|
SELECT
|
|
min(l_custkey), max(l_custkey)
|
|
FROM
|
|
multi_outer_join_right_reference a RIGHT JOIN multi_outer_join_left_hash b ON (l_custkey = r_custkey);
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ reference join "multi_outer_join_right_reference" ]
|
|
min | max
|
|
-----+-----
|
|
1 | 30
|
|
(1 row)
|
|
|
|
-- complex query tree should error out
|
|
SELECT
|
|
*
|
|
FROM
|
|
multi_outer_join_left_hash l1
|
|
LEFT JOIN multi_outer_join_right_reference r1 ON (l1.l_custkey = r1.r_custkey)
|
|
LEFT JOIN multi_outer_join_right_reference r2 ON (l1.l_custkey = r2.r_custkey)
|
|
RIGHT JOIN multi_outer_join_left_hash l2 ON (r2.r_custkey = l2.l_custkey);
|
|
ERROR: could not run distributed query with complex join orders
|
|
HINT: Consider joining tables on partition column and have equal filter on joining columns.
|
|
-- add an anti-join, this should also error out
|
|
SELECT
|
|
*
|
|
FROM
|
|
multi_outer_join_left_hash l1
|
|
LEFT JOIN multi_outer_join_right_reference r1 ON (l1.l_custkey = r1.r_custkey)
|
|
LEFT JOIN multi_outer_join_right_reference r2 ON (l1.l_custkey = r2.r_custkey)
|
|
RIGHT JOIN multi_outer_join_left_hash l2 ON (r2.r_custkey = l2.l_custkey)
|
|
WHERE
|
|
r1.r_custkey is NULL;
|
|
ERROR: could not run distributed query with complex join orders
|
|
HINT: Consider joining tables on partition column and have equal filter on joining columns.
|
|
-- Three way join 2-1-1 (broadcast + broadcast join) should work
|
|
SELECT
|
|
l_custkey, r_custkey, t_custkey
|
|
FROM
|
|
multi_outer_join_left_hash l1
|
|
LEFT JOIN multi_outer_join_right_reference r1 ON (l1.l_custkey = r1.r_custkey)
|
|
LEFT JOIN multi_outer_join_third_reference t1 ON (r1.r_custkey = t1.t_custkey)
|
|
ORDER BY 1;
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ reference join "multi_outer_join_right_reference" ][ reference join "multi_outer_join_third_reference" ]
|
|
l_custkey | r_custkey | t_custkey
|
|
-----------+-----------+-----------
|
|
1 | |
|
|
2 | |
|
|
3 | |
|
|
4 | |
|
|
5 | |
|
|
6 | |
|
|
7 | |
|
|
8 | |
|
|
9 | |
|
|
10 | |
|
|
11 | 11 | 11
|
|
12 | 12 | 12
|
|
13 | 13 | 13
|
|
14 | 14 | 14
|
|
15 | 15 | 15
|
|
21 | 21 | 21
|
|
22 | 22 | 22
|
|
23 | 23 | 23
|
|
24 | 24 | 24
|
|
25 | 25 | 25
|
|
26 | 26 | 26
|
|
27 | 27 | 27
|
|
28 | 28 | 28
|
|
29 | 29 | 29
|
|
30 | 30 | 30
|
|
(25 rows)
|
|
|
|
-- Right join with single shard right most table should error out
|
|
SELECT
|
|
l_custkey, r_custkey, t_custkey
|
|
FROM
|
|
multi_outer_join_left_hash l1
|
|
LEFT JOIN multi_outer_join_right_hash r1 ON (l1.l_custkey = r1.r_custkey)
|
|
RIGHT JOIN multi_outer_join_third_reference t1 ON (r1.r_custkey = t1.t_custkey);
|
|
ERROR: could not run distributed query with complex join orders
|
|
HINT: Consider joining tables on partition column and have equal filter on joining columns.
|
|
-- Right join with single shard left most table should work
|
|
SELECT
|
|
t_custkey, r_custkey, l_custkey
|
|
FROM
|
|
multi_outer_join_third_reference t1
|
|
RIGHT JOIN multi_outer_join_right_hash r1 ON (t1.t_custkey = r1.r_custkey)
|
|
LEFT JOIN multi_outer_join_left_hash l1 ON (r1.r_custkey = l1.l_custkey)
|
|
ORDER BY 1,2,3;
|
|
LOG: join order: [ "multi_outer_join_right_hash" ][ reference join "multi_outer_join_third_reference" ][ local partition join "multi_outer_join_left_hash" ]
|
|
t_custkey | r_custkey | l_custkey
|
|
-----------+-----------+-----------
|
|
11 | 11 | 11
|
|
12 | 12 | 12
|
|
13 | 13 | 13
|
|
14 | 14 | 14
|
|
15 | 15 | 15
|
|
16 | 16 |
|
|
17 | 17 |
|
|
18 | 18 |
|
|
19 | 19 |
|
|
20 | 20 |
|
|
21 | 21 | 21
|
|
22 | 22 | 22
|
|
23 | 23 | 23
|
|
24 | 24 | 24
|
|
25 | 25 | 25
|
|
26 | 26 | 26
|
|
27 | 27 | 27
|
|
28 | 28 | 28
|
|
29 | 29 | 29
|
|
30 | 30 | 30
|
|
(20 rows)
|
|
|
|
-- Make it anti-join, should display values with l_custkey is null
|
|
SELECT
|
|
t_custkey, r_custkey, l_custkey
|
|
FROM
|
|
multi_outer_join_third_reference t1
|
|
RIGHT JOIN multi_outer_join_right_hash r1 ON (t1.t_custkey = r1.r_custkey)
|
|
LEFT JOIN multi_outer_join_left_hash l1 ON (r1.r_custkey = l1.l_custkey)
|
|
WHERE
|
|
l_custkey is NULL
|
|
ORDER BY 1;
|
|
LOG: join order: [ "multi_outer_join_right_hash" ][ reference join "multi_outer_join_third_reference" ][ local partition join "multi_outer_join_left_hash" ]
|
|
t_custkey | r_custkey | l_custkey
|
|
-----------+-----------+-----------
|
|
16 | 16 |
|
|
17 | 17 |
|
|
18 | 18 |
|
|
19 | 19 |
|
|
20 | 20 |
|
|
(5 rows)
|
|
|
|
-- Cascading right join with single shard left most table should error out
|
|
SELECT
|
|
t_custkey, r_custkey, l_custkey
|
|
FROM
|
|
multi_outer_join_third_reference t1
|
|
RIGHT JOIN multi_outer_join_right_hash r1 ON (t1.t_custkey = r1.r_custkey)
|
|
RIGHT JOIN multi_outer_join_left_hash l1 ON (r1.r_custkey = l1.l_custkey);
|
|
ERROR: could not run distributed query with complex join orders
|
|
HINT: Consider joining tables on partition column and have equal filter on joining columns.
|
|
-- full outer join should work with 1-1 matched shards
|
|
SELECT
|
|
l_custkey, r_custkey
|
|
FROM
|
|
multi_outer_join_left_hash l1
|
|
FULL JOIN multi_outer_join_right_hash r1 ON (l1.l_custkey = r1.r_custkey)
|
|
ORDER BY 1,2;
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ local partition join "multi_outer_join_right_hash" ]
|
|
l_custkey | r_custkey
|
|
-----------+-----------
|
|
1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 | 11
|
|
12 | 12
|
|
13 | 13
|
|
14 | 14
|
|
15 | 15
|
|
21 | 21
|
|
22 | 22
|
|
23 | 23
|
|
24 | 24
|
|
25 | 25
|
|
26 | 26
|
|
27 | 27
|
|
28 | 28
|
|
29 | 29
|
|
30 | 30
|
|
| 16
|
|
| 17
|
|
| 18
|
|
| 19
|
|
| 20
|
|
(30 rows)
|
|
|
|
-- full outer join + anti (right) should work with 1-1 matched shards
|
|
SELECT
|
|
l_custkey, r_custkey
|
|
FROM
|
|
multi_outer_join_left_hash l1
|
|
FULL JOIN multi_outer_join_right_hash r1 ON (l1.l_custkey = r1.r_custkey)
|
|
WHERE
|
|
r_custkey is NULL
|
|
ORDER BY 1;
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ local partition join "multi_outer_join_right_hash" ]
|
|
l_custkey | r_custkey
|
|
-----------+-----------
|
|
1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
(10 rows)
|
|
|
|
-- full outer join + anti (left) should work with 1-1 matched shards
|
|
SELECT
|
|
l_custkey, r_custkey
|
|
FROM
|
|
multi_outer_join_left_hash l1
|
|
FULL JOIN multi_outer_join_right_hash r1 ON (l1.l_custkey = r1.r_custkey)
|
|
WHERE
|
|
l_custkey is NULL
|
|
ORDER BY 2;
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ local partition join "multi_outer_join_right_hash" ]
|
|
l_custkey | r_custkey
|
|
-----------+-----------
|
|
| 16
|
|
| 17
|
|
| 18
|
|
| 19
|
|
| 20
|
|
(5 rows)
|
|
|
|
-- full outer join + anti (both) should work with 1-1 matched shards
|
|
SELECT
|
|
l_custkey, r_custkey
|
|
FROM
|
|
multi_outer_join_left_hash l1
|
|
FULL JOIN multi_outer_join_right_hash r1 ON (l1.l_custkey = r1.r_custkey)
|
|
WHERE
|
|
l_custkey is NULL or r_custkey is NULL
|
|
ORDER BY 1,2 DESC;
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ local partition join "multi_outer_join_right_hash" ]
|
|
l_custkey | r_custkey
|
|
-----------+-----------
|
|
1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
| 20
|
|
| 19
|
|
| 18
|
|
| 17
|
|
| 16
|
|
(15 rows)
|
|
|
|
-- full outer join should error out for mismatched shards
|
|
SELECT
|
|
l_custkey, t_custkey
|
|
FROM
|
|
multi_outer_join_left_hash l1
|
|
FULL JOIN multi_outer_join_third_reference t1 ON (l1.l_custkey = t1.t_custkey);
|
|
ERROR: cannot run outer join query if join is not on the partition column
|
|
DETAIL: Outer joins requiring repartitioning are not supported.
|
|
-- inner join + single shard left join should work
|
|
SELECT
|
|
l_custkey, r_custkey, t_custkey
|
|
FROM
|
|
multi_outer_join_left_hash l1
|
|
INNER JOIN multi_outer_join_right_hash r1 ON (l1.l_custkey = r1.r_custkey)
|
|
LEFT JOIN multi_outer_join_third_reference t1 ON (r1.r_custkey = t1.t_custkey)
|
|
ORDER BY 1;
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ local partition join "multi_outer_join_right_hash" ][ reference join "multi_outer_join_third_reference" ]
|
|
l_custkey | r_custkey | t_custkey
|
|
-----------+-----------+-----------
|
|
11 | 11 | 11
|
|
12 | 12 | 12
|
|
13 | 13 | 13
|
|
14 | 14 | 14
|
|
15 | 15 | 15
|
|
21 | 21 | 21
|
|
22 | 22 | 22
|
|
23 | 23 | 23
|
|
24 | 24 | 24
|
|
25 | 25 | 25
|
|
26 | 26 | 26
|
|
27 | 27 | 27
|
|
28 | 28 | 28
|
|
29 | 29 | 29
|
|
30 | 30 | 30
|
|
(15 rows)
|
|
|
|
-- inner (broadcast) join + 2 shards left (local) join should work
|
|
SELECT
|
|
l_custkey, t_custkey, r_custkey
|
|
FROM
|
|
multi_outer_join_left_hash l1
|
|
INNER JOIN multi_outer_join_third_reference t1 ON (l1.l_custkey = t1.t_custkey)
|
|
LEFT JOIN multi_outer_join_right_hash r1 ON (l1.l_custkey = r1.r_custkey)
|
|
ORDER BY 1,2,3;
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ reference join "multi_outer_join_third_reference" ][ local partition join "multi_outer_join_right_hash" ]
|
|
l_custkey | t_custkey | r_custkey
|
|
-----------+-----------+-----------
|
|
1 | 1 |
|
|
2 | 2 |
|
|
3 | 3 |
|
|
4 | 4 |
|
|
5 | 5 |
|
|
6 | 6 |
|
|
7 | 7 |
|
|
8 | 8 |
|
|
9 | 9 |
|
|
10 | 10 |
|
|
11 | 11 | 11
|
|
12 | 12 | 12
|
|
13 | 13 | 13
|
|
14 | 14 | 14
|
|
15 | 15 | 15
|
|
21 | 21 | 21
|
|
22 | 22 | 22
|
|
23 | 23 | 23
|
|
24 | 24 | 24
|
|
25 | 25 | 25
|
|
26 | 26 | 26
|
|
27 | 27 | 27
|
|
28 | 28 | 28
|
|
29 | 29 | 29
|
|
30 | 30 | 30
|
|
(25 rows)
|
|
|
|
-- inner (local) join + 2 shards left (dual partition) join should error out
|
|
SELECT
|
|
t_custkey, l_custkey, r_custkey
|
|
FROM
|
|
multi_outer_join_third_reference t1
|
|
INNER JOIN multi_outer_join_left_hash l1 ON (l1.l_custkey = t1.t_custkey)
|
|
LEFT JOIN multi_outer_join_right_reference r1 ON (l1.l_custkey = r1.r_custkey);
|
|
ERROR: cannot run outer join query if join is not on the partition column
|
|
DETAIL: Outer joins requiring repartitioning are not supported.
|
|
-- inner (local) join + 2 shards left (dual partition) join should work
|
|
SELECT
|
|
l_custkey, t_custkey, r_custkey
|
|
FROM
|
|
multi_outer_join_left_hash l1
|
|
INNER JOIN multi_outer_join_third_reference t1 ON (l1.l_custkey = t1.t_custkey)
|
|
LEFT JOIN multi_outer_join_right_hash r1 ON (l1.l_custkey = r1.r_custkey)
|
|
ORDER BY 1,2,3;
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ reference join "multi_outer_join_third_reference" ][ local partition join "multi_outer_join_right_hash" ]
|
|
l_custkey | t_custkey | r_custkey
|
|
-----------+-----------+-----------
|
|
1 | 1 |
|
|
2 | 2 |
|
|
3 | 3 |
|
|
4 | 4 |
|
|
5 | 5 |
|
|
6 | 6 |
|
|
7 | 7 |
|
|
8 | 8 |
|
|
9 | 9 |
|
|
10 | 10 |
|
|
11 | 11 | 11
|
|
12 | 12 | 12
|
|
13 | 13 | 13
|
|
14 | 14 | 14
|
|
15 | 15 | 15
|
|
21 | 21 | 21
|
|
22 | 22 | 22
|
|
23 | 23 | 23
|
|
24 | 24 | 24
|
|
25 | 25 | 25
|
|
26 | 26 | 26
|
|
27 | 27 | 27
|
|
28 | 28 | 28
|
|
29 | 29 | 29
|
|
30 | 30 | 30
|
|
(25 rows)
|
|
|
|
-- inner (broadcast) join + 2 shards left (local) + anti join should work
|
|
SELECT
|
|
l_custkey, t_custkey, r_custkey
|
|
FROM
|
|
multi_outer_join_left_hash l1
|
|
INNER JOIN multi_outer_join_third_reference t1 ON (l1.l_custkey = t1.t_custkey)
|
|
LEFT JOIN multi_outer_join_right_hash r1 ON (l1.l_custkey = r1.r_custkey)
|
|
WHERE
|
|
r_custkey is NULL
|
|
ORDER BY 1;
|
|
LOG: join order: [ "multi_outer_join_left_hash" ][ reference join "multi_outer_join_third_reference" ][ local partition join "multi_outer_join_right_hash" ]
|
|
l_custkey | t_custkey | r_custkey
|
|
-----------+-----------+-----------
|
|
1 | 1 |
|
|
2 | 2 |
|
|
3 | 3 |
|
|
4 | 4 |
|
|
5 | 5 |
|
|
6 | 6 |
|
|
7 | 7 |
|
|
8 | 8 |
|
|
9 | 9 |
|
|
10 | 10 |
|
|
(10 rows)
|
|
|
|
-- Test joinExpr aliases by performing an outer-join.
|
|
SELECT
|
|
t_custkey
|
|
FROM
|
|
(multi_outer_join_right_hash r1
|
|
LEFT OUTER JOIN multi_outer_join_left_hash l1 ON (l1.l_custkey = r1.r_custkey)) AS
|
|
test(c_custkey, c_nationkey)
|
|
INNER JOIN multi_outer_join_third_reference t1 ON (test.c_custkey = t1.t_custkey)
|
|
ORDER BY 1;
|
|
LOG: join order: [ "multi_outer_join_right_hash" ][ local partition join "multi_outer_join_left_hash" ][ reference join "multi_outer_join_third_reference" ]
|
|
t_custkey
|
|
-----------
|
|
11
|
|
12
|
|
13
|
|
14
|
|
15
|
|
16
|
|
17
|
|
18
|
|
19
|
|
20
|
|
21
|
|
22
|
|
23
|
|
24
|
|
25
|
|
26
|
|
27
|
|
28
|
|
29
|
|
30
|
|
(20 rows)
|
|
|
|
-- flattened out subqueries with outer joins are not supported
|
|
SELECT
|
|
l1.l_custkey,
|
|
count(*) as cnt
|
|
FROM (
|
|
SELECT l_custkey, l_nationkey
|
|
FROM multi_outer_join_left_hash
|
|
WHERE l_comment like '%a%'
|
|
) l1
|
|
LEFT JOIN (
|
|
SELECT r_custkey, r_name
|
|
FROM multi_outer_join_right_reference
|
|
WHERE r_comment like '%b%'
|
|
) l2 ON l1.l_custkey = l2.r_custkey
|
|
GROUP BY l1.l_custkey
|
|
ORDER BY cnt DESC, l1.l_custkey DESC
|
|
LIMIT 20;
|
|
ERROR: cannot perform distributed planning on this query
|
|
DETAIL: Subqueries in outer joins are not supported
|
|
-- full join among reference tables should go thourgh router planner
|
|
SELECT
|
|
t_custkey, r_custkey
|
|
FROM
|
|
multi_outer_join_right_reference FULL JOIN
|
|
multi_outer_join_third_reference ON (t_custkey = r_custkey)
|
|
ORDER BY 1;
|
|
t_custkey | r_custkey
|
|
-----------+-----------
|
|
1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 | 11
|
|
12 | 12
|
|
13 | 13
|
|
14 | 14
|
|
15 | 15
|
|
16 | 16
|
|
17 | 17
|
|
18 | 18
|
|
19 | 19
|
|
20 | 20
|
|
21 | 21
|
|
22 | 22
|
|
23 | 23
|
|
24 | 24
|
|
25 | 25
|
|
26 | 26
|
|
27 | 27
|
|
28 | 28
|
|
29 | 29
|
|
30 | 30
|
|
(30 rows)
|
|
|
|
-- DROP unused tables to clean up workspace
|
|
DROP TABLE multi_outer_join_left_hash;
|
|
DROP TABLE multi_outer_join_right_reference;
|
|
DROP TABLE multi_outer_join_third_reference;
|
|
DROP TABLE multi_outer_join_right_hash;
|