Merge pull request #4360 from citusdata/marcocitus/sublinks

pull/4413/head
Marco Slot 2020-12-13 23:46:40 +01:00 committed by GitHub
commit cc04fce10f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 1072 additions and 405 deletions

View File

@ -39,12 +39,12 @@
#include "distributed/multi_logical_planner.h" #include "distributed/multi_logical_planner.h"
#include "distributed/multi_physical_planner.h" #include "distributed/multi_physical_planner.h"
#include "distributed/pg_dist_partition.h" #include "distributed/pg_dist_partition.h"
#include "distributed/query_pushdown_planning.h"
#include "distributed/tdigest_extension.h" #include "distributed/tdigest_extension.h"
#include "distributed/worker_protocol.h" #include "distributed/worker_protocol.h"
#include "distributed/version_compat.h" #include "distributed/version_compat.h"
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h" #include "nodes/nodeFuncs.h"
#include "nodes/print.h"
#include "optimizer/clauses.h" #include "optimizer/clauses.h"
#include "optimizer/tlist.h" #include "optimizer/tlist.h"
#if PG_VERSION_NUM >= PG_VERSION_12 #if PG_VERSION_NUM >= PG_VERSION_12
@ -482,6 +482,15 @@ MultiLogicalPlanOptimize(MultiTreeRoot *multiLogicalPlan)
errhint("You might need to disable approximations for either " errhint("You might need to disable approximations for either "
"count(distinct) or limit through configuration."))); "count(distinct) or limit through configuration.")));
} }
if (TargetListContainsSubquery(masterExtendedOpNode->targetList))
{
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot push down subquery on the target list"),
errdetail("Subqueries in the SELECT part of the query can only "
"be pushed down if they happen before aggregates and "
"window functions")));
}
} }

View File

