mirror of https://github.com/citusdata/citus.git
Recursively plan subqueries in WHERE clause when FROM recurs
parent
6ce4795f1c
commit
195ac948d2
|
@ -90,7 +90,6 @@ static bool ExtractSetOperationStatmentWalker(Node *node, List **setOperationLis
|
|||
static DeferredErrorMessage * DeferErrorIfUnsupportedTableCombination(Query *queryTree);
|
||||
static bool WindowPartitionOnDistributionColumn(Query *query);
|
||||
static bool AllTargetExpressionsAreColumnReferences(List *targetEntryList);
|
||||
static bool IsDistributedTableRTE(Node *node);
|
||||
static FieldSelect * CompositeFieldRecursive(Expr *expression, Query *query);
|
||||
static bool FullCompositeFieldList(List *compositeFieldList);
|
||||
static MultiNode * MultiNodeTree(Query *queryTree);
|
||||
|
@ -657,7 +656,8 @@ DeferErrorIfFromClauseRecurs(Query *queryTree)
|
|||
"cannot pushdown the subquery",
|
||||
"Reference tables are not allowed in FROM "
|
||||
"clause when the query has subqueries in "
|
||||
"WHERE clause", NULL);
|
||||
"WHERE clause and it references a column "
|
||||
"from another query", NULL);
|
||||
}
|
||||
else if (recurType == RECURRING_TUPLES_FUNCTION)
|
||||
{
|
||||
|
@ -665,7 +665,8 @@ DeferErrorIfFromClauseRecurs(Query *queryTree)
|
|||
"cannot pushdown the subquery",
|
||||
"Functions are not allowed in FROM "
|
||||
"clause when the query has subqueries in "
|
||||
"WHERE clause", NULL);
|
||||
"WHERE clause and it references a column "
|
||||
"from another query", NULL);
|
||||
}
|
||||
else if (recurType == RECURRING_TUPLES_RESULT_FUNCTION)
|
||||
{
|
||||
|
@ -673,7 +674,8 @@ DeferErrorIfFromClauseRecurs(Query *queryTree)
|
|||
"cannot pushdown the subquery",
|
||||
"Complex subqueries and CTEs are not allowed in "
|
||||
"the FROM clause when the query has subqueries in the "
|
||||
"WHERE clause", NULL);
|
||||
"WHERE clause and it references a column "
|
||||
"from another query", NULL);
|
||||
}
|
||||
else if (recurType == RECURRING_TUPLES_EMPTY_JOIN_TREE)
|
||||
{
|
||||
|
@ -681,7 +683,8 @@ DeferErrorIfFromClauseRecurs(Query *queryTree)
|
|||
"cannot pushdown the subquery",
|
||||
"Subqueries without FROM are not allowed in FROM "
|
||||
"clause when the outer query has subqueries in "
|
||||
"WHERE clause", NULL);
|
||||
"WHERE clause and it references a column "
|
||||
"from another query", NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1330,7 +1333,7 @@ QueryContainsDistributedTableRTE(Query *query)
|
|||
* is a range table relation entry that points to a distributed
|
||||
* relation (i.e., excluding reference tables).
|
||||
*/
|
||||
static bool
|
||||
bool
|
||||
IsDistributedTableRTE(Node *node)
|
||||
{
|
||||
RangeTblEntry *rangeTableEntry = NULL;
|
||||
|
|
|
@ -115,6 +115,9 @@ typedef struct VarLevelsUpWalkerContext
|
|||
static DeferredErrorMessage * RecursivelyPlanSubqueriesAndCTEs(Query *query,
|
||||
RecursivePlanningContext *
|
||||
context);
|
||||
static bool ShouldRecursivelyPlanAllSubqueriesInWhere(Query *query);
|
||||
static bool RecursivelyPlanAllSubqueries(Node *node,
|
||||
RecursivePlanningContext *planningContext);
|
||||
static DeferredErrorMessage * RecursivelyPlanCTEs(Query *query,
|
||||
RecursivePlanningContext *context);
|
||||
static bool RecursivelyPlanSubqueryWalker(Node *node, RecursivePlanningContext *context);
|
||||
|
@ -238,10 +241,85 @@ RecursivelyPlanSubqueriesAndCTEs(Query *query, RecursivePlanningContext *context
|
|||
RecursivelyPlanSetOperations(query, (Node *) query->setOperations, context);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the FROM clause is recurring (does not contain a distributed table),
|
||||
* then we cannot have any distributed tables appearing in subqueries in
|
||||
* the WHERE clause.
|
||||
*/
|
||||
if (ShouldRecursivelyPlanAllSubqueriesInWhere(query))
|
||||
{
|
||||
/* replace all subqueries in the WHERE clause */
|
||||
RecursivelyPlanAllSubqueries((Node *) query->jointree->quals, context);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ShouldRecursivelyPlanAllSubqueriesInWhere returns true if the query has
|
||||
* a WHERE clause and a recurring FROM clause (does not contain a distributed
|
||||
* table).
|
||||
*/
|
||||
static bool
|
||||
ShouldRecursivelyPlanAllSubqueriesInWhere(Query *query)
|
||||
{
|
||||
FromExpr *joinTree = NULL;
|
||||
Node *whereClause = NULL;
|
||||
|
||||
joinTree = query->jointree;
|
||||
if (joinTree == NULL)
|
||||
{
|
||||
/* there is no FROM clause */
|
||||
return false;
|
||||
}
|
||||
|
||||
whereClause = joinTree->quals;
|
||||
if (whereClause == NULL)
|
||||
{
|
||||
/* there is no WHERE clause */
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FindNodeCheckInRangeTableList(query->rtable, IsDistributedTableRTE))
|
||||
{
|
||||
/* there is a distributed table in the FROM clause */
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RecursivelyPlanAllSubqueries descends into an expression tree and recursively
|
||||
* plans all subqueries that contain at least one distributed table. The recursive
|
||||
* planning starts from the top of the input query.
|
||||
*/
|
||||
static bool
|
||||
RecursivelyPlanAllSubqueries(Node *node, RecursivePlanningContext *planningContext)
|
||||
{
|
||||
if (node == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsA(node, Query))
|
||||
{
|
||||
Query *query = (Query *) node;
|
||||
|
||||
if (FindNodeCheckInRangeTableList(query->rtable, IsDistributedTableRTE))
|
||||
{
|
||||
RecursivelyPlanSubquery(query, planningContext);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return expression_tree_walker(node, RecursivelyPlanAllSubqueries, planningContext);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RecursivelyPlanCTEs plans all CTEs in the query by recursively calling the planner
|
||||
* The resulting plan is added to planningContext->subPlanList and CTE references
|
||||
|
|
|
@ -195,6 +195,7 @@ extern DeferredErrorMessage * DeferErrorIfUnsupportedUnionQuery(Query *queryTree
|
|||
extern bool SafeToPushdownWindowFunction(Query *query, StringInfo *errorDetail);
|
||||
extern bool TargetListOnPartitionColumn(Query *query, List *targetEntryList);
|
||||
extern bool FindNodeCheckInRangeTableList(List *rtable, bool (*check)(Node *));
|
||||
extern bool IsDistributedTableRTE(Node *node);
|
||||
extern bool QueryContainsDistributedTableRTE(Query *query);
|
||||
extern bool ContainsReadIntermediateResultFunction(Node *node);
|
||||
extern MultiNode * ParentNode(MultiNode *multiNode);
|
||||
|
|
|
@ -46,8 +46,8 @@ LIMIT 3;
|
|||
---------
|
||||
(0 rows)
|
||||
|
||||
-- subqueries in WHERE with NOT EXISTS operator, should not work
|
||||
-- there is a reference table in the outer part of the join
|
||||
-- subqueries in WHERE with NOT EXISTS operator, should not work since
|
||||
-- there is a correlated subquery in WHERE clause
|
||||
SELECT
|
||||
user_id
|
||||
FROM
|
||||
|
@ -63,8 +63,9 @@ WHERE
|
|||
)
|
||||
LIMIT 3;
|
||||
ERROR: cannot pushdown the subquery
|
||||
DETAIL: Reference tables are not allowed in FROM clause when the query has subqueries in WHERE clause
|
||||
-- immutable functions are also treated as reference tables
|
||||
DETAIL: Reference tables are not allowed in FROM clause when the query has subqueries in WHERE clause and it references a column from another query
|
||||
-- immutable functions are also treated as reference tables, query should not
|
||||
-- work since there is a correlated subquery in the WHERE clause
|
||||
SELECT
|
||||
user_id
|
||||
FROM
|
||||
|
@ -80,8 +81,9 @@ WHERE
|
|||
)
|
||||
LIMIT 3;
|
||||
ERROR: cannot pushdown the subquery
|
||||
DETAIL: Functions are not allowed in FROM clause when the query has subqueries in WHERE clause
|
||||
-- subqueries without FROM are also treated as reference tables
|
||||
DETAIL: Functions are not allowed in FROM clause when the query has subqueries in WHERE clause and it references a column from another query
|
||||
-- subqueries without FROM are also treated as reference tables, query should not
|
||||
-- work since there is a correlated subquery in the WHERE clause
|
||||
SELECT
|
||||
user_id
|
||||
FROM
|
||||
|
@ -97,7 +99,7 @@ WHERE
|
|||
)
|
||||
LIMIT 3;
|
||||
ERROR: cannot pushdown the subquery
|
||||
DETAIL: Subqueries without FROM are not allowed in FROM clause when the outer query has subqueries in WHERE clause
|
||||
DETAIL: Subqueries without FROM are not allowed in FROM clause when the outer query has subqueries in WHERE clause and it references a column from another query
|
||||
-- join with distributed table prevents FROM from recurring
|
||||
SELECT
|
||||
DISTINCT user_id
|
||||
|
@ -413,7 +415,9 @@ ORDER BY 1, 2;
|
|||
5 | 5
|
||||
(2 rows)
|
||||
|
||||
-- reference tables are not allowed if there is sublink
|
||||
-- change debug level to check recursive planning output
|
||||
SET client_min_messages TO DEBUG1;
|
||||
-- recursively planning subqueries in WHERE clause due to recurring table in FROM
|
||||
SELECT
|
||||
count(*)
|
||||
FROM
|
||||
|
@ -421,9 +425,14 @@ FROM
|
|||
WHERE user_id
|
||||
NOT IN
|
||||
(SELECT users_table.value_2 FROM users_table JOIN users_reference_table as u2 ON users_table.value_2 = u2.value_2);
|
||||
ERROR: cannot pushdown the subquery
|
||||
DETAIL: Reference tables are not allowed in FROM clause when the query has subqueries in WHERE clause
|
||||
-- reference tables are not allowed if there is sublink
|
||||
DEBUG: generating subplan 16_1 for subquery SELECT users_table.value_2 FROM (public.users_table JOIN public.users_reference_table u2 ON ((users_table.value_2 = u2.value_2)))
|
||||
DEBUG: Plan 16 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM public.users_reference_table WHERE (NOT (user_id IN (SELECT intermediate_result.value_2 FROM read_intermediate_result('16_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer))))
|
||||
count
|
||||
-------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
-- recursively planning subqueries in WHERE clause due to recurring table in FROM
|
||||
SELECT count(*)
|
||||
FROM
|
||||
(SELECT
|
||||
|
@ -432,9 +441,14 @@ FROM
|
|||
(SELECT users_table.value_2
|
||||
FROM users_table
|
||||
JOIN users_reference_table AS u2 ON users_table.value_2 = u2.value_2);
|
||||
ERROR: cannot pushdown the subquery
|
||||
DETAIL: Reference tables are not allowed in FROM clause when the query has subqueries in WHERE clause
|
||||
-- reference tables are not allowed if there is sublink
|
||||
DEBUG: generating subplan 18_1 for subquery SELECT users_table.value_2 FROM (public.users_table JOIN public.users_reference_table u2 ON ((users_table.value_2 = u2.value_2)))
|
||||
DEBUG: Plan 18 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT users_reference_table.user_id, random() AS random FROM public.users_reference_table) vals WHERE (NOT (user_id IN (SELECT intermediate_result.value_2 FROM read_intermediate_result('18_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer))))
|
||||
count
|
||||
-------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
-- query should not work since there is a correlated subquery in the WHERE clause
|
||||
SELECT user_id,
|
||||
count(*)
|
||||
FROM users_reference_table
|
||||
|
@ -449,9 +463,8 @@ ORDER BY 2 DESC,
|
|||
1 DESC
|
||||
LIMIT 5;
|
||||
ERROR: cannot pushdown the subquery
|
||||
DETAIL: Reference tables are not allowed in FROM clause when the query has subqueries in WHERE clause
|
||||
-- reference tables are not allowed if there is sublink
|
||||
-- this time in the subquery
|
||||
DETAIL: Reference tables are not allowed in FROM clause when the query has subqueries in WHERE clause and it references a column from another query
|
||||
-- query will be planned as a SEMI JOIN
|
||||
SELECT *
|
||||
FROM users_table
|
||||
WHERE user_id IN
|
||||
|
@ -463,6 +476,7 @@ WHERE user_id IN
|
|||
FROM users_reference_table AS u2))
|
||||
ORDER BY 1,2,3
|
||||
LIMIT 5;
|
||||
DEBUG: push down of limit count: 5
|
||||
user_id | time | value_1 | value_2 | value_3 | value_4
|
||||
---------+---------------------------------+---------+---------+---------+---------
|
||||
1 | Wed Nov 22 22:51:43.132261 2017 | 4 | 0 | 3 |
|
||||
|
@ -472,6 +486,7 @@ LIMIT 5;
|
|||
1 | Thu Nov 23 11:44:57.515981 2017 | 4 | 3 | 4 |
|
||||
(5 rows)
|
||||
|
||||
SET client_min_messages TO DEFAULT;
|
||||
-- not supported since GROUP BY references to an upper level query
|
||||
SELECT
|
||||
user_id
|
||||
|
|
|
@ -260,11 +260,26 @@ DEBUG: Plan 45 query after replacing subqueries and CTEs: SELECT u.x, u.y, test
|
|||
---+---+---
|
||||
(0 rows)
|
||||
|
||||
-- distributed table in WHERE clause, but not FROM clause still disallowed
|
||||
-- set operations and the sublink can be recursively planned
|
||||
SELECT * FROM ((SELECT x FROM test) UNION (SELECT x FROM (SELECT x FROM local_test) as foo WHERE x IN (SELECT x FROM test))) u ORDER BY 1;
|
||||
DEBUG: generating subplan 48_1 for subquery SELECT x FROM recursive_set_local.local_test
|
||||
ERROR: cannot pushdown the subquery
|
||||
DETAIL: Complex subqueries and CTEs are not allowed in the FROM clause when the query has subqueries in the WHERE clause
|
||||
DEBUG: generating subplan 48_2 for subquery SELECT x FROM recursive_set_local.test
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
DEBUG: generating subplan 48_3 for subquery SELECT x FROM (SELECT intermediate_result.x FROM read_intermediate_result('48_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer)) foo WHERE (x IN (SELECT intermediate_result.x FROM read_intermediate_result('48_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer)))
|
||||
DEBUG: generating subplan 48_4 for subquery SELECT x FROM recursive_set_local.test
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
DEBUG: generating subplan 48_5 for subquery SELECT intermediate_result.x FROM read_intermediate_result('48_4'::text, 'binary'::citus_copy_format) intermediate_result(x integer) UNION SELECT intermediate_result.x FROM read_intermediate_result('48_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer)
|
||||
DEBUG: Plan 48 query after replacing subqueries and CTEs: SELECT x FROM (SELECT intermediate_result.x FROM read_intermediate_result('48_5'::text, 'binary'::citus_copy_format) intermediate_result(x integer)) u ORDER BY x
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
x
|
||||
---
|
||||
1
|
||||
2
|
||||
(2 rows)
|
||||
|
||||
SET citus.enable_repartition_joins TO ON;
|
||||
-- repartition is recursively planned before the set operation
|
||||
(SELECT x FROM test) INTERSECT (SELECT t1.x FROM test as t1, test as t2 WHERE t1.x = t2.y LIMIT 2) INTERSECT (((SELECT x FROM local_test) UNION ALL (SELECT x FROM test)) INTERSECT (SELECT i FROM generate_series(0, 100) i)) ORDER BY 1 DESC;
|
||||
|
@ -299,11 +314,11 @@ DEBUG: pruning merge fetch taskId 11
|
|||
DETAIL: Creating dependency on merge taskId 24
|
||||
DEBUG: cannot use real time executor with repartition jobs
|
||||
HINT: Since you enabled citus.enable_repartition_joins Citus chose to use task-tracker.
|
||||
DEBUG: generating subplan 50_1 for subquery SELECT t1.x FROM recursive_set_local.test t1, recursive_set_local.test t2 WHERE (t1.x = t2.y) LIMIT 2
|
||||
DEBUG: generating subplan 50_2 for subquery SELECT x FROM recursive_set_local.local_test
|
||||
DEBUG: generating subplan 50_3 for subquery SELECT x FROM recursive_set_local.test
|
||||
DEBUG: generating subplan 50_4 for subquery SELECT x FROM recursive_set_local.test
|
||||
DEBUG: Plan 50 query after replacing subqueries and CTEs: SELECT intermediate_result.x FROM read_intermediate_result('50_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer) INTERSECT SELECT intermediate_result.x FROM read_intermediate_result('50_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer) INTERSECT ((SELECT intermediate_result.x FROM read_intermediate_result('50_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer) UNION ALL SELECT intermediate_result.x FROM read_intermediate_result('50_4'::text, 'binary'::citus_copy_format) intermediate_result(x integer)) INTERSECT SELECT i.i FROM generate_series(0, 100) i(i)) ORDER BY 1 DESC
|
||||
DEBUG: generating subplan 53_1 for subquery SELECT t1.x FROM recursive_set_local.test t1, recursive_set_local.test t2 WHERE (t1.x = t2.y) LIMIT 2
|
||||
DEBUG: generating subplan 53_2 for subquery SELECT x FROM recursive_set_local.local_test
|
||||
DEBUG: generating subplan 53_3 for subquery SELECT x FROM recursive_set_local.test
|
||||
DEBUG: generating subplan 53_4 for subquery SELECT x FROM recursive_set_local.test
|
||||
DEBUG: Plan 53 query after replacing subqueries and CTEs: SELECT intermediate_result.x FROM read_intermediate_result('53_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer) INTERSECT SELECT intermediate_result.x FROM read_intermediate_result('53_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer) INTERSECT ((SELECT intermediate_result.x FROM read_intermediate_result('53_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer) UNION ALL SELECT intermediate_result.x FROM read_intermediate_result('53_4'::text, 'binary'::citus_copy_format) intermediate_result(x integer)) INTERSECT SELECT i.i FROM generate_series(0, 100) i(i)) ORDER BY 1 DESC
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
x
|
||||
|
|
|
@ -549,24 +549,31 @@ DEBUG: Plan is router executable
|
|||
2 | 2
|
||||
(2 rows)
|
||||
|
||||
-- set operations are recursively planned and not the sublink, thus should error out
|
||||
-- set operations and the sublink can be recursively planned
|
||||
SELECT * FROM ((SELECT x,y FROM test) UNION (SELECT y,x FROM test)) foo WHERE x IN (SELECT y FROM test) ORDER BY 1;
|
||||
DEBUG: generating subplan 112_1 for subquery SELECT x, y FROM recursive_union.test
|
||||
DEBUG: generating subplan 112_2 for subquery SELECT y, x FROM recursive_union.test
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
DEBUG: generating subplan 112_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('112_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION SELECT intermediate_result.y, intermediate_result.x FROM read_intermediate_result('112_2'::text, 'binary'::citus_copy_format) intermediate_result(y integer, x integer)
|
||||
DEBUG: Plan 112 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('112_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) foo WHERE (x IN (SELECT test.y FROM recursive_union.test)) ORDER BY x
|
||||
ERROR: cannot pushdown the subquery
|
||||
DETAIL: Complex subqueries and CTEs are not allowed in the FROM clause when the query has subqueries in the WHERE clause
|
||||
DEBUG: generating subplan 112_4 for subquery SELECT y FROM recursive_union.test
|
||||
DEBUG: Plan 112 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('112_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) foo WHERE (x IN (SELECT intermediate_result.y FROM read_intermediate_result('112_4'::text, 'binary'::citus_copy_format) intermediate_result(y integer))) ORDER BY x
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
x | y
|
||||
---+---
|
||||
1 | 1
|
||||
2 | 2
|
||||
(2 rows)
|
||||
|
||||
-- set operations works fine with pushdownable window functions
|
||||
SELECT x, y, rnk FROM (SELECT *, rank() OVER my_win as rnk FROM test WINDOW my_win AS (PARTITION BY x ORDER BY y DESC)) as foo
|
||||
UNION
|
||||
SELECT x, y, rnk FROM (SELECT *, rank() OVER my_win as rnk FROM test WINDOW my_win AS (PARTITION BY x ORDER BY y DESC)) as bar
|
||||
ORDER BY 1 DESC, 2 DESC, 3 DESC;
|
||||
DEBUG: generating subplan 116_1 for subquery SELECT x, y, rnk FROM (SELECT test.x, test.y, rank() OVER my_win AS rnk FROM recursive_union.test WINDOW my_win AS (PARTITION BY test.x ORDER BY test.y DESC)) foo
|
||||
DEBUG: generating subplan 116_2 for subquery SELECT x, y, rnk FROM (SELECT test.x, test.y, rank() OVER my_win AS rnk FROM recursive_union.test WINDOW my_win AS (PARTITION BY test.x ORDER BY test.y DESC)) bar
|
||||
DEBUG: Plan 116 query after replacing subqueries and CTEs: SELECT intermediate_result.x, intermediate_result.y, intermediate_result.rnk FROM read_intermediate_result('116_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer, rnk bigint) UNION SELECT intermediate_result.x, intermediate_result.y, intermediate_result.rnk FROM read_intermediate_result('116_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer, rnk bigint) ORDER BY 1 DESC, 2 DESC, 3 DESC
|
||||
DEBUG: generating subplan 117_1 for subquery SELECT x, y, rnk FROM (SELECT test.x, test.y, rank() OVER my_win AS rnk FROM recursive_union.test WINDOW my_win AS (PARTITION BY test.x ORDER BY test.y DESC)) foo
|
||||
DEBUG: generating subplan 117_2 for subquery SELECT x, y, rnk FROM (SELECT test.x, test.y, rank() OVER my_win AS rnk FROM recursive_union.test WINDOW my_win AS (PARTITION BY test.x ORDER BY test.y DESC)) bar
|
||||
DEBUG: Plan 117 query after replacing subqueries and CTEs: SELECT intermediate_result.x, intermediate_result.y, intermediate_result.rnk FROM read_intermediate_result('117_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer, rnk bigint) UNION SELECT intermediate_result.x, intermediate_result.y, intermediate_result.rnk FROM read_intermediate_result('117_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer, rnk bigint) ORDER BY 1 DESC, 2 DESC, 3 DESC
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
x | y | rnk
|
||||
|
@ -584,12 +591,12 @@ HINT: Window functions are supported in two ways. Either add an equality filter
|
|||
-- other set operations in joins also cannot be pushed down
|
||||
SELECT * FROM ((SELECT * FROM test) EXCEPT (SELECT * FROM test ORDER BY x LIMIT 1)) u JOIN test USING (x) ORDER BY 1,2;
|
||||
DEBUG: push down of limit count: 1
|
||||
DEBUG: generating subplan 121_1 for subquery SELECT x, y FROM recursive_union.test ORDER BY x LIMIT 1
|
||||
DEBUG: generating subplan 121_2 for subquery SELECT x, y FROM recursive_union.test
|
||||
DEBUG: generating subplan 122_1 for subquery SELECT x, y FROM recursive_union.test ORDER BY x LIMIT 1
|
||||
DEBUG: generating subplan 122_2 for subquery SELECT x, y FROM recursive_union.test
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
DEBUG: generating subplan 121_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('121_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) EXCEPT SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('121_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)
|
||||
DEBUG: Plan 121 query after replacing subqueries and CTEs: SELECT u.x, u.y, test.y FROM ((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('121_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u JOIN recursive_union.test USING (x)) ORDER BY u.x, u.y
|
||||
DEBUG: generating subplan 122_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('122_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) EXCEPT SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('122_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)
|
||||
DEBUG: Plan 122 query after replacing subqueries and CTEs: SELECT u.x, u.y, test.y FROM ((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('122_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u JOIN recursive_union.test USING (x)) ORDER BY u.x, u.y
|
||||
x | y | y
|
||||
---+---+---
|
||||
2 | 2 | 2
|
||||
|
@ -597,18 +604,33 @@ DEBUG: Plan 121 query after replacing subqueries and CTEs: SELECT u.x, u.y, tes
|
|||
|
||||
SELECT * FROM ((SELECT * FROM test) INTERSECT (SELECT * FROM test ORDER BY x LIMIT 1)) u LEFT JOIN test USING (x) ORDER BY 1,2;
|
||||
DEBUG: push down of limit count: 1
|
||||
DEBUG: generating subplan 125_1 for subquery SELECT x, y FROM recursive_union.test ORDER BY x LIMIT 1
|
||||
DEBUG: generating subplan 125_2 for subquery SELECT x, y FROM recursive_union.test
|
||||
DEBUG: generating subplan 126_1 for subquery SELECT x, y FROM recursive_union.test ORDER BY x LIMIT 1
|
||||
DEBUG: generating subplan 126_2 for subquery SELECT x, y FROM recursive_union.test
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
DEBUG: generating subplan 125_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('125_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) INTERSECT SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('125_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)
|
||||
DEBUG: Plan 125 query after replacing subqueries and CTEs: SELECT u.x, u.y, test.y FROM ((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('125_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u LEFT JOIN recursive_union.test USING (x)) ORDER BY u.x, u.y
|
||||
DEBUG: generating subplan 126_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('126_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) INTERSECT SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('126_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)
|
||||
DEBUG: Plan 126 query after replacing subqueries and CTEs: SELECT u.x, u.y, test.y FROM ((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('126_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u LEFT JOIN recursive_union.test USING (x)) ORDER BY u.x, u.y
|
||||
ERROR: cannot pushdown the subquery
|
||||
DETAIL: Complex subqueries and CTEs cannot be in the outer part of the outer join
|
||||
-- distributed table in WHERE clause, but not FROM clause still disallowed
|
||||
-- distributed table in WHERE clause is recursively planned
|
||||
SELECT * FROM ((SELECT * FROM test) UNION (SELECT * FROM ref WHERE a IN (SELECT x FROM test))) u ORDER BY 1,2;
|
||||
ERROR: cannot pushdown the subquery
|
||||
DETAIL: Reference tables are not allowed in FROM clause when the query has subqueries in WHERE clause
|
||||
DEBUG: generating subplan 130_1 for subquery SELECT x FROM recursive_union.test
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
DEBUG: generating subplan 130_2 for subquery SELECT a, b FROM recursive_union.ref WHERE (a IN (SELECT intermediate_result.x FROM read_intermediate_result('130_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer)))
|
||||
DEBUG: generating subplan 130_3 for subquery SELECT x, y FROM recursive_union.test
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
DEBUG: generating subplan 130_4 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('130_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION SELECT intermediate_result.a, intermediate_result.b FROM read_intermediate_result('130_2'::text, 'binary'::citus_copy_format) intermediate_result(a integer, b integer)
|
||||
DEBUG: Plan 130 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('130_4'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u ORDER BY x, y
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
x | y
|
||||
---+---
|
||||
1 | 1
|
||||
2 | 2
|
||||
(2 rows)
|
||||
|
||||
-- subquery union in WHERE clause with partition column equality and implicit join is pushed down
|
||||
SELECT * FROM test a WHERE x IN (SELECT x FROM test b WHERE y = 1 UNION SELECT x FROM test c WHERE y = 2) ORDER BY 1,2;
|
||||
x | y
|
||||
|
@ -622,12 +644,12 @@ SELECT * FROM test a WHERE x NOT IN (SELECT x FROM test b WHERE y = 1 UNION SELE
|
|||
ERROR: complex joins are only supported when all distributed tables are joined on their distribution columns with equal operator
|
||||
-- subquery union in WHERE clause without parition column equality is recursively planned
|
||||
SELECT * FROM test a WHERE x IN (SELECT x FROM test b UNION SELECT y FROM test c) ORDER BY 1,2;
|
||||
DEBUG: generating subplan 133_1 for subquery SELECT x FROM recursive_union.test b
|
||||
DEBUG: generating subplan 133_2 for subquery SELECT y FROM recursive_union.test c
|
||||
DEBUG: generating subplan 137_1 for subquery SELECT x FROM recursive_union.test b
|
||||
DEBUG: generating subplan 137_2 for subquery SELECT y FROM recursive_union.test c
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
DEBUG: generating subplan 133_3 for subquery SELECT intermediate_result.x FROM read_intermediate_result('133_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer) UNION SELECT intermediate_result.y FROM read_intermediate_result('133_2'::text, 'binary'::citus_copy_format) intermediate_result(y integer)
|
||||
DEBUG: Plan 133 query after replacing subqueries and CTEs: SELECT x, y FROM recursive_union.test a WHERE (x IN (SELECT intermediate_result.x FROM read_intermediate_result('133_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer))) ORDER BY x, y
|
||||
DEBUG: generating subplan 137_3 for subquery SELECT intermediate_result.x FROM read_intermediate_result('137_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer) UNION SELECT intermediate_result.y FROM read_intermediate_result('137_2'::text, 'binary'::citus_copy_format) intermediate_result(y integer)
|
||||
DEBUG: Plan 137 query after replacing subqueries and CTEs: SELECT x, y FROM recursive_union.test a WHERE (x IN (SELECT intermediate_result.x FROM read_intermediate_result('137_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer))) ORDER BY x, y
|
||||
x | y
|
||||
---+---
|
||||
1 | 1
|
||||
|
@ -636,22 +658,22 @@ DEBUG: Plan 133 query after replacing subqueries and CTEs: SELECT x, y FROM rec
|
|||
|
||||
-- correlated subquery with union in WHERE clause
|
||||
SELECT * FROM test a WHERE x IN (SELECT x FROM test b UNION SELECT y FROM test c WHERE a.x = c.x) ORDER BY 1,2;
|
||||
DEBUG: generating subplan 137_1 for subquery SELECT x FROM recursive_union.test b
|
||||
DEBUG: generating subplan 141_1 for subquery SELECT x FROM recursive_union.test b
|
||||
DEBUG: skipping recursive planning for the subquery since it contains references to outer queries
|
||||
DEBUG: skipping recursive planning for the subquery since it contains references to outer queries
|
||||
DEBUG: Plan 137 query after replacing subqueries and CTEs: SELECT x, y FROM recursive_union.test a WHERE (x IN (SELECT intermediate_result.x FROM read_intermediate_result('137_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer) UNION SELECT c.y FROM recursive_union.test c WHERE (a.x = c.x))) ORDER BY x, y
|
||||
DEBUG: Plan 141 query after replacing subqueries and CTEs: SELECT x, y FROM recursive_union.test a WHERE (x IN (SELECT intermediate_result.x FROM read_intermediate_result('141_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer) UNION SELECT c.y FROM recursive_union.test c WHERE (a.x = c.x))) ORDER BY x, y
|
||||
DEBUG: skipping recursive planning for the subquery since it contains references to outer queries
|
||||
DEBUG: skipping recursive planning for the subquery since it contains references to outer queries
|
||||
ERROR: complex joins are only supported when all distributed tables are joined on their distribution columns with equal operator
|
||||
-- force unions to be planned while subqueries are being planned
|
||||
SELECT * FROM ((SELECT * FROM test) UNION (SELECT * FROM test) ORDER BY 1,2 LIMIT 5) as foo ORDER BY 1 DESC LIMIT 3;
|
||||
DEBUG: generating subplan 140_1 for subquery SELECT x, y FROM recursive_union.test
|
||||
DEBUG: generating subplan 140_2 for subquery SELECT x, y FROM recursive_union.test
|
||||
DEBUG: Plan 140 query after replacing subqueries and CTEs: SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('140_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('140_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) ORDER BY 1, 2 LIMIT 5
|
||||
DEBUG: generating subplan 144_1 for subquery SELECT x, y FROM recursive_union.test
|
||||
DEBUG: generating subplan 144_2 for subquery SELECT x, y FROM recursive_union.test
|
||||
DEBUG: Plan 144 query after replacing subqueries and CTEs: SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('144_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('144_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) ORDER BY 1, 2 LIMIT 5
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
DEBUG: generating subplan 139_1 for subquery SELECT test.x, test.y FROM recursive_union.test UNION SELECT test.x, test.y FROM recursive_union.test ORDER BY 1, 2 LIMIT 5
|
||||
DEBUG: Plan 139 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('139_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) foo ORDER BY x DESC LIMIT 3
|
||||
DEBUG: generating subplan 143_1 for subquery SELECT test.x, test.y FROM recursive_union.test UNION SELECT test.x, test.y FROM recursive_union.test ORDER BY 1, 2 LIMIT 5
|
||||
DEBUG: Plan 143 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('143_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) foo ORDER BY x DESC LIMIT 3
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
x | y
|
||||
|
@ -662,12 +684,12 @@ DEBUG: Plan is router executable
|
|||
|
||||
-- distinct and count distinct should work without any problems
|
||||
select count(DISTINCT t.x) FROM ((SELECT DISTINCT x FROM test) UNION (SELECT DISTINCT y FROM test)) as t(x) ORDER BY 1;
|
||||
DEBUG: generating subplan 143_1 for subquery SELECT DISTINCT y FROM recursive_union.test
|
||||
DEBUG: generating subplan 143_2 for subquery SELECT DISTINCT x FROM recursive_union.test
|
||||
DEBUG: generating subplan 147_1 for subquery SELECT DISTINCT y FROM recursive_union.test
|
||||
DEBUG: generating subplan 147_2 for subquery SELECT DISTINCT x FROM recursive_union.test
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
DEBUG: generating subplan 143_3 for subquery SELECT intermediate_result.x FROM read_intermediate_result('143_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer) UNION SELECT intermediate_result.y FROM read_intermediate_result('143_1'::text, 'binary'::citus_copy_format) intermediate_result(y integer)
|
||||
DEBUG: Plan 143 query after replacing subqueries and CTEs: SELECT count(DISTINCT x) AS count FROM (SELECT intermediate_result.x FROM read_intermediate_result('143_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer)) t(x) ORDER BY (count(DISTINCT x))
|
||||
DEBUG: generating subplan 147_3 for subquery SELECT intermediate_result.x FROM read_intermediate_result('147_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer) UNION SELECT intermediate_result.y FROM read_intermediate_result('147_1'::text, 'binary'::citus_copy_format) intermediate_result(y integer)
|
||||
DEBUG: Plan 147 query after replacing subqueries and CTEs: SELECT count(DISTINCT x) AS count FROM (SELECT intermediate_result.x FROM read_intermediate_result('147_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer)) t(x) ORDER BY (count(DISTINCT x))
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
count
|
||||
|
@ -676,12 +698,12 @@ DEBUG: Plan is router executable
|
|||
(1 row)
|
||||
|
||||
select count(DISTINCT t.x) FROM ((SELECT count(DISTINCT x) FROM test) UNION (SELECT count(DISTINCT y) FROM test)) as t(x) ORDER BY 1;
|
||||
DEBUG: generating subplan 147_1 for subquery SELECT count(DISTINCT x) AS count FROM recursive_union.test
|
||||
DEBUG: generating subplan 147_2 for subquery SELECT count(DISTINCT y) AS count FROM recursive_union.test
|
||||
DEBUG: generating subplan 151_1 for subquery SELECT count(DISTINCT x) AS count FROM recursive_union.test
|
||||
DEBUG: generating subplan 151_2 for subquery SELECT count(DISTINCT y) AS count FROM recursive_union.test
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
DEBUG: generating subplan 147_3 for subquery SELECT intermediate_result.count FROM read_intermediate_result('147_1'::text, 'binary'::citus_copy_format) intermediate_result(count bigint) UNION SELECT intermediate_result.count FROM read_intermediate_result('147_2'::text, 'binary'::citus_copy_format) intermediate_result(count bigint)
|
||||
DEBUG: Plan 147 query after replacing subqueries and CTEs: SELECT count(DISTINCT x) AS count FROM (SELECT intermediate_result.count FROM read_intermediate_result('147_3'::text, 'binary'::citus_copy_format) intermediate_result(count bigint)) t(x) ORDER BY (count(DISTINCT x))
|
||||
DEBUG: generating subplan 151_3 for subquery SELECT intermediate_result.count FROM read_intermediate_result('151_1'::text, 'binary'::citus_copy_format) intermediate_result(count bigint) UNION SELECT intermediate_result.count FROM read_intermediate_result('151_2'::text, 'binary'::citus_copy_format) intermediate_result(count bigint)
|
||||
DEBUG: Plan 151 query after replacing subqueries and CTEs: SELECT count(DISTINCT x) AS count FROM (SELECT intermediate_result.count FROM read_intermediate_result('151_3'::text, 'binary'::citus_copy_format) intermediate_result(count bigint)) t(x) ORDER BY (count(DISTINCT x))
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
count
|
||||
|
@ -691,12 +713,12 @@ DEBUG: Plan is router executable
|
|||
|
||||
-- other agg. distincts are also supported when group by includes partition key
|
||||
select avg(DISTINCT t.x) FROM ((SELECT avg(DISTINCT y) FROM test GROUP BY x) UNION (SELECT avg(DISTINCT y) FROM test GROUP BY x)) as t(x) ORDER BY 1;
|
||||
DEBUG: generating subplan 151_1 for subquery SELECT avg(DISTINCT y) AS avg FROM recursive_union.test GROUP BY x
|
||||
DEBUG: generating subplan 151_2 for subquery SELECT avg(DISTINCT y) AS avg FROM recursive_union.test GROUP BY x
|
||||
DEBUG: generating subplan 155_1 for subquery SELECT avg(DISTINCT y) AS avg FROM recursive_union.test GROUP BY x
|
||||
DEBUG: generating subplan 155_2 for subquery SELECT avg(DISTINCT y) AS avg FROM recursive_union.test GROUP BY x
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
DEBUG: generating subplan 151_3 for subquery SELECT intermediate_result.avg FROM read_intermediate_result('151_1'::text, 'binary'::citus_copy_format) intermediate_result(avg numeric) UNION SELECT intermediate_result.avg FROM read_intermediate_result('151_2'::text, 'binary'::citus_copy_format) intermediate_result(avg numeric)
|
||||
DEBUG: Plan 151 query after replacing subqueries and CTEs: SELECT avg(DISTINCT x) AS avg FROM (SELECT intermediate_result.avg FROM read_intermediate_result('151_3'::text, 'binary'::citus_copy_format) intermediate_result(avg numeric)) t(x) ORDER BY (avg(DISTINCT x))
|
||||
DEBUG: generating subplan 155_3 for subquery SELECT intermediate_result.avg FROM read_intermediate_result('155_1'::text, 'binary'::citus_copy_format) intermediate_result(avg numeric) UNION SELECT intermediate_result.avg FROM read_intermediate_result('155_2'::text, 'binary'::citus_copy_format) intermediate_result(avg numeric)
|
||||
DEBUG: Plan 155 query after replacing subqueries and CTEs: SELECT avg(DISTINCT x) AS avg FROM (SELECT intermediate_result.avg FROM read_intermediate_result('155_3'::text, 'binary'::citus_copy_format) intermediate_result(avg numeric)) t(x) ORDER BY (avg(DISTINCT x))
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
avg
|
||||
|
@ -743,9 +765,9 @@ DEBUG: pruning merge fetch taskId 11
|
|||
DETAIL: Creating dependency on merge taskId 24
|
||||
DEBUG: cannot use real time executor with repartition jobs
|
||||
HINT: Since you enabled citus.enable_repartition_joins Citus chose to use task-tracker.
|
||||
DEBUG: generating subplan 157_1 for subquery SELECT t1.x FROM recursive_union.test t1, recursive_union.test t2 WHERE (t1.x = t2.y) LIMIT 0
|
||||
DEBUG: generating subplan 157_2 for subquery SELECT x FROM recursive_union.test
|
||||
DEBUG: Plan 157 query after replacing subqueries and CTEs: SELECT intermediate_result.x FROM read_intermediate_result('157_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer) INTERSECT SELECT intermediate_result.x FROM read_intermediate_result('157_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer) ORDER BY 1 DESC
|
||||
DEBUG: generating subplan 161_1 for subquery SELECT t1.x FROM recursive_union.test t1, recursive_union.test t2 WHERE (t1.x = t2.y) LIMIT 0
|
||||
DEBUG: generating subplan 161_2 for subquery SELECT x FROM recursive_union.test
|
||||
DEBUG: Plan 161 query after replacing subqueries and CTEs: SELECT intermediate_result.x FROM read_intermediate_result('161_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer) INTERSECT SELECT intermediate_result.x FROM read_intermediate_result('161_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer) ORDER BY 1 DESC
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
x
|
||||
|
@ -754,7 +776,7 @@ DEBUG: Plan is router executable
|
|||
|
||||
-- repartition is recursively planned with the set operation
|
||||
(SELECT x FROM test) INTERSECT (SELECT t1.x FROM test as t1, test as t2 WHERE t1.x = t2.y) ORDER BY 1 DESC;
|
||||
DEBUG: generating subplan 160_1 for subquery SELECT x FROM recursive_union.test
|
||||
DEBUG: generating subplan 164_1 for subquery SELECT x FROM recursive_union.test
|
||||
DEBUG: join prunable for task partitionId 0 and 1
|
||||
DEBUG: join prunable for task partitionId 0 and 2
|
||||
DEBUG: join prunable for task partitionId 0 and 3
|
||||
|
@ -785,8 +807,8 @@ DEBUG: pruning merge fetch taskId 11
|
|||
DETAIL: Creating dependency on merge taskId 24
|
||||
DEBUG: cannot use real time executor with repartition jobs
|
||||
HINT: Since you enabled citus.enable_repartition_joins Citus chose to use task-tracker.
|
||||
DEBUG: generating subplan 160_2 for subquery SELECT t1.x FROM recursive_union.test t1, recursive_union.test t2 WHERE (t1.x = t2.y)
|
||||
DEBUG: Plan 160 query after replacing subqueries and CTEs: SELECT intermediate_result.x FROM read_intermediate_result('160_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer) INTERSECT SELECT intermediate_result.x FROM read_intermediate_result('160_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer) ORDER BY 1 DESC
|
||||
DEBUG: generating subplan 164_2 for subquery SELECT t1.x FROM recursive_union.test t1, recursive_union.test t2 WHERE (t1.x = t2.y)
|
||||
DEBUG: Plan 164 query after replacing subqueries and CTEs: SELECT intermediate_result.x FROM read_intermediate_result('164_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer) INTERSECT SELECT intermediate_result.x FROM read_intermediate_result('164_2'::text, 'binary'::citus_copy_format) intermediate_result(x integer) ORDER BY 1 DESC
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
x
|
||||
|
@ -799,12 +821,12 @@ SET citus.enable_repartition_joins TO OFF;
|
|||
-- this should be recursively planned
|
||||
CREATE VIEW set_view_recursive AS (SELECT y FROM test) UNION (SELECT y FROM test);
|
||||
SELECT * FROM set_view_recursive ORDER BY 1 DESC;
|
||||
DEBUG: generating subplan 163_1 for subquery SELECT y FROM recursive_union.test
|
||||
DEBUG: generating subplan 163_2 for subquery SELECT y FROM recursive_union.test
|
||||
DEBUG: generating subplan 167_1 for subquery SELECT y FROM recursive_union.test
|
||||
DEBUG: generating subplan 167_2 for subquery SELECT y FROM recursive_union.test
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
DEBUG: generating subplan 163_3 for subquery SELECT intermediate_result.y FROM read_intermediate_result('163_1'::text, 'binary'::citus_copy_format) intermediate_result(y integer) UNION SELECT intermediate_result.y FROM read_intermediate_result('163_2'::text, 'binary'::citus_copy_format) intermediate_result(y integer)
|
||||
DEBUG: Plan 163 query after replacing subqueries and CTEs: SELECT y FROM (SELECT intermediate_result.y FROM read_intermediate_result('163_3'::text, 'binary'::citus_copy_format) intermediate_result(y integer)) set_view_recursive ORDER BY y DESC
|
||||
DEBUG: generating subplan 167_3 for subquery SELECT intermediate_result.y FROM read_intermediate_result('167_1'::text, 'binary'::citus_copy_format) intermediate_result(y integer) UNION SELECT intermediate_result.y FROM read_intermediate_result('167_2'::text, 'binary'::citus_copy_format) intermediate_result(y integer)
|
||||
DEBUG: Plan 167 query after replacing subqueries and CTEs: SELECT y FROM (SELECT intermediate_result.y FROM read_intermediate_result('167_3'::text, 'binary'::citus_copy_format) intermediate_result(y integer)) set_view_recursive ORDER BY y DESC
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
y
|
||||
|
@ -825,12 +847,12 @@ SELECT * FROM set_view_pushdown ORDER BY 1 DESC;
|
|||
-- this should be recursively planned
|
||||
CREATE VIEW set_view_recursive_second AS SELECT u.x, test.y FROM ((SELECT x, y FROM test) UNION (SELECT 1, 1 FROM test)) u JOIN test USING (x) ORDER BY 1,2;
|
||||
SELECT * FROM set_view_recursive_second;
|
||||
DEBUG: generating subplan 168_1 for subquery SELECT x, y FROM recursive_union.test
|
||||
DEBUG: generating subplan 168_2 for subquery SELECT 1, 1 FROM recursive_union.test
|
||||
DEBUG: generating subplan 172_1 for subquery SELECT x, y FROM recursive_union.test
|
||||
DEBUG: generating subplan 172_2 for subquery SELECT 1, 1 FROM recursive_union.test
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
DEBUG: generating subplan 168_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('168_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION SELECT intermediate_result."?column?", intermediate_result."?column?_1" AS "?column?" FROM read_intermediate_result('168_2'::text, 'binary'::citus_copy_format) intermediate_result("?column?" integer, "?column?_1" integer)
|
||||
DEBUG: Plan 168 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT u.x, test.y FROM ((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('168_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u JOIN recursive_union.test USING (x)) ORDER BY u.x, test.y) set_view_recursive_second
|
||||
DEBUG: generating subplan 172_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('172_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION SELECT intermediate_result."?column?", intermediate_result."?column?_1" AS "?column?" FROM read_intermediate_result('172_2'::text, 'binary'::citus_copy_format) intermediate_result("?column?" integer, "?column?_1" integer)
|
||||
DEBUG: Plan 172 query after replacing subqueries and CTEs: SELECT x, y FROM (SELECT u.x, test.y FROM ((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('172_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u JOIN recursive_union.test USING (x)) ORDER BY u.x, test.y) set_view_recursive_second
|
||||
x | y
|
||||
---+---
|
||||
1 | 1
|
||||
|
@ -839,19 +861,19 @@ DEBUG: Plan 168 query after replacing subqueries and CTEs: SELECT x, y FROM (SE
|
|||
|
||||
-- this should create lots of recursive calls since both views and set operations lead to recursive plans :)
|
||||
((SELECT x FROM set_view_recursive_second) INTERSECT (SELECT * FROM set_view_recursive)) EXCEPT (SELECT * FROM set_view_pushdown);
|
||||
DEBUG: generating subplan 172_1 for subquery SELECT x, y FROM recursive_union.test
|
||||
DEBUG: generating subplan 172_2 for subquery SELECT 1, 1 FROM recursive_union.test
|
||||
DEBUG: generating subplan 176_1 for subquery SELECT x, y FROM recursive_union.test
|
||||
DEBUG: generating subplan 176_2 for subquery SELECT 1, 1 FROM recursive_union.test
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
DEBUG: generating subplan 172_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('172_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION SELECT intermediate_result."?column?", intermediate_result."?column?_1" AS "?column?" FROM read_intermediate_result('172_2'::text, 'binary'::citus_copy_format) intermediate_result("?column?" integer, "?column?_1" integer)
|
||||
DEBUG: generating subplan 172_4 for subquery SELECT y FROM recursive_union.test
|
||||
DEBUG: generating subplan 172_5 for subquery SELECT y FROM recursive_union.test
|
||||
DEBUG: generating subplan 176_3 for subquery SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('176_1'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer) UNION SELECT intermediate_result."?column?", intermediate_result."?column?_1" AS "?column?" FROM read_intermediate_result('176_2'::text, 'binary'::citus_copy_format) intermediate_result("?column?" integer, "?column?_1" integer)
|
||||
DEBUG: generating subplan 176_4 for subquery SELECT y FROM recursive_union.test
|
||||
DEBUG: generating subplan 176_5 for subquery SELECT y FROM recursive_union.test
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
DEBUG: generating subplan 172_6 for subquery SELECT intermediate_result.y FROM read_intermediate_result('172_4'::text, 'binary'::citus_copy_format) intermediate_result(y integer) UNION SELECT intermediate_result.y FROM read_intermediate_result('172_5'::text, 'binary'::citus_copy_format) intermediate_result(y integer)
|
||||
DEBUG: generating subplan 172_7 for subquery SELECT x FROM (SELECT u.x, test.y FROM ((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('172_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u JOIN recursive_union.test USING (x)) ORDER BY u.x, test.y) set_view_recursive_second
|
||||
DEBUG: generating subplan 172_8 for subquery SELECT x FROM (SELECT test.x FROM recursive_union.test UNION SELECT test.x FROM recursive_union.test) set_view_pushdown
|
||||
DEBUG: Plan 172 query after replacing subqueries and CTEs: (SELECT intermediate_result.x FROM read_intermediate_result('172_7'::text, 'binary'::citus_copy_format) intermediate_result(x integer) INTERSECT SELECT set_view_recursive.y FROM (SELECT intermediate_result.y FROM read_intermediate_result('172_6'::text, 'binary'::citus_copy_format) intermediate_result(y integer)) set_view_recursive) EXCEPT SELECT intermediate_result.x FROM read_intermediate_result('172_8'::text, 'binary'::citus_copy_format) intermediate_result(x integer)
|
||||
DEBUG: generating subplan 176_6 for subquery SELECT intermediate_result.y FROM read_intermediate_result('176_4'::text, 'binary'::citus_copy_format) intermediate_result(y integer) UNION SELECT intermediate_result.y FROM read_intermediate_result('176_5'::text, 'binary'::citus_copy_format) intermediate_result(y integer)
|
||||
DEBUG: generating subplan 176_7 for subquery SELECT x FROM (SELECT u.x, test.y FROM ((SELECT intermediate_result.x, intermediate_result.y FROM read_intermediate_result('176_3'::text, 'binary'::citus_copy_format) intermediate_result(x integer, y integer)) u JOIN recursive_union.test USING (x)) ORDER BY u.x, test.y) set_view_recursive_second
|
||||
DEBUG: generating subplan 176_8 for subquery SELECT x FROM (SELECT test.x FROM recursive_union.test UNION SELECT test.x FROM recursive_union.test) set_view_pushdown
|
||||
DEBUG: Plan 176 query after replacing subqueries and CTEs: (SELECT intermediate_result.x FROM read_intermediate_result('176_7'::text, 'binary'::citus_copy_format) intermediate_result(x integer) INTERSECT SELECT set_view_recursive.y FROM (SELECT intermediate_result.y FROM read_intermediate_result('176_6'::text, 'binary'::citus_copy_format) intermediate_result(y integer)) set_view_recursive) EXCEPT SELECT intermediate_result.x FROM read_intermediate_result('176_8'::text, 'binary'::citus_copy_format) intermediate_result(x integer)
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
x
|
||||
|
|
|
@ -60,24 +60,6 @@ FROM
|
|||
LIMIT 5
|
||||
) as foo;
|
||||
ERROR: array_agg with order by is unsupported
|
||||
-- we don't support queries with recurring tuples in the FROM
|
||||
-- clause and subquery in WHERE clause
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
users_table.user_id
|
||||
FROM
|
||||
users_table, (SELECT user_id FROM events_table) as evs
|
||||
WHERE users_table.user_id = evs.user_id
|
||||
LIMIT 5
|
||||
) as foo WHERE user_id IN (SELECT count(*) FROM users_table GROUP BY user_id);
|
||||
DEBUG: push down of limit count: 5
|
||||
DEBUG: generating subplan 10_1 for subquery SELECT users_table.user_id FROM public.users_table, (SELECT events_table.user_id FROM public.events_table) evs WHERE (users_table.user_id = evs.user_id) LIMIT 5
|
||||
DEBUG: Plan 10 query after replacing subqueries and CTEs: SELECT user_id FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('10_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) foo WHERE (user_id IN (SELECT count(*) AS count FROM public.users_table GROUP BY users_table.user_id))
|
||||
ERROR: cannot pushdown the subquery
|
||||
DETAIL: Complex subqueries and CTEs are not allowed in the FROM clause when the query has subqueries in the WHERE clause
|
||||
-- we don't support recursive subqueries when router executor is disabled
|
||||
SET citus.enable_router_execution TO false;
|
||||
SELECT
|
||||
|
@ -94,8 +76,8 @@ FROM
|
|||
) as foo
|
||||
ORDER BY 1 DESC;
|
||||
DEBUG: push down of limit count: 5
|
||||
DEBUG: generating subplan 12_1 for subquery SELECT DISTINCT users_table.user_id FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4]))) ORDER BY users_table.user_id DESC LIMIT 5
|
||||
DEBUG: Plan 12 query after replacing subqueries and CTEs: SELECT user_id FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('12_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) foo ORDER BY user_id DESC
|
||||
DEBUG: generating subplan 10_1 for subquery SELECT DISTINCT users_table.user_id FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4]))) ORDER BY users_table.user_id DESC LIMIT 5
|
||||
DEBUG: Plan 10 query after replacing subqueries and CTEs: SELECT user_id FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('10_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) foo ORDER BY user_id DESC
|
||||
ERROR: cannot handle complex subqueries when the router executor is disabled
|
||||
SET citus.enable_router_execution TO true;
|
||||
-- window functions are not allowed if they're not partitioned on the distribution column
|
||||
|
@ -139,8 +121,8 @@ FROM
|
|||
(SELECT users_table.value_2 FROM users_table, events_table WHERE users_table.user_id = events_table.user_id AND event_type IN (5,6,7,8)) as bar
|
||||
ON(foo.value_2 = bar.value_2);
|
||||
DEBUG: push down of limit count: 5
|
||||
DEBUG: generating subplan 17_1 for subquery SELECT users_table.value_2 FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4]))) LIMIT 5
|
||||
DEBUG: Plan 17 query after replacing subqueries and CTEs: SELECT foo.value_2 FROM ((SELECT intermediate_result.value_2 FROM read_intermediate_result('17_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)) foo LEFT JOIN (SELECT users_table.value_2 FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[5, 6, 7, 8])))) bar ON ((foo.value_2 = bar.value_2)))
|
||||
DEBUG: generating subplan 15_1 for subquery SELECT users_table.value_2 FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4]))) LIMIT 5
|
||||
DEBUG: Plan 15 query after replacing subqueries and CTEs: SELECT foo.value_2 FROM ((SELECT intermediate_result.value_2 FROM read_intermediate_result('15_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)) foo LEFT JOIN (SELECT users_table.value_2 FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[5, 6, 7, 8])))) bar ON ((foo.value_2 = bar.value_2)))
|
||||
ERROR: cannot pushdown the subquery
|
||||
DETAIL: Complex subqueries and CTEs cannot be in the outer part of the outer join
|
||||
-- Aggregates in subquery without partition column can be planned recursively
|
||||
|
|
|
@ -113,10 +113,8 @@ DEBUG: Plan 10 query after replacing subqueries and CTEs: SELECT DISTINCT cte.u
|
|||
1
|
||||
(4 rows)
|
||||
|
||||
-- a very similar query as the above, but this time errors
|
||||
-- out since we don't support subqueries in WHERE clause
|
||||
-- when there is only intermediate results on the range table
|
||||
-- note that this time subquery in WHERE clause is not replaced
|
||||
-- subquery in WHERE clause is planned recursively due to the recurring table
|
||||
-- in FROM clause
|
||||
WITH cte AS (
|
||||
WITH local_cte AS (
|
||||
SELECT * FROM users_table_local
|
||||
|
@ -135,9 +133,18 @@ DEBUG: generating subplan 14_1 for CTE cte: WITH local_cte AS (SELECT users_tab
|
|||
DEBUG: generating subplan 15_1 for CTE local_cte: SELECT user_id, "time", value_1, value_2, value_3, value_4 FROM subquery_and_ctes.users_table_local
|
||||
DEBUG: generating subplan 15_2 for CTE dist_cte: SELECT user_id FROM public.events_table
|
||||
DEBUG: Plan 15 query after replacing subqueries and CTEs: SELECT dist_cte.user_id FROM ((SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.value_1, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('15_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, value_1 integer, value_2 integer, value_3 double precision, value_4 bigint)) local_cte JOIN (SELECT intermediate_result.user_id FROM read_intermediate_result('15_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) dist_cte ON ((dist_cte.user_id = local_cte.user_id)))
|
||||
DEBUG: Plan 14 query after replacing subqueries and CTEs: SELECT DISTINCT user_id FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('14_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) cte WHERE (user_id IN (SELECT DISTINCT users_table.user_id FROM public.users_table WHERE ((users_table.value_1 >= 1) AND (users_table.value_1 <= 20)))) ORDER BY user_id DESC
|
||||
ERROR: cannot pushdown the subquery
|
||||
DETAIL: Complex subqueries and CTEs are not allowed in the FROM clause when the query has subqueries in the WHERE clause
|
||||
DEBUG: generating subplan 14_2 for subquery SELECT DISTINCT user_id FROM public.users_table WHERE ((value_1 >= 1) AND (value_1 <= 20))
|
||||
DEBUG: Plan 14 query after replacing subqueries and CTEs: SELECT DISTINCT user_id FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('14_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) cte WHERE (user_id IN (SELECT intermediate_result.user_id FROM read_intermediate_result('14_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer))) ORDER BY user_id DESC
|
||||
user_id
|
||||
---------
|
||||
6
|
||||
5
|
||||
4
|
||||
3
|
||||
2
|
||||
1
|
||||
(6 rows)
|
||||
|
||||
-- CTEs inside a subquery and the final query becomes a router
|
||||
-- query
|
||||
SELECT
|
||||
|
@ -154,8 +161,8 @@ FROM
|
|||
event_type IN (1,2,3,4)
|
||||
) SELECT * FROM cte ORDER BY 1 DESC
|
||||
) as foo;
|
||||
DEBUG: generating subplan 17_1 for CTE cte: SELECT DISTINCT users_table.user_id FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4])))
|
||||
DEBUG: Plan 17 query after replacing subqueries and CTEs: SELECT user_id FROM (SELECT cte.user_id FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('17_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) cte ORDER BY cte.user_id DESC) foo
|
||||
DEBUG: generating subplan 18_1 for CTE cte: SELECT DISTINCT users_table.user_id FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4])))
|
||||
DEBUG: Plan 18 query after replacing subqueries and CTEs: SELECT user_id FROM (SELECT cte.user_id FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('18_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) cte ORDER BY cte.user_id DESC) foo
|
||||
user_id
|
||||
---------
|
||||
6
|
||||
|
@ -193,8 +200,8 @@ FROM
|
|||
|
||||
) as bar
|
||||
WHERE foo.user_id = bar.user_id;
|
||||
DEBUG: generating subplan 19_1 for CTE cte: SELECT DISTINCT users_table.user_id FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4])))
|
||||
DEBUG: Plan 19 query after replacing subqueries and CTEs: SELECT bar.user_id FROM (SELECT cte.user_id FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('19_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) cte ORDER BY cte.user_id DESC) foo, (SELECT DISTINCT users_table.user_id FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4])))) bar WHERE (foo.user_id = bar.user_id)
|
||||
DEBUG: generating subplan 20_1 for CTE cte: SELECT DISTINCT users_table.user_id FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4])))
|
||||
DEBUG: Plan 20 query after replacing subqueries and CTEs: SELECT bar.user_id FROM (SELECT cte.user_id FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('20_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) cte ORDER BY cte.user_id DESC) foo, (SELECT DISTINCT users_table.user_id FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4])))) bar WHERE (foo.user_id = bar.user_id)
|
||||
user_id
|
||||
---------
|
||||
5
|
||||
|
@ -246,11 +253,11 @@ FROM
|
|||
) as bar
|
||||
WHERE foo.user_id = bar.user_id
|
||||
ORDER BY 1 DESC LIMIT 5;
|
||||
DEBUG: generating subplan 21_1 for CTE cte: SELECT DISTINCT users_table.user_id FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4])))
|
||||
DEBUG: generating subplan 21_2 for CTE cte: SELECT events_table.event_type, users_table.user_id FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (users_table.value_1 = ANY (ARRAY[1, 2])))
|
||||
DEBUG: generating subplan 22_1 for CTE cte: SELECT DISTINCT users_table.user_id FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4])))
|
||||
DEBUG: generating subplan 22_2 for CTE cte: SELECT events_table.event_type, users_table.user_id FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (users_table.value_1 = ANY (ARRAY[1, 2])))
|
||||
DEBUG: push down of limit count: 2
|
||||
DEBUG: generating subplan 21_3 for subquery SELECT users_table.user_id, some_events.event_type FROM public.users_table, (SELECT cte.event_type, cte.user_id FROM (SELECT intermediate_result.event_type, intermediate_result.user_id FROM read_intermediate_result('21_2'::text, 'binary'::citus_copy_format) intermediate_result(event_type integer, user_id integer)) cte ORDER BY cte.event_type DESC) some_events WHERE ((users_table.user_id = some_events.user_id) AND (some_events.event_type = ANY (ARRAY[1, 2, 3, 4]))) ORDER BY some_events.event_type, users_table.user_id LIMIT 2
|
||||
DEBUG: Plan 21 query after replacing subqueries and CTEs: SELECT DISTINCT bar.user_id FROM (SELECT cte.user_id FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('21_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) cte ORDER BY cte.user_id DESC) foo, (SELECT intermediate_result.user_id, intermediate_result.event_type FROM read_intermediate_result('21_3'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, event_type integer)) bar WHERE (foo.user_id = bar.user_id) ORDER BY bar.user_id DESC LIMIT 5
|
||||
DEBUG: generating subplan 22_3 for subquery SELECT users_table.user_id, some_events.event_type FROM public.users_table, (SELECT cte.event_type, cte.user_id FROM (SELECT intermediate_result.event_type, intermediate_result.user_id FROM read_intermediate_result('22_2'::text, 'binary'::citus_copy_format) intermediate_result(event_type integer, user_id integer)) cte ORDER BY cte.event_type DESC) some_events WHERE ((users_table.user_id = some_events.user_id) AND (some_events.event_type = ANY (ARRAY[1, 2, 3, 4]))) ORDER BY some_events.event_type, users_table.user_id LIMIT 2
|
||||
DEBUG: Plan 22 query after replacing subqueries and CTEs: SELECT DISTINCT bar.user_id FROM (SELECT cte.user_id FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('22_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) cte ORDER BY cte.user_id DESC) foo, (SELECT intermediate_result.user_id, intermediate_result.event_type FROM read_intermediate_result('22_3'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, event_type integer)) bar WHERE (foo.user_id = bar.user_id) ORDER BY bar.user_id DESC LIMIT 5
|
||||
user_id
|
||||
---------
|
||||
1
|
||||
|
@ -283,14 +290,14 @@ SELECT * FROM
|
|||
foo.user_id = events_table.value_2
|
||||
ORDER BY 3 DESC, 2 DESC, 1 DESC
|
||||
LIMIT 5;
|
||||
DEBUG: generating subplan 25_1 for CTE cte: WITH local_cte AS (SELECT users_table_local.user_id, users_table_local."time", users_table_local.value_1, users_table_local.value_2, users_table_local.value_3, users_table_local.value_4 FROM subquery_and_ctes.users_table_local), dist_cte AS (SELECT events_table.user_id FROM public.events_table) SELECT dist_cte.user_id FROM (local_cte JOIN dist_cte ON ((dist_cte.user_id = local_cte.user_id)))
|
||||
DEBUG: generating subplan 26_1 for CTE local_cte: SELECT user_id, "time", value_1, value_2, value_3, value_4 FROM subquery_and_ctes.users_table_local
|
||||
DEBUG: generating subplan 26_2 for CTE dist_cte: SELECT user_id FROM public.events_table
|
||||
DEBUG: Plan 26 query after replacing subqueries and CTEs: SELECT dist_cte.user_id FROM ((SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.value_1, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('26_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, value_1 integer, value_2 integer, value_3 double precision, value_4 bigint)) local_cte JOIN (SELECT intermediate_result.user_id FROM read_intermediate_result('26_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) dist_cte ON ((dist_cte.user_id = local_cte.user_id)))
|
||||
DEBUG: generating subplan 25_2 for CTE cte_in_where: SELECT DISTINCT value_2 FROM public.users_table WHERE ((value_1 >= 1) AND (value_1 <= 20)) ORDER BY value_2 LIMIT 5
|
||||
DEBUG: generating subplan 26_1 for CTE cte: WITH local_cte AS (SELECT users_table_local.user_id, users_table_local."time", users_table_local.value_1, users_table_local.value_2, users_table_local.value_3, users_table_local.value_4 FROM subquery_and_ctes.users_table_local), dist_cte AS (SELECT events_table.user_id FROM public.events_table) SELECT dist_cte.user_id FROM (local_cte JOIN dist_cte ON ((dist_cte.user_id = local_cte.user_id)))
|
||||
DEBUG: generating subplan 27_1 for CTE local_cte: SELECT user_id, "time", value_1, value_2, value_3, value_4 FROM subquery_and_ctes.users_table_local
|
||||
DEBUG: generating subplan 27_2 for CTE dist_cte: SELECT user_id FROM public.events_table
|
||||
DEBUG: Plan 27 query after replacing subqueries and CTEs: SELECT dist_cte.user_id FROM ((SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.value_1, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('27_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, value_1 integer, value_2 integer, value_3 double precision, value_4 bigint)) local_cte JOIN (SELECT intermediate_result.user_id FROM read_intermediate_result('27_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) dist_cte ON ((dist_cte.user_id = local_cte.user_id)))
|
||||
DEBUG: generating subplan 26_2 for CTE cte_in_where: SELECT DISTINCT value_2 FROM public.users_table WHERE ((value_1 >= 1) AND (value_1 <= 20)) ORDER BY value_2 LIMIT 5
|
||||
DEBUG: push down of limit count: 5
|
||||
DEBUG: generating subplan 25_3 for subquery SELECT DISTINCT cte.user_id FROM public.users_table, (SELECT intermediate_result.user_id FROM read_intermediate_result('25_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) cte WHERE ((users_table.user_id = cte.user_id) AND (users_table.user_id IN (SELECT cte_in_where.value_2 FROM (SELECT intermediate_result.value_2 FROM read_intermediate_result('25_2'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)) cte_in_where))) ORDER BY cte.user_id DESC
|
||||
DEBUG: Plan 25 query after replacing subqueries and CTEs: SELECT foo.user_id, events_table.user_id, events_table."time", events_table.event_type, events_table.value_2, events_table.value_3, events_table.value_4 FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('25_3'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) foo, public.events_table WHERE (foo.user_id = events_table.value_2) ORDER BY events_table."time" DESC, events_table.user_id DESC, foo.user_id DESC LIMIT 5
|
||||
DEBUG: generating subplan 26_3 for subquery SELECT DISTINCT cte.user_id FROM public.users_table, (SELECT intermediate_result.user_id FROM read_intermediate_result('26_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) cte WHERE ((users_table.user_id = cte.user_id) AND (users_table.user_id IN (SELECT cte_in_where.value_2 FROM (SELECT intermediate_result.value_2 FROM read_intermediate_result('26_2'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)) cte_in_where))) ORDER BY cte.user_id DESC
|
||||
DEBUG: Plan 26 query after replacing subqueries and CTEs: SELECT foo.user_id, events_table.user_id, events_table."time", events_table.event_type, events_table.value_2, events_table.value_3, events_table.value_4 FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('26_3'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) foo, public.events_table WHERE (foo.user_id = events_table.value_2) ORDER BY events_table."time" DESC, events_table.user_id DESC, foo.user_id DESC LIMIT 5
|
||||
DEBUG: push down of limit count: 5
|
||||
user_id | user_id | time | event_type | value_2 | value_3 | value_4
|
||||
---------+---------+---------------------------------+------------+---------+---------+---------
|
||||
|
@ -332,17 +339,17 @@ FROM
|
|||
ORDER BY 1 DESC LIMIT 5
|
||||
) as foo
|
||||
WHERE foo.user_id = cte.user_id;
|
||||
DEBUG: generating subplan 30_1 for CTE cte: WITH local_cte AS (SELECT users_table_local.user_id, users_table_local."time", users_table_local.value_1, users_table_local.value_2, users_table_local.value_3, users_table_local.value_4 FROM subquery_and_ctes.users_table_local), dist_cte AS (SELECT events_table.user_id FROM public.events_table, (SELECT DISTINCT users_table.value_2 FROM public.users_table OFFSET 0) foo WHERE ((events_table.user_id = foo.value_2) AND (events_table.user_id IN (SELECT DISTINCT users_table.value_1 FROM public.users_table ORDER BY users_table.value_1 LIMIT 3)))) SELECT dist_cte.user_id FROM (local_cte JOIN dist_cte ON ((dist_cte.user_id = local_cte.user_id)))
|
||||
DEBUG: generating subplan 31_1 for CTE local_cte: SELECT user_id, "time", value_1, value_2, value_3, value_4 FROM subquery_and_ctes.users_table_local
|
||||
DEBUG: generating subplan 31_2 for CTE dist_cte: SELECT events_table.user_id FROM public.events_table, (SELECT DISTINCT users_table.value_2 FROM public.users_table OFFSET 0) foo WHERE ((events_table.user_id = foo.value_2) AND (events_table.user_id IN (SELECT DISTINCT users_table.value_1 FROM public.users_table ORDER BY users_table.value_1 LIMIT 3)))
|
||||
DEBUG: generating subplan 31_1 for CTE cte: WITH local_cte AS (SELECT users_table_local.user_id, users_table_local."time", users_table_local.value_1, users_table_local.value_2, users_table_local.value_3, users_table_local.value_4 FROM subquery_and_ctes.users_table_local), dist_cte AS (SELECT events_table.user_id FROM public.events_table, (SELECT DISTINCT users_table.value_2 FROM public.users_table OFFSET 0) foo WHERE ((events_table.user_id = foo.value_2) AND (events_table.user_id IN (SELECT DISTINCT users_table.value_1 FROM public.users_table ORDER BY users_table.value_1 LIMIT 3)))) SELECT dist_cte.user_id FROM (local_cte JOIN dist_cte ON ((dist_cte.user_id = local_cte.user_id)))
|
||||
DEBUG: generating subplan 32_1 for CTE local_cte: SELECT user_id, "time", value_1, value_2, value_3, value_4 FROM subquery_and_ctes.users_table_local
|
||||
DEBUG: generating subplan 32_2 for CTE dist_cte: SELECT events_table.user_id FROM public.events_table, (SELECT DISTINCT users_table.value_2 FROM public.users_table OFFSET 0) foo WHERE ((events_table.user_id = foo.value_2) AND (events_table.user_id IN (SELECT DISTINCT users_table.value_1 FROM public.users_table ORDER BY users_table.value_1 LIMIT 3)))
|
||||
DEBUG: push down of limit count: 3
|
||||
DEBUG: generating subplan 32_1 for subquery SELECT DISTINCT value_1 FROM public.users_table ORDER BY value_1 LIMIT 3
|
||||
DEBUG: generating subplan 32_2 for subquery SELECT DISTINCT value_2 FROM public.users_table OFFSET 0
|
||||
DEBUG: Plan 32 query after replacing subqueries and CTEs: SELECT events_table.user_id FROM public.events_table, (SELECT intermediate_result.value_2 FROM read_intermediate_result('32_2'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)) foo WHERE ((events_table.user_id = foo.value_2) AND (events_table.user_id IN (SELECT intermediate_result.value_1 FROM read_intermediate_result('32_1'::text, 'binary'::citus_copy_format) intermediate_result(value_1 integer))))
|
||||
DEBUG: Plan 31 query after replacing subqueries and CTEs: SELECT dist_cte.user_id FROM ((SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.value_1, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('31_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, value_1 integer, value_2 integer, value_3 double precision, value_4 bigint)) local_cte JOIN (SELECT intermediate_result.user_id FROM read_intermediate_result('31_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) dist_cte ON ((dist_cte.user_id = local_cte.user_id)))
|
||||
DEBUG: generating subplan 33_1 for subquery SELECT DISTINCT value_1 FROM public.users_table ORDER BY value_1 LIMIT 3
|
||||
DEBUG: generating subplan 33_2 for subquery SELECT DISTINCT value_2 FROM public.users_table OFFSET 0
|
||||
DEBUG: Plan 33 query after replacing subqueries and CTEs: SELECT events_table.user_id FROM public.events_table, (SELECT intermediate_result.value_2 FROM read_intermediate_result('33_2'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)) foo WHERE ((events_table.user_id = foo.value_2) AND (events_table.user_id IN (SELECT intermediate_result.value_1 FROM read_intermediate_result('33_1'::text, 'binary'::citus_copy_format) intermediate_result(value_1 integer))))
|
||||
DEBUG: Plan 32 query after replacing subqueries and CTEs: SELECT dist_cte.user_id FROM ((SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.value_1, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('32_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, value_1 integer, value_2 integer, value_3 double precision, value_4 bigint)) local_cte JOIN (SELECT intermediate_result.user_id FROM read_intermediate_result('32_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) dist_cte ON ((dist_cte.user_id = local_cte.user_id)))
|
||||
DEBUG: push down of limit count: 5
|
||||
DEBUG: generating subplan 30_2 for subquery SELECT DISTINCT users_table.user_id FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4]))) ORDER BY users_table.user_id DESC LIMIT 5
|
||||
DEBUG: Plan 30 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('30_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) cte, (SELECT intermediate_result.user_id FROM read_intermediate_result('30_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) foo WHERE (foo.user_id = cte.user_id)
|
||||
DEBUG: generating subplan 31_2 for subquery SELECT DISTINCT users_table.user_id FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4]))) ORDER BY users_table.user_id DESC LIMIT 5
|
||||
DEBUG: Plan 31 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('31_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) cte, (SELECT intermediate_result.user_id FROM read_intermediate_result('31_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) foo WHERE (foo.user_id = cte.user_id)
|
||||
count
|
||||
-------
|
||||
432
|
||||
|
@ -386,18 +393,18 @@ FROM
|
|||
) as foo, users_table WHERE foo.cnt > users_table.value_2
|
||||
ORDER BY 3 DESC, 1 DESC, 2 DESC, 4 DESC
|
||||
LIMIT 5;
|
||||
DEBUG: generating subplan 36_1 for CTE cte: WITH local_cte AS (SELECT users_table_local.user_id, users_table_local."time", users_table_local.value_1, users_table_local.value_2, users_table_local.value_3, users_table_local.value_4 FROM subquery_and_ctes.users_table_local), dist_cte AS (SELECT events_table.user_id FROM public.events_table, (SELECT DISTINCT users_table.value_2 FROM public.users_table OFFSET 0) foo WHERE ((events_table.user_id = foo.value_2) AND (events_table.user_id IN (SELECT DISTINCT users_table.value_1 FROM public.users_table ORDER BY users_table.value_1 LIMIT 3)))) SELECT dist_cte.user_id FROM (local_cte JOIN dist_cte ON ((dist_cte.user_id = local_cte.user_id)))
|
||||
DEBUG: generating subplan 37_1 for CTE local_cte: SELECT user_id, "time", value_1, value_2, value_3, value_4 FROM subquery_and_ctes.users_table_local
|
||||
DEBUG: generating subplan 37_2 for CTE dist_cte: SELECT events_table.user_id FROM public.events_table, (SELECT DISTINCT users_table.value_2 FROM public.users_table OFFSET 0) foo WHERE ((events_table.user_id = foo.value_2) AND (events_table.user_id IN (SELECT DISTINCT users_table.value_1 FROM public.users_table ORDER BY users_table.value_1 LIMIT 3)))
|
||||
DEBUG: generating subplan 37_1 for CTE cte: WITH local_cte AS (SELECT users_table_local.user_id, users_table_local."time", users_table_local.value_1, users_table_local.value_2, users_table_local.value_3, users_table_local.value_4 FROM subquery_and_ctes.users_table_local), dist_cte AS (SELECT events_table.user_id FROM public.events_table, (SELECT DISTINCT users_table.value_2 FROM public.users_table OFFSET 0) foo WHERE ((events_table.user_id = foo.value_2) AND (events_table.user_id IN (SELECT DISTINCT users_table.value_1 FROM public.users_table ORDER BY users_table.value_1 LIMIT 3)))) SELECT dist_cte.user_id FROM (local_cte JOIN dist_cte ON ((dist_cte.user_id = local_cte.user_id)))
|
||||
DEBUG: generating subplan 38_1 for CTE local_cte: SELECT user_id, "time", value_1, value_2, value_3, value_4 FROM subquery_and_ctes.users_table_local
|
||||
DEBUG: generating subplan 38_2 for CTE dist_cte: SELECT events_table.user_id FROM public.events_table, (SELECT DISTINCT users_table.value_2 FROM public.users_table OFFSET 0) foo WHERE ((events_table.user_id = foo.value_2) AND (events_table.user_id IN (SELECT DISTINCT users_table.value_1 FROM public.users_table ORDER BY users_table.value_1 LIMIT 3)))
|
||||
DEBUG: push down of limit count: 3
|
||||
DEBUG: generating subplan 38_1 for subquery SELECT DISTINCT value_1 FROM public.users_table ORDER BY value_1 LIMIT 3
|
||||
DEBUG: generating subplan 38_2 for subquery SELECT DISTINCT value_2 FROM public.users_table OFFSET 0
|
||||
DEBUG: Plan 38 query after replacing subqueries and CTEs: SELECT events_table.user_id FROM public.events_table, (SELECT intermediate_result.value_2 FROM read_intermediate_result('38_2'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)) foo WHERE ((events_table.user_id = foo.value_2) AND (events_table.user_id IN (SELECT intermediate_result.value_1 FROM read_intermediate_result('38_1'::text, 'binary'::citus_copy_format) intermediate_result(value_1 integer))))
|
||||
DEBUG: Plan 37 query after replacing subqueries and CTEs: SELECT dist_cte.user_id FROM ((SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.value_1, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('37_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, value_1 integer, value_2 integer, value_3 double precision, value_4 bigint)) local_cte JOIN (SELECT intermediate_result.user_id FROM read_intermediate_result('37_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) dist_cte ON ((dist_cte.user_id = local_cte.user_id)))
|
||||
DEBUG: generating subplan 39_1 for subquery SELECT DISTINCT value_1 FROM public.users_table ORDER BY value_1 LIMIT 3
|
||||
DEBUG: generating subplan 39_2 for subquery SELECT DISTINCT value_2 FROM public.users_table OFFSET 0
|
||||
DEBUG: Plan 39 query after replacing subqueries and CTEs: SELECT events_table.user_id FROM public.events_table, (SELECT intermediate_result.value_2 FROM read_intermediate_result('39_2'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)) foo WHERE ((events_table.user_id = foo.value_2) AND (events_table.user_id IN (SELECT intermediate_result.value_1 FROM read_intermediate_result('39_1'::text, 'binary'::citus_copy_format) intermediate_result(value_1 integer))))
|
||||
DEBUG: Plan 38 query after replacing subqueries and CTEs: SELECT dist_cte.user_id FROM ((SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.value_1, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('38_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, value_1 integer, value_2 integer, value_3 double precision, value_4 bigint)) local_cte JOIN (SELECT intermediate_result.user_id FROM read_intermediate_result('38_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) dist_cte ON ((dist_cte.user_id = local_cte.user_id)))
|
||||
DEBUG: push down of limit count: 5
|
||||
DEBUG: generating subplan 36_2 for subquery SELECT DISTINCT users_table.user_id FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4]))) ORDER BY users_table.user_id DESC LIMIT 5
|
||||
DEBUG: generating subplan 36_3 for subquery SELECT count(*) AS cnt FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('36_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) cte, (SELECT intermediate_result.user_id FROM read_intermediate_result('36_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) foo WHERE (foo.user_id = cte.user_id)
|
||||
DEBUG: Plan 36 query after replacing subqueries and CTEs: SELECT foo.cnt, users_table.user_id, users_table."time", users_table.value_1, users_table.value_2, users_table.value_3, users_table.value_4 FROM (SELECT intermediate_result.cnt FROM read_intermediate_result('36_3'::text, 'binary'::citus_copy_format) intermediate_result(cnt bigint)) foo, public.users_table WHERE (foo.cnt > users_table.value_2) ORDER BY users_table."time" DESC, foo.cnt DESC, users_table.user_id DESC, users_table.value_1 DESC LIMIT 5
|
||||
DEBUG: generating subplan 37_2 for subquery SELECT DISTINCT users_table.user_id FROM public.users_table, public.events_table WHERE ((users_table.user_id = events_table.user_id) AND (events_table.event_type = ANY (ARRAY[1, 2, 3, 4]))) ORDER BY users_table.user_id DESC LIMIT 5
|
||||
DEBUG: generating subplan 37_3 for subquery SELECT count(*) AS cnt FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('37_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) cte, (SELECT intermediate_result.user_id FROM read_intermediate_result('37_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) foo WHERE (foo.user_id = cte.user_id)
|
||||
DEBUG: Plan 37 query after replacing subqueries and CTEs: SELECT foo.cnt, users_table.user_id, users_table."time", users_table.value_1, users_table.value_2, users_table.value_3, users_table.value_4 FROM (SELECT intermediate_result.cnt FROM read_intermediate_result('37_3'::text, 'binary'::citus_copy_format) intermediate_result(cnt bigint)) foo, public.users_table WHERE (foo.cnt > users_table.value_2) ORDER BY users_table."time" DESC, foo.cnt DESC, users_table.user_id DESC, users_table.value_1 DESC LIMIT 5
|
||||
DEBUG: push down of limit count: 5
|
||||
cnt | user_id | time | value_1 | value_2 | value_3 | value_4
|
||||
-----+---------+---------------------------------+---------+---------+---------+---------
|
||||
|
|
|
@ -422,3 +422,25 @@ DEBUG: Plan 26 query after replacing subqueries and CTEs: SELECT user_id FROM p
|
|||
3
|
||||
(2 rows)
|
||||
|
||||
-- we support queries with recurring tuples in the FROM
|
||||
-- clause and subquery in WHERE clause
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
users_table.user_id
|
||||
FROM
|
||||
users_table, (SELECT user_id FROM events_table) as evs
|
||||
WHERE users_table.user_id = evs.user_id
|
||||
ORDER BY 1
|
||||
LIMIT 5
|
||||
) as foo WHERE user_id IN (SELECT count(*) FROM users_table GROUP BY user_id);
|
||||
DEBUG: push down of limit count: 5
|
||||
DEBUG: generating subplan 28_1 for subquery SELECT users_table.user_id FROM public.users_table, (SELECT events_table.user_id FROM public.events_table) evs WHERE (users_table.user_id = evs.user_id) ORDER BY users_table.user_id LIMIT 5
|
||||
DEBUG: generating subplan 28_2 for subquery SELECT count(*) AS count FROM public.users_table GROUP BY user_id
|
||||
DEBUG: Plan 28 query after replacing subqueries and CTEs: SELECT user_id FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('28_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) foo WHERE (user_id IN (SELECT intermediate_result.count FROM read_intermediate_result('28_2'::text, 'binary'::citus_copy_format) intermediate_result(count bigint)))
|
||||
user_id
|
||||
---------
|
||||
(0 rows)
|
||||
|
||||
|
|
|
@ -0,0 +1,691 @@
|
|||
-- ===================================================================
|
||||
-- test recursive planning functionality with subqueries in WHERE
|
||||
-- ===================================================================
|
||||
CREATE SCHEMA subquery_in_where;
|
||||
SET search_path TO subquery_in_where, public;
|
||||
SET client_min_messages TO DEBUG1;
|
||||
--CTEs can be used as a recurring tuple with subqueries in WHERE
|
||||
WITH event_id
|
||||
AS (SELECT user_id AS events_user_id,
|
||||
time AS events_time,
|
||||
event_type
|
||||
FROM events_table)
|
||||
SELECT Count(*)
|
||||
FROM event_id
|
||||
WHERE events_user_id IN (SELECT user_id
|
||||
FROM users_table);
|
||||
DEBUG: generating subplan 1_1 for CTE event_id: SELECT user_id AS events_user_id, "time" AS events_time, event_type FROM public.events_table
|
||||
DEBUG: generating subplan 1_2 for subquery SELECT user_id FROM public.users_table
|
||||
DEBUG: Plan 1 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.events_user_id, intermediate_result.events_time, intermediate_result.event_type FROM read_intermediate_result('1_1'::text, 'binary'::citus_copy_format) intermediate_result(events_user_id integer, events_time timestamp without time zone, event_type integer)) event_id WHERE (events_user_id IN (SELECT intermediate_result.user_id FROM read_intermediate_result('1_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)))
|
||||
count
|
||||
-------
|
||||
101
|
||||
(1 row)
|
||||
|
||||
--Correlated subqueries can not be used in WHERE clause
|
||||
WITH event_id
|
||||
AS (SELECT user_id AS events_user_id,
|
||||
time AS events_time,
|
||||
event_type
|
||||
FROM events_table)
|
||||
SELECT Count(*)
|
||||
FROM event_id
|
||||
WHERE events_user_id IN (SELECT user_id
|
||||
FROM users_table
|
||||
WHERE users_table.time = events_time);
|
||||
DEBUG: generating subplan 4_1 for CTE event_id: SELECT user_id AS events_user_id, "time" AS events_time, event_type FROM public.events_table
|
||||
DEBUG: Plan 4 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.events_user_id, intermediate_result.events_time, intermediate_result.event_type FROM read_intermediate_result('4_1'::text, 'binary'::citus_copy_format) intermediate_result(events_user_id integer, events_time timestamp without time zone, event_type integer)) event_id WHERE (events_user_id IN (SELECT users_table.user_id FROM public.users_table WHERE (users_table."time" = event_id.events_time)))
|
||||
ERROR: cannot pushdown the subquery
|
||||
DETAIL: Complex subqueries and CTEs are not allowed in the FROM clause when the query has subqueries in the WHERE clause and it references a column from another query
|
||||
-- Recurring tuples as empty join tree
|
||||
SELECT *
|
||||
FROM (SELECT 1 AS id,
|
||||
2 AS value_1,
|
||||
3 AS value_3) AS tt1
|
||||
WHERE id IN (SELECT user_id
|
||||
FROM events_table);
|
||||
DEBUG: generating subplan 6_1 for subquery SELECT user_id FROM public.events_table
|
||||
DEBUG: Plan 6 query after replacing subqueries and CTEs: SELECT id, value_1, value_3 FROM (SELECT 1 AS id, 2 AS value_1, 3 AS value_3) tt1 WHERE (id IN (SELECT intermediate_result.user_id FROM read_intermediate_result('6_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)))
|
||||
id | value_1 | value_3
|
||||
----+---------+---------
|
||||
1 | 2 | 3
|
||||
(1 row)
|
||||
|
||||
-- Recurring tuples in from clause as CTE and SET operation in WHERE clause
|
||||
SELECT Count(*)
|
||||
FROM (WITH event_id AS
|
||||
(SELECT user_id AS events_user_id, time AS events_time, event_type
|
||||
FROM events_table)
|
||||
SELECT events_user_id, events_time, event_type
|
||||
FROM event_id
|
||||
ORDER BY 1,2,3
|
||||
LIMIT 10) AS sub_table
|
||||
WHERE events_user_id IN (
|
||||
(SELECT user_id
|
||||
FROM users_table
|
||||
ORDER BY 1
|
||||
LIMIT 10)
|
||||
UNION ALL
|
||||
(SELECT value_1
|
||||
FROM users_table
|
||||
ORDER BY 1
|
||||
limit 10));
|
||||
DEBUG: push down of limit count: 10
|
||||
DEBUG: generating subplan 8_1 for subquery SELECT user_id FROM public.users_table ORDER BY user_id LIMIT 10
|
||||
DEBUG: push down of limit count: 10
|
||||
DEBUG: generating subplan 8_2 for subquery SELECT value_1 FROM public.users_table ORDER BY value_1 LIMIT 10
|
||||
DEBUG: generating subplan 8_3 for subquery SELECT intermediate_result.user_id FROM read_intermediate_result('8_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) UNION ALL SELECT intermediate_result.value_1 FROM read_intermediate_result('8_2'::text, 'binary'::citus_copy_format) intermediate_result(value_1 integer)
|
||||
DEBUG: generating subplan 8_4 for CTE event_id: SELECT user_id AS events_user_id, "time" AS events_time, event_type FROM public.events_table
|
||||
DEBUG: generating subplan 8_5 for subquery SELECT events_user_id, events_time, event_type FROM (SELECT intermediate_result.events_user_id, intermediate_result.events_time, intermediate_result.event_type FROM read_intermediate_result('8_4'::text, 'binary'::citus_copy_format) intermediate_result(events_user_id integer, events_time timestamp without time zone, event_type integer)) event_id ORDER BY events_user_id, events_time, event_type LIMIT 10
|
||||
DEBUG: Plan 8 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.events_user_id, intermediate_result.events_time, intermediate_result.event_type FROM read_intermediate_result('8_5'::text, 'binary'::citus_copy_format) intermediate_result(events_user_id integer, events_time timestamp without time zone, event_type integer)) sub_table WHERE (events_user_id IN (SELECT intermediate_result.user_id FROM read_intermediate_result('8_3'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)))
|
||||
count
|
||||
-------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
-- Recurring tuples in from clause as SET operation on recursively plannable
|
||||
-- queries and CTE in WHERE clause
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(
|
||||
(SELECT
|
||||
user_id
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id ASC
|
||||
LIMIT
|
||||
10
|
||||
)
|
||||
UNION ALL
|
||||
(SELECT
|
||||
value_1
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
value_1 ASC
|
||||
LIMIT
|
||||
10
|
||||
)
|
||||
) as SUB_TABLE
|
||||
WHERE
|
||||
user_id
|
||||
IN
|
||||
(
|
||||
WITH event_id AS (
|
||||
SELECT
|
||||
user_id as events_user_id, time as events_time, event_type
|
||||
FROM
|
||||
events_table
|
||||
)
|
||||
SELECT
|
||||
events_user_id
|
||||
FROM
|
||||
event_id
|
||||
ORDER BY
|
||||
events_user_id
|
||||
LIMIT
|
||||
10
|
||||
);
|
||||
DEBUG: generating subplan 14_1 for CTE event_id: SELECT user_id AS events_user_id, "time" AS events_time, event_type FROM public.events_table
|
||||
DEBUG: generating subplan 14_2 for subquery SELECT events_user_id FROM (SELECT intermediate_result.events_user_id, intermediate_result.events_time, intermediate_result.event_type FROM read_intermediate_result('14_1'::text, 'binary'::citus_copy_format) intermediate_result(events_user_id integer, events_time timestamp without time zone, event_type integer)) event_id ORDER BY events_user_id LIMIT 10
|
||||
DEBUG: push down of limit count: 10
|
||||
DEBUG: generating subplan 14_3 for subquery SELECT user_id FROM public.users_table ORDER BY user_id LIMIT 10
|
||||
DEBUG: push down of limit count: 10
|
||||
DEBUG: generating subplan 14_4 for subquery SELECT value_1 FROM public.users_table ORDER BY value_1 LIMIT 10
|
||||
DEBUG: generating subplan 14_5 for subquery SELECT intermediate_result.user_id FROM read_intermediate_result('14_3'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer) UNION ALL SELECT intermediate_result.value_1 FROM read_intermediate_result('14_4'::text, 'binary'::citus_copy_format) intermediate_result(value_1 integer)
|
||||
DEBUG: Plan 14 query after replacing subqueries and CTEs: SELECT user_id FROM (SELECT intermediate_result.user_id FROM read_intermediate_result('14_5'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) sub_table WHERE (user_id IN (SELECT intermediate_result.events_user_id FROM read_intermediate_result('14_2'::text, 'binary'::citus_copy_format) intermediate_result(events_user_id integer)))
|
||||
user_id
|
||||
---------
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
(7 rows)
|
||||
|
||||
-- Complex target list in WHERE clause
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
(SELECT
|
||||
user_id as events_user_id, time as events_time, event_type
|
||||
FROM
|
||||
events_table
|
||||
ORDER BY
|
||||
1,2
|
||||
LIMIT
|
||||
10
|
||||
) as SUB_TABLE
|
||||
WHERE
|
||||
events_user_id
|
||||
<=ANY (
|
||||
SELECT
|
||||
max(abs(user_id * 1) + mod(user_id, 3)) as val_1
|
||||
FROM
|
||||
users_table
|
||||
GROUP BY
|
||||
user_id
|
||||
);
|
||||
DEBUG: push down of limit count: 10
|
||||
DEBUG: generating subplan 20_1 for subquery SELECT user_id AS events_user_id, "time" AS events_time, event_type FROM public.events_table ORDER BY user_id, "time" LIMIT 10
|
||||
DEBUG: generating subplan 20_2 for subquery SELECT max((abs((user_id * 1)) + mod(user_id, 3))) AS val_1 FROM public.users_table GROUP BY user_id
|
||||
DEBUG: Plan 20 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.events_user_id, intermediate_result.events_time, intermediate_result.event_type FROM read_intermediate_result('20_1'::text, 'binary'::citus_copy_format) intermediate_result(events_user_id integer, events_time timestamp without time zone, event_type integer)) sub_table WHERE (events_user_id <= ANY (SELECT intermediate_result.val_1 FROM read_intermediate_result('20_2'::text, 'binary'::citus_copy_format) intermediate_result(val_1 integer)))
|
||||
count
|
||||
-------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
-- DISTINCT clause in WHERE
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
(SELECT
|
||||
user_id as events_user_id, time as events_time, event_type
|
||||
FROM
|
||||
events_table
|
||||
LIMIT
|
||||
10
|
||||
) as SUB_TABLE
|
||||
WHERE
|
||||
events_user_id
|
||||
IN (
|
||||
SELECT
|
||||
distinct user_id
|
||||
FROM
|
||||
users_table
|
||||
GROUP BY
|
||||
user_id
|
||||
);
|
||||
DEBUG: push down of limit count: 10
|
||||
DEBUG: generating subplan 23_1 for subquery SELECT user_id AS events_user_id, "time" AS events_time, event_type FROM public.events_table LIMIT 10
|
||||
DEBUG: generating subplan 23_2 for subquery SELECT DISTINCT user_id FROM public.users_table GROUP BY user_id
|
||||
DEBUG: Plan 23 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.events_user_id, intermediate_result.events_time, intermediate_result.event_type FROM read_intermediate_result('23_1'::text, 'binary'::citus_copy_format) intermediate_result(events_user_id integer, events_time timestamp without time zone, event_type integer)) sub_table WHERE (events_user_id IN (SELECT intermediate_result.user_id FROM read_intermediate_result('23_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)))
|
||||
count
|
||||
-------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
-- AND in WHERE clause
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
(SELECT
|
||||
user_id as events_user_id, time as events_time, event_type
|
||||
FROM
|
||||
events_table
|
||||
ORDER BY
|
||||
1,2,3
|
||||
LIMIT
|
||||
10
|
||||
) as SUB_TABLE
|
||||
WHERE
|
||||
events_user_id
|
||||
>=ANY (
|
||||
SELECT
|
||||
min(user_id)
|
||||
FROM
|
||||
users_table
|
||||
GROUP BY
|
||||
user_id
|
||||
)
|
||||
AND
|
||||
events_user_id
|
||||
<=ANY (
|
||||
SELECT
|
||||
max(user_id)
|
||||
FROM
|
||||
users_table
|
||||
GROUP BY
|
||||
user_id
|
||||
);
|
||||
DEBUG: push down of limit count: 10
|
||||
DEBUG: generating subplan 26_1 for subquery SELECT user_id AS events_user_id, "time" AS events_time, event_type FROM public.events_table ORDER BY user_id, "time", event_type LIMIT 10
|
||||
DEBUG: generating subplan 26_2 for subquery SELECT min(user_id) AS min FROM public.users_table GROUP BY user_id
|
||||
DEBUG: generating subplan 26_3 for subquery SELECT max(user_id) AS max FROM public.users_table GROUP BY user_id
|
||||
DEBUG: Plan 26 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.events_user_id, intermediate_result.events_time, intermediate_result.event_type FROM read_intermediate_result('26_1'::text, 'binary'::citus_copy_format) intermediate_result(events_user_id integer, events_time timestamp without time zone, event_type integer)) sub_table WHERE ((events_user_id >= ANY (SELECT intermediate_result.min FROM read_intermediate_result('26_2'::text, 'binary'::citus_copy_format) intermediate_result(min integer))) AND (events_user_id <= ANY (SELECT intermediate_result.max FROM read_intermediate_result('26_3'::text, 'binary'::citus_copy_format) intermediate_result(max integer))))
|
||||
count
|
||||
-------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
-- AND in WHERE clause, part of the AND is pushdownable other is not
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
(SELECT
|
||||
user_id as events_user_id, time as events_time, event_type
|
||||
FROM
|
||||
events_table
|
||||
ORDER BY
|
||||
1,2,3
|
||||
LIMIT
|
||||
10
|
||||
) as SUB_TABLE
|
||||
WHERE
|
||||
events_user_id
|
||||
>=ANY (
|
||||
SELECT
|
||||
min(user_id)
|
||||
FROM
|
||||
users_table
|
||||
GROUP BY
|
||||
user_id
|
||||
)
|
||||
AND
|
||||
events_user_id
|
||||
<=ANY (
|
||||
SELECT
|
||||
max(value_2)
|
||||
FROM
|
||||
users_table
|
||||
GROUP BY
|
||||
user_id
|
||||
);
|
||||
DEBUG: push down of limit count: 10
|
||||
DEBUG: generating subplan 30_1 for subquery SELECT user_id AS events_user_id, "time" AS events_time, event_type FROM public.events_table ORDER BY user_id, "time", event_type LIMIT 10
|
||||
DEBUG: generating subplan 30_2 for subquery SELECT min(user_id) AS min FROM public.users_table GROUP BY user_id
|
||||
DEBUG: generating subplan 30_3 for subquery SELECT max(value_2) AS max FROM public.users_table GROUP BY user_id
|
||||
DEBUG: Plan 30 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.events_user_id, intermediate_result.events_time, intermediate_result.event_type FROM read_intermediate_result('30_1'::text, 'binary'::citus_copy_format) intermediate_result(events_user_id integer, events_time timestamp without time zone, event_type integer)) sub_table WHERE ((events_user_id >= ANY (SELECT intermediate_result.min FROM read_intermediate_result('30_2'::text, 'binary'::citus_copy_format) intermediate_result(min integer))) AND (events_user_id <= ANY (SELECT intermediate_result.max FROM read_intermediate_result('30_3'::text, 'binary'::citus_copy_format) intermediate_result(max integer))))
|
||||
count
|
||||
-------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
-- Planning subqueries in WHERE clause in CTE recursively
|
||||
WITH cte AS (
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id ASC,
|
||||
value_2 DESC
|
||||
LIMIT
|
||||
10
|
||||
) as sub_table
|
||||
WHERE
|
||||
user_id
|
||||
IN
|
||||
(SELECT
|
||||
value_2
|
||||
FROM
|
||||
events_table
|
||||
)
|
||||
)
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
cte;
|
||||
DEBUG: generating subplan 34_1 for CTE cte: SELECT user_id, "time", value_1, value_2, value_3, value_4 FROM (SELECT users_table.user_id, users_table."time", users_table.value_1, users_table.value_2, users_table.value_3, users_table.value_4 FROM public.users_table ORDER BY users_table.user_id, users_table.value_2 DESC LIMIT 10) sub_table WHERE (user_id IN (SELECT events_table.value_2 FROM public.events_table))
|
||||
DEBUG: push down of limit count: 10
|
||||
DEBUG: generating subplan 35_1 for subquery SELECT user_id, "time", value_1, value_2, value_3, value_4 FROM public.users_table ORDER BY user_id, value_2 DESC LIMIT 10
|
||||
DEBUG: generating subplan 35_2 for subquery SELECT value_2 FROM public.events_table
|
||||
DEBUG: Plan 35 query after replacing subqueries and CTEs: SELECT user_id, "time", value_1, value_2, value_3, value_4 FROM (SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.value_1, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('35_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, value_1 integer, value_2 integer, value_3 double precision, value_4 bigint)) sub_table WHERE (user_id IN (SELECT intermediate_result.value_2 FROM read_intermediate_result('35_2'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)))
|
||||
DEBUG: Plan 34 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.value_1, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('34_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, value_1 integer, value_2 integer, value_3 double precision, value_4 bigint)) cte
|
||||
count
|
||||
-------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
-- Planing subquery in WHERE clause in FROM clause of a subquery recursively
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id ASC,
|
||||
value_2 DESC
|
||||
LIMIT
|
||||
10
|
||||
) as sub_table_1
|
||||
WHERE
|
||||
user_id
|
||||
IN
|
||||
(SELECT
|
||||
value_2
|
||||
FROM
|
||||
events_table
|
||||
)
|
||||
) as sub_table_2;
|
||||
DEBUG: push down of limit count: 10
|
||||
DEBUG: generating subplan 38_1 for subquery SELECT user_id, "time", value_1, value_2, value_3, value_4 FROM public.users_table ORDER BY user_id, value_2 DESC LIMIT 10
|
||||
DEBUG: generating subplan 38_2 for subquery SELECT value_2 FROM public.events_table
|
||||
DEBUG: generating subplan 38_3 for subquery SELECT user_id, "time", value_1, value_2, value_3, value_4 FROM (SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.value_1, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('38_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, value_1 integer, value_2 integer, value_3 double precision, value_4 bigint)) sub_table_1 WHERE (user_id IN (SELECT intermediate_result.value_2 FROM read_intermediate_result('38_2'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)))
|
||||
DEBUG: Plan 38 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.value_1, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('38_3'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, value_1 integer, value_2 integer, value_3 double precision, value_4 bigint)) sub_table_2
|
||||
count
|
||||
-------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
-- Recurring table in the FROM clause of a subquery in the FROM clause
|
||||
-- Recurring table is created by joining a two recurrign table
|
||||
SELECT
|
||||
SUM(user_id)
|
||||
FROM
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT
|
||||
user_id
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id
|
||||
LIMIT 10) as t1
|
||||
INNER JOIN
|
||||
(SELECT
|
||||
user_id as user_id_2
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id
|
||||
LIMIT
|
||||
10) as t2
|
||||
ON
|
||||
t1.user_id = t2.user_id_2
|
||||
WHERE
|
||||
t1.user_id
|
||||
IN
|
||||
(SELECT
|
||||
value_2
|
||||
FROM
|
||||
events_table)
|
||||
) as t3
|
||||
WHERE
|
||||
user_id
|
||||
>ANY
|
||||
(SELECT
|
||||
min(user_id)
|
||||
FROM
|
||||
events_table
|
||||
GROUP BY
|
||||
user_id);
|
||||
DEBUG: push down of limit count: 10
|
||||
DEBUG: generating subplan 42_1 for subquery SELECT user_id FROM public.users_table ORDER BY user_id LIMIT 10
|
||||
DEBUG: push down of limit count: 10
|
||||
DEBUG: generating subplan 42_2 for subquery SELECT user_id AS user_id_2 FROM public.users_table ORDER BY user_id LIMIT 10
|
||||
DEBUG: generating subplan 42_3 for subquery SELECT value_2 FROM public.events_table
|
||||
DEBUG: generating subplan 42_4 for subquery SELECT t1.user_id, t2.user_id_2 FROM ((SELECT intermediate_result.user_id FROM read_intermediate_result('42_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) t1 JOIN (SELECT intermediate_result.user_id_2 FROM read_intermediate_result('42_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id_2 integer)) t2 ON ((t1.user_id = t2.user_id_2))) WHERE (t1.user_id IN (SELECT intermediate_result.value_2 FROM read_intermediate_result('42_3'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)))
|
||||
DEBUG: generating subplan 42_5 for subquery SELECT min(user_id) AS min FROM public.events_table GROUP BY user_id
|
||||
DEBUG: Plan 42 query after replacing subqueries and CTEs: SELECT sum(user_id) AS sum FROM (SELECT intermediate_result.user_id, intermediate_result.user_id_2 FROM read_intermediate_result('42_4'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, user_id_2 integer)) t3 WHERE (user_id > ANY (SELECT intermediate_result.min FROM read_intermediate_result('42_5'::text, 'binary'::citus_copy_format) intermediate_result(min integer)))
|
||||
sum
|
||||
-----
|
||||
18
|
||||
(1 row)
|
||||
|
||||
-- Same example with the above query, but now check the rows with EXISTS
|
||||
SELECT
|
||||
SUM(user_id)
|
||||
FROM
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT
|
||||
user_id
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id
|
||||
LIMIT 10) as t1
|
||||
INNER JOIN
|
||||
(SELECT
|
||||
user_id as user_id_2
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id
|
||||
LIMIT
|
||||
10) as t2
|
||||
ON
|
||||
t1.user_id = t2.user_id_2
|
||||
WHERE
|
||||
t1.user_id
|
||||
IN
|
||||
(SELECT
|
||||
value_2
|
||||
FROM
|
||||
events_table)
|
||||
) as t3
|
||||
WHERE EXISTS
|
||||
(SELECT
|
||||
1,2
|
||||
FROM
|
||||
events_table
|
||||
WHERE
|
||||
events_table.value_2 = events_table.user_id);
|
||||
DEBUG: push down of limit count: 10
|
||||
DEBUG: generating subplan 48_1 for subquery SELECT user_id FROM public.users_table ORDER BY user_id LIMIT 10
|
||||
DEBUG: push down of limit count: 10
|
||||
DEBUG: generating subplan 48_2 for subquery SELECT user_id AS user_id_2 FROM public.users_table ORDER BY user_id LIMIT 10
|
||||
DEBUG: generating subplan 48_3 for subquery SELECT value_2 FROM public.events_table
|
||||
DEBUG: generating subplan 48_4 for subquery SELECT t1.user_id, t2.user_id_2 FROM ((SELECT intermediate_result.user_id FROM read_intermediate_result('48_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) t1 JOIN (SELECT intermediate_result.user_id_2 FROM read_intermediate_result('48_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id_2 integer)) t2 ON ((t1.user_id = t2.user_id_2))) WHERE (t1.user_id IN (SELECT intermediate_result.value_2 FROM read_intermediate_result('48_3'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)))
|
||||
DEBUG: generating subplan 48_5 for subquery SELECT 1, 2 FROM public.events_table WHERE (value_2 = user_id)
|
||||
DEBUG: Plan 48 query after replacing subqueries and CTEs: SELECT sum(user_id) AS sum FROM (SELECT intermediate_result.user_id, intermediate_result.user_id_2 FROM read_intermediate_result('48_4'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, user_id_2 integer)) t3 WHERE (EXISTS (SELECT intermediate_result."?column?", intermediate_result."?column?_1" AS "?column?" FROM read_intermediate_result('48_5'::text, 'binary'::citus_copy_format) intermediate_result("?column?" integer, "?column?_1" integer)))
|
||||
sum
|
||||
-----
|
||||
67
|
||||
(1 row)
|
||||
|
||||
-- Same query with the above one, yet now we check the row's NON-existence
|
||||
-- by NOT EXISTS. Note that, max value_2 of events_table is 5
|
||||
SELECT
|
||||
SUM(user_id)
|
||||
FROM
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT
|
||||
user_id
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id
|
||||
LIMIT 10) as t1
|
||||
INNER JOIN
|
||||
(SELECT
|
||||
user_id as user_id_2
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id
|
||||
LIMIT
|
||||
10) as t2
|
||||
ON
|
||||
t1.user_id = t2.user_id_2
|
||||
WHERE
|
||||
t1.user_id
|
||||
IN
|
||||
(SELECT
|
||||
value_2
|
||||
FROM
|
||||
events_table)
|
||||
) as t3
|
||||
WHERE NOT EXISTS
|
||||
(SELECT
|
||||
1,2
|
||||
FROM
|
||||
events_table
|
||||
WHERE
|
||||
events_table.value_2 = events_table.user_id + 6);
|
||||
DEBUG: push down of limit count: 10
|
||||
DEBUG: generating subplan 54_1 for subquery SELECT user_id FROM public.users_table ORDER BY user_id LIMIT 10
|
||||
DEBUG: push down of limit count: 10
|
||||
DEBUG: generating subplan 54_2 for subquery SELECT user_id AS user_id_2 FROM public.users_table ORDER BY user_id LIMIT 10
|
||||
DEBUG: generating subplan 54_3 for subquery SELECT value_2 FROM public.events_table
|
||||
DEBUG: generating subplan 54_4 for subquery SELECT t1.user_id, t2.user_id_2 FROM ((SELECT intermediate_result.user_id FROM read_intermediate_result('54_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) t1 JOIN (SELECT intermediate_result.user_id_2 FROM read_intermediate_result('54_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id_2 integer)) t2 ON ((t1.user_id = t2.user_id_2))) WHERE (t1.user_id IN (SELECT intermediate_result.value_2 FROM read_intermediate_result('54_3'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer)))
|
||||
DEBUG: generating subplan 54_5 for subquery SELECT 1, 2 FROM public.events_table WHERE (value_2 = (user_id + 6))
|
||||
DEBUG: Plan 54 query after replacing subqueries and CTEs: SELECT sum(user_id) AS sum FROM (SELECT intermediate_result.user_id, intermediate_result.user_id_2 FROM read_intermediate_result('54_4'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, user_id_2 integer)) t3 WHERE (NOT (EXISTS (SELECT intermediate_result."?column?", intermediate_result."?column?_1" AS "?column?" FROM read_intermediate_result('54_5'::text, 'binary'::citus_copy_format) intermediate_result("?column?" integer, "?column?_1" integer))))
|
||||
sum
|
||||
-----
|
||||
67
|
||||
(1 row)
|
||||
|
||||
-- Check the existence of row by comparing it with the result of subquery in
|
||||
-- WHERE clause. Note that subquery is planned recursively since there is no
|
||||
-- distributed table in the from
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT
|
||||
user_id, value_1
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id ASC,
|
||||
value_1 ASC
|
||||
LIMIT 10) as t3
|
||||
WHERE row(user_id, value_1) =
|
||||
(SELECT
|
||||
min(user_id) + 1, min(user_id) + 1
|
||||
FROM
|
||||
events_table);
|
||||
DEBUG: generating subplan 60_1 for subquery SELECT (min(user_id) + 1), (min(user_id) + 1) FROM public.events_table
|
||||
DEBUG: push down of limit count: 10
|
||||
DEBUG: generating subplan 60_2 for subquery SELECT user_id, value_1 FROM public.users_table ORDER BY user_id, value_1 LIMIT 10
|
||||
DEBUG: Plan 60 query after replacing subqueries and CTEs: SELECT user_id, value_1 FROM (SELECT intermediate_result.user_id, intermediate_result.value_1 FROM read_intermediate_result('60_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, value_1 integer)) t3 WHERE ((user_id, value_1) = (SELECT intermediate_result."?column?", intermediate_result."?column?_1" AS "?column?" FROM read_intermediate_result('60_1'::text, 'binary'::citus_copy_format) intermediate_result("?column?" integer, "?column?_1" integer)))
|
||||
user_id | value_1
|
||||
---------+---------
|
||||
(0 rows)
|
||||
|
||||
-- Recursively plan subquery in WHERE clause when the FROM clause has a subquery
|
||||
-- generated by generate_series function
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
generate_series(1,10)
|
||||
) as gst
|
||||
WHERE
|
||||
generate_series
|
||||
IN
|
||||
(SELECT
|
||||
value_2
|
||||
FROM
|
||||
events_table
|
||||
)
|
||||
ORDER BY
|
||||
generate_series ASC;
|
||||
DEBUG: generating subplan 63_1 for subquery SELECT value_2 FROM public.events_table
|
||||
DEBUG: Plan 63 query after replacing subqueries and CTEs: SELECT generate_series FROM (SELECT generate_series.generate_series FROM generate_series(1, 10) generate_series(generate_series)) gst WHERE (generate_series IN (SELECT intermediate_result.value_2 FROM read_intermediate_result('63_1'::text, 'binary'::citus_copy_format) intermediate_result(value_2 integer))) ORDER BY generate_series
|
||||
generate_series
|
||||
-----------------
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
(5 rows)
|
||||
|
||||
-- Similar to the test above, now we also have a generate_series in WHERE clause
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
generate_series(1,10)
|
||||
) as gst
|
||||
WHERE
|
||||
generate_series
|
||||
IN
|
||||
(SELECT
|
||||
user_id
|
||||
FROM
|
||||
users_table
|
||||
WHERE
|
||||
user_id
|
||||
IN
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
generate_series(1,3)
|
||||
)
|
||||
)
|
||||
ORDER BY
|
||||
generate_series ASC;
|
||||
DEBUG: generating subplan 65_1 for subquery SELECT user_id FROM public.users_table WHERE (user_id IN (SELECT generate_series.generate_series FROM generate_series(1, 3) generate_series(generate_series)))
|
||||
DEBUG: Plan 65 query after replacing subqueries and CTEs: SELECT generate_series FROM (SELECT generate_series.generate_series FROM generate_series(1, 10) generate_series(generate_series)) gst WHERE (generate_series IN (SELECT intermediate_result.user_id FROM read_intermediate_result('65_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer))) ORDER BY generate_series
|
||||
generate_series
|
||||
-----------------
|
||||
1
|
||||
2
|
||||
3
|
||||
(3 rows)
|
||||
|
||||
|
||||
-- Local tables also planned recursively, so using it as part of the FROM clause
|
||||
-- make the clause recurring
|
||||
CREATE TABLE local_table(id int, value_1 int);
|
||||
INSERT INTO local_table VALUES(1,1), (2,2);
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
local_table) as sub_table
|
||||
WHERE
|
||||
id
|
||||
IN
|
||||
(SELECT
|
||||
user_id
|
||||
FROM
|
||||
users_table);
|
||||
DEBUG: generating subplan 67_1 for subquery SELECT id, value_1 FROM subquery_in_where.local_table
|
||||
DEBUG: generating subplan 67_2 for subquery SELECT user_id FROM public.users_table
|
||||
DEBUG: Plan 67 query after replacing subqueries and CTEs: SELECT id, value_1 FROM (SELECT intermediate_result.id, intermediate_result.value_1 FROM read_intermediate_result('67_1'::text, 'binary'::citus_copy_format) intermediate_result(id integer, value_1 integer)) sub_table WHERE (id IN (SELECT intermediate_result.user_id FROM read_intermediate_result('67_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)))
|
||||
id | value_1
|
||||
----+---------
|
||||
1 | 1
|
||||
2 | 2
|
||||
(2 rows)
|
||||
|
||||
|
||||
-- Use local table in WHERE clause
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id
|
||||
LIMIT
|
||||
10) as sub_table
|
||||
WHERE
|
||||
user_id
|
||||
IN
|
||||
(SELECT
|
||||
id
|
||||
FROM
|
||||
local_table);
|
||||
DEBUG: generating subplan 69_1 for subquery SELECT id FROM subquery_in_where.local_table
|
||||
DEBUG: push down of limit count: 10
|
||||
DEBUG: generating subplan 69_2 for subquery SELECT user_id, "time", value_1, value_2, value_3, value_4 FROM public.users_table ORDER BY user_id LIMIT 10
|
||||
DEBUG: Plan 69 query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.user_id, intermediate_result."time", intermediate_result.value_1, intermediate_result.value_2, intermediate_result.value_3, intermediate_result.value_4 FROM read_intermediate_result('69_2'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer, "time" timestamp without time zone, value_1 integer, value_2 integer, value_3 double precision, value_4 bigint)) sub_table WHERE (user_id IN (SELECT intermediate_result.id FROM read_intermediate_result('69_1'::text, 'binary'::citus_copy_format) intermediate_result(id integer)))
|
||||
count
|
||||
-------
|
||||
10
|
||||
(1 row)
|
||||
|
||||
DROP TABLE local_table;
|
||||
DEBUG: EventTriggerInvoke 19921
|
||||
SET client_min_messages TO DEFAULT;
|
||||
DROP SCHEMA subquery_in_where CASCADE;
|
||||
SET search_path TO public;
|
|
@ -174,6 +174,18 @@ FROM
|
|||
ORDER BY
|
||||
1, 2, 3, 4, 5, 6
|
||||
LIMIT 10;
|
||||
-- Prepare a statement with a sublink in WHERE clause and recurring tuple in FORM
|
||||
PREPARE prepared_test_6 AS
|
||||
WITH event_id AS (
|
||||
SELECT user_id as events_user_id, time as events_time, event_type
|
||||
FROM events_table
|
||||
)
|
||||
SELECT
|
||||
count(*)
|
||||
FROM
|
||||
event_id
|
||||
WHERE
|
||||
events_user_id IN (SELECT user_id FROM users_table);
|
||||
EXECUTE prepared_test_1;
|
||||
user_id | time | value_1 | value_2 | value_3 | value_4
|
||||
---------+---------------------------------+---------+---------+---------+---------
|
||||
|
@ -542,6 +554,42 @@ EXECUTE prepared_test_5(6, 7, 8);
|
|||
6 | Thu Nov 23 14:43:18.024104 2017 | 3 | 2 | 5 |
|
||||
(10 rows)
|
||||
|
||||
EXECUTE prepared_test_6;
|
||||
count
|
||||
-------
|
||||
101
|
||||
(1 row)
|
||||
|
||||
EXECUTE prepared_test_6;
|
||||
count
|
||||
-------
|
||||
101
|
||||
(1 row)
|
||||
|
||||
EXECUTE prepared_test_6;
|
||||
count
|
||||
-------
|
||||
101
|
||||
(1 row)
|
||||
|
||||
EXECUTE prepared_test_6;
|
||||
count
|
||||
-------
|
||||
101
|
||||
(1 row)
|
||||
|
||||
EXECUTE prepared_test_6;
|
||||
count
|
||||
-------
|
||||
101
|
||||
(1 row)
|
||||
|
||||
EXECUTE prepared_test_6;
|
||||
count
|
||||
-------
|
||||
101
|
||||
(1 row)
|
||||
|
||||
EXECUTE prepared_partition_column_insert(1);
|
||||
ERROR: data-modifying statements are not supported in the WITH clauses of distributed queries
|
||||
DEALLOCATE ALL;
|
||||
|
|
|
@ -43,7 +43,7 @@ test: multi_partitioning_utils multi_partitioning
|
|||
# Tests for recursive subquery planning
|
||||
# ----------
|
||||
test: subquery_basics subquery_local_tables subquery_executors subquery_and_cte set_operations set_operation_and_local_tables
|
||||
test: subqueries_deep subquery_view subquery_partitioning subquery_complex_target_list subqueries_not_supported
|
||||
test: subqueries_deep subquery_view subquery_partitioning subquery_complex_target_list subqueries_not_supported subquery_in_where
|
||||
test: subquery_prepared_statements
|
||||
|
||||
# ----------
|
||||
|
|
|
@ -38,8 +38,8 @@ GROUP BY user_id
|
|||
ORDER BY user_id
|
||||
LIMIT 3;
|
||||
|
||||
-- subqueries in WHERE with NOT EXISTS operator, should not work
|
||||
-- there is a reference table in the outer part of the join
|
||||
-- subqueries in WHERE with NOT EXISTS operator, should not work since
|
||||
-- there is a correlated subquery in WHERE clause
|
||||
SELECT
|
||||
user_id
|
||||
FROM
|
||||
|
@ -55,7 +55,8 @@ WHERE
|
|||
)
|
||||
LIMIT 3;
|
||||
|
||||
-- immutable functions are also treated as reference tables
|
||||
-- immutable functions are also treated as reference tables, query should not
|
||||
-- work since there is a correlated subquery in the WHERE clause
|
||||
SELECT
|
||||
user_id
|
||||
FROM
|
||||
|
@ -71,7 +72,8 @@ WHERE
|
|||
)
|
||||
LIMIT 3;
|
||||
|
||||
-- subqueries without FROM are also treated as reference tables
|
||||
-- subqueries without FROM are also treated as reference tables, query should not
|
||||
-- work since there is a correlated subquery in the WHERE clause
|
||||
SELECT
|
||||
user_id
|
||||
FROM
|
||||
|
@ -353,7 +355,10 @@ SELECT user_id, value_2 FROM users_table WHERE
|
|||
)
|
||||
ORDER BY 1, 2;
|
||||
|
||||
-- reference tables are not allowed if there is sublink
|
||||
-- change debug level to check recursive planning output
|
||||
SET client_min_messages TO DEBUG1;
|
||||
|
||||
-- recursively planning subqueries in WHERE clause due to recurring table in FROM
|
||||
SELECT
|
||||
count(*)
|
||||
FROM
|
||||
|
@ -362,8 +367,7 @@ WHERE user_id
|
|||
NOT IN
|
||||
(SELECT users_table.value_2 FROM users_table JOIN users_reference_table as u2 ON users_table.value_2 = u2.value_2);
|
||||
|
||||
|
||||
-- reference tables are not allowed if there is sublink
|
||||
-- recursively planning subqueries in WHERE clause due to recurring table in FROM
|
||||
SELECT count(*)
|
||||
FROM
|
||||
(SELECT
|
||||
|
@ -373,7 +377,7 @@ FROM
|
|||
FROM users_table
|
||||
JOIN users_reference_table AS u2 ON users_table.value_2 = u2.value_2);
|
||||
|
||||
-- reference tables are not allowed if there is sublink
|
||||
-- query should not work since there is a correlated subquery in the WHERE clause
|
||||
SELECT user_id,
|
||||
count(*)
|
||||
FROM users_reference_table
|
||||
|
@ -388,8 +392,7 @@ ORDER BY 2 DESC,
|
|||
1 DESC
|
||||
LIMIT 5;
|
||||
|
||||
-- reference tables are not allowed if there is sublink
|
||||
-- this time in the subquery
|
||||
-- query will be planned as a SEMI JOIN
|
||||
SELECT *
|
||||
FROM users_table
|
||||
WHERE user_id IN
|
||||
|
@ -402,6 +405,8 @@ WHERE user_id IN
|
|||
ORDER BY 1,2,3
|
||||
LIMIT 5;
|
||||
|
||||
SET client_min_messages TO DEFAULT;
|
||||
|
||||
-- not supported since GROUP BY references to an upper level query
|
||||
SELECT
|
||||
user_id
|
||||
|
|
|
@ -88,7 +88,7 @@ SELECT * FROM ((SELECT * FROM local_test) INTERSECT (SELECT * FROM test ORDER BY
|
|||
-- recurively plan left part of the join, and run a final real-time query
|
||||
SELECT * FROM ((SELECT * FROM local_test) INTERSECT (SELECT * FROM test ORDER BY x LIMIT 1)) u INNER JOIN test USING (x) ORDER BY 1,2;
|
||||
|
||||
-- distributed table in WHERE clause, but not FROM clause still disallowed
|
||||
-- set operations and the sublink can be recursively planned
|
||||
SELECT * FROM ((SELECT x FROM test) UNION (SELECT x FROM (SELECT x FROM local_test) as foo WHERE x IN (SELECT x FROM test))) u ORDER BY 1;
|
||||
|
||||
SET citus.enable_repartition_joins TO ON;
|
||||
|
|
|
@ -97,7 +97,7 @@ SELECT * FROM ((SELECT * FROM test) UNION (SELECT * FROM test)) foo WHERE x IN (
|
|||
-- now both the set operations and the sublink is recursively planned
|
||||
SELECT * FROM ((SELECT x,y FROM test) UNION (SELECT y,x FROM test)) foo WHERE x IN (SELECT y FROM test ORDER BY 1 LIMIT 4) ORDER BY 1;
|
||||
|
||||
-- set operations are recursively planned and not the sublink, thus should error out
|
||||
-- set operations and the sublink can be recursively planned
|
||||
SELECT * FROM ((SELECT x,y FROM test) UNION (SELECT y,x FROM test)) foo WHERE x IN (SELECT y FROM test) ORDER BY 1;
|
||||
|
||||
-- set operations works fine with pushdownable window functions
|
||||
|
@ -115,7 +115,7 @@ SELECT x, y, rnk FROM (SELECT *, rank() OVER my_win as rnk FROM test WINDOW my_w
|
|||
SELECT * FROM ((SELECT * FROM test) EXCEPT (SELECT * FROM test ORDER BY x LIMIT 1)) u JOIN test USING (x) ORDER BY 1,2;
|
||||
SELECT * FROM ((SELECT * FROM test) INTERSECT (SELECT * FROM test ORDER BY x LIMIT 1)) u LEFT JOIN test USING (x) ORDER BY 1,2;
|
||||
|
||||
-- distributed table in WHERE clause, but not FROM clause still disallowed
|
||||
-- distributed table in WHERE clause is recursively planned
|
||||
SELECT * FROM ((SELECT * FROM test) UNION (SELECT * FROM ref WHERE a IN (SELECT x FROM test))) u ORDER BY 1,2;
|
||||
|
||||
-- subquery union in WHERE clause with partition column equality and implicit join is pushed down
|
||||
|
|
|
@ -58,20 +58,6 @@ FROM
|
|||
LIMIT 5
|
||||
) as foo;
|
||||
|
||||
-- we don't support queries with recurring tuples in the FROM
|
||||
-- clause and subquery in WHERE clause
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
users_table.user_id
|
||||
FROM
|
||||
users_table, (SELECT user_id FROM events_table) as evs
|
||||
WHERE users_table.user_id = evs.user_id
|
||||
LIMIT 5
|
||||
) as foo WHERE user_id IN (SELECT count(*) FROM users_table GROUP BY user_id);
|
||||
|
||||
-- we don't support recursive subqueries when router executor is disabled
|
||||
SET citus.enable_router_execution TO false;
|
||||
SELECT
|
||||
|
|
|
@ -81,10 +81,8 @@ WHERE
|
|||
users_table.user_id IN (SELECT DISTINCT value_2 FROM users_table WHERE value_1 >= 1 AND value_1 <= 20 ORDER BY 1 LIMIT 5)
|
||||
ORDER BY 1 DESC;
|
||||
|
||||
-- a very similar query as the above, but this time errors
|
||||
-- out since we don't support subqueries in WHERE clause
|
||||
-- when there is only intermediate results on the range table
|
||||
-- note that this time subquery in WHERE clause is not replaced
|
||||
-- subquery in WHERE clause is planned recursively due to the recurring table
|
||||
-- in FROM clause
|
||||
WITH cte AS (
|
||||
WITH local_cte AS (
|
||||
SELECT * FROM users_table_local
|
||||
|
|
|
@ -311,3 +311,17 @@ GROUP BY user_id
|
|||
HAVING count(*) > 1 AND sum(value_2) > 29
|
||||
ORDER BY 1;
|
||||
|
||||
-- we support queries with recurring tuples in the FROM
|
||||
-- clause and subquery in WHERE clause
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
users_table.user_id
|
||||
FROM
|
||||
users_table, (SELECT user_id FROM events_table) as evs
|
||||
WHERE users_table.user_id = evs.user_id
|
||||
ORDER BY 1
|
||||
LIMIT 5
|
||||
) as foo WHERE user_id IN (SELECT count(*) FROM users_table GROUP BY user_id);
|
||||
|
|
|
@ -0,0 +1,517 @@
|
|||
-- ===================================================================
|
||||
-- test recursive planning functionality with subqueries in WHERE
|
||||
-- ===================================================================
|
||||
CREATE SCHEMA subquery_in_where;
|
||||
SET search_path TO subquery_in_where, public;
|
||||
|
||||
SET client_min_messages TO DEBUG1;
|
||||
|
||||
--CTEs can be used as a recurring tuple with subqueries in WHERE
|
||||
WITH event_id
|
||||
AS (SELECT user_id AS events_user_id,
|
||||
time AS events_time,
|
||||
event_type
|
||||
FROM events_table)
|
||||
SELECT Count(*)
|
||||
FROM event_id
|
||||
WHERE events_user_id IN (SELECT user_id
|
||||
FROM users_table);
|
||||
|
||||
--Correlated subqueries can not be used in WHERE clause
|
||||
WITH event_id
|
||||
AS (SELECT user_id AS events_user_id,
|
||||
time AS events_time,
|
||||
event_type
|
||||
FROM events_table)
|
||||
SELECT Count(*)
|
||||
FROM event_id
|
||||
WHERE events_user_id IN (SELECT user_id
|
||||
FROM users_table
|
||||
WHERE users_table.time = events_time);
|
||||
|
||||
-- Recurring tuples as empty join tree
|
||||
SELECT *
|
||||
FROM (SELECT 1 AS id,
|
||||
2 AS value_1,
|
||||
3 AS value_3) AS tt1
|
||||
WHERE id IN (SELECT user_id
|
||||
FROM events_table);
|
||||
|
||||
-- Recurring tuples in from clause as CTE and SET operation in WHERE clause
|
||||
SELECT Count(*)
|
||||
FROM (WITH event_id AS
|
||||
(SELECT user_id AS events_user_id, time AS events_time, event_type
|
||||
FROM events_table)
|
||||
SELECT events_user_id, events_time, event_type
|
||||
FROM event_id
|
||||
ORDER BY 1,2,3
|
||||
LIMIT 10) AS sub_table
|
||||
WHERE events_user_id IN (
|
||||
(SELECT user_id
|
||||
FROM users_table
|
||||
ORDER BY 1
|
||||
LIMIT 10)
|
||||
UNION ALL
|
||||
(SELECT value_1
|
||||
FROM users_table
|
||||
ORDER BY 1
|
||||
limit 10));
|
||||
|
||||
-- Recurring tuples in from clause as SET operation on recursively plannable
|
||||
-- queries and CTE in WHERE clause
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(
|
||||
(SELECT
|
||||
user_id
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id ASC
|
||||
LIMIT
|
||||
10
|
||||
)
|
||||
UNION ALL
|
||||
(SELECT
|
||||
value_1
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
value_1 ASC
|
||||
LIMIT
|
||||
10
|
||||
)
|
||||
) as SUB_TABLE
|
||||
WHERE
|
||||
user_id
|
||||
IN
|
||||
(
|
||||
WITH event_id AS (
|
||||
SELECT
|
||||
user_id as events_user_id, time as events_time, event_type
|
||||
FROM
|
||||
events_table
|
||||
)
|
||||
SELECT
|
||||
events_user_id
|
||||
FROM
|
||||
event_id
|
||||
ORDER BY
|
||||
events_user_id
|
||||
LIMIT
|
||||
10
|
||||
);
|
||||
|
||||
-- Complex target list in WHERE clause
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
(SELECT
|
||||
user_id as events_user_id, time as events_time, event_type
|
||||
FROM
|
||||
events_table
|
||||
ORDER BY
|
||||
1,2
|
||||
LIMIT
|
||||
10
|
||||
) as SUB_TABLE
|
||||
WHERE
|
||||
events_user_id
|
||||
<=ANY (
|
||||
SELECT
|
||||
max(abs(user_id * 1) + mod(user_id, 3)) as val_1
|
||||
FROM
|
||||
users_table
|
||||
GROUP BY
|
||||
user_id
|
||||
);
|
||||
|
||||
-- DISTINCT clause in WHERE
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
(SELECT
|
||||
user_id as events_user_id, time as events_time, event_type
|
||||
FROM
|
||||
events_table
|
||||
LIMIT
|
||||
10
|
||||
) as SUB_TABLE
|
||||
WHERE
|
||||
events_user_id
|
||||
IN (
|
||||
SELECT
|
||||
distinct user_id
|
||||
FROM
|
||||
users_table
|
||||
GROUP BY
|
||||
user_id
|
||||
);
|
||||
|
||||
-- AND in WHERE clause
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
(SELECT
|
||||
user_id as events_user_id, time as events_time, event_type
|
||||
FROM
|
||||
events_table
|
||||
ORDER BY
|
||||
1,2,3
|
||||
LIMIT
|
||||
10
|
||||
) as SUB_TABLE
|
||||
WHERE
|
||||
events_user_id
|
||||
>=ANY (
|
||||
SELECT
|
||||
min(user_id)
|
||||
FROM
|
||||
users_table
|
||||
GROUP BY
|
||||
user_id
|
||||
)
|
||||
AND
|
||||
events_user_id
|
||||
<=ANY (
|
||||
SELECT
|
||||
max(user_id)
|
||||
FROM
|
||||
users_table
|
||||
GROUP BY
|
||||
user_id
|
||||
);
|
||||
|
||||
-- AND in WHERE clause, part of the AND is pushdownable other is not
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
(SELECT
|
||||
user_id as events_user_id, time as events_time, event_type
|
||||
FROM
|
||||
events_table
|
||||
ORDER BY
|
||||
1,2,3
|
||||
LIMIT
|
||||
10
|
||||
) as SUB_TABLE
|
||||
WHERE
|
||||
events_user_id
|
||||
>=ANY (
|
||||
SELECT
|
||||
min(user_id)
|
||||
FROM
|
||||
users_table
|
||||
GROUP BY
|
||||
user_id
|
||||
)
|
||||
AND
|
||||
events_user_id
|
||||
<=ANY (
|
||||
SELECT
|
||||
max(value_2)
|
||||
FROM
|
||||
users_table
|
||||
GROUP BY
|
||||
user_id
|
||||
);
|
||||
|
||||
-- Planning subqueries in WHERE clause in CTE recursively
|
||||
WITH cte AS (
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id ASC,
|
||||
value_2 DESC
|
||||
LIMIT
|
||||
10
|
||||
) as sub_table
|
||||
WHERE
|
||||
user_id
|
||||
IN
|
||||
(SELECT
|
||||
value_2
|
||||
FROM
|
||||
events_table
|
||||
)
|
||||
)
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
cte;
|
||||
|
||||
-- Planing subquery in WHERE clause in FROM clause of a subquery recursively
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id ASC,
|
||||
value_2 DESC
|
||||
LIMIT
|
||||
10
|
||||
) as sub_table_1
|
||||
WHERE
|
||||
user_id
|
||||
IN
|
||||
(SELECT
|
||||
value_2
|
||||
FROM
|
||||
events_table
|
||||
)
|
||||
) as sub_table_2;
|
||||
|
||||
-- Recurring table in the FROM clause of a subquery in the FROM clause
|
||||
-- Recurring table is created by joining a two recurrign table
|
||||
SELECT
|
||||
SUM(user_id)
|
||||
FROM
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT
|
||||
user_id
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id
|
||||
LIMIT 10) as t1
|
||||
INNER JOIN
|
||||
(SELECT
|
||||
user_id as user_id_2
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id
|
||||
LIMIT
|
||||
10) as t2
|
||||
ON
|
||||
t1.user_id = t2.user_id_2
|
||||
WHERE
|
||||
t1.user_id
|
||||
IN
|
||||
(SELECT
|
||||
value_2
|
||||
FROM
|
||||
events_table)
|
||||
) as t3
|
||||
WHERE
|
||||
user_id
|
||||
>ANY
|
||||
(SELECT
|
||||
min(user_id)
|
||||
FROM
|
||||
events_table
|
||||
GROUP BY
|
||||
user_id);
|
||||
|
||||
-- Same example with the above query, but now check the rows with EXISTS
|
||||
SELECT
|
||||
SUM(user_id)
|
||||
FROM
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT
|
||||
user_id
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id
|
||||
LIMIT 10) as t1
|
||||
INNER JOIN
|
||||
(SELECT
|
||||
user_id as user_id_2
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id
|
||||
LIMIT
|
||||
10) as t2
|
||||
ON
|
||||
t1.user_id = t2.user_id_2
|
||||
WHERE
|
||||
t1.user_id
|
||||
IN
|
||||
(SELECT
|
||||
value_2
|
||||
FROM
|
||||
events_table)
|
||||
) as t3
|
||||
WHERE EXISTS
|
||||
(SELECT
|
||||
1,2
|
||||
FROM
|
||||
events_table
|
||||
WHERE
|
||||
events_table.value_2 = events_table.user_id);
|
||||
|
||||
-- Same query with the above one, yet now we check the row's NON-existence
|
||||
-- by NOT EXISTS. Note that, max value_2 of events_table is 5
|
||||
SELECT
|
||||
SUM(user_id)
|
||||
FROM
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT
|
||||
user_id
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id
|
||||
LIMIT 10) as t1
|
||||
INNER JOIN
|
||||
(SELECT
|
||||
user_id as user_id_2
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id
|
||||
LIMIT
|
||||
10) as t2
|
||||
ON
|
||||
t1.user_id = t2.user_id_2
|
||||
WHERE
|
||||
t1.user_id
|
||||
IN
|
||||
(SELECT
|
||||
value_2
|
||||
FROM
|
||||
events_table)
|
||||
) as t3
|
||||
WHERE NOT EXISTS
|
||||
(SELECT
|
||||
1,2
|
||||
FROM
|
||||
events_table
|
||||
WHERE
|
||||
events_table.value_2 = events_table.user_id + 6);
|
||||
|
||||
-- Check the existence of row by comparing it with the result of subquery in
|
||||
-- WHERE clause. Note that subquery is planned recursively since there is no
|
||||
-- distributed table in the from
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT
|
||||
user_id, value_1
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id ASC,
|
||||
value_1 ASC
|
||||
LIMIT 10) as t3
|
||||
WHERE row(user_id, value_1) =
|
||||
(SELECT
|
||||
min(user_id) + 1, min(user_id) + 1
|
||||
FROM
|
||||
events_table);
|
||||
|
||||
-- Recursively plan subquery in WHERE clause when the FROM clause has a subquery
|
||||
-- generated by generate_series function
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
generate_series(1,10)
|
||||
) as gst
|
||||
WHERE
|
||||
generate_series
|
||||
IN
|
||||
(SELECT
|
||||
value_2
|
||||
FROM
|
||||
events_table
|
||||
)
|
||||
ORDER BY
|
||||
generate_series ASC;
|
||||
|
||||
-- Similar to the test above, now we also have a generate_series in WHERE clause
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
generate_series(1,10)
|
||||
) as gst
|
||||
WHERE
|
||||
generate_series
|
||||
IN
|
||||
(SELECT
|
||||
user_id
|
||||
FROM
|
||||
users_table
|
||||
WHERE
|
||||
user_id
|
||||
IN
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
generate_series(1,3)
|
||||
)
|
||||
)
|
||||
ORDER BY
|
||||
generate_series ASC;
|
||||
|
||||
-- Local tables also planned recursively, so using it as part of the FROM clause
|
||||
-- make the clause recurring
|
||||
CREATE TABLE local_table(id int, value_1 int);
|
||||
INSERT INTO local_table VALUES(1,1), (2,2);
|
||||
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
local_table) as sub_table
|
||||
WHERE
|
||||
id
|
||||
IN
|
||||
(SELECT
|
||||
user_id
|
||||
FROM
|
||||
users_table);
|
||||
|
||||
-- Use local table in WHERE clause
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
(SELECT
|
||||
*
|
||||
FROM
|
||||
users_table
|
||||
ORDER BY
|
||||
user_id
|
||||
LIMIT
|
||||
10) as sub_table
|
||||
WHERE
|
||||
user_id
|
||||
IN
|
||||
(SELECT
|
||||
id
|
||||
FROM
|
||||
local_table);
|
||||
|
||||
DROP TABLE local_table;
|
||||
|
||||
SET client_min_messages TO DEFAULT;
|
||||
|
||||
DROP SCHEMA subquery_in_where CASCADE;
|
||||
SET search_path TO public;
|
|
@ -185,6 +185,18 @@ ORDER BY
|
|||
1, 2, 3, 4, 5, 6
|
||||
LIMIT 10;
|
||||
|
||||
-- Prepare a statement with a sublink in WHERE clause and recurring tuple in FORM
|
||||
PREPARE prepared_test_6 AS
|
||||
WITH event_id AS (
|
||||
SELECT user_id as events_user_id, time as events_time, event_type
|
||||
FROM events_table
|
||||
)
|
||||
SELECT
|
||||
count(*)
|
||||
FROM
|
||||
event_id
|
||||
WHERE
|
||||
events_user_id IN (SELECT user_id FROM users_table);
|
||||
|
||||
|
||||
EXECUTE prepared_test_1;
|
||||
|
@ -222,6 +234,13 @@ EXECUTE prepared_test_5(4, 5, 6);
|
|||
EXECUTE prepared_test_5(5, 6, 7);
|
||||
EXECUTE prepared_test_5(6, 7, 8);
|
||||
|
||||
EXECUTE prepared_test_6;
|
||||
EXECUTE prepared_test_6;
|
||||
EXECUTE prepared_test_6;
|
||||
EXECUTE prepared_test_6;
|
||||
EXECUTE prepared_test_6;
|
||||
EXECUTE prepared_test_6;
|
||||
|
||||
EXECUTE prepared_partition_column_insert(1);
|
||||
|
||||
DEALLOCATE ALL;
|
||||
|
|
Loading…
Reference in New Issue