mirror of https://github.com/citusdata/citus.git
Merge pull request #1106 from citusdata/error_out_cte_with_modify
Error out on CTEs with data modifying statementpull/1095/head
commit
2a13f23176
|
@ -127,7 +127,7 @@ static void ErrorIfInsertPartitionColumnDoesNotMatchSelect(Query *query,
|
||||||
Oid *
|
Oid *
|
||||||
selectPartitionColumnTableId);
|
selectPartitionColumnTableId);
|
||||||
static void AddUninstantiatedEqualityQual(Query *query, Var *targetPartitionColumnVar);
|
static void AddUninstantiatedEqualityQual(Query *query, Var *targetPartitionColumnVar);
|
||||||
|
static void ErrorIfQueryHasModifyingCTE(Query *queryTree);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MultiRouterPlanCreate creates a multi plan for the queries
|
* MultiRouterPlanCreate creates a multi plan for the queries
|
||||||
|
@ -202,8 +202,7 @@ CreateSingleTaskRouterPlan(Query *originalQuery, Query *query,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Assert(commandType == CMD_SELECT);
|
ErrorIfQueryHasModifyingCTE(query);
|
||||||
|
|
||||||
task = RouterSelectTask(originalQuery, restrictionContext, &placementList);
|
task = RouterSelectTask(originalQuery, restrictionContext, &placementList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2850,3 +2849,43 @@ InstantiatePartitionQual(Node *node, void *context)
|
||||||
|
|
||||||
return expression_tree_mutator(node, InstantiatePartitionQual, context);
|
return expression_tree_mutator(node, InstantiatePartitionQual, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ErrorIfQueryHasModifyingCTE checks if the query contains modifying common table
|
||||||
|
* expressions and errors out if it does.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ErrorIfQueryHasModifyingCTE(Query *queryTree)
|
||||||
|
{
|
||||||
|
ListCell *cteCell = NULL;
|
||||||
|
|
||||||
|
Assert(queryTree->commandType == CMD_SELECT);
|
||||||
|
|
||||||
|
/* we do not need to do anything if there are no CTEs */
|
||||||
|
if (queryTree->cteList == NIL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(cteCell, queryTree->cteList)
|
||||||
|
{
|
||||||
|
CommonTableExpr *cte = (CommonTableExpr *) lfirst(cteCell);
|
||||||
|
Query *cteQuery = (Query *) cte->ctequery;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Here we only check for command type of top level query. Normally there can be
|
||||||
|
* nested CTE, however PostgreSQL dictates that data-modifying statements must
|
||||||
|
* be at top level of CTE. Therefore it is OK to just check for top level.
|
||||||
|
* Similarly, we do not need to check for subqueries.
|
||||||
|
*/
|
||||||
|
if (cteQuery->commandType != CMD_SELECT)
|
||||||
|
{
|
||||||
|
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
|
errmsg("cannot perform distributed planning for the given "
|
||||||
|
"modification"),
|
||||||
|
errdetail("Data-modifying statements are not supported in "
|
||||||
|
"the WITH clauses of distributed queries.")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -439,6 +439,34 @@ DEBUG: predicate pruning for shardId 840004
|
||||||
DEBUG: predicate pruning for shardId 840005
|
DEBUG: predicate pruning for shardId 840005
|
||||||
ERROR: cannot perform distributed planning on this query
|
ERROR: cannot perform distributed planning on this query
|
||||||
DETAIL: Complex table expressions are currently unsupported
|
DETAIL: Complex table expressions are currently unsupported
|
||||||
|
-- CTE with queries other than SELECT is not supported
|
||||||
|
WITH new_article AS (
|
||||||
|
INSERT INTO articles_hash VALUES (1, 1, 'arsenous', 9572) RETURNING *
|
||||||
|
)
|
||||||
|
SELECT * FROM new_article;
|
||||||
|
ERROR: cannot perform distributed planning for the given modification
|
||||||
|
DETAIL: Data-modifying statements are not supported in the WITH clauses of distributed queries.
|
||||||
|
-- Modifying statement in nested CTE case is covered by PostgreSQL itself
|
||||||
|
WITH new_article AS (
|
||||||
|
WITH nested_cte AS (
|
||||||
|
INSERT INTO articles_hash VALUES (1, 1, 'arsenous', 9572) RETURNING *
|
||||||
|
)
|
||||||
|
SELECT * FROM nested_cte
|
||||||
|
)
|
||||||
|
SELECT * FROM new_article;
|
||||||
|
ERROR: WITH clause containing a data-modifying statement must be at the top level
|
||||||
|
LINE 2: WITH nested_cte AS (
|
||||||
|
^
|
||||||
|
-- Modifying statement in a CTE in subquwey is also covered by PostgreSQL
|
||||||
|
SELECT * FROM (
|
||||||
|
WITH new_article AS (
|
||||||
|
INSERT INTO articles_hash VALUES (1, 1, 'arsenous', 9572) RETURNING *
|
||||||
|
)
|
||||||
|
SELECT * FROM new_article
|
||||||
|
) AS subquery_cte;
|
||||||
|
ERROR: WITH clause containing a data-modifying statement must be at the top level
|
||||||
|
LINE 2: WITH new_article AS (
|
||||||
|
^
|
||||||
-- grouping sets are supported on single shard
|
-- grouping sets are supported on single shard
|
||||||
SELECT
|
SELECT
|
||||||
id, substring(title, 2, 1) AS subtitle, count(*)
|
id, substring(title, 2, 1) AS subtitle, count(*)
|
||||||
|
|
|
@ -226,6 +226,29 @@ WITH RECURSIVE hierarchy as (
|
||||||
ce.company_id = 2))
|
ce.company_id = 2))
|
||||||
SELECT * FROM hierarchy WHERE LEVEL <= 2;
|
SELECT * FROM hierarchy WHERE LEVEL <= 2;
|
||||||
|
|
||||||
|
-- CTE with queries other than SELECT is not supported
|
||||||
|
WITH new_article AS (
|
||||||
|
INSERT INTO articles_hash VALUES (1, 1, 'arsenous', 9572) RETURNING *
|
||||||
|
)
|
||||||
|
SELECT * FROM new_article;
|
||||||
|
|
||||||
|
-- Modifying statement in nested CTE case is covered by PostgreSQL itself
|
||||||
|
WITH new_article AS (
|
||||||
|
WITH nested_cte AS (
|
||||||
|
INSERT INTO articles_hash VALUES (1, 1, 'arsenous', 9572) RETURNING *
|
||||||
|
)
|
||||||
|
SELECT * FROM nested_cte
|
||||||
|
)
|
||||||
|
SELECT * FROM new_article;
|
||||||
|
|
||||||
|
-- Modifying statement in a CTE in subquwey is also covered by PostgreSQL
|
||||||
|
SELECT * FROM (
|
||||||
|
WITH new_article AS (
|
||||||
|
INSERT INTO articles_hash VALUES (1, 1, 'arsenous', 9572) RETURNING *
|
||||||
|
)
|
||||||
|
SELECT * FROM new_article
|
||||||
|
) AS subquery_cte;
|
||||||
|
|
||||||
-- grouping sets are supported on single shard
|
-- grouping sets are supported on single shard
|
||||||
SELECT
|
SELECT
|
||||||
id, substring(title, 2, 1) AS subtitle, count(*)
|
id, substring(title, 2, 1) AS subtitle, count(*)
|
||||||
|
|
Loading…
Reference in New Issue