@ -833,18 +833,6 @@ DeferErrorIfQueryNotSupported(Query *queryTree)
const char *filterHint = "Consider using an equality filter on the distributed " const char *filterHint = "Consider using an equality filter on the distributed "
"table's partition column."; "table's partition column.";
/*
* There could be Sublinks in the target list as well. To produce better
* error messages we're checking if that's the case.
*/
if (queryTree->hasSubLinks && TargetListContainsSubquery(queryTree))
{
preconditionsSatisfied = false;
errorMessage = "could not run distributed query with subquery outside the "
"FROM, WHERE and HAVING clauses";
errorHint = filterHint;
}
if (queryTree->setOperations) if (queryTree->setOperations)
{ {
preconditionsSatisfied = false; preconditionsSatisfied = false;

View File

@ -86,12 +86,9 @@ static bool ContainsRecurringRTE(RangeTblEntry *rangeTableEntry,
static bool ContainsRecurringRangeTable(List *rangeTable, RecurringTuplesType *recurType); static bool ContainsRecurringRangeTable(List *rangeTable, RecurringTuplesType *recurType);
static bool HasRecurringTuples(Node *node, RecurringTuplesType *recurType); static bool HasRecurringTuples(Node *node, RecurringTuplesType *recurType);
static MultiNode * SubqueryPushdownMultiNodeTree(Query *queryTree); static MultiNode * SubqueryPushdownMultiNodeTree(Query *queryTree);
static void UpdateVarMappingsForExtendedOpNode(List *columnList,
List *subqueryTargetEntryList);
static void UpdateColumnToMatchingTargetEntry(Var *column,
List *targetEntryList);
static MultiTable * MultiSubqueryPushdownTable(Query *subquery); static MultiTable * MultiSubqueryPushdownTable(Query *subquery);
static List * CreateSubqueryTargetEntryList(List *columnList); static List * CreateSubqueryTargetListAndAdjustVars(List *columnList);
static AttrNumber FindResnoForVarInTargetList(List *targetList, int varno, int varattno);
static bool RelationInfoContainsOnlyRecurringTuples(PlannerInfo *plannerInfo, static bool RelationInfoContainsOnlyRecurringTuples(PlannerInfo *plannerInfo,
Relids relids); Relids relids);
@ -125,6 +122,16 @@ ShouldUseSubqueryPushDown(Query *originalQuery, Query *rewrittenQuery,
return true; return true;
} }
/*
* We check the existence of subqueries in the SELECT clause on the modified
* query.
*/
if (TargetListContainsSubquery(rewrittenQuery->targetList))
{
return true;
}
/* /*
* We check if postgres planned any semi joins, MultiNodeTree doesn't * We check if postgres planned any semi joins, MultiNodeTree doesn't
* support these so we fail. Postgres is able to replace some IN/ANY * support these so we fail. Postgres is able to replace some IN/ANY
@ -303,9 +310,9 @@ WhereOrHavingClauseContainsSubquery(Query *query)
* any subqueries in the WHERE clause. * any subqueries in the WHERE clause.
*/ */
bool bool
TargetListContainsSubquery(Query *query) TargetListContainsSubquery(List *targetList)
{ {
return FindNodeMatchingCheckFunction((Node *) query->targetList, IsNodeSubquery); return FindNodeMatchingCheckFunction((Node *) targetList, IsNodeSubquery);
} }
@ -662,38 +669,28 @@ DeferErrorIfFromClauseRecurs(Query *queryTree)
if (recurType == RECURRING_TUPLES_REFERENCE_TABLE) if (recurType == RECURRING_TUPLES_REFERENCE_TABLE)
{ {
return DeferredError(ERRCODE_FEATURE_NOT_SUPPORTED, return DeferredError(ERRCODE_FEATURE_NOT_SUPPORTED,
"cannot pushdown the subquery", "correlated subqueries are not supported when "
"Reference tables are not allowed in FROM " "the FROM clause contains a reference table", NULL, NULL);
"clause when the query has subqueries in "
"WHERE clause and it references a column "
"from another query", NULL);
} }
else if (recurType == RECURRING_TUPLES_FUNCTION) else if (recurType == RECURRING_TUPLES_FUNCTION)
{ {
return DeferredError(ERRCODE_FEATURE_NOT_SUPPORTED, return DeferredError(ERRCODE_FEATURE_NOT_SUPPORTED,
"cannot pushdown the subquery", "correlated subqueries are not supported when "
"Functions are not allowed in FROM " "the FROM clause contains a set returning function", NULL,
"clause when the query has subqueries in " 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)
{ {
return DeferredError(ERRCODE_FEATURE_NOT_SUPPORTED, return DeferredError(ERRCODE_FEATURE_NOT_SUPPORTED,
"cannot pushdown the subquery", "correlated subqueries are not supported when "
"Complex subqueries and CTEs are not allowed in " "the FROM clause contains a CTE or subquery", NULL, NULL);
"the FROM clause when the query has subqueries in the "
"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)
{ {
return DeferredError(ERRCODE_FEATURE_NOT_SUPPORTED, return DeferredError(ERRCODE_FEATURE_NOT_SUPPORTED,
"cannot pushdown the subquery", "correlated subqueries are not supported when "
"Subqueries without FROM are not allowed in FROM " "the FROM clause contains a subquery without FROM", NULL,
"clause when the outer query has subqueries in " NULL);
"WHERE clause and it references a column "
"from another query", NULL);
} }
/* /*
@ -1058,8 +1055,7 @@ DeferErrorIfCannotPushdownSubquery(Query *subqueryTree, bool outerMostQueryHasLi
deferredError = DeferErrorIfFromClauseRecurs(subqueryTree); deferredError = DeferErrorIfFromClauseRecurs(subqueryTree);
if (deferredError) if (deferredError)
{ {
preconditionsSatisfied = false; return deferredError;
errorDetail = (char *) deferredError->detail;
} }
@ -1539,18 +1535,12 @@ SubqueryPushdownMultiNodeTree(Query *originalQuery)
* columnList. Columns mentioned in multiProject node and multiExtendedOp * columnList. Columns mentioned in multiProject node and multiExtendedOp
* node are indexed with their respective position in columnList. * node are indexed with their respective position in columnList.
*/ */
List *targetColumnList = pull_var_clause_default((Node *) targetEntryList); List *targetColumnList = pull_vars_of_level((Node *) targetEntryList, 0);
List *havingClauseColumnList = pull_var_clause_default(queryTree->havingQual); List *havingClauseColumnList = pull_var_clause_default(queryTree->havingQual);
List *columnList = list_concat(targetColumnList, havingClauseColumnList); List *columnList = list_concat(targetColumnList, havingClauseColumnList);
/* create a target entry for each unique column */ /* create a target entry for each unique column */
List *subqueryTargetEntryList = CreateSubqueryTargetEntryList(columnList); List *subqueryTargetEntryList = CreateSubqueryTargetListAndAdjustVars(columnList);
/*
* Update varno/varattno fields of columns in columnList to
* point to corresponding target entry in subquery target entry list.
*/
UpdateVarMappingsForExtendedOpNode(columnList, subqueryTargetEntryList);
/* new query only has target entries, join tree, and rtable*/ /* new query only has target entries, join tree, and rtable*/
Query *pushedDownQuery = makeNode(Query); Query *pushedDownQuery = makeNode(Query);
@ -1633,33 +1623,55 @@ SubqueryPushdownMultiNodeTree(Query *originalQuery)
/* /*
* CreateSubqueryTargetEntryList creates a target entry for each unique column * CreateSubqueryTargetListAndAdjustVars creates a target entry for each unique
* in the column list and returns the target entry list. * column in the column list, adjusts the columns to point into the subquery target
* list and returns the new subquery target list.
*/ */
static List * static List *
CreateSubqueryTargetEntryList(List *columnList) CreateSubqueryTargetListAndAdjustVars(List *columnList)
{ {
AttrNumber resNo = 1; Var *column = NULL;
List *uniqueColumnList = NIL;
List *subqueryTargetEntryList = NIL; List *subqueryTargetEntryList = NIL;
Node *column = NULL;
foreach_ptr(column, columnList) foreach_ptr(column, columnList)
{ {
uniqueColumnList = list_append_unique(uniqueColumnList, column); /*
} * To avoid adding the same column multiple times, we first check whether there
* is already a target entry containing a Var with the given varno and varattno.
foreach_ptr(column, uniqueColumnList) */
AttrNumber resNo = FindResnoForVarInTargetList(subqueryTargetEntryList,
column->varno, column->varattno);
if (resNo == InvalidAttrNumber)
{ {
TargetEntry *newTargetEntry = makeNode(TargetEntry); /* Var is not yet on the target list, create a new entry */
resNo = list_length(subqueryTargetEntryList) + 1;
newTargetEntry->expr = (Expr *) copyObject(column); /*
* The join tree in the subquery is an exact duplicate of the original
* query. Hence, we can make a copy of the original Var. However, if the
* original Var was in a sublink it would be pointing up whereas now it
* will be placed directly on the target list. Hence we reset the
* varlevelsup.
*/
Var *subqueryTargetListVar = (Var *) copyObject(column);
subqueryTargetListVar->varlevelsup = 0;
TargetEntry *newTargetEntry = makeNode(TargetEntry);
newTargetEntry->expr = (Expr *) subqueryTargetListVar;
newTargetEntry->resname = WorkerColumnName(resNo); newTargetEntry->resname = WorkerColumnName(resNo);
newTargetEntry->resjunk = false; newTargetEntry->resjunk = false;
newTargetEntry->resno = resNo; newTargetEntry->resno = resNo;
subqueryTargetEntryList = lappend(subqueryTargetEntryList, newTargetEntry); subqueryTargetEntryList = lappend(subqueryTargetEntryList, newTargetEntry);
resNo++; }
/*
* Change the original column reference to point to the target list
* entry in the subquery. There is only 1 subquery, so the varno is 1.
*/
column->varno = 1;
column->varattno = resNo;
} }
return subqueryTargetEntryList; return subqueryTargetEntryList;
@ -1667,63 +1679,30 @@ CreateSubqueryTargetEntryList(List *columnList)
/* /*
* UpdateVarMappingsForExtendedOpNode updates varno/varattno fields of columns * FindResnoForVarInTargetList finds a Var on a target list that has the given varno
* in columnList to point to corresponding target in subquery target entry * (range table entry number) and varattno (column number) and returns the resno
* list. * of the target list entry.
*/ */
static void static AttrNumber
UpdateVarMappingsForExtendedOpNode(List *columnList, List *subqueryTargetEntryList) FindResnoForVarInTargetList(List *targetList, int varno, int varattno)
{ {
Var *column = NULL; TargetEntry *targetEntry = NULL;
foreach_ptr(column, columnList) foreach_ptr(targetEntry, targetList)
{ {
/* if (!IsA(targetEntry->expr, Var))
* As an optimization, subqueryTargetEntryList only consists of {
* distinct elements. In other words, any duplicate entries in the continue;
* target list consolidated into a single element to prevent pulling
* unnecessary data from the worker nodes (e.g. SELECT a,a,a,b,b,b FROM x;
* is turned into SELECT a,b FROM x_102008).
*
* Thus, at this point we should iterate on the subqueryTargetEntryList
* and ensure that the column on the extended op node points to the
* correct target entry.
*/
UpdateColumnToMatchingTargetEntry(column, subqueryTargetEntryList);
} }
}
/*
* UpdateColumnToMatchingTargetEntry sets the variable of given column entry to
* the matching entry of the targetEntryList. Since data type of the column can
* be different from the types of the elements of targetEntryList, we use flattenedExpr.
*/
static void
UpdateColumnToMatchingTargetEntry(Var *column, List *targetEntryList)
{
ListCell *targetEntryCell = NULL;
foreach(targetEntryCell, targetEntryList)
{
TargetEntry *targetEntry = (TargetEntry *) lfirst(targetEntryCell);
if (IsA(targetEntry->expr, Var))
{
Var *targetEntryVar = (Var *) targetEntry->expr; Var *targetEntryVar = (Var *) targetEntry->expr;
if (IsA(column, Var) && equal(column, targetEntryVar)) if (targetEntryVar->varno == varno && targetEntryVar->varattno == varattno)
{ {
column->varno = 1; return targetEntry->resno;
column->varattno = targetEntry->resno;
break;
}
}
else
{
elog(ERROR, "unrecognized node type on the target list: %d",
nodeTag(targetEntry->expr));
} }
} }
return InvalidAttrNumber;
} }

View File

@ -29,7 +29,7 @@ extern bool JoinTreeContainsSubquery(Query *query);
extern bool IsNodeSubquery(Node *node); extern bool IsNodeSubquery(Node *node);
extern bool HasEmptyJoinTree(Query *query); extern bool HasEmptyJoinTree(Query *query);
extern bool WhereOrHavingClauseContainsSubquery(Query *query); extern bool WhereOrHavingClauseContainsSubquery(Query *query);
extern bool TargetListContainsSubquery(Query *query); extern bool TargetListContainsSubquery(List *targetList);
extern bool SafeToPushdownWindowFunction(Query *query, StringInfo *errorDetail); extern bool SafeToPushdownWindowFunction(Query *query, StringInfo *errorDetail);
extern MultiNode * SubqueryMultiNodeTree(Query *originalQuery, extern MultiNode * SubqueryMultiNodeTree(Query *originalQuery,
Query *queryTree, Query *queryTree,

View File

@ -23,41 +23,41 @@ SET client_min_messages TO DEBUG;
-- plan the query -- plan the query
WITH cte_1 AS (SELECT * FROM test_table) WITH cte_1 AS (SELECT * FROM test_table)
SELECT SELECT
*, (SELECT 1) *
FROM FROM
cte_1 test_table LEFT JOIN cte_1 USING (value)
ORDER BY 1 DESC LIMIT 3; ORDER BY 1 DESC LIMIT 3;
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT test_table.value, test_table.key, test_table.other_value, cte_1.key, cte_1.other_value FROM (cte_inline.test_table LEFT JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 USING (value)) ORDER BY test_table.value DESC LIMIT 3
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, value, other_value, (SELECT 1) FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 ORDER BY key DESC LIMIT 3 DEBUG: push down of limit count: 3
DEBUG: Creating router plan value | key | other_value | key | other_value
key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
9 | test9 | {"f1": 9, "f2": 162, "f3": "test9"} | 1 test99 | 9 | {"f1": 99, "f2": 1782, "f3": "test99"} | 9 | {"f1": 99, "f2": 1782, "f3": "test99"}
9 | test19 | {"f1": 19, "f2": 342, "f3": "test19"} | 1 test98 | 8 | {"f1": 98, "f2": 1764, "f3": "test98"} | 8 | {"f1": 98, "f2": 1764, "f3": "test98"}
9 | test29 | {"f1": 29, "f2": 522, "f3": "test29"} | 1 test97 | 7 | {"f1": 97, "f2": 1746, "f3": "test97"} | 7 | {"f1": 97, "f2": 1746, "f3": "test97"}
(3 rows) (3 rows)
-- Should still not be inlined even if NOT MATERIALIZED is passed -- Should still not be inlined even if NOT MATERIALIZED is passed
WITH cte_1 AS NOT MATERIALIZED (SELECT * FROM test_table) WITH cte_1 AS NOT MATERIALIZED (SELECT * FROM test_table)
SELECT SELECT
*, (SELECT 1) *
FROM FROM
cte_1 test_table LEFT JOIN cte_1 USING (value)
ORDER BY 2 DESC LIMIT 1; ORDER BY 2 DESC LIMIT 1;
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT test_table.value, test_table.key, test_table.other_value, cte_1.key, cte_1.other_value FROM (cte_inline.test_table LEFT JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 USING (value)) ORDER BY test_table.key DESC LIMIT 1
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, value, other_value, (SELECT 1) FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 ORDER BY value DESC LIMIT 1 DEBUG: push down of limit count: 1
DEBUG: Creating router plan value | key | other_value | key | other_value
key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
9 | test99 | {"f1": 99, "f2": 1782, "f3": "test99"} | 1 test9 | 9 | {"f1": 9, "f2": 162, "f3": "test9"} | 9 | {"f1": 9, "f2": 162, "f3": "test9"}
(1 row) (1 row)
-- the cte can be inlined because the unsupported -- the cte can be inlined because the unsupported
@ -125,11 +125,7 @@ FROM
ORDER BY 2 DESC LIMIT 1; ORDER BY 2 DESC LIMIT 1;
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: push down of limit count: 1
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table
DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, value, other_value, (SELECT 1) FROM (SELECT cte_1.key, cte_1.value, cte_1.other_value FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1) foo ORDER BY value DESC LIMIT 1
DEBUG: Creating router plan
key | value | other_value | ?column? key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
9 | test99 | {"f1": 99, "f2": 1782, "f3": "test99"} | 1 9 | test99 | {"f1": 99, "f2": 1782, "f3": "test99"} | 1
@ -153,15 +149,9 @@ DEBUG: CTE top_cte is going to be inlined via distributed planning
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value, (SELECT 1) FROM (SELECT cte_1.key, cte_1.value, cte_1.other_value FROM (SELECT test_table.key, test_table.value, test_table.other_value FROM cte_inline.test_table) cte_1) foo
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT test_table.key, test_table.value, test_table.other_value FROM cte_inline.test_table) top_cte, (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value, intermediate_result."?column?" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb, "?column?" integer)) bar(key, value, other_value, "?column?")
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE top_cte: SELECT key, value, other_value FROM cte_inline.test_table
DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_2 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table
DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Creating router plan
DEBUG: generating subplan XXX_3 for subquery SELECT key, value, other_value, (SELECT 1) FROM (SELECT cte_1.key, cte_1.value, cte_1.other_value FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1) foo
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) top_cte, (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value, intermediate_result."?column?" FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb, "?column?" integer)) bar(key, value, other_value, "?column?")
DEBUG: Creating router plan
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
10201 10201
@ -187,12 +177,8 @@ WHERE KEY IN
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: generating subplan XXX_1 for subquery SELECT (SELECT 1) FROM (SELECT foo.key, foo.value, foo.other_value, random() AS random FROM (SELECT cte_1.key, cte_1.value, cte_1.other_value FROM (SELECT test_table.key, test_table.value, test_table.other_value FROM cte_inline.test_table) cte_1) foo) bar
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result."?column?" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result("?column?" integer)))
DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Creating router plan
DEBUG: generating subplan XXX_2 for subquery SELECT (SELECT 1) FROM (SELECT foo.key, foo.value, foo.other_value, random() AS random FROM (SELECT cte_1.key, cte_1.value, cte_1.other_value FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1) foo) bar
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result."?column?" FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result("?column?" integer)))
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
@ -734,17 +720,10 @@ DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: push down of limit count: 3 DEBUG: push down of limit count: 3
DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table ORDER BY key DESC LIMIT 3 DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table ORDER BY key DESC LIMIT 3
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_2 for subquery SELECT key, value, other_value, (SELECT 1) FROM (SELECT test_table.key, test_table.value, test_table.other_value FROM cte_inline.test_table) cte_1
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table DEBUG: generating subplan XXX_3 for subquery SELECT key, value, other_value, 1 FROM cte_inline.test_table
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Plan XXX query after replacing subqueries and CTEs: (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value, intermediate_result."?column?" FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb, "?column?" integer) EXCEPT SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value, intermediate_result."?column?" FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb, "?column?" integer)) UNION SELECT cte_2.key, cte_2.value, cte_2.other_value, 1 FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_2 ORDER BY 1, 2
DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT key, value, other_value FROM cte_inline.test_table ORDER BY key DESC LIMIT 3
DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: push down of limit count: 3
DEBUG: Creating router plan
DEBUG: generating subplan XXX_3 for subquery SELECT key, value, other_value, (SELECT 1) FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1
DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_4 for subquery SELECT key, value, other_value, 1 FROM cte_inline.test_table
DEBUG: Plan XXX query after replacing subqueries and CTEs: (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value, intermediate_result."?column?" FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb, "?column?" integer) EXCEPT SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value, intermediate_result."?column?" FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb, "?column?" integer)) UNION SELECT cte_2.key, cte_2.value, cte_2.other_value, 1 FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_2 ORDER BY 1, 2
DEBUG: Creating router plan DEBUG: Creating router plan
key | value | other_value | ?column? key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
@ -772,8 +751,11 @@ DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT key, value, other_value FROM cte_inline.test_table DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT key, value, other_value FROM cte_inline.test_table
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
ERROR: could not run distributed query with subquery outside the FROM, WHERE and HAVING clauses DEBUG: generating subplan XXX_3 for subquery SELECT key, value, other_value, (SELECT cte_1.key FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1) AS key FROM cte_inline.test_table
HINT: Consider using an equality filter on the distributed table's partition column. DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value, intermediate_result.key_1 AS key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb, key_1 integer) UNION SELECT cte_2.key, cte_2.value, cte_2.other_value, 1 FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_2
DEBUG: Creating router plan
ERROR: more than one row returned by a subquery used as an expression
CONTEXT: while executing command on localhost:xxxxx
-- after inlining CTEs, the query becomes -- after inlining CTEs, the query becomes
-- subquery pushdown with set operations -- subquery pushdown with set operations
WITH cte_1 AS (SELECT * FROM test_table), WITH cte_1 AS (SELECT * FROM test_table),
@ -1002,9 +984,9 @@ PREPARE inlined_cte_without_params AS
PREPARE non_inlined_cte_without_params AS PREPARE non_inlined_cte_without_params AS
WITH cte_1 AS (SELECT * FROM test_table) WITH cte_1 AS (SELECT * FROM test_table)
SELECT SELECT
*, (SELECT 1) *
FROM FROM
cte_1 ORDER BY 1 DESC, 2 DESC, 3 DESC LIMIT 3; test_table LEFT JOIN cte_1 USING (value) ORDER BY 1 DESC, 2 DESC, 3 DESC LIMIT 3;
PREPARE inlined_cte_has_parameter_on_non_dist_key(text) AS PREPARE inlined_cte_has_parameter_on_non_dist_key(text) AS
WITH cte_1 AS (SELECT count(*) FROM test_table WHERE value = $1 GROUP BY key) WITH cte_1 AS (SELECT count(*) FROM test_table WHERE value = $1 GROUP BY key)
SELECT * FROM cte_1 ORDER BY 1 DESC LIMIT 3; SELECT * FROM cte_1 ORDER BY 1 DESC LIMIT 3;
@ -1014,9 +996,9 @@ PREPARE inlined_cte_has_parameter_on_dist_key(int) AS
PREPARE non_inlined_cte_has_parameter_on_dist_key(int) AS PREPARE non_inlined_cte_has_parameter_on_dist_key(int) AS
WITH cte_1 AS (SELECT * FROM test_table where key > $1) WITH cte_1 AS (SELECT * FROM test_table where key > $1)
SELECT SELECT
*, (SELECT 1) *
FROM FROM
cte_1 ORDER BY 1 DESC, 2 DESC, 3 DESC LIMIT 3; test_table LEFT JOIN cte_1 USING (value) ORDER BY 1 DESC, 2 DESC, 3 DESC LIMIT 3;
PREPARE retry_planning(int) AS PREPARE retry_planning(int) AS
WITH cte_1 AS (SELECT * FROM test_table WHERE key > $1) WITH cte_1 AS (SELECT * FROM test_table WHERE key > $1)
SELECT json_object_agg(DISTINCT key, value) FROM cte_1 ORDER BY max(key), min(value) DESC LIMIT 3; SELECT json_object_agg(DISTINCT key, value) FROM cte_1 ORDER BY max(key), min(value) DESC LIMIT 3;
@ -1075,55 +1057,55 @@ EXECUTE non_inlined_cte_without_params;
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT test_table.value, test_table.key, test_table.other_value, cte_1.key, cte_1.other_value FROM (cte_inline.test_table LEFT JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 USING (value)) ORDER BY test_table.value DESC, test_table.key DESC, test_table.other_value DESC LIMIT 3
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, value, other_value, (SELECT 1) FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 ORDER BY key DESC, value DESC, other_value DESC LIMIT 3 DEBUG: push down of limit count: 3
DEBUG: Creating router plan value | key | other_value | key | other_value
key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
(3 rows) (3 rows)
EXECUTE non_inlined_cte_without_params; EXECUTE non_inlined_cte_without_params;
key | value | other_value | ?column? value | key | other_value | key | other_value
--------------------------------------------------------------------- ---------------------------------------------------------------------
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
(3 rows) (3 rows)
EXECUTE non_inlined_cte_without_params; EXECUTE non_inlined_cte_without_params;
key | value | other_value | ?column? value | key | other_value | key | other_value
--------------------------------------------------------------------- ---------------------------------------------------------------------
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
(3 rows) (3 rows)
EXECUTE non_inlined_cte_without_params; EXECUTE non_inlined_cte_without_params;
key | value | other_value | ?column? value | key | other_value | key | other_value
--------------------------------------------------------------------- ---------------------------------------------------------------------
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
(3 rows) (3 rows)
EXECUTE non_inlined_cte_without_params; EXECUTE non_inlined_cte_without_params;
key | value | other_value | ?column? value | key | other_value | key | other_value
--------------------------------------------------------------------- ---------------------------------------------------------------------
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
(3 rows) (3 rows)
EXECUTE non_inlined_cte_without_params; EXECUTE non_inlined_cte_without_params;
key | value | other_value | ?column? value | key | other_value | key | other_value
--------------------------------------------------------------------- ---------------------------------------------------------------------
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
(3 rows) (3 rows)
EXECUTE inlined_cte_has_parameter_on_non_dist_key('test1'); EXECUTE inlined_cte_has_parameter_on_non_dist_key('test1');
@ -1243,75 +1225,75 @@ EXECUTE non_inlined_cte_has_parameter_on_dist_key(1);
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 1) DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 1)
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT test_table.value, test_table.key, test_table.other_value, cte_1.key, cte_1.other_value FROM (cte_inline.test_table LEFT JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 USING (value)) ORDER BY test_table.value DESC, test_table.key DESC, test_table.other_value DESC LIMIT 3
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, value, other_value, (SELECT 1) FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 ORDER BY key DESC, value DESC, other_value DESC LIMIT 3 DEBUG: push down of limit count: 3
DEBUG: Creating router plan value | key | other_value | key | other_value
key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
(3 rows) (3 rows)
EXECUTE non_inlined_cte_has_parameter_on_dist_key(2); EXECUTE non_inlined_cte_has_parameter_on_dist_key(2);
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 2) DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 2)
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT test_table.value, test_table.key, test_table.other_value, cte_1.key, cte_1.other_value FROM (cte_inline.test_table LEFT JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 USING (value)) ORDER BY test_table.value DESC, test_table.key DESC, test_table.other_value DESC LIMIT 3
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, value, other_value, (SELECT 1) FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 ORDER BY key DESC, value DESC, other_value DESC LIMIT 3 DEBUG: push down of limit count: 3
DEBUG: Creating router plan value | key | other_value | key | other_value
key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
(3 rows) (3 rows)
EXECUTE non_inlined_cte_has_parameter_on_dist_key(3); EXECUTE non_inlined_cte_has_parameter_on_dist_key(3);
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 3) DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 3)
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT test_table.value, test_table.key, test_table.other_value, cte_1.key, cte_1.other_value FROM (cte_inline.test_table LEFT JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 USING (value)) ORDER BY test_table.value DESC, test_table.key DESC, test_table.other_value DESC LIMIT 3
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, value, other_value, (SELECT 1) FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 ORDER BY key DESC, value DESC, other_value DESC LIMIT 3 DEBUG: push down of limit count: 3
DEBUG: Creating router plan value | key | other_value | key | other_value
key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
(3 rows) (3 rows)
EXECUTE non_inlined_cte_has_parameter_on_dist_key(4); EXECUTE non_inlined_cte_has_parameter_on_dist_key(4);
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 4) DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 4)
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT test_table.value, test_table.key, test_table.other_value, cte_1.key, cte_1.other_value FROM (cte_inline.test_table LEFT JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 USING (value)) ORDER BY test_table.value DESC, test_table.key DESC, test_table.other_value DESC LIMIT 3
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, value, other_value, (SELECT 1) FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 ORDER BY key DESC, value DESC, other_value DESC LIMIT 3 DEBUG: push down of limit count: 3
DEBUG: Creating router plan value | key | other_value | key | other_value
key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
(3 rows) (3 rows)
EXECUTE non_inlined_cte_has_parameter_on_dist_key(5); EXECUTE non_inlined_cte_has_parameter_on_dist_key(5);
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 5) DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 5)
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT test_table.value, test_table.key, test_table.other_value, cte_1.key, cte_1.other_value FROM (cte_inline.test_table LEFT JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 USING (value)) ORDER BY test_table.value DESC, test_table.key DESC, test_table.other_value DESC LIMIT 3
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, value, other_value, (SELECT 1) FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 ORDER BY key DESC, value DESC, other_value DESC LIMIT 3 DEBUG: push down of limit count: 3
DEBUG: Creating router plan value | key | other_value | key | other_value
key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
(3 rows) (3 rows)
EXECUTE non_inlined_cte_has_parameter_on_dist_key(6); EXECUTE non_inlined_cte_has_parameter_on_dist_key(6);
@ -1320,15 +1302,15 @@ DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 6) DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 6)
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT test_table.value, test_table.key, test_table.other_value, cte_1.key, cte_1.other_value FROM (cte_inline.test_table LEFT JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 USING (value)) ORDER BY test_table.value DESC, test_table.key DESC, test_table.other_value DESC LIMIT 3
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, value, other_value, (SELECT 1) FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 ORDER BY key DESC, value DESC, other_value DESC LIMIT 3 DEBUG: push down of limit count: 3
DEBUG: Creating router plan value | key | other_value | key | other_value
key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
8 | test98 | | 1 test98 | 8 | | 8 |
(3 rows) (3 rows)
EXECUTE retry_planning(1); EXECUTE retry_planning(1);

