mirror of https://github.com/citusdata/citus.git
257 lines
12 KiB
PL/PgSQL
257 lines
12 KiB
PL/PgSQL
\SET VERBOSITY terse
|
|
|
|
SET citus.next_shard_id TO 1513000;
|
|
SET citus.shard_replication_factor TO 1;
|
|
|
|
CREATE SCHEMA mixed_relkind_tests;
|
|
SET search_path TO mixed_relkind_tests;
|
|
|
|
-- ensure that coordinator is added to pg_dist_node
|
|
SET client_min_messages TO ERROR;
|
|
SELECT 1 FROM master_add_node('localhost', :master_port, groupId => 0);
|
|
RESET client_min_messages;
|
|
|
|
-- make results consistent
|
|
|
|
-- create test tables
|
|
CREATE TABLE postgres_local_table (a int);
|
|
|
|
CREATE TABLE partitioned_postgres_local_table(a int) PARTITION BY RANGE(a);
|
|
CREATE TABLE partitioned_postgres_local_table_1 PARTITION OF partitioned_postgres_local_table FOR VALUES FROM (0) TO (3);
|
|
CREATE TABLE partitioned_postgres_local_table_2 PARTITION OF partitioned_postgres_local_table FOR VALUES FROM (3) TO (1000);
|
|
|
|
CREATE TABLE reference_table(a int);
|
|
SELECT create_reference_table('reference_table');
|
|
|
|
CREATE VIEW view_on_ref AS SELECT * FROM reference_table;
|
|
|
|
CREATE TABLE citus_local_table(a int);
|
|
SELECT citus_add_local_table_to_metadata('citus_local_table');
|
|
|
|
CREATE VIEW view_on_citus_local AS SELECT * FROM citus_local_table;
|
|
|
|
CREATE UNLOGGED TABLE unlogged_distributed_table(a int, b int);
|
|
SELECT create_distributed_table('unlogged_distributed_table', 'a');
|
|
|
|
CREATE TABLE distributed_table(a int);
|
|
SELECT create_distributed_table('distributed_table', 'a');
|
|
|
|
CREATE VIEW view_on_dist AS SELECT * FROM distributed_table;
|
|
CREATE MATERIALIZED VIEW mat_view_on_dist AS SELECT * FROM distributed_table;
|
|
|
|
CREATE TABLE partitioned_distributed_table(a int, b int) PARTITION BY RANGE(a);
|
|
CREATE TABLE partitioned_distributed_table_1 PARTITION OF partitioned_distributed_table FOR VALUES FROM (0) TO (3);
|
|
CREATE TABLE partitioned_distributed_table_2 PARTITION OF partitioned_distributed_table FOR VALUES FROM (3) TO (1000);
|
|
SELECT create_distributed_table('partitioned_distributed_table', 'a');
|
|
|
|
CREATE VIEW view_on_part_dist AS SELECT * FROM partitioned_distributed_table;
|
|
CREATE MATERIALIZED VIEW mat_view_on_part_dist AS SELECT * FROM partitioned_distributed_table;
|
|
|
|
-- and insert some data
|
|
INSERT INTO postgres_local_table SELECT * FROM generate_series(0, 5);
|
|
INSERT INTO partitioned_postgres_local_table SELECT * FROM generate_series(0, 5);
|
|
INSERT INTO reference_table SELECT * FROM generate_series(0, 5);
|
|
INSERT INTO citus_local_table SELECT * FROM generate_series(0, 5);
|
|
INSERT INTO unlogged_distributed_table SELECT a,a+1 FROM generate_series(0, 5) AS a;
|
|
INSERT INTO distributed_table SELECT * FROM generate_series(0, 5);
|
|
INSERT INTO partitioned_distributed_table SELECT a,a+1 FROM generate_series(0, 5) AS a;
|
|
|
|
-- should work
|
|
SELECT * FROM partitioned_distributed_table UNION SELECT 1,1 ORDER BY 1,2;
|
|
SELECT * FROM partitioned_distributed_table UNION SELECT 1, * FROM postgres_local_table ORDER BY 1,2;
|
|
SELECT * FROM partitioned_distributed_table UNION SELECT * FROM unlogged_distributed_table ORDER BY 1,2;
|
|
SELECT *, 1 FROM postgres_local_table UNION SELECT * FROM unlogged_distributed_table ORDER BY 1,2;
|
|
SELECT * FROM unlogged_distributed_table UNION SELECT 1,1 ORDER BY 1,2;
|
|
SELECT 1 UNION SELECT * FROM citus_local_table ORDER BY 1;
|
|
|
|
SELECT * FROM view_on_part_dist UNION SELECT 1,1 ORDER BY 1,2;
|
|
SELECT * FROM mat_view_on_part_dist UNION SELECT 1,1 ORDER BY 1,2;
|
|
SELECT * FROM view_on_citus_local UNION SELECT 1 ORDER BY 1;
|
|
SELECT * FROM view_on_dist UNION SELECT 1 ORDER BY 1;
|
|
SELECT * FROM mat_view_on_dist UNION SELECT 1 ORDER BY 1;
|
|
|
|
SET client_min_messages TO DEBUG1;
|
|
|
|
-- can push down the union in subquery
|
|
SELECT * FROM (SELECT * FROM partitioned_distributed_table UNION SELECT * FROM partitioned_distributed_table) AS foo ORDER BY 1,2;
|
|
|
|
-- cannot push down the subquery, should evaluate subquery by creating a subplan
|
|
SELECT COUNT(*) FROM (SELECT b, random() FROM partitioned_distributed_table GROUP BY b) AS foo;
|
|
SELECT * FROM partitioned_distributed_table WHERE b IN (SELECT a FROM postgres_local_table) ORDER BY 1,2;
|
|
|
|
-- can push down the subquery
|
|
SELECT * FROM partitioned_distributed_table WHERE a IN (SELECT a FROM distributed_table) ORDER BY 1,2;
|
|
SELECT * FROM partitioned_distributed_table WHERE a IN (SELECT a FROM view_on_part_dist) ORDER BY 1,2;
|
|
SELECT * FROM distributed_table WHERE a IN (SELECT a FROM view_on_part_dist) ORDER BY 1;
|
|
SELECT * FROM view_on_dist WHERE a IN (SELECT a FROM view_on_part_dist) ORDER BY 1;
|
|
SELECT * FROM view_on_citus_local WHERE a IN (SELECT a FROM reference_table) ORDER BY 1;
|
|
SELECT COUNT(*) FROM (SELECT a, random() FROM partitioned_distributed_table GROUP BY a) AS foo;
|
|
|
|
-- should add (a IS NOT NULL) filters similar to regular distributed tables
|
|
RESET client_min_messages;
|
|
SELECT public.explain_has_is_not_null(
|
|
$$
|
|
EXPLAIN (COSTS OFF)
|
|
INSERT INTO partitioned_distributed_table SELECT * FROM partitioned_distributed_table;
|
|
$$);
|
|
SET client_min_messages TO DEBUG1;
|
|
|
|
SELECT COUNT(*) FROM partitioned_postgres_local_table JOIN distributed_table ON (true);
|
|
SELECT COUNT(*) FROM partitioned_postgres_local_table JOIN partitioned_distributed_table ON (true);
|
|
SELECT COUNT(*) FROM distributed_table JOIN partitioned_postgres_local_table ON (true);
|
|
INSERT INTO partitioned_distributed_table SELECT foo.* FROM partitioned_distributed_table AS foo JOIN citus_local_table ON (true);
|
|
INSERT INTO partitioned_distributed_table SELECT foo.* FROM distributed_table AS foo JOIN citus_local_table ON (true);
|
|
INSERT INTO distributed_table SELECT foo.a FROM partitioned_distributed_table AS foo JOIN citus_local_table ON (true);
|
|
|
|
SELECT COUNT(*) FROM reference_table LEFT JOIN partitioned_distributed_table ON true;
|
|
|
|
-- non-colocated subquery should work
|
|
SELECT COUNT(*) FROM
|
|
(SELECT *, random() FROM partitioned_distributed_table) AS foo,
|
|
(SELECT *, random() FROM partitioned_distributed_table) AS bar
|
|
WHERE foo.a = bar.b;
|
|
|
|
UPDATE partitioned_distributed_table SET b = foo.a FROM citus_local_table AS foo;
|
|
UPDATE partitioned_distributed_table SET b = foo.a FROM postgres_local_table AS foo;
|
|
UPDATE partitioned_distributed_table SET a = foo.a FROM postgres_local_table AS foo WHERE foo.a = partitioned_distributed_table.a;
|
|
UPDATE partitioned_distributed_table SET a = foo.a FROM citus_local_table AS foo WHERE foo.a = partitioned_distributed_table.a;
|
|
-- should fail
|
|
UPDATE partitioned_distributed_table SET a = foo.a FROM mat_view_on_part_dist AS foo WHERE foo.a = partitioned_distributed_table.a;
|
|
UPDATE partitioned_distributed_table SET a = foo.a FROM partitioned_distributed_table AS foo WHERE foo.a < partitioned_distributed_table.a;
|
|
UPDATE partitioned_distributed_table SET a = foo.a FROM distributed_table AS foo WHERE foo.a < partitioned_distributed_table.a;
|
|
|
|
-- should work
|
|
UPDATE partitioned_distributed_table SET a = foo.a FROM partitioned_distributed_table AS foo WHERE foo.a = partitioned_distributed_table.a;
|
|
UPDATE partitioned_distributed_table SET a = foo.a FROM view_on_part_dist AS foo WHERE foo.a = partitioned_distributed_table.a;
|
|
UPDATE partitioned_distributed_table SET a = foo.a FROM view_on_dist AS foo WHERE foo.a = partitioned_distributed_table.a;
|
|
UPDATE partitioned_distributed_table SET a = foo.a FROM view_on_ref AS foo WHERE foo.a = partitioned_distributed_table.a;
|
|
|
|
-- JOINs on the distribution key
|
|
SELECT COUNT(*) FROM partitioned_distributed_table p1 JOIN partitioned_distributed_table p2 USING (a);
|
|
SELECT COUNT(*) FROM unlogged_distributed_table u1 JOIN partitioned_distributed_table p2 USING (a);
|
|
SELECT COUNT(*) FROM partitioned_distributed_table p1 LEFT JOIN partitioned_distributed_table p2 USING (a);
|
|
|
|
-- lateral JOIN
|
|
SELECT COUNT(*) FROM partitioned_distributed_table p1 JOIN LATERAL (SELECT * FROM partitioned_distributed_table p2 WHERE p1.a = p2.a) AS foo ON (true);
|
|
|
|
-- router query
|
|
SELECT COUNT(*) FROM partitioned_distributed_table p1 JOIN partitioned_distributed_table p2 USING (a) WHERE a = 1;
|
|
|
|
-- repartition query
|
|
SET citus.enable_repartition_joins TO ON;
|
|
SELECT COUNT(*) FROM partitioned_distributed_table p1 JOIN partitioned_distributed_table p2 USING (b) WHERE b = 1;
|
|
SELECT COUNT(*) FROM unlogged_distributed_table u1 JOIN partitioned_distributed_table p2 USING (b) WHERE b = 1;
|
|
RESET citus.enable_repartition_joins;
|
|
|
|
-- joins with cte's
|
|
WITH cte_1 AS MATERIALIZED (SELECT * FROM partitioned_distributed_table)
|
|
SELECT COUNT(*) FROM cte_1;
|
|
|
|
WITH cte_1 AS MATERIALIZED (SELECT * FROM partitioned_distributed_table)
|
|
SELECT COUNT(*) FROM cte_1 JOIN partitioned_distributed_table USING (a);
|
|
|
|
WITH cte_1 AS MATERIALIZED (SELECT * FROM partitioned_distributed_table)
|
|
SELECT COUNT(*) FROM cte_1 JOIN partitioned_distributed_table USING (b);
|
|
|
|
-- multi shard colocated update
|
|
UPDATE partitioned_distributed_table dt
|
|
SET b = sub1.a + sub2.a
|
|
FROM (SELECT * FROM partitioned_distributed_table WHERE b = 1) AS sub1,
|
|
(SELECT * FROM partitioned_distributed_table WHERE b = 2) AS sub2
|
|
WHERE sub1.a = sub2.a AND sub1.a = dt.a AND dt.a > 1;
|
|
|
|
UPDATE unlogged_distributed_table dt
|
|
SET b = sub1.a + sub2.a
|
|
FROM (SELECT * FROM unlogged_distributed_table WHERE b = 1) AS sub1,
|
|
(SELECT * FROM unlogged_distributed_table WHERE b = 2) AS sub2
|
|
WHERE sub1.a = sub2.a AND sub1.a = dt.a AND dt.a > 1;
|
|
|
|
-- multi shard non-colocated update
|
|
WITH cte1 AS MATERIALIZED (SELECT * FROM partitioned_distributed_table WHERE b = 1),
|
|
cte2 AS MATERIALIZED (SELECT * FROM partitioned_distributed_table WHERE b = 2)
|
|
UPDATE partitioned_distributed_table dt SET b = cte1.a + cte2.a
|
|
FROM cte1, cte2 WHERE cte1.a != cte2.a AND cte1.a = dt.a AND dt.a > 1;
|
|
|
|
-- router update with CTE
|
|
UPDATE partitioned_distributed_table dt
|
|
SET b = sub1.a + sub2.a
|
|
FROM (SELECT * FROM partitioned_distributed_table WHERE b = 1) AS sub1,
|
|
(SELECT * FROM partitioned_distributed_table WHERE b = 2) AS sub2
|
|
WHERE sub1.a = sub2.a AND sub1.a = dt.a AND dt.a = 1;
|
|
|
|
-- INSERT .. SELECT via coordinator
|
|
RESET client_min_messages;
|
|
|
|
SELECT public.coordinator_plan($Q$
|
|
EXPLAIN (COSTS OFF)
|
|
INSERT INTO partitioned_distributed_table SELECT * FROM partitioned_distributed_table ORDER BY 1,2 LIMIT 5;
|
|
$Q$);
|
|
|
|
SELECT public.coordinator_plan($Q$
|
|
EXPLAIN (COSTS OFF)
|
|
INSERT INTO unlogged_distributed_table SELECT * FROM partitioned_distributed_table ORDER BY 1,2 LIMIT 5;
|
|
$Q$);
|
|
|
|
SELECT public.coordinator_plan($Q$
|
|
EXPLAIN (COSTS OFF)
|
|
INSERT INTO partitioned_distributed_table SELECT * FROM distributed_table ORDER BY 1 LIMIT 5;
|
|
$Q$);
|
|
|
|
-- INSERT .. SELECT via repartition
|
|
SELECT public.coordinator_plan($Q$
|
|
EXPLAIN (COSTS OFF)
|
|
INSERT INTO partitioned_distributed_table SELECT a + 1 FROM partitioned_distributed_table;
|
|
$Q$);
|
|
|
|
SELECT public.coordinator_plan($Q$
|
|
EXPLAIN (COSTS OFF)
|
|
INSERT INTO unlogged_distributed_table SELECT a + 1 FROM partitioned_distributed_table;
|
|
$Q$);
|
|
|
|
SELECT public.coordinator_plan($Q$
|
|
EXPLAIN (COSTS OFF)
|
|
INSERT INTO partitioned_distributed_table SELECT a + 1 FROM distributed_table;
|
|
$Q$);
|
|
|
|
SELECT public.coordinator_plan($Q$
|
|
EXPLAIN (COSTS OFF)
|
|
INSERT INTO partitioned_distributed_table SELECT a + 1 FROM unlogged_distributed_table;
|
|
$Q$);
|
|
|
|
SET client_min_messages TO DEBUG1;
|
|
|
|
-- some aggregate queries
|
|
SELECT sum(a) FROM partitioned_distributed_table;
|
|
SELECT ceil(regr_syy(a, b)) FROM partitioned_distributed_table;
|
|
SELECT ceil(regr_syy(a, b)) FROM unlogged_distributed_table;
|
|
|
|
-- pushdown WINDOW
|
|
SELECT public.coordinator_plan($Q$
|
|
EXPLAIN (COSTS OFF)
|
|
SELECT a, COUNT(*) OVER (PARTITION BY a) FROM partitioned_distributed_table ORDER BY 1,2;
|
|
$Q$);
|
|
|
|
-- pull to coordinator WINDOW
|
|
SELECT public.coordinator_plan($Q$
|
|
EXPLAIN (COSTS OFF)
|
|
SELECT a, COUNT(*) OVER (PARTITION BY a+1) FROM partitioned_distributed_table ORDER BY 1,2;
|
|
$Q$);
|
|
|
|
-- FOR UPDATE
|
|
SELECT * FROM partitioned_distributed_table WHERE a = 1 ORDER BY 1,2 FOR UPDATE;
|
|
SELECT * FROM unlogged_distributed_table WHERE a = 1 ORDER BY 1,2 FOR UPDATE;
|
|
|
|
VACUUM partitioned_distributed_table;
|
|
TRUNCATE partitioned_distributed_table;
|
|
|
|
SET client_min_messages TO ERROR;
|
|
|
|
-- drop column followed by SELECT in transaction block
|
|
BEGIN;
|
|
ALTER TABLE partitioned_distributed_table DROP COLUMN b CASCADE;
|
|
SELECT * FROM partitioned_distributed_table;
|
|
COMMIT;
|
|
|
|
-- cleanup at exit
|
|
DROP SCHEMA mixed_relkind_tests CASCADE;
|