From 56651c7511838cf74fd476a8d4ce7af022169ca7 Mon Sep 17 00:00:00 2001 From: Onder Kalaci Date: Thu, 20 Oct 2016 09:39:32 +0300 Subject: [PATCH] improve comments/ error checks for CTEs and set operations --- .../planner/multi_router_planner.c | 40 +++--- .../regress/expected/multi_insert_select.out | 124 +++++++++++------- src/test/regress/sql/multi_insert_select.sql | 91 +++++++------ 3 files changed, 147 insertions(+), 108 deletions(-) diff --git a/src/backend/distributed/planner/multi_router_planner.c b/src/backend/distributed/planner/multi_router_planner.c index cb7e20fb1..e14974eaa 100644 --- a/src/backend/distributed/planner/multi_router_planner.c +++ b/src/backend/distributed/planner/multi_router_planner.c @@ -551,6 +551,19 @@ ErrorIfMultiTaskRouterSelectQueryUnsupported(Query *query) "INSERT ... SELECT queries"))); } + /* + * We currently do not support CTEs. In order to handle CTEs, consider expanding + * IsPartitionColumnRecursive() to handle CTEs. + */ + if (subquery->cteList != NULL) + { + ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot perform distributed planning for the given " + "modification"), + errdetail("Common table expressions are not allowed in " + "INSERT ... SELECT queries"))); + } + /* see comment on AddUninstantiatedPartitionColumnEqualityQual() */ if (subquery->setOperations != NULL) { @@ -655,32 +668,15 @@ AddUninstantiatedPartitionColumnEqualityQual(Query *originalQuery) Assert(InsertSelectQuery(originalQuery)); - /* we currently do not support CTEs */ - if (originalQuery->cteList != NULL) - { - return; - } - subqueryEntry = ExtractSelectRangeTableEntry(originalQuery); subquery = subqueryEntry->subquery; /* - * We currently not support the subquery with set operations for three reasons. - * - * (i) Adding only a single qual where there are more than one join trees - * leads to an assertion failure on the standard planner (i.e., - * Assert(parse->jointree->quals == NULL); on plan_set_operations()). - * [THE ABOVE COMMENT IS TO EASE THE REVIEW, REMOVE LATER ON] - * - * (ii) There are potentially multiple jointree quals that we need to add - * the qual, and we haven't implemented that logic yet. - * - * (iii) We cannot get the source tables OID via target entries resorigtbl field. - * This makes hard to check the colocation requirement of the source and target - * tables. - * - * Note that we do not allow set operations on the lower level's of the subquery - * as well, which is handled on ErrorIfMultiTaskRouterSelectQueryUnsupported(). + * We currently not support the subquery with set operations. The main reason is that + * there is an "Assert(parse->jointree->quals == NULL);" on standard planner's execution + * path (i.e., plan_set_operations). + * If we are to add uninstantiated equality qual to the query, we may end up hitting that + * assertion, so it's better not to support for now. */ if (subquery->setOperations != NULL) { diff --git a/src/test/regress/expected/multi_insert_select.out b/src/test/regress/expected/multi_insert_select.out index 9da37beb8..72a26230d 100644 --- a/src/test/regress/expected/multi_insert_select.out +++ b/src/test/regress/expected/multi_insert_select.out @@ -640,10 +640,10 @@ DEBUG: sent COMMIT over connection 13300010 (1 row) -- TODO:: add hll and date_trunc -INSERT INTO agg_events (user_id, value_1_agg) -SELECT - user_id, sum(value_1 + value_2) -FROM +INSERT INTO agg_events (user_id, value_1_agg) +SELECT + user_id, sum(value_1 + value_2) +FROM raw_events_first GROUP BY user_id; DEBUG: StartTransactionCommand DEBUG: StartTransaction @@ -678,10 +678,10 @@ DEBUG: sent COMMIT over connection 13300009 DEBUG: sent COMMIT over connection 13300010 DEBUG: sent COMMIT over connection 13300010 -- FILTER CLAUSE -INSERT INTO agg_events (user_id, value_1_agg) -SELECT +INSERT INTO agg_events (user_id, value_1_agg) +SELECT user_id, sum(value_1 + value_2) FILTER (where value_3 = 15) -FROM +FROM raw_events_first GROUP BY user_id; DEBUG: StartTransactionCommand DEBUG: StartTransaction @@ -715,51 +715,15 @@ DEBUG: sent COMMIT over connection 13300009 DEBUG: sent COMMIT over connection 13300009 DEBUG: sent COMMIT over connection 13300010 DEBUG: sent COMMIT over connection 13300010 --- a very simple UNION query -INSERT INTO - raw_events_first(user_id) -SELECT - user_id -FROM - ((SELECT user_id FROM raw_events_first) UNION - (SELECT user_id FROM raw_events_second)) as foo; -DEBUG: StartTransactionCommand -DEBUG: StartTransaction -DEBUG: name: unnamed; blockState: DEFAULT; state: INPROGR, xid/subid/cid: 0/1/0, nestlvl: 1, children: -ERROR: cannot perform distributed planning for the given modification -DETAIL: Set operations are not allowed in INSERT ... SELECT queries --- same query with slightly different syntax, but this time we cannot push it down -INSERT INTO - raw_events_first(user_id) - (SELECT user_id FROM raw_events_first) UNION - (SELECT user_id FROM raw_events_first); -DEBUG: StartTransactionCommand -DEBUG: StartTransaction -DEBUG: name: unnamed; blockState: DEFAULT; state: INPROGR, xid/subid/cid: 0/1/0, nestlvl: 1, children: -ERROR: cannot perform distributed planning for the given modification -DETAIL: Set operations are not allowed in INSERT ... SELECT queries --- similar query with a filter on two of the queries -INSERT INTO - raw_events_first(user_id) -SELECT - user_id -FROM - ((SELECT user_id FROM raw_events_first WHERE user_id = 15) UNION - (SELECT user_id FROM raw_events_second where user_id = 17)) as foo; -DEBUG: StartTransactionCommand -DEBUG: StartTransaction -DEBUG: name: unnamed; blockState: DEFAULT; state: INPROGR, xid/subid/cid: 0/1/0, nestlvl: 1, children: -ERROR: cannot perform distributed planning for the given modification -DETAIL: Set operations are not allowed in INSERT ... SELECT queries -- TODO: UUIDs -- a test with reference table JOINs -INSERT INTO - agg_events (user_id, value_1_agg) -SELECT +INSERT INTO + agg_events (user_id, value_1_agg) +SELECT raw_events_first.user_id, sum(value_1) -FROM - reference_table, raw_events_first -WHERE +FROM + reference_table, raw_events_first +WHERE raw_events_first.user_id = reference_table.user_id GROUP BY raw_events_first.user_id; @@ -795,6 +759,68 @@ DEBUG: sent COMMIT over connection 13300009 DEBUG: sent COMMIT over connection 13300009 DEBUG: sent COMMIT over connection 13300010 DEBUG: sent COMMIT over connection 13300010 +-- We do not support CTEs +WITH fist_table_agg AS + (SELECT sum(value_1) as v1_agg, user_id FROM raw_events_first GROUP BY user_id) +INSERT INTO agg_events + (value_1_agg, user_id) + SELECT + v1_agg, user_id + FROM + fist_table_agg; +DEBUG: StartTransactionCommand +DEBUG: StartTransaction +DEBUG: name: unnamed; blockState: DEFAULT; state: INPROGR, xid/subid/cid: 0/1/0, nestlvl: 1, children: +ERROR: cannot perform distributed planning for the given modification +DETAIL: Common table expressions are not allowed in INSERT ... SELECT queries +-- We do not support CTEs in the INSERT as well +INSERT INTO agg_events + WITH sub_cte AS (SELECT 1) + SELECT + raw_events_first.user_id, (SELECT * FROM sub_cte) + FROM + raw_events_first; +DEBUG: StartTransactionCommand +DEBUG: StartTransaction +DEBUG: name: unnamed; blockState: DEFAULT; state: INPROGR, xid/subid/cid: 0/1/0, nestlvl: 1, children: +ERROR: cannot perform distributed planning for the given modification +DETAIL: Common table expressions are not allowed in INSERT ... SELECT queries +-- We do not support any set operations +INSERT INTO + raw_events_first(user_id) +SELECT + user_id +FROM + ((SELECT user_id FROM raw_events_first) UNION + (SELECT user_id FROM raw_events_second)) as foo; +DEBUG: StartTransactionCommand +DEBUG: StartTransaction +DEBUG: name: unnamed; blockState: DEFAULT; state: INPROGR, xid/subid/cid: 0/1/0, nestlvl: 1, children: +ERROR: cannot perform distributed planning for the given modification +DETAIL: Set operations are not allowed in INSERT ... SELECT queries +-- We do not support any set operations +INSERT INTO + raw_events_first(user_id) + (SELECT user_id FROM raw_events_first) INTERSECT + (SELECT user_id FROM raw_events_first); +DEBUG: StartTransactionCommand +DEBUG: StartTransaction +DEBUG: name: unnamed; blockState: DEFAULT; state: INPROGR, xid/subid/cid: 0/1/0, nestlvl: 1, children: +ERROR: cannot perform distributed planning for the given modification +DETAIL: Set operations are not allowed in INSERT ... SELECT queries +-- We do not support any set operations +INSERT INTO + raw_events_first(user_id) +SELECT + user_id +FROM + ((SELECT user_id FROM raw_events_first WHERE user_id = 15) EXCEPT + (SELECT user_id FROM raw_events_second where user_id = 17)) as foo; +DEBUG: StartTransactionCommand +DEBUG: StartTransaction +DEBUG: name: unnamed; blockState: DEFAULT; state: INPROGR, xid/subid/cid: 0/1/0, nestlvl: 1, children: +ERROR: cannot perform distributed planning for the given modification +DETAIL: Set operations are not allowed in INSERT ... SELECT queries -- unsupported JOIN INSERT INTO agg_events (value_4_agg, diff --git a/src/test/regress/sql/multi_insert_select.sql b/src/test/regress/sql/multi_insert_select.sql index 218d034eb..e04496a60 100644 --- a/src/test/regress/sql/multi_insert_select.sql +++ b/src/test/regress/sql/multi_insert_select.sql @@ -217,57 +217,74 @@ RETURNING user_id, value_1_agg; -- TODO:: add hll and date_trunc -INSERT INTO agg_events (user_id, value_1_agg) -SELECT - user_id, sum(value_1 + value_2) -FROM +INSERT INTO agg_events (user_id, value_1_agg) +SELECT + user_id, sum(value_1 + value_2) +FROM raw_events_first GROUP BY user_id; -- FILTER CLAUSE -INSERT INTO agg_events (user_id, value_1_agg) -SELECT +INSERT INTO agg_events (user_id, value_1_agg) +SELECT user_id, sum(value_1 + value_2) FILTER (where value_3 = 15) -FROM +FROM raw_events_first GROUP BY user_id; --- a very simple UNION query -INSERT INTO - raw_events_first(user_id) -SELECT - user_id -FROM - ((SELECT user_id FROM raw_events_first) UNION - (SELECT user_id FROM raw_events_second)) as foo; - --- same query with slightly different syntax, but this time we cannot push it down -INSERT INTO - raw_events_first(user_id) - (SELECT user_id FROM raw_events_first) UNION - (SELECT user_id FROM raw_events_first); - --- similar query with a filter on two of the queries -INSERT INTO - raw_events_first(user_id) -SELECT - user_id -FROM - ((SELECT user_id FROM raw_events_first WHERE user_id = 15) UNION - (SELECT user_id FROM raw_events_second where user_id = 17)) as foo; - -- TODO: UUIDs -- a test with reference table JOINs -INSERT INTO - agg_events (user_id, value_1_agg) -SELECT +INSERT INTO + agg_events (user_id, value_1_agg) +SELECT raw_events_first.user_id, sum(value_1) -FROM - reference_table, raw_events_first -WHERE +FROM + reference_table, raw_events_first +WHERE raw_events_first.user_id = reference_table.user_id GROUP BY raw_events_first.user_id; +-- We do not support CTEs +WITH fist_table_agg AS + (SELECT sum(value_1) as v1_agg, user_id FROM raw_events_first GROUP BY user_id) +INSERT INTO agg_events + (value_1_agg, user_id) + SELECT + v1_agg, user_id + FROM + fist_table_agg; + +-- We do not support CTEs in the INSERT as well +INSERT INTO agg_events + WITH sub_cte AS (SELECT 1) + SELECT + raw_events_first.user_id, (SELECT * FROM sub_cte) + FROM + raw_events_first; + +-- We do not support any set operations +INSERT INTO + raw_events_first(user_id) +SELECT + user_id +FROM + ((SELECT user_id FROM raw_events_first) UNION + (SELECT user_id FROM raw_events_second)) as foo; + +-- We do not support any set operations +INSERT INTO + raw_events_first(user_id) + (SELECT user_id FROM raw_events_first) INTERSECT + (SELECT user_id FROM raw_events_first); + +-- We do not support any set operations +INSERT INTO + raw_events_first(user_id) +SELECT + user_id +FROM + ((SELECT user_id FROM raw_events_first WHERE user_id = 15) EXCEPT + (SELECT user_id FROM raw_events_second where user_id = 17)) as foo; -- unsupported JOIN INSERT INTO agg_events