View File

@ -23,30 +23,30 @@ SET client_min_messages TO DEBUG;
-- plan the query -- plan the query
WITH cte_1 AS (SELECT * FROM test_table) WITH cte_1 AS (SELECT * FROM test_table)
SELECT SELECT
*, (SELECT 1) *
FROM FROM
cte_1 test_table LEFT JOIN cte_1 USING (value)
ORDER BY 1 DESC LIMIT 3; ORDER BY 1 DESC LIMIT 3;
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT test_table.value, test_table.key, test_table.other_value, cte_1.key, cte_1.other_value FROM (cte_inline.test_table LEFT JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 USING (value)) ORDER BY test_table.value DESC LIMIT 3
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, value, other_value, (SELECT 1) FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 ORDER BY key DESC LIMIT 3 DEBUG: push down of limit count: 3
DEBUG: Creating router plan value | key | other_value | key | other_value
key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
9 | test9 | {"f1": 9, "f2": 162, "f3": "test9"} | 1 test99 | 9 | {"f1": 99, "f2": 1782, "f3": "test99"} | 9 | {"f1": 99, "f2": 1782, "f3": "test99"}
9 | test19 | {"f1": 19, "f2": 342, "f3": "test19"} | 1 test98 | 8 | {"f1": 98, "f2": 1764, "f3": "test98"} | 8 | {"f1": 98, "f2": 1764, "f3": "test98"}
9 | test29 | {"f1": 29, "f2": 522, "f3": "test29"} | 1 test97 | 7 | {"f1": 97, "f2": 1746, "f3": "test97"} | 7 | {"f1": 97, "f2": 1746, "f3": "test97"}
(3 rows) (3 rows)
-- Should still not be inlined even if NOT MATERIALIZED is passed -- Should still not be inlined even if NOT MATERIALIZED is passed
WITH cte_1 AS NOT MATERIALIZED (SELECT * FROM test_table) WITH cte_1 AS NOT MATERIALIZED (SELECT * FROM test_table)
SELECT SELECT
*, (SELECT 1) *
FROM FROM
cte_1 test_table LEFT JOIN cte_1 USING (value)
ORDER BY 2 DESC LIMIT 1; ORDER BY 2 DESC LIMIT 1;
ERROR: syntax error at or near "NOT" ERROR: syntax error at or near "NOT"
-- the cte can be inlined because the unsupported -- the cte can be inlined because the unsupported
@ -114,11 +114,7 @@ FROM
ORDER BY 2 DESC LIMIT 1; ORDER BY 2 DESC LIMIT 1;
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: push down of limit count: 1
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table
DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, value, other_value, (SELECT 1) FROM (SELECT cte_1.key, cte_1.value, cte_1.other_value FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1) foo ORDER BY value DESC LIMIT 1
DEBUG: Creating router plan
key | value | other_value | ?column? key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
9 | test99 | {"f1": 99, "f2": 1782, "f3": "test99"} | 1 9 | test99 | {"f1": 99, "f2": 1782, "f3": "test99"} | 1
@ -142,15 +138,9 @@ DEBUG: CTE top_cte is going to be inlined via distributed planning
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value, (SELECT 1) FROM (SELECT cte_1.key, cte_1.value, cte_1.other_value FROM (SELECT test_table.key, test_table.value, test_table.other_value FROM cte_inline.test_table) cte_1) foo
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT test_table.key, test_table.value, test_table.other_value FROM cte_inline.test_table) top_cte, (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value, intermediate_result."?column?" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb, "?column?" integer)) bar(key, value, other_value, "?column?")
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE top_cte: SELECT key, value, other_value FROM cte_inline.test_table
DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_2 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table
DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Creating router plan
DEBUG: generating subplan XXX_3 for subquery SELECT key, value, other_value, (SELECT 1) FROM (SELECT cte_1.key, cte_1.value, cte_1.other_value FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1) foo
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) top_cte, (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value, intermediate_result."?column?" FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb, "?column?" integer)) bar(key, value, other_value, "?column?")
DEBUG: Creating router plan
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
10201 10201
@ -176,12 +166,8 @@ WHERE KEY IN
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: generating subplan XXX_1 for subquery SELECT (SELECT 1) FROM (SELECT foo.key, foo.value, foo.other_value, random() AS random FROM (SELECT cte_1.key, cte_1.value, cte_1.other_value FROM (SELECT test_table.key, test_table.value, test_table.other_value FROM cte_inline.test_table) cte_1) foo) bar
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result."?column?" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result("?column?" integer)))
DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Creating router plan
DEBUG: generating subplan XXX_2 for subquery SELECT (SELECT 1) FROM (SELECT foo.key, foo.value, foo.other_value, random() AS random FROM (SELECT cte_1.key, cte_1.value, cte_1.other_value FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1) foo) bar
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.=) ANY (SELECT intermediate_result."?column?" FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result("?column?" integer)))
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
@ -626,17 +612,10 @@ DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: push down of limit count: 3 DEBUG: push down of limit count: 3
DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table ORDER BY key DESC LIMIT 3 DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table ORDER BY key DESC LIMIT 3
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_2 for subquery SELECT key, value, other_value, (SELECT 1) FROM (SELECT test_table.key, test_table.value, test_table.other_value FROM cte_inline.test_table) cte_1
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table DEBUG: generating subplan XXX_3 for subquery SELECT key, value, other_value, 1 FROM cte_inline.test_table
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Plan XXX query after replacing subqueries and CTEs: (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value, intermediate_result."?column?" FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb, "?column?" integer) EXCEPT SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value, intermediate_result."?column?" FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb, "?column?" integer)) UNION SELECT cte_2.key, cte_2.value, cte_2.other_value, 1 FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_2 ORDER BY 1, 2
DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT key, value, other_value FROM cte_inline.test_table ORDER BY key DESC LIMIT 3
DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: push down of limit count: 3
DEBUG: Creating router plan
DEBUG: generating subplan XXX_3 for subquery SELECT key, value, other_value, (SELECT 1) FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1
DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_4 for subquery SELECT key, value, other_value, 1 FROM cte_inline.test_table
DEBUG: Plan XXX query after replacing subqueries and CTEs: (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value, intermediate_result."?column?" FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb, "?column?" integer) EXCEPT SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value, intermediate_result."?column?" FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb, "?column?" integer)) UNION SELECT cte_2.key, cte_2.value, cte_2.other_value, 1 FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_2 ORDER BY 1, 2
DEBUG: Creating router plan DEBUG: Creating router plan
key | value | other_value | ?column? key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
@ -664,8 +643,11 @@ DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT key, value, other_value FROM cte_inline.test_table DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT key, value, other_value FROM cte_inline.test_table
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
ERROR: could not run distributed query with subquery outside the FROM, WHERE and HAVING clauses DEBUG: generating subplan XXX_3 for subquery SELECT key, value, other_value, (SELECT cte_1.key FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1) AS key FROM cte_inline.test_table
HINT: Consider using an equality filter on the distributed table's partition column. DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value, intermediate_result.key_1 AS key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb, key_1 integer) UNION SELECT cte_2.key, cte_2.value, cte_2.other_value, 1 FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_2
DEBUG: Creating router plan
ERROR: more than one row returned by a subquery used as an expression
CONTEXT: while executing command on localhost:xxxxx
-- after inlining CTEs, the query becomes -- after inlining CTEs, the query becomes
-- subquery pushdown with set operations -- subquery pushdown with set operations
WITH cte_1 AS (SELECT * FROM test_table), WITH cte_1 AS (SELECT * FROM test_table),
@ -881,9 +863,9 @@ PREPARE inlined_cte_without_params AS
PREPARE non_inlined_cte_without_params AS PREPARE non_inlined_cte_without_params AS
WITH cte_1 AS (SELECT * FROM test_table) WITH cte_1 AS (SELECT * FROM test_table)
SELECT SELECT
*, (SELECT 1) *
FROM FROM
cte_1 ORDER BY 1 DESC, 2 DESC, 3 DESC LIMIT 3; test_table LEFT JOIN cte_1 USING (value) ORDER BY 1 DESC, 2 DESC, 3 DESC LIMIT 3;
PREPARE inlined_cte_has_parameter_on_non_dist_key(text) AS PREPARE inlined_cte_has_parameter_on_non_dist_key(text) AS
WITH cte_1 AS (SELECT count(*) FROM test_table WHERE value = $1 GROUP BY key) WITH cte_1 AS (SELECT count(*) FROM test_table WHERE value = $1 GROUP BY key)
SELECT * FROM cte_1 ORDER BY 1 DESC LIMIT 3; SELECT * FROM cte_1 ORDER BY 1 DESC LIMIT 3;
@ -893,9 +875,9 @@ PREPARE inlined_cte_has_parameter_on_dist_key(int) AS
PREPARE non_inlined_cte_has_parameter_on_dist_key(int) AS PREPARE non_inlined_cte_has_parameter_on_dist_key(int) AS
WITH cte_1 AS (SELECT * FROM test_table where key > $1) WITH cte_1 AS (SELECT * FROM test_table where key > $1)
SELECT SELECT
*, (SELECT 1) *
FROM FROM
cte_1 ORDER BY 1 DESC, 2 DESC, 3 DESC LIMIT 3; test_table LEFT JOIN cte_1 USING (value) ORDER BY 1 DESC, 2 DESC, 3 DESC LIMIT 3;
PREPARE retry_planning(int) AS PREPARE retry_planning(int) AS
WITH cte_1 AS (SELECT * FROM test_table WHERE key > $1) WITH cte_1 AS (SELECT * FROM test_table WHERE key > $1)
SELECT json_object_agg(DISTINCT key, value) FROM cte_1 ORDER BY max(key), min(value) DESC LIMIT 3; SELECT json_object_agg(DISTINCT key, value) FROM cte_1 ORDER BY max(key), min(value) DESC LIMIT 3;
@ -954,55 +936,55 @@ EXECUTE non_inlined_cte_without_params;
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT test_table.value, test_table.key, test_table.other_value, cte_1.key, cte_1.other_value FROM (cte_inline.test_table LEFT JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 USING (value)) ORDER BY test_table.value DESC, test_table.key DESC, test_table.other_value DESC LIMIT 3
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, value, other_value, (SELECT 1) FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 ORDER BY key DESC, value DESC, other_value DESC LIMIT 3 DEBUG: push down of limit count: 3
DEBUG: Creating router plan value | key | other_value | key | other_value
key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
(3 rows) (3 rows)
EXECUTE non_inlined_cte_without_params; EXECUTE non_inlined_cte_without_params;
key | value | other_value | ?column? value | key | other_value | key | other_value
--------------------------------------------------------------------- ---------------------------------------------------------------------
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
(3 rows) (3 rows)
EXECUTE non_inlined_cte_without_params; EXECUTE non_inlined_cte_without_params;
key | value | other_value | ?column? value | key | other_value | key | other_value
--------------------------------------------------------------------- ---------------------------------------------------------------------
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
(3 rows) (3 rows)
EXECUTE non_inlined_cte_without_params; EXECUTE non_inlined_cte_without_params;
key | value | other_value | ?column? value | key | other_value | key | other_value
--------------------------------------------------------------------- ---------------------------------------------------------------------
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
(3 rows) (3 rows)
EXECUTE non_inlined_cte_without_params; EXECUTE non_inlined_cte_without_params;
key | value | other_value | ?column? value | key | other_value | key | other_value
--------------------------------------------------------------------- ---------------------------------------------------------------------
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
(3 rows) (3 rows)
EXECUTE non_inlined_cte_without_params; EXECUTE non_inlined_cte_without_params;
key | value | other_value | ?column? value | key | other_value | key | other_value
--------------------------------------------------------------------- ---------------------------------------------------------------------
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
(3 rows) (3 rows)
EXECUTE inlined_cte_has_parameter_on_non_dist_key('test1'); EXECUTE inlined_cte_has_parameter_on_non_dist_key('test1');
@ -1130,75 +1112,75 @@ EXECUTE non_inlined_cte_has_parameter_on_dist_key(1);
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 1) DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 1)
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT test_table.value, test_table.key, test_table.other_value, cte_1.key, cte_1.other_value FROM (cte_inline.test_table LEFT JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 USING (value)) ORDER BY test_table.value DESC, test_table.key DESC, test_table.other_value DESC LIMIT 3
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, value, other_value, (SELECT 1) FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 ORDER BY key DESC, value DESC, other_value DESC LIMIT 3 DEBUG: push down of limit count: 3
DEBUG: Creating router plan value | key | other_value | key | other_value
key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
(3 rows) (3 rows)
EXECUTE non_inlined_cte_has_parameter_on_dist_key(2); EXECUTE non_inlined_cte_has_parameter_on_dist_key(2);
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 2) DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 2)
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT test_table.value, test_table.key, test_table.other_value, cte_1.key, cte_1.other_value FROM (cte_inline.test_table LEFT JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 USING (value)) ORDER BY test_table.value DESC, test_table.key DESC, test_table.other_value DESC LIMIT 3
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, value, other_value, (SELECT 1) FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 ORDER BY key DESC, value DESC, other_value DESC LIMIT 3 DEBUG: push down of limit count: 3
DEBUG: Creating router plan value | key | other_value | key | other_value
key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
(3 rows) (3 rows)
EXECUTE non_inlined_cte_has_parameter_on_dist_key(3); EXECUTE non_inlined_cte_has_parameter_on_dist_key(3);
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 3) DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 3)
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT test_table.value, test_table.key, test_table.other_value, cte_1.key, cte_1.other_value FROM (cte_inline.test_table LEFT JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 USING (value)) ORDER BY test_table.value DESC, test_table.key DESC, test_table.other_value DESC LIMIT 3
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, value, other_value, (SELECT 1) FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 ORDER BY key DESC, value DESC, other_value DESC LIMIT 3 DEBUG: push down of limit count: 3
DEBUG: Creating router plan value | key | other_value | key | other_value
key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
(3 rows) (3 rows)
EXECUTE non_inlined_cte_has_parameter_on_dist_key(4); EXECUTE non_inlined_cte_has_parameter_on_dist_key(4);
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 4) DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 4)
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT test_table.value, test_table.key, test_table.other_value, cte_1.key, cte_1.other_value FROM (cte_inline.test_table LEFT JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 USING (value)) ORDER BY test_table.value DESC, test_table.key DESC, test_table.other_value DESC LIMIT 3
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, value, other_value, (SELECT 1) FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 ORDER BY key DESC, value DESC, other_value DESC LIMIT 3 DEBUG: push down of limit count: 3
DEBUG: Creating router plan value | key | other_value | key | other_value
key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
(3 rows) (3 rows)
EXECUTE non_inlined_cte_has_parameter_on_dist_key(5); EXECUTE non_inlined_cte_has_parameter_on_dist_key(5);
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 5) DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 5)
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT test_table.value, test_table.key, test_table.other_value, cte_1.key, cte_1.other_value FROM (cte_inline.test_table LEFT JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 USING (value)) ORDER BY test_table.value DESC, test_table.key DESC, test_table.other_value DESC LIMIT 3
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, value, other_value, (SELECT 1) FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 ORDER BY key DESC, value DESC, other_value DESC LIMIT 3 DEBUG: push down of limit count: 3
DEBUG: Creating router plan value | key | other_value | key | other_value
key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
(3 rows) (3 rows)
EXECUTE non_inlined_cte_has_parameter_on_dist_key(6); EXECUTE non_inlined_cte_has_parameter_on_dist_key(6);
@ -1207,15 +1189,15 @@ DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: CTE cte_1 is going to be inlined via distributed planning DEBUG: CTE cte_1 is going to be inlined via distributed planning
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 6) DEBUG: generating subplan XXX_1 for subquery SELECT key, value, other_value FROM cte_inline.test_table WHERE (key OPERATOR(pg_catalog.>) 6)
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT test_table.value, test_table.key, test_table.other_value, cte_1.key, cte_1.other_value FROM (cte_inline.test_table LEFT JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 USING (value)) ORDER BY test_table.value DESC, test_table.key DESC, test_table.other_value DESC LIMIT 3
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, value, other_value, (SELECT 1) FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.other_value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, other_value jsonb)) cte_1 ORDER BY key DESC, value DESC, other_value DESC LIMIT 3 DEBUG: push down of limit count: 3
DEBUG: Creating router plan value | key | other_value | key | other_value
key | value | other_value | ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
9 | test99 | | 1 test99 | 9 | | 9 |
(3 rows) (3 rows)
EXECUTE retry_planning(1); EXECUTE retry_planning(1);

