mirror of https://github.com/citusdata/citus.git
251 lines
5.8 KiB
Plaintext
251 lines
5.8 KiB
Plaintext
--
|
|
-- Full join with subquery pushdown support
|
|
--
|
|
SET citus.next_shard_id TO 9000000;
|
|
CREATE SCHEMA full_join;
|
|
SET search_path TO full_join, public;
|
|
CREATE TABLE test_table_1(id int, val1 int);
|
|
CREATE TABLE test_table_2(id bigint, val1 int);
|
|
CREATE TABLE test_table_3(id int, val1 bigint);
|
|
SELECT create_distributed_table('test_table_1', 'id');
|
|
create_distributed_table
|
|
--------------------------
|
|
|
|
(1 row)
|
|
|
|
SELECT create_distributed_table('test_table_2', 'id');
|
|
create_distributed_table
|
|
--------------------------
|
|
|
|
(1 row)
|
|
|
|
SELECT create_distributed_table('test_table_3', 'id');
|
|
create_distributed_table
|
|
--------------------------
|
|
|
|
(1 row)
|
|
|
|
INSERT INTO test_table_1 VALUES(1,1),(2,2),(3,3);
|
|
INSERT INTO test_table_2 VALUES(2,2),(3,3),(4,4);
|
|
INSERT INTO test_table_3 VALUES(1,1),(3,3),(4,5);
|
|
-- Simple full outer join
|
|
SELECT id FROM test_table_1 FULL JOIN test_table_3 using(id) ORDER BY 1;
|
|
id
|
|
----
|
|
1
|
|
2
|
|
3
|
|
4
|
|
(4 rows)
|
|
|
|
-- Get all columns as the result of the full join
|
|
SELECT * FROM test_table_1 FULL JOIN test_table_3 using(id) ORDER BY 1;
|
|
id | val1 | val1
|
|
----+------+------
|
|
1 | 1 | 1
|
|
2 | 2 |
|
|
3 | 3 | 3
|
|
4 | | 5
|
|
(4 rows)
|
|
|
|
-- Join subqueries using single column
|
|
SELECT * FROM
|
|
(SELECT test_table_1.id FROM test_table_1 FULL JOIN test_table_3 using(id)) as j1
|
|
FULL JOIN
|
|
(SELECT test_table_1.id FROM test_table_1 FULL JOIN test_table_3 using(id)) as j2
|
|
USING(id)
|
|
ORDER BY 1;
|
|
id
|
|
----
|
|
1
|
|
2
|
|
3
|
|
|
|
|
|
(5 rows)
|
|
|
|
-- Join subqueries using multiple columns
|
|
SELECT * FROM
|
|
(SELECT test_table_1.id, test_table_1.val1 FROM test_table_1 FULL JOIN test_table_3 using(id)) as j1
|
|
FULL JOIN
|
|
(SELECT test_table_1.id, test_table_1.val1 FROM test_table_1 FULL JOIN test_table_3 using(id)) as j2
|
|
USING(id, val1)
|
|
ORDER BY 1;
|
|
id | val1
|
|
----+------
|
|
1 | 1
|
|
2 | 2
|
|
3 | 3
|
|
|
|
|
|
|
|
(5 rows)
|
|
|
|
-- Full join using multiple columns
|
|
SELECT * FROM test_table_1 FULL JOIN test_table_3 USING(id, val1) ORDER BY 1;
|
|
id | val1
|
|
----+------
|
|
1 | 1
|
|
2 | 2
|
|
3 | 3
|
|
4 | 5
|
|
(4 rows)
|
|
|
|
-- Full join with complicated target lists
|
|
SELECT count(DISTINCT id), (avg(test_table_1.val1) + id * id)::integer as avg_value, id::numeric IS NOT NULL as not_null
|
|
FROM test_table_1 FULL JOIN test_table_3 using(id)
|
|
WHERE id::bigint < 55
|
|
GROUP BY id
|
|
ORDER BY 2
|
|
ASC LIMIT 3;
|
|
count | avg_value | not_null
|
|
-------+-----------+----------
|
|
1 | 2 | t
|
|
1 | 6 | t
|
|
1 | 12 | t
|
|
(3 rows)
|
|
|
|
SELECT max(val1)
|
|
FROM test_table_1 FULL JOIN test_table_3 USING(id, val1)
|
|
GROUP BY test_table_1.id
|
|
ORDER BY 1;
|
|
max
|
|
-----
|
|
1
|
|
2
|
|
3
|
|
5
|
|
(4 rows)
|
|
|
|
-- Test the left join as well
|
|
SELECT max(val1)
|
|
FROM test_table_1 LEFT JOIN test_table_3 USING(id, val1)
|
|
GROUP BY test_table_1.id
|
|
ORDER BY 1;
|
|
max
|
|
-----
|
|
1
|
|
2
|
|
3
|
|
(3 rows)
|
|
|
|
-- Full outer join with different distribution column types, should error out
|
|
SELECT * FROM test_table_1 full join test_table_2 using(id);
|
|
ERROR: cannot push down this subquery
|
|
DETAIL: Shards of relations in subquery need to have 1-to-1 shard partitioning
|
|
-- Test when the non-distributed column has the value of NULL
|
|
INSERT INTO test_table_1 VALUES(7, NULL);
|
|
INSERT INTO test_table_2 VALUES(7, NULL);
|
|
INSERT INTO test_table_3 VALUES(7, NULL);
|
|
-- Get all columns as the result of the full join
|
|
SELECT * FROM test_table_1 FULL JOIN test_table_3 using(id) ORDER BY 1;
|
|
id | val1 | val1
|
|
----+------+------
|
|
1 | 1 | 1
|
|
2 | 2 |
|
|
3 | 3 | 3
|
|
4 | | 5
|
|
7 | |
|
|
(5 rows)
|
|
|
|
-- Get the same result (with multiple id)
|
|
SELECT * FROM test_table_1 FULL JOIN test_table_3 ON (test_table_1.id = test_table_3.id) ORDER BY 1;
|
|
id | val1 | id | val1
|
|
----+------+----+------
|
|
1 | 1 | 1 | 1
|
|
2 | 2 | |
|
|
3 | 3 | 3 | 3
|
|
7 | | 7 |
|
|
| | 4 | 5
|
|
(5 rows)
|
|
|
|
-- Full join using multiple columns
|
|
SELECT * FROM test_table_1 FULL JOIN test_table_3 USING(id, val1) ORDER BY 1;
|
|
id | val1
|
|
----+------
|
|
1 | 1
|
|
2 | 2
|
|
3 | 3
|
|
4 | 5
|
|
7 |
|
|
7 |
|
|
(6 rows)
|
|
|
|
-- In order to make the same test with different data types use text-varchar pair
|
|
-- instead of using int-bigint pair.
|
|
DROP TABLE test_table_1;
|
|
DROP TABLE test_table_2;
|
|
DROP TABLE test_table_3;
|
|
CREATE TABLE test_table_1(id int, val1 text);
|
|
CREATE TABLE test_table_2(id int, val1 varchar(30));
|
|
SELECT create_distributed_table('test_table_1', 'id');
|
|
create_distributed_table
|
|
--------------------------
|
|
|
|
(1 row)
|
|
|
|
SELECT create_distributed_table('test_table_2', 'id');
|
|
create_distributed_table
|
|
--------------------------
|
|
|
|
(1 row)
|
|
|
|
INSERT INTO test_table_1 VALUES(1,'val_1'),(2,'val_2'),(3,'val_3'), (4, NULL);
|
|
INSERT INTO test_table_2 VALUES(2,'val_2'),(3,'val_3'),(4,'val_4'), (5, NULL);
|
|
-- Simple full outer join
|
|
SELECT id FROM test_table_1 FULL JOIN test_table_2 using(id) ORDER BY 1;
|
|
id
|
|
----
|
|
1
|
|
2
|
|
3
|
|
4
|
|
5
|
|
(5 rows)
|
|
|
|
-- Get all columns as the result of the full join
|
|
SELECT * FROM test_table_1 FULL JOIN test_table_2 using(id) ORDER BY 1;
|
|
id | val1 | val1
|
|
----+-------+-------
|
|
1 | val_1 |
|
|
2 | val_2 | val_2
|
|
3 | val_3 | val_3
|
|
4 | | val_4
|
|
5 | |
|
|
(5 rows)
|
|
|
|
-- Join subqueries using multiple columns
|
|
SELECT * FROM
|
|
(SELECT test_table_1.id, test_table_1.val1 FROM test_table_1 FULL JOIN test_table_2 using(id)) as j1
|
|
FULL JOIN
|
|
(SELECT test_table_2.id, test_table_2.val1 FROM test_table_1 FULL JOIN test_table_2 using(id)) as j2
|
|
USING(id, val1)
|
|
ORDER BY 1,2;
|
|
id | val1
|
|
----+-------
|
|
1 | val_1
|
|
2 | val_2
|
|
3 | val_3
|
|
4 | val_4
|
|
4 |
|
|
5 |
|
|
|
|
|
|
|
|
(8 rows)
|
|
|
|
-- Full join using multiple columns
|
|
SELECT * FROM test_table_1 FULL JOIN test_table_2 USING(id, val1) ORDER BY 1,2;
|
|
id | val1
|
|
----+-------
|
|
1 | val_1
|
|
2 | val_2
|
|
3 | val_3
|
|
4 | val_4
|
|
4 |
|
|
5 |
|
|
(6 rows)
|
|
|
|
DROP SCHEMA full_join CASCADE;
|
|
NOTICE: drop cascades to 2 other objects
|
|
DETAIL: drop cascades to table test_table_1
|
|
drop cascades to table test_table_2
|