mirror of https://github.com/citusdata/citus.git
Support materialized view joins as well
parent
5f46abffd9
commit
a008fc611c
|
@ -1476,7 +1476,8 @@ IsRecursivelyPlannableRelation(RangeTblEntry *rangeTableEntry)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return rangeTableEntry->relkind == RELKIND_PARTITIONED_TABLE ||
|
return rangeTableEntry->relkind == RELKIND_PARTITIONED_TABLE ||
|
||||||
rangeTableEntry->relkind == RELKIND_RELATION;
|
rangeTableEntry->relkind == RELKIND_RELATION ||
|
||||||
|
rangeTableEntry->relkind == RELKIND_MATVIEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1505,8 +1506,7 @@ ContainsLocalTableDistributedTableJoin(List *rangeTableList)
|
||||||
{
|
{
|
||||||
containsDistributedTable = true;
|
containsDistributedTable = true;
|
||||||
}
|
}
|
||||||
else if (IsCitusTableType(rangeTableEntry->relid, CITUS_LOCAL_TABLE) ||
|
else if (IsLocalTableRteOrMatView((Node*) rangeTableEntry))
|
||||||
!IsCitusTable(rangeTableEntry->relid))
|
|
||||||
{
|
{
|
||||||
/* we consider citus local tables as local table */
|
/* we consider citus local tables as local table */
|
||||||
containsLocalTable = true;
|
containsLocalTable = true;
|
||||||
|
@ -1542,7 +1542,7 @@ ContainsLocalTableSubqueryJoin(List *rangeTableList, Oid resultRelationId)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsCitusTable(rangeTableEntry->relid) && rangeTableEntry->relid != resultRelationId)
|
if (IsLocalTableRteOrMatView((Node*) rangeTableEntry) && rangeTableEntry->relid != resultRelationId)
|
||||||
{
|
{
|
||||||
containsLocalTable = true;
|
containsLocalTable = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,8 @@ SELECT create_distributed_table('distributed_table_composite', 'key');
|
||||||
|
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
CREATE MATERIALIZED VIEW mv1 AS SELECT * FROM postgres_table;
|
||||||
|
CREATE MATERIALIZED VIEW mv2 AS SELECT * FROM distributed_table;
|
||||||
SET client_min_messages TO DEBUG1;
|
SET client_min_messages TO DEBUG1;
|
||||||
-- the user doesn't allow local / distributed table joinn
|
-- the user doesn't allow local / distributed table joinn
|
||||||
SET citus.local_table_join_policy TO 'never';
|
SET citus.local_table_join_policy TO 'never';
|
||||||
|
@ -159,6 +161,79 @@ DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS c
|
||||||
0
|
0
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- materialized views should work too
|
||||||
|
SELECT count(*) FROM distributed_table JOIN mv1 USING(key);
|
||||||
|
DEBUG: Wrapping local relation "mv1" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true OFFSET 0
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true OFFSET 0
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.distributed_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) mv1 USING (key))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT count(*) FROM (SELECT * FROM distributed_table) d1 JOIN mv1 USING(key);
|
||||||
|
DEBUG: Wrapping local relation "mv1" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true OFFSET 0
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true OFFSET 0
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed_table.key, distributed_table.value, distributed_table.value_2 FROM local_table_join.distributed_table) d1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) mv1 USING (key))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT count(*) FROM reference_table JOIN mv1 USING(key);
|
||||||
|
DEBUG: Wrapping local relation "mv1" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true OFFSET 0
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true OFFSET 0
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.reference_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) mv1 USING (key))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT count(*) FROM distributed_table JOIN mv1 USING(key) JOIN reference_table USING (key);
|
||||||
|
DEBUG: Wrapping local relation "mv1" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true OFFSET 0
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true OFFSET 0
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((local_table_join.distributed_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) mv1 USING (key)) JOIN local_table_join.reference_table USING (key))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT count(*) FROM distributed_table JOIN mv2 USING(key);
|
||||||
|
DEBUG: Wrapping local relation "mv2" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true OFFSET 0
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true OFFSET 0
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.distributed_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) mv2 USING (key))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT count(*) FROM (SELECT * FROM distributed_table) d1 JOIN mv2 USING(key);
|
||||||
|
DEBUG: Wrapping local relation "mv2" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true OFFSET 0
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true OFFSET 0
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed_table.key, distributed_table.value, distributed_table.value_2 FROM local_table_join.distributed_table) d1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) mv2 USING (key))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT count(*) FROM reference_table JOIN mv2 USING(key);
|
||||||
|
DEBUG: Wrapping local relation "mv2" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true OFFSET 0
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true OFFSET 0
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.reference_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) mv2 USING (key))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT count(*) FROM distributed_table JOIN mv2 USING(key) JOIN reference_table USING (key);
|
||||||
|
DEBUG: Wrapping local relation "mv2" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true OFFSET 0
|
||||||
|
DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true OFFSET 0
|
||||||
|
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((local_table_join.distributed_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) mv2 USING (key)) JOIN local_table_join.reference_table USING (key))
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
-- partitioned tables should work as well
|
-- partitioned tables should work as well
|
||||||
SELECT count(*) FROM distributed_partitioned_table JOIN postgres_table USING(key);
|
SELECT count(*) FROM distributed_partitioned_table JOIN postgres_table USING(key);
|
||||||
DEBUG: Wrapping local relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0
|
DEBUG: Wrapping local relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0
|
||||||
|
@ -936,4 +1011,4 @@ SELECT master_remove_node('localhost', :master_port);
|
||||||
|
|
||||||
\set VERBOSITY terse
|
\set VERBOSITY terse
|
||||||
DROP SCHEMA local_table_join CASCADE;
|
DROP SCHEMA local_table_join CASCADE;
|
||||||
NOTICE: drop cascades to 9 other objects
|
NOTICE: drop cascades to 11 other objects
|
||||||
|
|
|
@ -26,6 +26,10 @@ CREATE TABLE local_partitioned_table_2 PARTITION OF local_partitioned_table FOR
|
||||||
CREATE TABLE distributed_table_composite (key int, value text, value_2 jsonb, primary key (key, value));
|
CREATE TABLE distributed_table_composite (key int, value text, value_2 jsonb, primary key (key, value));
|
||||||
SELECT create_distributed_table('distributed_table_composite', 'key');
|
SELECT create_distributed_table('distributed_table_composite', 'key');
|
||||||
|
|
||||||
|
CREATE MATERIALIZED VIEW mv1 AS SELECT * FROM postgres_table;
|
||||||
|
CREATE MATERIALIZED VIEW mv2 AS SELECT * FROM distributed_table;
|
||||||
|
|
||||||
|
|
||||||
SET client_min_messages TO DEBUG1;
|
SET client_min_messages TO DEBUG1;
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,6 +66,16 @@ SELECT count(*) FROM distributed_table JOIN local_partitioned_table USING(key);
|
||||||
SELECT count(*) FROM reference_table JOIN local_partitioned_table USING(key);
|
SELECT count(*) FROM reference_table JOIN local_partitioned_table USING(key);
|
||||||
SELECT count(*) FROM distributed_table JOIN local_partitioned_table USING(key) JOIN reference_table USING (key);
|
SELECT count(*) FROM distributed_table JOIN local_partitioned_table USING(key) JOIN reference_table USING (key);
|
||||||
|
|
||||||
|
-- materialized views should work too
|
||||||
|
SELECT count(*) FROM distributed_table JOIN mv1 USING(key);
|
||||||
|
SELECT count(*) FROM (SELECT * FROM distributed_table) d1 JOIN mv1 USING(key);
|
||||||
|
SELECT count(*) FROM reference_table JOIN mv1 USING(key);
|
||||||
|
SELECT count(*) FROM distributed_table JOIN mv1 USING(key) JOIN reference_table USING (key);
|
||||||
|
SELECT count(*) FROM distributed_table JOIN mv2 USING(key);
|
||||||
|
SELECT count(*) FROM (SELECT * FROM distributed_table) d1 JOIN mv2 USING(key);
|
||||||
|
SELECT count(*) FROM reference_table JOIN mv2 USING(key);
|
||||||
|
SELECT count(*) FROM distributed_table JOIN mv2 USING(key) JOIN reference_table USING (key);
|
||||||
|
|
||||||
-- partitioned tables should work as well
|
-- partitioned tables should work as well
|
||||||
SELECT count(*) FROM distributed_partitioned_table JOIN postgres_table USING(key);
|
SELECT count(*) FROM distributed_partitioned_table JOIN postgres_table USING(key);
|
||||||
SELECT count(*) FROM distributed_partitioned_table JOIN postgres_table USING(key) WHERE distributed_partitioned_table.key = 10;
|
SELECT count(*) FROM distributed_partitioned_table JOIN postgres_table USING(key) WHERE distributed_partitioned_table.key = 10;
|
||||||
|
|
Loading…
Reference in New Issue