View File

@ -684,15 +684,12 @@ INSERT INTO agg_events
DEBUG: CTE sub_cte is going to be inlined via distributed planning DEBUG: CTE sub_cte is going to be inlined via distributed planning
DEBUG: Subqueries without relations are not allowed in distributed INSERT ... SELECT queries DEBUG: Subqueries without relations are not allowed in distributed INSERT ... SELECT queries
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select queries
DEBUG: Subqueries without relations are not allowed in distributed INSERT ... SELECT queries DEBUG: performing repartitioned INSERT ... SELECT
DEBUG: CTE sub_cte is going to be inlined via distributed planning DEBUG: partitioning SELECT query by column index 0 with name 'user_id'
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: distributed statement: INSERT INTO public.agg_events_13300008 AS citus_table_alias (user_id, value_1_agg) SELECT user_id, value_1_agg FROM read_intermediate_results('{repartitioned_results_xxxxx_from_13300000_to_0}'::text[], 'binary'::citus_copy_format) intermediate_result(user_id integer, value_1_agg integer)
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: distributed statement: INSERT INTO public.agg_events_13300009 AS citus_table_alias (user_id, value_1_agg) SELECT user_id, value_1_agg FROM read_intermediate_results('{repartitioned_results_xxxxx_from_13300001_to_1}'::text[], 'binary'::citus_copy_format) intermediate_result(user_id integer, value_1_agg integer)
DEBUG: generating subplan XXX_1 for CTE sub_cte: SELECT 1 DEBUG: distributed statement: INSERT INTO public.agg_events_13300010 AS citus_table_alias (user_id, value_1_agg) SELECT user_id, value_1_agg FROM read_intermediate_results('{repartitioned_results_xxxxx_from_13300002_to_2}'::text[], 'binary'::citus_copy_format) intermediate_result(user_id integer, value_1_agg integer)
DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT user_id, (SELECT sub_cte."?column?" FROM (SELECT intermediate_result."?column?" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result("?column?" integer)) sub_cte("?column?")) AS value_1_agg FROM public.raw_events_first DEBUG: distributed statement: INSERT INTO public.agg_events_13300011 AS citus_table_alias (user_id, value_1_agg) SELECT user_id, value_1_agg FROM read_intermediate_results('{repartitioned_results_xxxxx_from_13300003_to_3}'::text[], 'binary'::citus_copy_format) intermediate_result(user_id integer, value_1_agg integer)
DEBUG: Router planner cannot handle multi-shard select queries
ERROR: could not run distributed query with subquery outside the FROM, WHERE and HAVING clauses
HINT: Consider using an equality filter on the distributed table's partition column.
-- We support set operations via the coordinator -- We support set operations via the coordinator
BEGIN; BEGIN;
INSERT INTO INSERT INTO

