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 DeferredErrorMessage * DeferErrorIfUnsupportedTableCombination(Query *queryTree);
|
||||||
static bool WindowPartitionOnDistributionColumn(Query *query);
|
static bool WindowPartitionOnDistributionColumn(Query *query);
|
||||||
static bool AllTargetExpressionsAreColumnReferences(List *targetEntryList);
|
static bool AllTargetExpressionsAreColumnReferences(List *targetEntryList);
|
||||||
static bool IsDistributedTableRTE(Node *node);
|
|
||||||
static FieldSelect * CompositeFieldRecursive(Expr *expression, Query *query);
|
static FieldSelect * CompositeFieldRecursive(Expr *expression, Query *query);
|
||||||
static bool FullCompositeFieldList(List *compositeFieldList);
|
static bool FullCompositeFieldList(List *compositeFieldList);
|
||||||
static MultiNode * MultiNodeTree(Query *queryTree);
|
static MultiNode * MultiNodeTree(Query *queryTree);
|
||||||
|
@ -657,7 +656,8 @@ DeferErrorIfFromClauseRecurs(Query *queryTree)
|
||||||
"cannot pushdown the subquery",
|
"cannot pushdown the subquery",
|
||||||
"Reference tables are not allowed in FROM "
|
"Reference tables are not allowed in FROM "
|
||||||
"clause when the query has subqueries in "
|
"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)
|
else if (recurType == RECURRING_TUPLES_FUNCTION)
|
||||||
{
|
{
|
||||||
|
@ -665,7 +665,8 @@ DeferErrorIfFromClauseRecurs(Query *queryTree)
|
||||||
"cannot pushdown the subquery",
|
"cannot pushdown the subquery",
|
||||||
"Functions are not allowed in FROM "
|
"Functions are not allowed in FROM "
|
||||||
"clause when the query has subqueries in "
|
"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)
|
else if (recurType == RECURRING_TUPLES_RESULT_FUNCTION)
|
||||||
{
|
{
|
||||||
|
@ -673,7 +674,8 @@ DeferErrorIfFromClauseRecurs(Query *queryTree)
|
||||||
"cannot pushdown the subquery",
|
"cannot pushdown the subquery",
|
||||||
"Complex subqueries and CTEs are not allowed in "
|
"Complex subqueries and CTEs are not allowed in "
|
||||||
"the FROM clause when the query has subqueries in the "
|
"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)
|
else if (recurType == RECURRING_TUPLES_EMPTY_JOIN_TREE)
|
||||||
{
|
{
|
||||||
|
@ -681,7 +683,8 @@ DeferErrorIfFromClauseRecurs(Query *queryTree)
|
||||||
"cannot pushdown the subquery",
|
"cannot pushdown the subquery",
|
||||||
"Subqueries without FROM are not allowed in FROM "
|
"Subqueries without FROM are not allowed in FROM "
|
||||||
"clause when the outer query has subqueries in "
|
"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
|
* is a range table relation entry that points to a distributed
|
||||||
* relation (i.e., excluding reference tables).
|
* relation (i.e., excluding reference tables).
|
||||||
*/
|
*/
|
||||||
static bool
|
bool
|
||||||
IsDistributedTableRTE(Node *node)
|
IsDistributedTableRTE(Node *node)
|
||||||
{
|
{
|
||||||
RangeTblEntry *rangeTableEntry = NULL;
|
RangeTblEntry *rangeTableEntry = NULL;
|
||||||
|
|
|
@ -115,6 +115,9 @@ typedef struct VarLevelsUpWalkerContext
|
||||||
static DeferredErrorMessage * RecursivelyPlanSubqueriesAndCTEs(Query *query,
|
static DeferredErrorMessage * RecursivelyPlanSubqueriesAndCTEs(Query *query,
|
||||||
RecursivePlanningContext *
|
RecursivePlanningContext *
|
||||||
context);
|
context);
|
||||||
|
static bool ShouldRecursivelyPlanAllSubqueriesInWhere(Query *query);
|
||||||
|
static bool RecursivelyPlanAllSubqueries(Node *node,
|
||||||
|
RecursivePlanningContext *planningContext);
|
||||||
static DeferredErrorMessage * RecursivelyPlanCTEs(Query *query,
|
static DeferredErrorMessage * RecursivelyPlanCTEs(Query *query,
|
||||||
RecursivePlanningContext *context);
|
RecursivePlanningContext *context);
|
||||||
static bool RecursivelyPlanSubqueryWalker(Node *node, RecursivePlanningContext *context);
|
static bool RecursivelyPlanSubqueryWalker(Node *node, RecursivePlanningContext *context);
|
||||||
|
@ -238,10 +241,85 @@ RecursivelyPlanSubqueriesAndCTEs(Query *query, RecursivePlanningContext *context
|
||||||
RecursivelyPlanSetOperations(query, (Node *) query->setOperations, 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;
|
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
|
* RecursivelyPlanCTEs plans all CTEs in the query by recursively calling the planner
|
||||||
* The resulting plan is added to planningContext->subPlanList and CTE references
|
* 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 SafeToPushdownWindowFunction(Query *query, StringInfo *errorDetail);
|
||||||
extern bool TargetListOnPartitionColumn(Query *query, List *targetEntryList);
|
extern bool TargetListOnPartitionColumn(Query *query, List *targetEntryList);
|
||||||
extern bool FindNodeCheckInRangeTableList(List *rtable, bool (*check)(Node *));
|
extern bool FindNodeCheckInRangeTableList(List *rtable, bool (*check)(Node *));
|
||||||
|
extern bool IsDistributedTableRTE(Node *node);
|
||||||
extern bool QueryContainsDistributedTableRTE(Query *query);
|
extern bool QueryContainsDistributedTableRTE(Query *query);
|
||||||
extern bool ContainsReadIntermediateResultFunction(Node *node);
|
extern bool ContainsReadIntermediateResultFunction(Node *node);
|
||||||
extern MultiNode * ParentNode(MultiNode *multiNode);
|
extern MultiNode * ParentNode(MultiNode *multiNode);
|
||||||
|
|
|
@ -46,8 +46,8 @@ LIMIT 3;
|
||||||
---------
|
---------
|
||||||
(0 rows)
|
(0 rows)
|
||||||
|
|
||||||
-- subqueries in WHERE with NOT EXISTS operator, should not work
|
-- subqueries in WHERE with NOT EXISTS operator, should not work since
|
||||||
-- there is a reference table in the outer part of the join
|
-- there is a correlated subquery in WHERE clause
|
||||||
SELECT
|
SELECT
|
||||||
user_id
|
user_id
|
||||||
FROM
|
FROM
|
||||||
|
@ -63,8 +63,9 @@ WHERE
|
||||||
)
|
)
|
||||||
LIMIT 3;
|
LIMIT 3;
|
||||||
ERROR: cannot pushdown the subquery
|
ERROR: cannot pushdown the subquery
|
||||||
DETAIL: Reference tables are not allowed in FROM clause when the query has subqueries in WHERE clause
|
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
|
-- immutable functions are also treated as reference tables, query should not
|
||||||
|
-- work since there is a correlated subquery in the WHERE clause
|
||||||
SELECT
|
SELECT
|
||||||
user_id
|
user_id
|
||||||
FROM
|
FROM
|
||||||
|
@ -80,8 +81,9 @@ WHERE
|
||||||
)
|
)
|
||||||
LIMIT 3;
|
LIMIT 3;
|
||||||
ERROR: cannot pushdown the subquery
|
ERROR: cannot pushdown the subquery
|
||||||
DETAIL: Functions are not allowed in FROM clause when the query has subqueries in WHERE clause
|
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
|
-- subqueries without FROM are also treated as reference tables, query should not
|
||||||
|
-- work since there is a correlated subquery in the WHERE clause
|
||||||
SELECT
|
SELECT
|
||||||
user_id
|
user_id
|
||||||
FROM
|
FROM
|
||||||
|
@ -97,7 +99,7 @@ WHERE
|
||||||
)
|
)
|
||||||
LIMIT 3;
|
LIMIT 3;
|
||||||
ERROR: cannot pushdown the subquery
|
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
|
-- join with distributed table prevents FROM from recurring
|
||||||
SELECT
|
SELECT
|
||||||
DISTINCT user_id
|
DISTINCT user_id
|
||||||
|
@ -413,7 +415,9 @@ ORDER BY 1, 2;
|
||||||
5 | 5
|
5 | 5
|
||||||
(2 rows)
|
(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
|
SELECT
|
||||||
count(*)
|
count(*)
|
||||||
FROM
|
FROM
|
||||||
|
@ -421,9 +425,14 @@ FROM
|
||||||
WHERE user_id
|
WHERE user_id
|
||||||
NOT IN
|
NOT IN
|
||||||
(SELECT users_table.value_2 FROM users_table JOIN users_reference_table as u2 ON users_table.value_2 = u2.value_2);
|
(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
|
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)))
|
||||||
DETAIL: Reference tables are not allowed in FROM clause when the query has subqueries in WHERE clause
|
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))))
|
||||||
-- reference tables are not allowed if there is sublink
|
count
|
||||||
|
-------
|
||||||
|
10
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- recursively planning subqueries in WHERE clause due to recurring table in FROM
|
||||||
SELECT count(*)
|
SELECT count(*)
|
||||||
FROM
|
FROM
|
||||||
(SELECT
|
(SELECT
|
||||||
|
@ -432,9 +441,14 @@ FROM
|
||||||
(SELECT users_table.value_2
|
(SELECT users_table.value_2
|
||||||
FROM users_table
|
FROM users_table
|
||||||
JOIN users_reference_table AS u2 ON users_table.value_2 = u2.value_2);
|
JOIN users_reference_table AS u2 ON users_table.value_2 = u2.value_2);
|
||||||
ERROR: cannot pushdown the subquery
|
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)))
|
||||||
DETAIL: Reference tables are not allowed in FROM clause when the query has subqueries in WHERE clause
|
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))))
|
||||||
-- reference tables are not allowed if there is sublink
|
count
|
||||||
|
-------
|
||||||
|
10
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- query should not work since there is a correlated subquery in the WHERE clause
|
||||||
SELECT user_id,
|
SELECT user_id,
|
||||||
count(*)
|
count(*)
|
||||||
FROM users_reference_table
|
FROM users_reference_table
|
||||||
|
@ -449,9 +463,8 @@ ORDER BY 2 DESC,
|
||||||
1 DESC
|
1 DESC
|
||||||
LIMIT 5;
|
LIMIT 5;
|
||||||
ERROR: cannot pushdown the subquery
|
ERROR: cannot pushdown the subquery
|
||||||
DETAIL: Reference tables are not allowed in FROM clause when the query has subqueries in WHERE clause
|
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
|
||||||
-- reference tables are not allowed if there is sublink
|
-- query will be planned as a SEMI JOIN
|
||||||
-- this time in the subquery
|
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM users_table
|
FROM users_table
|
||||||
WHERE user_id IN
|
WHERE user_id IN
|
||||||
|
@ -463,6 +476,7 @@ WHERE user_id IN
|
||||||
FROM users_reference_table AS u2))
|
FROM users_reference_table AS u2))
|
||||||
ORDER BY 1,2,3
|
ORDER BY 1,2,3
|
||||||
LIMIT 5;
|
LIMIT 5;
|
||||||
|
DEBUG: push down of limit count: 5
|
||||||
user_id | time | value_1 | value_2 | value_3 | value_4
|
user_id | time | value_1 | value_2 | value_3 | value_4
|
||||||
---------+---------------------------------+---------+---------+---------+---------
|
---------+---------------------------------+---------+---------+---------+---------
|
||||||
1 | Wed Nov 22 22:51:43.132261 2017 | 4 | 0 | 3 |
|
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 |
|
1 | Thu Nov 23 11:44:57.515981 2017 | 4 | 3 | 4 |
|
||||||
(5 rows)
|
(5 rows)
|
||||||
|
|
||||||
|
SET client_min_messages TO DEFAULT;
|
||||||
-- not supported since GROUP BY references to an upper level query
|
-- not supported since GROUP BY references to an upper level query
|
||||||
SELECT
|
SELECT
|
||||||
user_id
|
user_id
|
||||||
|
|
|
@ -260,11 +260,26 @@ DEBUG: Plan 45 query after replacing subqueries and CTEs: SELECT u.x, u.y, test
|
||||||
---+---+---
|
---+---+---
|
||||||
(0 rows)
|
(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;
|
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
|
DEBUG: generating subplan 48_1 for subquery SELECT x FROM recursive_set_local.local_test
|
||||||
ERROR: cannot pushdown the subquery
|
DEBUG: generating subplan 48_2 for subquery SELECT x FROM recursive_set_local.test
|
||||||
DETAIL: Complex subqueries and CTEs are not allowed in the FROM clause when the query has subqueries in the WHERE clause
|
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;
|
SET citus.enable_repartition_joins TO ON;
|
||||||
-- repartition is recursively planned before the set operation
|
-- 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;
|
(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
|
DETAIL: Creating dependency on merge taskId 24
|
||||||
DEBUG: cannot use real time executor with repartition jobs
|
DEBUG: cannot use real time executor with repartition jobs
|
||||||
HINT: Since you enabled citus.enable_repartition_joins Citus chose to use task-tracker.
|
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 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 50_2 for subquery SELECT x FROM recursive_set_local.local_test
|
DEBUG: generating subplan 53_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 53_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: generating subplan 53_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: 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: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
DEBUG: Plan is router executable
|
||||||
x
|
x
|
||||||
|
|
|
@ -549,24 +549,31 @@ DEBUG: Plan is router executable
|
||||||
2 | 2
|
2 | 2
|
||||||
(2 rows)
|
(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;
|
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_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: generating subplan 112_2 for subquery SELECT y, x FROM recursive_union.test
|
||||||
DEBUG: Creating router plan
|
DEBUG: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
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: 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
|
DEBUG: generating subplan 112_4 for subquery SELECT y FROM recursive_union.test
|
||||||
ERROR: cannot pushdown the subquery
|
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
|
||||||
DETAIL: Complex subqueries and CTEs are not allowed in the FROM clause when the query has subqueries in the WHERE clause
|
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
|
-- 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
|
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
|
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
|
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;
|
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 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 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: 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 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: 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: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
DEBUG: Plan is router executable
|
||||||
x | y | rnk
|
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
|
-- 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;
|
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: 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 122_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_2 for subquery SELECT x, y FROM recursive_union.test
|
||||||
DEBUG: Creating router plan
|
DEBUG: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
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: 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 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: 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
|
x | y | y
|
||||||
---+---+---
|
---+---+---
|
||||||
2 | 2 | 2
|
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;
|
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: 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 126_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_2 for subquery SELECT x, y FROM recursive_union.test
|
||||||
DEBUG: Creating router plan
|
DEBUG: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
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: 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 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: 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
|
ERROR: cannot pushdown the subquery
|
||||||
DETAIL: Complex subqueries and CTEs cannot be in the outer part of the outer join
|
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;
|
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
|
DEBUG: generating subplan 130_1 for subquery SELECT x FROM recursive_union.test
|
||||||
DETAIL: Reference tables are not allowed in FROM clause when the query has subqueries in WHERE clause
|
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
|
-- 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;
|
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
|
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
|
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
|
-- 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;
|
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 137_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_2 for subquery SELECT y FROM recursive_union.test c
|
||||||
DEBUG: Creating router plan
|
DEBUG: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
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: 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 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: 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
|
x | y
|
||||||
---+---
|
---+---
|
||||||
1 | 1
|
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
|
-- 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;
|
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: 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
|
||||||
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
|
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
|
-- 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;
|
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 144_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: generating subplan 144_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: 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: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
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: 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 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: 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: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
DEBUG: Plan is router executable
|
||||||
x | y
|
x | y
|
||||||
|
@ -662,12 +684,12 @@ DEBUG: Plan is router executable
|
||||||
|
|
||||||
-- distinct and count distinct should work without any problems
|
-- 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;
|
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 147_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_2 for subquery SELECT DISTINCT x FROM recursive_union.test
|
||||||
DEBUG: Creating router plan
|
DEBUG: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
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: 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 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: 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: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
DEBUG: Plan is router executable
|
||||||
count
|
count
|
||||||
|
@ -676,12 +698,12 @@ DEBUG: Plan is router executable
|
||||||
(1 row)
|
(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;
|
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 151_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_2 for subquery SELECT count(DISTINCT y) AS count FROM recursive_union.test
|
||||||
DEBUG: Creating router plan
|
DEBUG: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
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: 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 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: 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: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
DEBUG: Plan is router executable
|
||||||
count
|
count
|
||||||
|
@ -691,12 +713,12 @@ DEBUG: Plan is router executable
|
||||||
|
|
||||||
-- other agg. distincts are also supported when group by includes partition key
|
-- 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;
|
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 155_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_2 for subquery SELECT avg(DISTINCT y) AS avg FROM recursive_union.test GROUP BY x
|
||||||
DEBUG: Creating router plan
|
DEBUG: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
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: 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 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: 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: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
DEBUG: Plan is router executable
|
||||||
avg
|
avg
|
||||||
|
@ -743,9 +765,9 @@ DEBUG: pruning merge fetch taskId 11
|
||||||
DETAIL: Creating dependency on merge taskId 24
|
DETAIL: Creating dependency on merge taskId 24
|
||||||
DEBUG: cannot use real time executor with repartition jobs
|
DEBUG: cannot use real time executor with repartition jobs
|
||||||
HINT: Since you enabled citus.enable_repartition_joins Citus chose to use task-tracker.
|
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 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 157_2 for subquery SELECT x FROM recursive_union.test
|
DEBUG: generating subplan 161_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: 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: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
DEBUG: Plan is router executable
|
||||||
x
|
x
|
||||||
|
@ -754,7 +776,7 @@ DEBUG: Plan is router executable
|
||||||
|
|
||||||
-- repartition is recursively planned with the set operation
|
-- 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;
|
(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 1
|
||||||
DEBUG: join prunable for task partitionId 0 and 2
|
DEBUG: join prunable for task partitionId 0 and 2
|
||||||
DEBUG: join prunable for task partitionId 0 and 3
|
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
|
DETAIL: Creating dependency on merge taskId 24
|
||||||
DEBUG: cannot use real time executor with repartition jobs
|
DEBUG: cannot use real time executor with repartition jobs
|
||||||
HINT: Since you enabled citus.enable_repartition_joins Citus chose to use task-tracker.
|
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: 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 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: 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: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
DEBUG: Plan is router executable
|
||||||
x
|
x
|
||||||
|
@ -799,12 +821,12 @@ SET citus.enable_repartition_joins TO OFF;
|
||||||
-- this should be recursively planned
|
-- this should be recursively planned
|
||||||
CREATE VIEW set_view_recursive AS (SELECT y FROM test) UNION (SELECT y FROM test);
|
CREATE VIEW set_view_recursive AS (SELECT y FROM test) UNION (SELECT y FROM test);
|
||||||
SELECT * FROM set_view_recursive ORDER BY 1 DESC;
|
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 167_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_2 for subquery SELECT y FROM recursive_union.test
|
||||||
DEBUG: Creating router plan
|
DEBUG: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
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: 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 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: 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: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
DEBUG: Plan is router executable
|
||||||
y
|
y
|
||||||
|
@ -825,12 +847,12 @@ SELECT * FROM set_view_pushdown ORDER BY 1 DESC;
|
||||||
-- this should be recursively planned
|
-- 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;
|
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;
|
SELECT * FROM set_view_recursive_second;
|
||||||
DEBUG: generating subplan 168_1 for subquery SELECT x, y FROM recursive_union.test
|
DEBUG: generating subplan 172_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_2 for subquery SELECT 1, 1 FROM recursive_union.test
|
||||||
DEBUG: Creating router plan
|
DEBUG: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
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: 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 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: 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
|
x | y
|
||||||
---+---
|
---+---
|
||||||
1 | 1
|
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 :)
|
-- 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);
|
((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 176_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_2 for subquery SELECT 1, 1 FROM recursive_union.test
|
||||||
DEBUG: Creating router plan
|
DEBUG: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
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 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 172_4 for subquery SELECT y FROM recursive_union.test
|
DEBUG: generating subplan 176_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_5 for subquery SELECT y FROM recursive_union.test
|
||||||
DEBUG: Creating router plan
|
DEBUG: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
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 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 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 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 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: 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 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: 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: Creating router plan
|
||||||
DEBUG: Plan is router executable
|
DEBUG: Plan is router executable
|
||||||
x
|
x
|
||||||
|
|
|
@ -60,24 +60,6 @@ FROM
|
||||||
LIMIT 5
|
LIMIT 5
|
||||||
) as foo;
|
) as foo;
|
||||||
ERROR: array_agg with order by is unsupported
|
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
|
-- we don't support recursive subqueries when router executor is disabled
|
||||||
SET citus.enable_router_execution TO false;
|
SET citus.enable_router_execution TO false;
|
||||||
SELECT
|
SELECT
|
||||||
|
@ -94,8 +76,8 @@ FROM
|
||||||
) as foo
|
) as foo
|
||||||
ORDER BY 1 DESC;
|
ORDER BY 1 DESC;
|
||||||
DEBUG: push down of limit count: 5
|
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: 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 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: 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
|
ERROR: cannot handle complex subqueries when the router executor is disabled
|
||||||
SET citus.enable_router_execution TO true;
|
SET citus.enable_router_execution TO true;
|
||||||
-- window functions are not allowed if they're not partitioned on the distribution column
|
-- 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
|
(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);
|
ON(foo.value_2 = bar.value_2);
|
||||||
DEBUG: push down of limit count: 5
|
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: 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 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: 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
|
ERROR: cannot pushdown the subquery
|
||||||
DETAIL: Complex subqueries and CTEs cannot be in the outer part of the outer join
|
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
|
-- 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
|
1
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
-- a very similar query as the above, but this time errors
|
-- subquery in WHERE clause is planned recursively due to the recurring table
|
||||||
-- out since we don't support subqueries in WHERE clause
|
-- in FROM clause
|
||||||
-- when there is only intermediate results on the range table
|
|
||||||
-- note that this time subquery in WHERE clause is not replaced
|
|
||||||
WITH cte AS (
|
WITH cte AS (
|
||||||
WITH local_cte AS (
|
WITH local_cte AS (
|
||||||
SELECT * FROM users_table_local
|
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_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: 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 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
|
DEBUG: generating subplan 14_2 for subquery SELECT DISTINCT user_id FROM public.users_table WHERE ((value_1 >= 1) AND (value_1 <= 20))
|
||||||
ERROR: cannot pushdown the subquery
|
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
|
||||||
DETAIL: Complex subqueries and CTEs are not allowed in the FROM clause when the query has subqueries in the WHERE clause
|
user_id
|
||||||
|
---------
|
||||||
|
6
|
||||||
|
5
|
||||||
|
4
|
||||||
|
3
|
||||||
|
2
|
||||||
|
1
|
||||||
|
(6 rows)
|
||||||
|
|
||||||
-- CTEs inside a subquery and the final query becomes a router
|
-- CTEs inside a subquery and the final query becomes a router
|
||||||
-- query
|
-- query
|
||||||
SELECT
|
SELECT
|
||||||
|
@ -154,8 +161,8 @@ FROM
|
||||||
event_type IN (1,2,3,4)
|
event_type IN (1,2,3,4)
|
||||||
) SELECT * FROM cte ORDER BY 1 DESC
|
) SELECT * FROM cte ORDER BY 1 DESC
|
||||||
) as foo;
|
) 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: 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 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: 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
|
user_id
|
||||||
---------
|
---------
|
||||||
6
|
6
|
||||||
|
@ -193,8 +200,8 @@ FROM
|
||||||
|
|
||||||
) as bar
|
) as bar
|
||||||
WHERE foo.user_id = bar.user_id;
|
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: 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 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: 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
|
user_id
|
||||||
---------
|
---------
|
||||||
5
|
5
|
||||||
|
@ -246,11 +253,11 @@ FROM
|
||||||
) as bar
|
) as bar
|
||||||
WHERE foo.user_id = bar.user_id
|
WHERE foo.user_id = bar.user_id
|
||||||
ORDER BY 1 DESC LIMIT 5;
|
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 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 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_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: 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: 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 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: 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
|
user_id
|
||||||
---------
|
---------
|
||||||
1
|
1
|
||||||
|
@ -283,14 +290,14 @@ SELECT * FROM
|
||||||
foo.user_id = events_table.value_2
|
foo.user_id = events_table.value_2
|
||||||
ORDER BY 3 DESC, 2 DESC, 1 DESC
|
ORDER BY 3 DESC, 2 DESC, 1 DESC
|
||||||
LIMIT 5;
|
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 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 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 26_2 for CTE dist_cte: SELECT user_id FROM public.events_table
|
DEBUG: generating subplan 27_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: 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 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_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: 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: 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 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: 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
|
DEBUG: push down of limit count: 5
|
||||||
user_id | user_id | time | event_type | value_2 | value_3 | value_4
|
user_id | user_id | time | event_type | value_2 | value_3 | value_4
|
||||||
---------+---------+---------------------------------+------------+---------+---------+---------
|
---------+---------+---------------------------------+------------+---------+---------+---------
|
||||||
|
@ -332,17 +339,17 @@ FROM
|
||||||
ORDER BY 1 DESC LIMIT 5
|
ORDER BY 1 DESC LIMIT 5
|
||||||
) as foo
|
) as foo
|
||||||
WHERE foo.user_id = cte.user_id;
|
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 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 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 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 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: 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 33_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: generating subplan 33_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 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 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: 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: 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: 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 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: 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
|
count
|
||||||
-------
|
-------
|
||||||
432
|
432
|
||||||
|
@ -386,18 +393,18 @@ FROM
|
||||||
) as foo, users_table WHERE foo.cnt > users_table.value_2
|
) as foo, users_table WHERE foo.cnt > users_table.value_2
|
||||||
ORDER BY 3 DESC, 1 DESC, 2 DESC, 4 DESC
|
ORDER BY 3 DESC, 1 DESC, 2 DESC, 4 DESC
|
||||||
LIMIT 5;
|
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 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 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 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 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: 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 39_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: generating subplan 39_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 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 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: 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: 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 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 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: 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 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: 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
|
DEBUG: push down of limit count: 5
|
||||||
cnt | user_id | time | value_1 | value_2 | value_3 | value_4
|
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
|
3
|
||||||
(2 rows)
|
(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
|
ORDER BY
|
||||||
1, 2, 3, 4, 5, 6
|
1, 2, 3, 4, 5, 6
|
||||||
LIMIT 10;
|
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;
|
EXECUTE prepared_test_1;
|
||||||
user_id | time | value_1 | value_2 | value_3 | value_4
|
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 |
|
6 | Thu Nov 23 14:43:18.024104 2017 | 3 | 2 | 5 |
|
||||||
(10 rows)
|
(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);
|
EXECUTE prepared_partition_column_insert(1);
|
||||||
ERROR: data-modifying statements are not supported in the WITH clauses of distributed queries
|
ERROR: data-modifying statements are not supported in the WITH clauses of distributed queries
|
||||||
DEALLOCATE ALL;
|
DEALLOCATE ALL;
|
||||||
|
|
|
@ -43,7 +43,7 @@ test: multi_partitioning_utils multi_partitioning
|
||||||
# Tests for recursive subquery planning
|
# Tests for recursive subquery planning
|
||||||
# ----------
|
# ----------
|
||||||
test: subquery_basics subquery_local_tables subquery_executors subquery_and_cte set_operations set_operation_and_local_tables
|
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
|
test: subquery_prepared_statements
|
||||||
|
|
||||||
# ----------
|
# ----------
|
||||||
|
|
|
@ -38,8 +38,8 @@ GROUP BY user_id
|
||||||
ORDER BY user_id
|
ORDER BY user_id
|
||||||
LIMIT 3;
|
LIMIT 3;
|
||||||
|
|
||||||
-- subqueries in WHERE with NOT EXISTS operator, should not work
|
-- subqueries in WHERE with NOT EXISTS operator, should not work since
|
||||||
-- there is a reference table in the outer part of the join
|
-- there is a correlated subquery in WHERE clause
|
||||||
SELECT
|
SELECT
|
||||||
user_id
|
user_id
|
||||||
FROM
|
FROM
|
||||||
|
@ -55,7 +55,8 @@ WHERE
|
||||||
)
|
)
|
||||||
LIMIT 3;
|
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
|
SELECT
|
||||||
user_id
|
user_id
|
||||||
FROM
|
FROM
|
||||||
|
@ -71,7 +72,8 @@ WHERE
|
||||||
)
|
)
|
||||||
LIMIT 3;
|
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
|
SELECT
|
||||||
user_id
|
user_id
|
||||||
FROM
|
FROM
|
||||||
|
@ -353,7 +355,10 @@ SELECT user_id, value_2 FROM users_table WHERE
|
||||||
)
|
)
|
||||||
ORDER BY 1, 2;
|
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
|
SELECT
|
||||||
count(*)
|
count(*)
|
||||||
FROM
|
FROM
|
||||||
|
@ -362,8 +367,7 @@ WHERE user_id
|
||||||
NOT IN
|
NOT IN
|
||||||
(SELECT users_table.value_2 FROM users_table JOIN users_reference_table as u2 ON users_table.value_2 = u2.value_2);
|
(SELECT users_table.value_2 FROM users_table JOIN users_reference_table as u2 ON users_table.value_2 = u2.value_2);
|
||||||
|
|
||||||
|
-- recursively planning subqueries in WHERE clause due to recurring table in FROM
|
||||||
-- reference tables are not allowed if there is sublink
|
|
||||||
SELECT count(*)
|
SELECT count(*)
|
||||||
FROM
|
FROM
|
||||||
(SELECT
|
(SELECT
|
||||||
|
@ -373,7 +377,7 @@ FROM
|
||||||
FROM users_table
|
FROM users_table
|
||||||
JOIN users_reference_table AS u2 ON users_table.value_2 = u2.value_2);
|
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,
|
SELECT user_id,
|
||||||
count(*)
|
count(*)
|
||||||
FROM users_reference_table
|
FROM users_reference_table
|
||||||
|
@ -388,8 +392,7 @@ ORDER BY 2 DESC,
|
||||||
1 DESC
|
1 DESC
|
||||||
LIMIT 5;
|
LIMIT 5;
|
||||||
|
|
||||||
-- reference tables are not allowed if there is sublink
|
-- query will be planned as a SEMI JOIN
|
||||||
-- this time in the subquery
|
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM users_table
|
FROM users_table
|
||||||
WHERE user_id IN
|
WHERE user_id IN
|
||||||
|
@ -402,6 +405,8 @@ WHERE user_id IN
|
||||||
ORDER BY 1,2,3
|
ORDER BY 1,2,3
|
||||||
LIMIT 5;
|
LIMIT 5;
|
||||||
|
|
||||||
|
SET client_min_messages TO DEFAULT;
|
||||||
|
|
||||||
-- not supported since GROUP BY references to an upper level query
|
-- not supported since GROUP BY references to an upper level query
|
||||||
SELECT
|
SELECT
|
||||||
user_id
|
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
|
-- 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;
|
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;
|
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;
|
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
|
-- 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;
|
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;
|
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
|
-- 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) 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;
|
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;
|
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
|
-- subquery union in WHERE clause with partition column equality and implicit join is pushed down
|
||||||
|
|
|
@ -58,20 +58,6 @@ FROM
|
||||||
LIMIT 5
|
LIMIT 5
|
||||||
) as foo;
|
) 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
|
-- we don't support recursive subqueries when router executor is disabled
|
||||||
SET citus.enable_router_execution TO false;
|
SET citus.enable_router_execution TO false;
|
||||||
SELECT
|
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)
|
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;
|
ORDER BY 1 DESC;
|
||||||
|
|
||||||
-- a very similar query as the above, but this time errors
|
-- subquery in WHERE clause is planned recursively due to the recurring table
|
||||||
-- out since we don't support subqueries in WHERE clause
|
-- in FROM clause
|
||||||
-- when there is only intermediate results on the range table
|
|
||||||
-- note that this time subquery in WHERE clause is not replaced
|
|
||||||
WITH cte AS (
|
WITH cte AS (
|
||||||
WITH local_cte AS (
|
WITH local_cte AS (
|
||||||
SELECT * FROM users_table_local
|
SELECT * FROM users_table_local
|
||||||
|
|
|
@ -311,3 +311,17 @@ GROUP BY user_id
|
||||||
HAVING count(*) > 1 AND sum(value_2) > 29
|
HAVING count(*) > 1 AND sum(value_2) > 29
|
||||||
ORDER BY 1;
|
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
|
1, 2, 3, 4, 5, 6
|
||||||
LIMIT 10;
|
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;
|
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(5, 6, 7);
|
||||||
EXECUTE prepared_test_5(6, 7, 8);
|
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);
|
EXECUTE prepared_partition_column_insert(1);
|
||||||
|
|
||||||
DEALLOCATE ALL;
|
DEALLOCATE ALL;
|
||||||
|
|
Loading…
Reference in New Issue