Allow DML commands with unreferenced SELECT CTEs

pull/2137/head
Marco Slot 2018-05-03 14:42:14 +02:00
parent f8cfe07fd1
commit 2f9c8c6af0
3 changed files with 70 additions and 6 deletions

View File

@ -573,6 +573,7 @@ CreateDistributedPlan(uint64 planId, Query *originalQuery, Query *query, ParamLi
DistributedPlan *distributedPlan = NULL;
MultiTreeRoot *logicalPlan = NULL;
List *subPlanList = NIL;
bool hasCtes = originalQuery->cteList != NIL;
if (IsModifyCommand(originalQuery))
{
@ -670,8 +671,13 @@ CreateDistributedPlan(uint64 planId, Query *originalQuery, Query *query, ParamLi
* We could simplify this code if the logical planner was capable of dealing
* with an original query. In that case, we would only have to filter the
* planner restriction context.
*
* Note that we check both for subplans and whether the query had CTEs
* prior to calling GenerateSubplansForSubqueriesAndCTEs. If none of
* the CTEs are referenced then there are no subplans, but we still want
* to retry the router planner.
*/
if (list_length(subPlanList) > 0)
if (list_length(subPlanList) > 0 || hasCtes)
{
Query *newQuery = copyObject(originalQuery);
bool setPartitionedTablesInherited = false;

View File

@ -1,5 +1,6 @@
CREATE SCHEMA recursive_dml_queries;
SET search_path TO recursive_dml_queries, public;
SET citus.next_shard_id TO 2370000;
CREATE TABLE recursive_dml_queries.distributed_table (tenant_id text, dept int, info jsonb);
SELECT create_distributed_table('distributed_table', 'tenant_id');
create_distributed_table
@ -274,8 +275,7 @@ DEBUG: subqueries are not supported within INSERT queries
HINT: Try rewriting your queries with 'INSERT INTO ... SELECT' syntax.
ERROR: subqueries are not supported within INSERT queries
HINT: Try rewriting your queries with 'INSERT INTO ... SELECT' syntax.
-- we error out of the CTE is not referenced
-- by any part of the query (e.g., cte2 is not referenced)
-- DML with an unreferenced SELECT CTE
WITH cte_1 AS (
WITH cte_2 AS (
SELECT tenant_id as cte2_id
@ -294,7 +294,49 @@ WHERE distributed_table.tenant_id < cte_1.tenant_id;
DEBUG: common table expressions are not supported in distributed modifications
DEBUG: generating subplan 20_1 for CTE cte_1: WITH cte_2 AS (SELECT second_distributed_table.tenant_id AS cte2_id FROM recursive_dml_queries.second_distributed_table WHERE (second_distributed_table.dept >= 2)) UPDATE recursive_dml_queries.distributed_table SET dept = 10 RETURNING tenant_id, dept, info
DEBUG: common table expressions are not supported in distributed modifications
ERROR: common table expressions are not supported in distributed modifications
DEBUG: Plan 20 query after replacing subqueries and CTEs: UPDATE recursive_dml_queries.distributed_table SET dept = 5 FROM (SELECT intermediate_result.tenant_id, intermediate_result.dept, intermediate_result.info FROM read_intermediate_result('20_1'::text, 'binary'::citus_copy_format) intermediate_result(tenant_id text, dept integer, info jsonb)) cte_1 WHERE (distributed_table.tenant_id < cte_1.tenant_id)
EXPLAIN (COSTS FALSE) WITH cte_1 AS (
WITH cte_2 AS (
SELECT tenant_id as cte2_id
FROM second_distributed_table
WHERE dept >= 2
)
UPDATE distributed_table
SET dept = 10
RETURNING *
)
UPDATE distributed_table
SET dept = 5
FROM cte_1
WHERE distributed_table.tenant_id < cte_1.tenant_id;
DEBUG: common table expressions are not supported in distributed modifications
DEBUG: generating subplan 22_1 for CTE cte_1: WITH cte_2 AS (SELECT second_distributed_table.tenant_id AS cte2_id FROM recursive_dml_queries.second_distributed_table WHERE (second_distributed_table.dept >= 2)) UPDATE recursive_dml_queries.distributed_table SET dept = 10 RETURNING tenant_id, dept, info
DEBUG: common table expressions are not supported in distributed modifications
DEBUG: Plan 22 query after replacing subqueries and CTEs: UPDATE recursive_dml_queries.distributed_table SET dept = 5 FROM (SELECT intermediate_result.tenant_id, intermediate_result.dept, intermediate_result.info FROM read_intermediate_result('22_1'::text, 'binary'::citus_copy_format) intermediate_result(tenant_id text, dept integer, info jsonb)) cte_1 WHERE (distributed_table.tenant_id < cte_1.tenant_id)
QUERY PLAN
------------------------------------------------------------------------------------------------
Custom Scan (Citus Router)
-> Distributed Subplan 22_1
-> Custom Scan (Citus Router)
Task Count: 4
Tasks Shown: One of 4
-> Task
Node: host=localhost port=57638 dbname=regression
-> Update on distributed_table_2370000 distributed_table
-> Seq Scan on distributed_table_2370000 distributed_table
Task Count: 4
Tasks Shown: One of 4
-> Task
Node: host=localhost port=57638 dbname=regression
-> Update on distributed_table_2370000 distributed_table
-> Nested Loop
Join Filter: (distributed_table.tenant_id < intermediate_result.tenant_id)
-> Function Scan on read_intermediate_result intermediate_result
-> Materialize
-> Seq Scan on distributed_table_2370000 distributed_table
(19 rows)
-- we don't support updating local table with a join with
-- distributed tables
UPDATE

View File

@ -1,5 +1,6 @@
CREATE SCHEMA recursive_dml_queries;
SET search_path TO recursive_dml_queries, public;
SET citus.next_shard_id TO 2370000;
CREATE TABLE recursive_dml_queries.distributed_table (tenant_id text, dept int, info jsonb);
SELECT create_distributed_table('distributed_table', 'tenant_id');
@ -216,8 +217,7 @@ INSERT INTO
second_distributed_table (tenant_id, dept)
VALUES ('3', (SELECT 3));
-- we error out of the CTE is not referenced
-- by any part of the query (e.g., cte2 is not referenced)
-- DML with an unreferenced SELECT CTE
WITH cte_1 AS (
WITH cte_2 AS (
SELECT tenant_id as cte2_id
@ -234,6 +234,22 @@ SET dept = 5
FROM cte_1
WHERE distributed_table.tenant_id < cte_1.tenant_id;
EXPLAIN (COSTS FALSE) WITH cte_1 AS (
WITH cte_2 AS (
SELECT tenant_id as cte2_id
FROM second_distributed_table
WHERE dept >= 2
)
UPDATE distributed_table
SET dept = 10
RETURNING *
)
UPDATE distributed_table
SET dept = 5
FROM cte_1
WHERE distributed_table.tenant_id < cte_1.tenant_id;
-- we don't support updating local table with a join with
-- distributed tables
UPDATE