View File

@ -489,8 +489,7 @@ SELECT a.title AS name, (SELECT a2.id FROM articles_single_shard_hash_mx a2 WHER
AS special_price FROM articles_hash_mx a; AS special_price FROM articles_hash_mx a;
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select 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: could not run distributed query with subquery outside the FROM, WHERE and HAVING clauses ERROR: complex joins are only supported when all distributed tables are co-located and joined on their distribution columns
HINT: Consider using an equality filter on the distributed table's partition column.
-- simple lookup query -- simple lookup query
SELECT * SELECT *
FROM articles_hash_mx FROM articles_hash_mx

View File

@ -678,8 +678,7 @@ SELECT a.title AS name, (SELECT a2.id FROM articles_single_shard_hash a2 WHERE a
AS special_price FROM articles_hash a; AS special_price FROM articles_hash a;
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select 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: could not run distributed query with subquery outside the FROM, WHERE and HAVING clauses ERROR: complex joins are only supported when all distributed tables are co-located and joined on their distribution columns
HINT: Consider using an equality filter on the distributed table's partition column.
-- simple lookup query -- simple lookup query
SELECT * SELECT *
FROM articles_hash FROM articles_hash

View File

@ -424,8 +424,7 @@ SELECT a.title AS name, (SELECT a2.id FROM articles_hash a2 WHERE a.id = a2.id
AS special_price FROM articles_hash a; AS special_price FROM articles_hash a;
DEBUG: Router planner cannot handle multi-shard select queries DEBUG: Router planner cannot handle multi-shard select 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: could not run distributed query with subquery outside the FROM, WHERE and HAVING clauses ERROR: complex joins are only supported when all distributed tables are co-located and joined on their distribution columns
HINT: Consider using an equality filter on the distributed table's partition column.
-- simple lookup query just works -- simple lookup query just works
SELECT * SELECT *
FROM articles_hash FROM articles_hash

View File

@ -280,8 +280,7 @@ ORDER BY articles.id;
-- subqueries are not supported in SELECT clause -- subqueries are not supported in SELECT clause
SELECT a.title AS name, (SELECT a2.id FROM articles_single_shard a2 WHERE a.id = a2.id LIMIT 1) SELECT a.title AS name, (SELECT a2.id FROM articles_single_shard a2 WHERE a.id = a2.id LIMIT 1)
AS special_price FROM articles a; AS special_price FROM articles a;
ERROR: could not run distributed query with subquery outside the FROM, WHERE and HAVING clauses ERROR: complex joins are only supported when all distributed tables are co-located and joined on their distribution columns
HINT: Consider using an equality filter on the distributed table's partition column.
-- joins are not supported between local and distributed tables -- joins are not supported between local and distributed tables
SELECT title, authors.name FROM authors, articles WHERE authors.id = articles.author_id; SELECT title, authors.name FROM authors, articles WHERE authors.id = articles.author_id;
ERROR: direct joins between distributed and local tables are not supported ERROR: direct joins between distributed and local tables are not supported

View File

@ -702,11 +702,19 @@ WHERE
4968.4946466804019323 4968.4946466804019323
(1 row) (1 row)
-- Check unsupported subqueries in target list -- Check subqueries in target list
SELECT (SELECT 1) FROM orders_subquery; SELECT (SELECT 1) FROM orders_subquery ORDER BY 1 LIMIT 1;
ERROR: could not run distributed query with subquery outside the FROM, WHERE and HAVING clauses ?column?
---------------------------------------------------------------------
1
(1 row)
SELECT sum((SELECT 1)) FROM orders_subquery; SELECT sum((SELECT 1)) FROM orders_subquery;
ERROR: could not run distributed query with subquery outside the FROM, WHERE and HAVING clauses sum
---------------------------------------------------------------------
2985
(1 row)
-- Check that if subquery is pulled, we don't error and run query properly. -- Check that if subquery is pulled, we don't error and run query properly.
SELECT count(*) FROM SELECT count(*) FROM
( (

View File

@ -62,8 +62,7 @@ WHERE
users_reference_table.user_id = events_table.user_id users_reference_table.user_id = events_table.user_id
) )
LIMIT 3; LIMIT 3;
ERROR: cannot pushdown the subquery ERROR: correlated subqueries are not supported when the FROM clause contains a reference table
DETAIL: Reference tables are not allowed in FROM clause when the query has subqueries in WHERE clause and it references a column from another query
-- immutable functions are also treated as reference tables, query should not -- immutable functions are also treated as reference tables, query should not
-- work since there is a correlated subquery in the WHERE clause -- work since there is a correlated subquery in the WHERE clause
SELECT SELECT
@ -80,8 +79,7 @@ WHERE
users_reference_table.user_id = events_table.user_id users_reference_table.user_id = events_table.user_id
) )
LIMIT 3; LIMIT 3;
ERROR: cannot pushdown the subquery ERROR: correlated subqueries are not supported when the FROM clause contains a set returning function
DETAIL: Functions are not allowed in FROM clause when the query has subqueries in WHERE clause and it references a column from another query
-- subqueries without FROM are also treated as reference tables, query should not -- subqueries without FROM are also treated as reference tables, query should not
-- work since there is a correlated subquery in the WHERE clause -- work since there is a correlated subquery in the WHERE clause
SELECT SELECT
@ -98,8 +96,7 @@ WHERE
users_reference_table.user_id = events_table.user_id users_reference_table.user_id = events_table.user_id
) )
LIMIT 3; LIMIT 3;
ERROR: cannot pushdown the subquery ERROR: correlated subqueries are not supported when the FROM clause contains a CTE or 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
-- join with distributed table prevents FROM from recurring -- join with distributed table prevents FROM from recurring
SELECT SELECT
DISTINCT user_id DISTINCT user_id
@ -528,8 +525,7 @@ HAVING count(*) > 3
ORDER BY 2 DESC, ORDER BY 2 DESC,
1 DESC 1 DESC
LIMIT 5; LIMIT 5;
ERROR: cannot pushdown the subquery ERROR: correlated subqueries are not supported when the FROM clause contains a reference table
DETAIL: Reference tables are not allowed in FROM clause when the query has subqueries in WHERE clause and it references a column from another query
-- query will be planned as a SEMI JOIN -- query will be planned as a SEMI JOIN
SELECT * SELECT *
FROM users_table FROM users_table

View File

@ -290,9 +290,7 @@ RETURNS void AS $$
DECLARE c4 CURSOR WITH HOLD FOR SELECT *, (SELECT 1) FROM cursor_me WHERE x = $1; DECLARE c4 CURSOR WITH HOLD FOR SELECT *, (SELECT 1) FROM cursor_me WHERE x = $1;
$$ LANGUAGE SQL; $$ LANGUAGE SQL;
SELECT declares_cursor_4(19); SELECT declares_cursor_4(19);
ERROR: could not run distributed query with subquery outside the FROM, WHERE and HAVING clauses ERROR: Cursors for queries on distributed tables with parameters are currently unsupported
HINT: Consider using an equality filter on the distributed table's partition column.
CONTEXT: SQL function "declares_cursor_4" statement 1
CREATE OR REPLACE FUNCTION cursor_plpgsql(p int) CREATE OR REPLACE FUNCTION cursor_plpgsql(p int)
RETURNS SETOF int AS $$ RETURNS SETOF int AS $$
DECLARE DECLARE

View File

@ -0,0 +1,431 @@
CREATE SCHEMA subquery_in_targetlist;
SET search_path TO subquery_in_targetlist, public;
-- simple empty target list
SELECT event_type, (SELECT 1 + 3 + e.value_2)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
event_type | ?column?
---------------------------------------------------------------------
0 | 4
(1 row)
-- simple reference table sublink
SELECT event_type, (SELECT user_id FROM users_reference_table WHERE user_id = 1 AND value_1 = 1)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
event_type | user_id
---------------------------------------------------------------------
0 | 1
(1 row)
-- duplicate vars
SELECT event_type, (SELECT e.value_2 FROM users_reference_table WHERE user_id = 1 AND value_1 = 1), (SELECT e.value_2)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
event_type | value_2 | value_2
---------------------------------------------------------------------
0 | 0 | 0
(1 row)
-- correlated subquery with aggregate
SELECT event_type, (SELECT max(time) FROM users_table WHERE user_id = e.user_id)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
ERROR: cannot push down this subquery
DETAIL: Aggregates without group by are currently unsupported when a subquery references a column from another query
-- correlated subquery wtth limit
SELECT event_type, (SELECT time FROM users_table WHERE user_id = e.user_id ORDER BY time LIMIT 1)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
ERROR: cannot push down this subquery
DETAIL: Limit in subquery is currently unsupported when a subquery references a column from another query
-- correlated subquery with group by distribution column
SELECT event_type, (SELECT max(time) FROM users_table WHERE user_id = e.user_id GROUP BY user_id)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
event_type | max
---------------------------------------------------------------------
0 | Thu Nov 23 13:52:54.83829 2017
(1 row)
-- correlated subquery with group by almost distribution column
SELECT event_type, (SELECT max(time) FROM users_table WHERE user_id = e.user_id GROUP BY e.user_id)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
ERROR: cannot push down this subquery
DETAIL: Group by list without partition column is currently unsupported when a subquery references a column from another query
-- correlated subquery co-located join in outer query
SELECT event_type, (SELECT max(time) FROM users_table WHERE user_id = e.user_id GROUP BY user_id)
FROM users_table u JOIN events_table e USING (user_id)
ORDER BY 1,2 LIMIT 1;
event_type | max
---------------------------------------------------------------------
0 | Thu Nov 23 13:52:54.83829 2017
(1 row)
-- correlated subquery non-co-located join in outer query
SELECT event_type, (SELECT max(time) FROM users_table WHERE user_id = e.user_id GROUP BY user_id)
FROM users_table u JOIN events_table e USING (value_2)
ORDER BY 1,2 LIMIT 1;
ERROR: complex joins are only supported when all distributed tables are co-located and joined on their distribution columns
-- correlated subuqery with non-co-located join
SELECT event_type, (SELECT max(time) FROM users_table WHERE user_id = e.value_2)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
ERROR: complex joins are only supported when all distributed tables are co-located and joined on their distribution columns
SELECT event_type, (SELECT max(time) FROM users_table WHERE user_id = e.value_2 GROUP BY user_id)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
ERROR: complex joins are only supported when all distributed tables are co-located and joined on their distribution columns
-- correlated subquery with reference table and aggregate
SELECT event_type, (SELECT max(time) FROM users_reference_table WHERE user_id = e.value_2)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
ERROR: cannot push down this subquery
DETAIL: Aggregates without group by are currently unsupported when a subquery references a column from another query
-- correlated subquery with reference table and group by
SELECT event_type, (SELECT max(time) FROM users_reference_table WHERE user_id = e.value_2 GROUP BY user_id)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
event_type | max
---------------------------------------------------------------------
0 | Thu Nov 23 13:52:54.83829 2017
(1 row)
-- correlated subquery with reference table join
SELECT (SELECT max(u1.time) FROM users_table u1 JOIN users_reference_table u2 USING (user_id) WHERE u2.user_id = e.user_id GROUP BY user_id), 5
FROM events_table e
GROUP BY 1
ORDER BY 1,2 LIMIT 1;
max | ?column?
---------------------------------------------------------------------
Thu Nov 23 13:52:54.83829 2017 | 5
(1 row)
-- correlated subquery with reference table join and reference table in outer query
SELECT (SELECT max(u1.time) FROM users_table u1 JOIN users_reference_table u2 USING (user_id) WHERE u2.user_id = e.user_id GROUP BY user_id), 5
FROM events_reference_table e
GROUP BY 1
ORDER BY 1,2 LIMIT 1;
ERROR: correlated subqueries are not supported when the FROM clause contains a reference table
-- correlated subquery with non-co-located join in outer query
SELECT event_type, (SELECT max(time) FROM users_table WHERE user_id = e.user_id GROUP BY user_id)
FROM users_table u JOIN events_table e USING (value_2)
ORDER BY 1,2 LIMIT 1;
ERROR: complex joins are only supported when all distributed tables are co-located and joined on their distribution columns
-- aggregate in sublink without join
SELECT event_type, (SELECT max(time) FROM users_table)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
event_type | max
---------------------------------------------------------------------
0 | Thu Nov 23 17:30:34.635085 2017
(1 row)
-- aggregate in ctes in sublink
WITH cte_1 AS (SELECT max(time) FROM users_table)
SELECT event_type, (SELECT * FROM cte_1)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
event_type | max
---------------------------------------------------------------------
0 | Thu Nov 23 17:30:34.635085 2017
(1 row)
-- aggregate in ctes in sublink with limit
WITH cte_1 AS (SELECT max(time) FROM users_table)
SELECT event_type, (SELECT * FROM cte_1 LIMIT 1)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
event_type | max
---------------------------------------------------------------------
0 | Thu Nov 23 17:30:34.635085 2017
(1 row)
-- aggregate in ctes in sublink with join
WITH cte_1 AS (SELECT max(time) m FROM users_table)
SELECT count(*), (SELECT * FROM cte_1 c1 join cte_1 c2 using (m))
FROM events_table e
GROUP BY 2
ORDER BY 1,2 LIMIT 1;
count | m
---------------------------------------------------------------------
101 | Thu Nov 23 17:30:34.635085 2017
(1 row)
-- correlated subquery with cte in outer query
WITH cte_1 AS (SELECT min(user_id) u, max(time) m FROM users_table)
SELECT count(*), (SELECT max(time) FROM users_table WHERE user_id = cte_1.u GROUP BY user_id)
FROM cte_1
GROUP BY 2
ORDER BY 1,2 LIMIT 1;
ERROR: correlated subqueries are not supported when the FROM clause contains a CTE or subquery
-- correlated subquery in an aggregate
SELECT sum((SELECT max(value_3) FROM users_table WHERE user_id = e.user_id GROUP BY user_id))
FROM events_table e;
sum
---------------------------------------------------------------------
490
(1 row)
-- correlated subquery outside of an aggregate
SELECT sum(e.user_id) + (SELECT max(value_3) FROM users_table WHERE user_id = e.user_id GROUP BY user_id)
FROM events_table e
GROUP BY e.user_id
ORDER BY 1 LIMIT 3;
ERROR: cannot push down subquery on the target list
DETAIL: Subqueries in the SELECT part of the query can only be pushed down if they happen before aggregates and window functions
-- subquery outside of an aggregate
SELECT sum(e.user_id) + (SELECT user_id FROM users_reference_table WHERE user_id = 1 AND value_1 = 1)
FROM events_table e;
ERROR: cannot push down subquery on the target list
DETAIL: Subqueries in the SELECT part of the query can only be pushed down if they happen before aggregates and window functions
-- sublink in a pushdownable window function
SELECT e.user_id, sum((SELECT any_value(value_3) FROM users_reference_table WHERE user_id = e.user_id GROUP BY user_id)) OVER (PARTITION BY e.user_id)
FROM events_table e
ORDER BY 1, 2 LIMIT 3;
user_id | sum
---------------------------------------------------------------------
1 | 60
1 | 60
1 | 60
(3 rows)
-- sublink in a non-pushdownable window function
SELECT e.value_2, sum((SELECT any_value(value_3) FROM users_reference_table WHERE user_id = e.user_id GROUP BY user_id)) OVER (PARTITION BY e.value_2)
FROM events_table e
ORDER BY 1, 2 LIMIT 3;
ERROR: cannot push down subquery on the target list
DETAIL: Subqueries in the SELECT part of the query can only be pushed down if they happen before aggregates and window functions
-- sublink in a group by expression
SELECT e.value_2 + (SELECT any_value(value_3) FROM users_reference_table WHERE user_id = e.user_id GROUP BY user_id)
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
?column?
---------------------------------------------------------------------
0
1
2
(3 rows)
-- sublink in sublink
SELECT (SELECT (SELECT user_id + 2) * 2 FROM users_table WHERE user_id = e.user_id GROUP BY user_id)
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
?column?
---------------------------------------------------------------------
6
8
10
(3 rows)
-- sublink in sublink with outer table reference
SELECT (SELECT (SELECT e.user_id + user_id) FROM users_table WHERE user_id = e.user_id GROUP BY user_id)
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
?column?
---------------------------------------------------------------------
2
4
6
(3 rows)
-- sublink in sublink with reference table
SELECT (SELECT (SELECT e.user_id + user_id) FROM users_reference_table WHERE user_id = e.user_id GROUP BY user_id)
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
ERROR: correlated subqueries are not supported when the FROM clause contains a reference table
-- sublink in sublink with cte
WITH cte_1 AS (SELECT user_id FROM users_table ORDER BY 1 LIMIT 1)
SELECT (SELECT (SELECT e.user_id + user_id) FROM cte_1 WHERE user_id = e.user_id GROUP BY user_id)
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
ERROR: correlated subqueries are not supported when the FROM clause contains a CTE or subquery
-- sublink in sublink
SELECT (SELECT (SELECT e.user_id + user_id) FROM (SELECT 1 AS user_id) s WHERE user_id = e.user_id GROUP BY user_id)
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
ERROR: correlated subqueries are not supported when the FROM clause contains a subquery without FROM
-- sublink on view
CREATE TEMP VIEW view_1 AS (SELECT user_id, value_2 FROM users_table WHERE user_id = 1 AND value_1 = 1 ORDER BY 1,2);
-- with distribution column group by
SELECT (SELECT value_2 FROM view_1 WHERE user_id = e.user_id GROUP BY user_id, value_2)
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
value_2
---------------------------------------------------------------------
3
(2 rows)
-- without distribution column group by
SELECT (SELECT value_2 FROM view_1 WHERE user_id = e.user_id GROUP BY value_2)
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
ERROR: cannot push down this subquery
DETAIL: Group by list without partition column is currently unsupported when a subquery references a column from another query
-- without view in the outer query FROM
SELECT (SELECT value_2 FROM view_1 WHERE user_id = e.user_id GROUP BY user_id, value_2)
FROM view_1 e
GROUP BY 1
ORDER BY 1 LIMIT 3;
value_2
---------------------------------------------------------------------
3
(1 row)
-- sublink in sublink on view
SELECT (SELECT (SELECT e.user_id + user_id) FROM view_1 WHERE user_id = e.user_id GROUP BY user_id)
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
?column?
---------------------------------------------------------------------
2
(2 rows)
-- sublink on reference table view
CREATE TEMP VIEW view_2 AS (SELECT user_id, value_2 FROM users_reference_table WHERE user_id = 1 AND value_1 = 1);
SELECT (SELECT value_2 FROM view_2 WHERE user_id = e.user_id GROUP BY user_id, value_2)
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
value_2
---------------------------------------------------------------------
3
(2 rows)
-- without distributed table view in FROM, reference table view in sublink
SELECT (SELECT value_2 FROM view_2 WHERE user_id = e.user_id GROUP BY user_id, value_2)
FROM view_1 e
GROUP BY 1
ORDER BY 1 LIMIT 3;
value_2
---------------------------------------------------------------------
3
(1 row)
-- without reference table view in FROM, distributed in sublink
SELECT (SELECT value_2 FROM view_1 WHERE user_id = e.user_id GROUP BY user_id, value_2)
FROM view_2 e
GROUP BY 1
ORDER BY 1 LIMIT 3;
value_2
---------------------------------------------------------------------
3
(1 row)
-- use view as a type
SELECT (SELECT view_1)
FROM view_1
ORDER BY 1 LIMIT 1;
ERROR: type "view_1" does not exist
CONTEXT: while executing command on localhost:xxxxx
-- nested correlated sublink
SELECT (SELECT (SELECT user_id))
FROM events_table e
ORDER BY 1 LIMIT 1;
ERROR: correlated subqueries are not supported when the FROM clause contains a subquery without FROM
-- sublink with record type
SELECT (SELECT u FROM users_table u WHERE u.user_id = e.user_id AND time = 'Thu Nov 23 09:26:42.145043 2017')
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
u
---------------------------------------------------------------------
(1,"Thu Nov 23 09:26:42.145043 2017",1,3,3,)
(2 rows)
-- sublink with anonymous record type
SELECT (SELECT (user_id,value_1) FROM users_table u WHERE u.user_id = e.user_id AND time = 'Thu Nov 23 09:26:42.145043 2017')
FROM events_table e
WHERE user_id < 3
GROUP BY 1
ORDER BY 1 LIMIT 3;
ERROR: input of anonymous composite types is not implemented
-- complex query using row_to_json
SELECT coalesce(json_agg(root ORDER BY user_id), '[]') AS root
FROM
(SELECT row_to_json(
(SELECT _1_e
FROM
(SELECT "_0_root.base".user_id AS user_id) AS _1_e)) AS root, user_id
FROM
(SELECT DISTINCT user_id FROM public.users_table ORDER BY 1) AS "_0_root.base") AS _2_root ;
root
---------------------------------------------------------------------
[{"user_id":1}, {"user_id":2}, {"user_id":3}, {"user_id":4}, {"user_id":5}, {"user_id":6}]
(1 row)
SELECT *
FROM
(SELECT
row_to_json((SELECT _1_e FROM (SELECT user_id) AS _1_e)) AS root, user_id
FROM
(SELECT DISTINCT user_id FROM public.users_table ORDER BY 1) as bar) AS foo ORDER BY user_id;
root | user_id
---------------------------------------------------------------------
{"user_id":1} | 1
{"user_id":2} | 2
{"user_id":3} | 3
{"user_id":4} | 4
{"user_id":5} | 5
{"user_id":6} | 6
(6 rows)
-- non-colocated subquery join
SELECT count(*) FROM
(SELECT event_type, (SELECT e.value_2 FROM users_reference_table WHERE user_id = 1 AND value_1 = 1 AND value_2 = 1), (SELECT e.value_2)
FROM events_table e) as foo
JOIN
(SELECT event_type, (SELECT e.value_2 FROM users_reference_table WHERE user_id = 5 AND value_1 = 1 AND value_2 = 1), (SELECT e.value_2)
FROM events_table e) as bar
ON bar.event_type = foo.event_type;
count
---------------------------------------------------------------------
1993
(1 row)
-- subquery in the target list in HAVING should be fine
SELECT
user_id, count(*)
FROM
events_table e1
GROUP BY user_id
HAVING
count(*) > (SELECT count(*) FROM (SELECT
(SELECT sum(user_id) FROM users_table WHERE user_id = u1.user_id GROUP BY user_id)
FROM users_table u1
GROUP BY user_id) as foo) ORDER BY 1 DESC;
user_id | count
---------------------------------------------------------------------
6 | 10
5 | 14
4 | 17
3 | 21
2 | 24
1 | 15
(6 rows)
-- make sure that we don't pushdown subqueries in the target list if no FROM clause
SELECT (SELECT DISTINCT user_id FROM users_table WHERE user_id = (SELECT max(user_id) FROM users_table ));
ERROR: correlated subqueries are not supported when the FROM clause contains a subquery without FROM
-- not meaningful SELECT FOR UPDATE query that should fail
SELECT count(*) FROM (SELECT
(SELECT user_id FROM users_table WHERE user_id = u1.user_id FOR UPDATE)
FROM users_table u1
GROUP BY user_id) as foo;
ERROR: cannot push down this subquery
DETAIL: For Update/Share commands are currently unsupported
DROP SCHEMA subquery_in_targetlist CASCADE;

View File

@ -39,8 +39,7 @@ WHERE events_user_id IN (SELECT user_id
DEBUG: CTE event_id is going to be inlined via distributed planning DEBUG: CTE event_id is going to be inlined via distributed planning
DEBUG: generating subplan XXX_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 XXX_1 for CTE event_id: SELECT user_id AS events_user_id, "time" AS events_time, event_type FROM public.events_table
DEBUG: Plan XXX 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('XXX_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 OPERATOR(pg_catalog.=) ANY (SELECT users_table.user_id FROM public.users_table WHERE (users_table."time" OPERATOR(pg_catalog.=) event_id.events_time))) DEBUG: Plan XXX 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('XXX_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 OPERATOR(pg_catalog.=) ANY (SELECT users_table.user_id FROM public.users_table WHERE (users_table."time" OPERATOR(pg_catalog.=) event_id.events_time)))
ERROR: cannot pushdown the subquery ERROR: correlated subqueries are not supported when the FROM clause contains a CTE or 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 -- Recurring tuples as empty join tree
SELECT * SELECT *
FROM (SELECT 1 AS id, 2 AS value_1, 3 AS value_3 FROM (SELECT 1 AS id, 2 AS value_1, 3 AS value_3

View File

@ -95,21 +95,26 @@ SELECT user_id FROM (
2 2
(3 rows) (3 rows)
-- CTE outside of FROM/WHERE errors out -- CTE outside of FROM/WHERE errors
WITH cte AS ( WITH cte AS (
SELECT user_id FROM users_table WHERE value_2 IN (1, 2) SELECT user_id FROM users_table WHERE value_2 IN (1, 2)
) )
SELECT (SELECT * FROM cte); SELECT (SELECT * FROM cte);
ERROR: more than one row returned by a subquery used as an expression ERROR: more than one row returned by a subquery used as an expression
WITH cte_basic AS ( WITH cte_basic AS (
SELECT user_id FROM users_table WHERE user_id = 1 SELECT user_id FROM users_table WHERE user_id = 1 LIMIT 1
) )
SELECT SELECT
(SELECT user_id FROM cte_basic), user_id (SELECT user_id FROM cte_basic), user_id
FROM FROM
users_table; users_table
ERROR: could not run distributed query with subquery outside the FROM, WHERE and HAVING clauses ORDER BY 1,2
HINT: Consider using an equality filter on the distributed table's partition column. LIMIT 1;
user_id | user_id
---------------------------------------------------------------------
1 | 1
(1 row)
-- single-row sublink is acceptable when there is no FROM -- single-row sublink is acceptable when there is no FROM
WITH cte AS ( WITH cte AS (
SELECT user_id FROM users_table WHERE value_2 IN (1, 2) SELECT user_id FROM users_table WHERE value_2 IN (1, 2)

View File

@ -83,7 +83,8 @@ test: subquery_and_cte
test: set_operations test: set_operations
test: set_operation_and_local_tables test: set_operation_and_local_tables
test: subqueries_deep subquery_view subquery_partitioning subquery_complex_target_list subqueries_not_supported subquery_in_where test: subqueries_deep subquery_view subquery_partitioning subqueries_not_supported
test: subquery_in_targetlist subquery_in_where subquery_complex_target_list
test: subquery_prepared_statements test: subquery_prepared_statements
test: non_colocated_leaf_subquery_joins non_colocated_subquery_joins non_colocated_join_order test: non_colocated_leaf_subquery_joins non_colocated_subquery_joins non_colocated_join_order
test: cte_inline recursive_view_local_table test: cte_inline recursive_view_local_table

View File

@ -17,17 +17,17 @@ SET client_min_messages TO DEBUG;
-- plan the query -- plan the query
WITH cte_1 AS (SELECT * FROM test_table) WITH cte_1 AS (SELECT * FROM test_table)
SELECT SELECT
*, (SELECT 1) *
FROM FROM
cte_1 test_table LEFT JOIN cte_1 USING (value)
ORDER BY 1 DESC LIMIT 3; ORDER BY 1 DESC LIMIT 3;
-- Should still not be inlined even if NOT MATERIALIZED is passed -- Should still not be inlined even if NOT MATERIALIZED is passed
WITH cte_1 AS NOT MATERIALIZED (SELECT * FROM test_table) WITH cte_1 AS NOT MATERIALIZED (SELECT * FROM test_table)
SELECT SELECT
*, (SELECT 1) *
FROM FROM
cte_1 test_table LEFT JOIN cte_1 USING (value)
ORDER BY 2 DESC LIMIT 1; ORDER BY 2 DESC LIMIT 1;
-- the cte can be inlined because the unsupported -- the cte can be inlined because the unsupported
@ -494,9 +494,9 @@ PREPARE inlined_cte_without_params AS
PREPARE non_inlined_cte_without_params AS PREPARE non_inlined_cte_without_params AS
WITH cte_1 AS (SELECT * FROM test_table) WITH cte_1 AS (SELECT * FROM test_table)
SELECT SELECT
*, (SELECT 1) *
FROM FROM
cte_1 ORDER BY 1 DESC, 2 DESC, 3 DESC LIMIT 3; test_table LEFT JOIN cte_1 USING (value) ORDER BY 1 DESC, 2 DESC, 3 DESC LIMIT 3;
PREPARE inlined_cte_has_parameter_on_non_dist_key(text) AS PREPARE inlined_cte_has_parameter_on_non_dist_key(text) AS
WITH cte_1 AS (SELECT count(*) FROM test_table WHERE value = $1 GROUP BY key) WITH cte_1 AS (SELECT count(*) FROM test_table WHERE value = $1 GROUP BY key)
SELECT * FROM cte_1 ORDER BY 1 DESC LIMIT 3; SELECT * FROM cte_1 ORDER BY 1 DESC LIMIT 3;
@ -506,9 +506,9 @@ PREPARE inlined_cte_has_parameter_on_dist_key(int) AS
PREPARE non_inlined_cte_has_parameter_on_dist_key(int) AS PREPARE non_inlined_cte_has_parameter_on_dist_key(int) AS
WITH cte_1 AS (SELECT * FROM test_table where key > $1) WITH cte_1 AS (SELECT * FROM test_table where key > $1)
SELECT SELECT
*, (SELECT 1) *
FROM FROM
cte_1 ORDER BY 1 DESC, 2 DESC, 3 DESC LIMIT 3; test_table LEFT JOIN cte_1 USING (value) ORDER BY 1 DESC, 2 DESC, 3 DESC LIMIT 3;
PREPARE retry_planning(int) AS PREPARE retry_planning(int) AS
WITH cte_1 AS (SELECT * FROM test_table WHERE key > $1) WITH cte_1 AS (SELECT * FROM test_table WHERE key > $1)
SELECT json_object_agg(DISTINCT key, value) FROM cte_1 ORDER BY max(key), min(value) DESC LIMIT 3; SELECT json_object_agg(DISTINCT key, value) FROM cte_1 ORDER BY max(key), min(value) DESC LIMIT 3;

View File

@ -468,8 +468,8 @@ WHERE
unit_price > 1000 AND unit_price > 1000 AND
unit_price < 10000; unit_price < 10000;
-- Check unsupported subqueries in target list -- Check subqueries in target list
SELECT (SELECT 1) FROM orders_subquery; SELECT (SELECT 1) FROM orders_subquery ORDER BY 1 LIMIT 1;
SELECT sum((SELECT 1)) FROM orders_subquery; SELECT sum((SELECT 1)) FROM orders_subquery;
-- Check that if subquery is pulled, we don't error and run query properly. -- Check that if subquery is pulled, we don't error and run query properly.

View File

@ -0,0 +1,294 @@
CREATE SCHEMA subquery_in_targetlist;
SET search_path TO subquery_in_targetlist, public;
-- simple empty target list
SELECT event_type, (SELECT 1 + 3 + e.value_2)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
-- simple reference table sublink
SELECT event_type, (SELECT user_id FROM users_reference_table WHERE user_id = 1 AND value_1 = 1)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
-- duplicate vars
SELECT event_type, (SELECT e.value_2 FROM users_reference_table WHERE user_id = 1 AND value_1 = 1), (SELECT e.value_2)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
-- correlated subquery with aggregate
SELECT event_type, (SELECT max(time) FROM users_table WHERE user_id = e.user_id)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
-- correlated subquery wtth limit
SELECT event_type, (SELECT time FROM users_table WHERE user_id = e.user_id ORDER BY time LIMIT 1)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
-- correlated subquery with group by distribution column
SELECT event_type, (SELECT max(time) FROM users_table WHERE user_id = e.user_id GROUP BY user_id)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
-- correlated subquery with group by almost distribution column
SELECT event_type, (SELECT max(time) FROM users_table WHERE user_id = e.user_id GROUP BY e.user_id)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
-- correlated subquery co-located join in outer query
SELECT event_type, (SELECT max(time) FROM users_table WHERE user_id = e.user_id GROUP BY user_id)
FROM users_table u JOIN events_table e USING (user_id)
ORDER BY 1,2 LIMIT 1;
-- correlated subquery non-co-located join in outer query
SELECT event_type, (SELECT max(time) FROM users_table WHERE user_id = e.user_id GROUP BY user_id)
FROM users_table u JOIN events_table e USING (value_2)
ORDER BY 1,2 LIMIT 1;
-- correlated subuqery with non-co-located join
SELECT event_type, (SELECT max(time) FROM users_table WHERE user_id = e.value_2)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
SELECT event_type, (SELECT max(time) FROM users_table WHERE user_id = e.value_2 GROUP BY user_id)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
-- correlated subquery with reference table and aggregate
SELECT event_type, (SELECT max(time) FROM users_reference_table WHERE user_id = e.value_2)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
-- correlated subquery with reference table and group by
SELECT event_type, (SELECT max(time) FROM users_reference_table WHERE user_id = e.value_2 GROUP BY user_id)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
-- correlated subquery with reference table join
SELECT (SELECT max(u1.time) FROM users_table u1 JOIN users_reference_table u2 USING (user_id) WHERE u2.user_id = e.user_id GROUP BY user_id), 5
FROM events_table e
GROUP BY 1
ORDER BY 1,2 LIMIT 1;
-- correlated subquery with reference table join and reference table in outer query
SELECT (SELECT max(u1.time) FROM users_table u1 JOIN users_reference_table u2 USING (user_id) WHERE u2.user_id = e.user_id GROUP BY user_id), 5
FROM events_reference_table e
GROUP BY 1
ORDER BY 1,2 LIMIT 1;
-- correlated subquery with non-co-located join in outer query
SELECT event_type, (SELECT max(time) FROM users_table WHERE user_id = e.user_id GROUP BY user_id)
FROM users_table u JOIN events_table e USING (value_2)
ORDER BY 1,2 LIMIT 1;
-- aggregate in sublink without join
SELECT event_type, (SELECT max(time) FROM users_table)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
-- aggregate in ctes in sublink
WITH cte_1 AS (SELECT max(time) FROM users_table)
SELECT event_type, (SELECT * FROM cte_1)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
-- aggregate in ctes in sublink with limit
WITH cte_1 AS (SELECT max(time) FROM users_table)
SELECT event_type, (SELECT * FROM cte_1 LIMIT 1)
FROM events_table e
ORDER BY 1,2 LIMIT 1;
-- aggregate in ctes in sublink with join
WITH cte_1 AS (SELECT max(time) m FROM users_table)
SELECT count(*), (SELECT * FROM cte_1 c1 join cte_1 c2 using (m))
FROM events_table e
GROUP BY 2
ORDER BY 1,2 LIMIT 1;
-- correlated subquery with cte in outer query
WITH cte_1 AS (SELECT min(user_id) u, max(time) m FROM users_table)
SELECT count(*), (SELECT max(time) FROM users_table WHERE user_id = cte_1.u GROUP BY user_id)
FROM cte_1
GROUP BY 2
ORDER BY 1,2 LIMIT 1;
-- correlated subquery in an aggregate
SELECT sum((SELECT max(value_3) FROM users_table WHERE user_id = e.user_id GROUP BY user_id))
FROM events_table e;
-- correlated subquery outside of an aggregate
SELECT sum(e.user_id) + (SELECT max(value_3) FROM users_table WHERE user_id = e.user_id GROUP BY user_id)
FROM events_table e
GROUP BY e.user_id
ORDER BY 1 LIMIT 3;
-- subquery outside of an aggregate
SELECT sum(e.user_id) + (SELECT user_id FROM users_reference_table WHERE user_id = 1 AND value_1 = 1)
FROM events_table e;
-- sublink in a pushdownable window function
SELECT e.user_id, sum((SELECT any_value(value_3) FROM users_reference_table WHERE user_id = e.user_id GROUP BY user_id)) OVER (PARTITION BY e.user_id)
FROM events_table e
ORDER BY 1, 2 LIMIT 3;
-- sublink in a non-pushdownable window function
SELECT e.value_2, sum((SELECT any_value(value_3) FROM users_reference_table WHERE user_id = e.user_id GROUP BY user_id)) OVER (PARTITION BY e.value_2)
FROM events_table e
ORDER BY 1, 2 LIMIT 3;
-- sublink in a group by expression
SELECT e.value_2 + (SELECT any_value(value_3) FROM users_reference_table WHERE user_id = e.user_id GROUP BY user_id)
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
-- sublink in sublink
SELECT (SELECT (SELECT user_id + 2) * 2 FROM users_table WHERE user_id = e.user_id GROUP BY user_id)
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
-- sublink in sublink with outer table reference
SELECT (SELECT (SELECT e.user_id + user_id) FROM users_table WHERE user_id = e.user_id GROUP BY user_id)
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
-- sublink in sublink with reference table
SELECT (SELECT (SELECT e.user_id + user_id) FROM users_reference_table WHERE user_id = e.user_id GROUP BY user_id)
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
-- sublink in sublink with cte
WITH cte_1 AS (SELECT user_id FROM users_table ORDER BY 1 LIMIT 1)
SELECT (SELECT (SELECT e.user_id + user_id) FROM cte_1 WHERE user_id = e.user_id GROUP BY user_id)
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
-- sublink in sublink
SELECT (SELECT (SELECT e.user_id + user_id) FROM (SELECT 1 AS user_id) s WHERE user_id = e.user_id GROUP BY user_id)
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
-- sublink on view
CREATE TEMP VIEW view_1 AS (SELECT user_id, value_2 FROM users_table WHERE user_id = 1 AND value_1 = 1 ORDER BY 1,2);
-- with distribution column group by
SELECT (SELECT value_2 FROM view_1 WHERE user_id = e.user_id GROUP BY user_id, value_2)
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
-- without distribution column group by
SELECT (SELECT value_2 FROM view_1 WHERE user_id = e.user_id GROUP BY value_2)
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
-- without view in the outer query FROM
SELECT (SELECT value_2 FROM view_1 WHERE user_id = e.user_id GROUP BY user_id, value_2)
FROM view_1 e
GROUP BY 1
ORDER BY 1 LIMIT 3;
-- sublink in sublink on view
SELECT (SELECT (SELECT e.user_id + user_id) FROM view_1 WHERE user_id = e.user_id GROUP BY user_id)
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
-- sublink on reference table view
CREATE TEMP VIEW view_2 AS (SELECT user_id, value_2 FROM users_reference_table WHERE user_id = 1 AND value_1 = 1);
SELECT (SELECT value_2 FROM view_2 WHERE user_id = e.user_id GROUP BY user_id, value_2)
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
-- without distributed table view in FROM, reference table view in sublink
SELECT (SELECT value_2 FROM view_2 WHERE user_id = e.user_id GROUP BY user_id, value_2)
FROM view_1 e
GROUP BY 1
ORDER BY 1 LIMIT 3;
-- without reference table view in FROM, distributed in sublink
SELECT (SELECT value_2 FROM view_1 WHERE user_id = e.user_id GROUP BY user_id, value_2)
FROM view_2 e
GROUP BY 1
ORDER BY 1 LIMIT 3;
-- use view as a type
SELECT (SELECT view_1)
FROM view_1
ORDER BY 1 LIMIT 1;
-- nested correlated sublink
SELECT (SELECT (SELECT user_id))
FROM events_table e
ORDER BY 1 LIMIT 1;
-- sublink with record type
SELECT (SELECT u FROM users_table u WHERE u.user_id = e.user_id AND time = 'Thu Nov 23 09:26:42.145043 2017')
FROM events_table e
GROUP BY 1
ORDER BY 1 LIMIT 3;
-- sublink with anonymous record type
SELECT (SELECT (user_id,value_1) FROM users_table u WHERE u.user_id = e.user_id AND time = 'Thu Nov 23 09:26:42.145043 2017')
FROM events_table e
WHERE user_id < 3
GROUP BY 1
ORDER BY 1 LIMIT 3;
-- complex query using row_to_json
SELECT coalesce(json_agg(root ORDER BY user_id), '[]') AS root
FROM
(SELECT row_to_json(
(SELECT _1_e
FROM
(SELECT "_0_root.base".user_id AS user_id) AS _1_e)) AS root, user_id
FROM
(SELECT DISTINCT user_id FROM public.users_table ORDER BY 1) AS "_0_root.base") AS _2_root ;
SELECT *
FROM
(SELECT
row_to_json((SELECT _1_e FROM (SELECT user_id) AS _1_e)) AS root, user_id
FROM
(SELECT DISTINCT user_id FROM public.users_table ORDER BY 1) as bar) AS foo ORDER BY user_id;
-- non-colocated subquery join
SELECT count(*) FROM
(SELECT event_type, (SELECT e.value_2 FROM users_reference_table WHERE user_id = 1 AND value_1 = 1 AND value_2 = 1), (SELECT e.value_2)
FROM events_table e) as foo
JOIN
(SELECT event_type, (SELECT e.value_2 FROM users_reference_table WHERE user_id = 5 AND value_1 = 1 AND value_2 = 1), (SELECT e.value_2)
FROM events_table e) as bar
ON bar.event_type = foo.event_type;
-- subquery in the target list in HAVING should be fine
SELECT
user_id, count(*)
FROM
events_table e1
GROUP BY user_id
HAVING
count(*) > (SELECT count(*) FROM (SELECT
(SELECT sum(user_id) FROM users_table WHERE user_id = u1.user_id GROUP BY user_id)
FROM users_table u1
GROUP BY user_id) as foo) ORDER BY 1 DESC;
-- make sure that we don't pushdown subqueries in the target list if no FROM clause
SELECT (SELECT DISTINCT user_id FROM users_table WHERE user_id = (SELECT max(user_id) FROM users_table ));
-- not meaningful SELECT FOR UPDATE query that should fail
SELECT count(*) FROM (SELECT
(SELECT user_id FROM users_table WHERE user_id = u1.user_id FOR UPDATE)
FROM users_table u1
GROUP BY user_id) as foo;
DROP SCHEMA subquery_in_targetlist CASCADE;

View File

@ -62,19 +62,21 @@ SELECT user_id FROM (
SELECT user_id FROM cte WHERE value_2 > 0 SELECT user_id FROM cte WHERE value_2 > 0
) a ORDER BY 1 LIMIT 3; ) a ORDER BY 1 LIMIT 3;
-- CTE outside of FROM/WHERE errors out -- CTE outside of FROM/WHERE errors
WITH cte AS ( WITH cte AS (
SELECT user_id FROM users_table WHERE value_2 IN (1, 2) SELECT user_id FROM users_table WHERE value_2 IN (1, 2)
) )
SELECT (SELECT * FROM cte); SELECT (SELECT * FROM cte);
WITH cte_basic AS ( WITH cte_basic AS (
SELECT user_id FROM users_table WHERE user_id = 1 SELECT user_id FROM users_table WHERE user_id = 1 LIMIT 1
) )
SELECT SELECT
(SELECT user_id FROM cte_basic), user_id (SELECT user_id FROM cte_basic), user_id
FROM FROM
users_table; users_table
ORDER BY 1,2
LIMIT 1;
-- single-row sublink is acceptable when there is no FROM -- single-row sublink is acceptable when there is no FROM
WITH cte AS ( WITH cte AS (