diff --git a/src/backend/distributed/metadata/metadata_cache.c b/src/backend/distributed/metadata/metadata_cache.c index 1e5ebac6a..324a5ac38 100644 --- a/src/backend/distributed/metadata/metadata_cache.c +++ b/src/backend/distributed/metadata/metadata_cache.c @@ -357,6 +357,12 @@ IsCitusTableTypeInternal(char partitionMethod, char replicationModel, partitionMethod == DISTRIBUTE_BY_APPEND; } + case STRICTLY_PARTITIONED_DISTRIBUTED_TABLE: + { + return partitionMethod == DISTRIBUTE_BY_HASH || + partitionMethod == DISTRIBUTE_BY_RANGE; + } + case REFERENCE_TABLE: { return partitionMethod == DISTRIBUTE_BY_NONE && diff --git a/src/backend/distributed/planner/extended_op_node_utils.c b/src/backend/distributed/planner/extended_op_node_utils.c index 30367fe20..22a950424 100644 --- a/src/backend/distributed/planner/extended_op_node_utils.c +++ b/src/backend/distributed/planner/extended_op_node_utils.c @@ -122,18 +122,18 @@ GroupedByPartitionColumn(MultiNode *node, MultiExtendedOp *opNode) Oid relationId = tableNode->relationId; - if (relationId == SUBQUERY_RELATION_ID || - relationId == SUBQUERY_PUSHDOWN_RELATION_ID) + if (relationId == SUBQUERY_RELATION_ID) { /* ignore subqueries for now */ return false; } - - if (!IsCitusTableType(relationId, RANGE_DISTRIBUTED) && - !IsCitusTableType(relationId, HASH_DISTRIBUTED)) + else if (relationId != SUBQUERY_PUSHDOWN_RELATION_ID) { - /* only range- and hash-distributed tables are strictly partitioned */ - return false; + if (!IsCitusTableType(relationId, STRICTLY_PARTITIONED_DISTRIBUTED_TABLE)) + { + /* only range- and hash-distributed tables are strictly partitioned */ + return false; + } } if (GroupedByColumn(opNode->groupClauseList, opNode->targetList, @@ -295,8 +295,6 @@ PartitionColumnInTableList(Var *column, List *tableNodeList) partitionColumn->varno == column->varno && partitionColumn->varattno == column->varattno) { - Assert(partitionColumn->varno == tableNode->rangeTableId); - if (!IsCitusTableType(tableNode->relationId, APPEND_DISTRIBUTED)) { return true; diff --git a/src/backend/distributed/planner/multi_logical_optimizer.c b/src/backend/distributed/planner/multi_logical_optimizer.c index 5a3f78745..3e66bed80 100644 --- a/src/backend/distributed/planner/multi_logical_optimizer.c +++ b/src/backend/distributed/planner/multi_logical_optimizer.c @@ -4346,6 +4346,11 @@ GroupedByColumn(List *groupClauseList, List *targetList, Var *column) { bool groupedByColumn = false; + if (column == NULL) + { + return false; + } + SortGroupClause *groupClause = NULL; foreach_ptr(groupClause, groupClauseList) { @@ -4500,7 +4505,16 @@ FindReferencedTableColumn(Expr *columnExpression, List *parentQueryList, Query * return; } - Index rangeTableEntryIndex = candidateColumn->varno - 1; + if (candidateColumn->varattno == InvalidAttrNumber) + { + /* + * varattno can be 0 in case of SELECT table FROM table, but that Var + * definitely does not correspond to a specific column. + */ + return; + } + + int rangeTableEntryIndex = candidateColumn->varno - 1; RangeTblEntry *rangeTableEntry = list_nth(rangetableList, rangeTableEntryIndex); if (rangeTableEntry->rtekind == RTE_RELATION) diff --git a/src/backend/distributed/planner/query_pushdown_planning.c b/src/backend/distributed/planner/query_pushdown_planning.c index 38cc844ab..043bf7a96 100644 --- a/src/backend/distributed/planner/query_pushdown_planning.c +++ b/src/backend/distributed/planner/query_pushdown_planning.c @@ -93,6 +93,8 @@ static List * CreateSubqueryTargetListAndAdjustVars(List *columnList); static AttrNumber FindResnoForVarInTargetList(List *targetList, int varno, int varattno); static bool RelationInfoContainsOnlyRecurringTuples(PlannerInfo *plannerInfo, Relids relids); +static Var * PartitionColumnForPushedDownSubquery(Query *query); + /* * ShouldUseSubqueryPushDown determines whether it's desirable to use @@ -1769,7 +1771,7 @@ MultiSubqueryPushdownTable(Query *subquery) subqueryTableNode->subquery = subquery; subqueryTableNode->relationId = SUBQUERY_PUSHDOWN_RELATION_ID; subqueryTableNode->rangeTableId = SUBQUERY_RANGE_TABLE_ID; - subqueryTableNode->partitionColumn = NULL; + subqueryTableNode->partitionColumn = PartitionColumnForPushedDownSubquery(subquery); subqueryTableNode->alias = makeNode(Alias); subqueryTableNode->alias->aliasname = rteName->data; subqueryTableNode->referenceNames = makeNode(Alias); @@ -1778,3 +1780,43 @@ MultiSubqueryPushdownTable(Query *subquery) return subqueryTableNode; } + + +/* + * PartitionColumnForPushedDownSubquery finds the partition column on the target + * list of a pushed down subquery. + */ +static Var * +PartitionColumnForPushedDownSubquery(Query *query) +{ + List *targetEntryList = query->targetList; + + TargetEntry *targetEntry = NULL; + foreach_ptr(targetEntry, targetEntryList) + { + if (targetEntry->resjunk) + { + continue; + } + + Expr *targetExpression = targetEntry->expr; + if (IsA(targetExpression, Var)) + { + bool isPartitionColumn = IsPartitionColumn(targetExpression, query); + if (isPartitionColumn) + { + Var *partitionColumn = copyObject((Var *) targetExpression); + + /* the pushed down subquery is the only range table entry */ + partitionColumn->varno = 1; + + /* point the var to the position in the subquery target list */ + partitionColumn->varattno = targetEntry->resno; + + return partitionColumn; + } + } + } + + return NULL; +} diff --git a/src/include/distributed/metadata_cache.h b/src/include/distributed/metadata_cache.h index 36a0a5d23..da5d45d84 100644 --- a/src/include/distributed/metadata_cache.h +++ b/src/include/distributed/metadata_cache.h @@ -125,6 +125,9 @@ typedef enum /* hash, range or append distributed table */ DISTRIBUTED_TABLE, + /* hash- or range-distributed table */ + STRICTLY_PARTITIONED_DISTRIBUTED_TABLE, + REFERENCE_TABLE, CITUS_LOCAL_TABLE, diff --git a/src/test/regress/expected/cte_inline.out b/src/test/regress/expected/cte_inline.out index a1b9ba078..34bdc8fd2 100644 --- a/src/test/regress/expected/cte_inline.out +++ b/src/test/regress/expected/cte_inline.out @@ -947,6 +947,7 @@ DEBUG: Router planner cannot handle multi-shard select queries DEBUG: generating subplan XXX_1 for subquery SELECT max(key) AS max FROM cte_inline.test_table DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, count(*) AS count FROM cte_inline.test_table GROUP BY key HAVING (count(*) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max integer)) cte_1)) ORDER BY (count(*)) DESC, key DESC LIMIT 5 DEBUG: Router planner cannot handle multi-shard select queries +DEBUG: push down of limit count: 5 key | count --------------------------------------------------------------------- 8 | 40 diff --git a/src/test/regress/expected/cte_inline_0.out b/src/test/regress/expected/cte_inline_0.out index 7338e4ffe..35653633f 100644 --- a/src/test/regress/expected/cte_inline_0.out +++ b/src/test/regress/expected/cte_inline_0.out @@ -824,6 +824,7 @@ DEBUG: Router planner cannot handle multi-shard select queries DEBUG: generating subplan XXX_1 for subquery SELECT max(key) AS max FROM cte_inline.test_table DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT key, count(*) AS count FROM cte_inline.test_table GROUP BY key HAVING (count(*) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max integer)) cte_1)) ORDER BY (count(*)) DESC, key DESC LIMIT 5 DEBUG: Router planner cannot handle multi-shard select queries +DEBUG: push down of limit count: 5 key | count --------------------------------------------------------------------- 0 | 44 diff --git a/src/test/regress/expected/intermediate_result_pruning.out b/src/test/regress/expected/intermediate_result_pruning.out index 89641bc48..6977a3caf 100644 --- a/src/test/regress/expected/intermediate_result_pruning.out +++ b/src/test/regress/expected/intermediate_result_pruning.out @@ -1043,6 +1043,7 @@ inserts AS ( DEBUG: generating subplan XXX_1 for CTE stats: SELECT count(key) AS m FROM intermediate_result_pruning.table_3 DEBUG: generating subplan XXX_2 for CTE inserts: INSERT INTO intermediate_result_pruning.table_2 (key, value) SELECT key, count(*) AS count FROM intermediate_result_pruning.table_1 WHERE (key OPERATOR(pg_catalog.>) (SELECT stats.m FROM (SELECT intermediate_result.m FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(m bigint)) stats)) GROUP BY key HAVING (count(*) OPERATOR(pg_catalog.<) (SELECT stats.m FROM (SELECT intermediate_result.m FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(m bigint)) stats)) LIMIT 1 RETURNING table_2.key, table_2.value DEBUG: LIMIT clauses are not allowed in distributed INSERT ... SELECT queries +DEBUG: push down of limit count: 1 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) inserts DEBUG: Subplan XXX_1 will be written to local file DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx diff --git a/src/test/regress/expected/locally_execute_intermediate_results.out b/src/test/regress/expected/locally_execute_intermediate_results.out index 406f203da..b148a6620 100644 --- a/src/test/regress/expected/locally_execute_intermediate_results.out +++ b/src/test/regress/expected/locally_execute_intermediate_results.out @@ -46,11 +46,29 @@ SELECT count(*) FROM table_2 +GROUP BY value +HAVING max(value) > (SELECT max FROM cte_1); +DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) +DEBUG: Subplan XXX_1 will be written to local file + count +--------------------------------------------------------------------- + 1 + 1 +(2 rows) + +-- in this case, the HAVING Is also pushed down +WITH cte_1 AS (SELECT max(value) FROM table_1) +SELECT +count(*) +FROM +table_2 GROUP BY key HAVING max(value) > (SELECT max FROM cte_1); DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) -DEBUG: Subplan XXX_1 will be written to local file +DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx +DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx count --------------------------------------------------------------------- 1 @@ -72,7 +90,8 @@ DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM lo DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT key, value FROM locally_execute_intermediate_results.table_2 DEBUG: generating subplan XXX_3 for subquery SELECT key FROM (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) cte_2 ORDER BY key LIMIT 1 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 WHERE (key OPERATOR(pg_catalog.>) (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer))) GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) -DEBUG: Subplan XXX_1 will be written to local file +DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx +DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx DEBUG: Subplan XXX_2 will be written to local file DEBUG: Subplan XXX_3 will be sent to localhost:xxxxx DEBUG: Subplan XXX_3 will be sent to localhost:xxxxx @@ -98,7 +117,8 @@ HAVING max(value) > (SELECT max FROM cte_1); DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT max(key) AS max FROM locally_execute_intermediate_results.table_2 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 WHERE (key OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max integer)) cte_2)) GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) -DEBUG: Subplan XXX_1 will be written to local file +DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx +DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx DEBUG: Subplan XXX_2 will be sent to localhost:xxxxx DEBUG: Subplan XXX_2 will be sent to localhost:xxxxx count @@ -137,13 +157,35 @@ SELECT count(*) FROM table_2 +GROUP BY value +HAVING max(value) > (SELECT max FROM cte_1 JOIN cte_2 USING (max)); +DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 +DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM ((SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1 JOIN (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_2 USING (max)))) +DEBUG: Subplan XXX_1 will be written to local file +DEBUG: Subplan XXX_2 will be written to local file + count +--------------------------------------------------------------------- + 1 + 1 +(2 rows) + +-- same as above, but HAVING pushed down to workers +WITH cte_1 AS (SELECT max(value) FROM table_1), +cte_2 AS (SELECT max(value) FROM table_1) +SELECT +count(*) +FROM +table_2 GROUP BY key HAVING max(value) > (SELECT max FROM cte_1 JOIN cte_2 USING (max)); DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM ((SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1 JOIN (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_2 USING (max)))) -DEBUG: Subplan XXX_1 will be written to local file -DEBUG: Subplan XXX_2 will be written to local file +DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx +DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx +DEBUG: Subplan XXX_2 will be sent to localhost:xxxxx +DEBUG: Subplan XXX_2 will be sent to localhost:xxxxx count --------------------------------------------------------------------- 1 @@ -184,13 +226,34 @@ SELECT count(*) FROM table_2 +GROUP BY value +HAVING max(value) > (SELECT max(max) FROM cte_1); +DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 +DEBUG: generating subplan XXX_2 for subquery SELECT max(max) AS max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1 +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text))) +DEBUG: Subplan XXX_1 will be written to local file +DEBUG: Subplan XXX_2 will be written to local file +NOTICE: executing the command locally: SELECT max(max) AS max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1 + count +--------------------------------------------------------------------- + 1 + 1 +(2 rows) + +-- same as above, but with HAVING pushed down +WITH cte_1 AS (SELECT max(value) FROM table_1) +SELECT +count(*) +FROM +table_2 GROUP BY key HAVING max(value) > (SELECT max(max) FROM cte_1); DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 DEBUG: generating subplan XXX_2 for subquery SELECT max(max) AS max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text))) DEBUG: Subplan XXX_1 will be written to local file -DEBUG: Subplan XXX_2 will be written to local file +DEBUG: Subplan XXX_2 will be sent to localhost:xxxxx +DEBUG: Subplan XXX_2 will be sent to localhost:xxxxx NOTICE: executing the command locally: SELECT max(max) AS max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1 count --------------------------------------------------------------------- @@ -421,6 +484,27 @@ DEBUG: Subplan XXX_2 will be sent to localhost:xxxxx -- the second subquery needs to be recursively planned due to non-colocated subquery join -- so cte_2 becomes part of master query of that recursive subquery planning +WITH cte_1 AS (SELECT max(value) FROM table_1), + cte_2 AS (SELECT max(value) FROM table_2) +SELECT * FROM + (SELECT value AS key FROM table_1 GROUP BY value HAVING max(value) > (SELECT * FROM cte_1)) as foo, + (SELECT value AS key FROM table_2 GROUP BY value HAVING max(value) > (SELECT * FROM cte_2)) as bar + WHERE foo.key != bar.key; +DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 +DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_2 +DEBUG: generating subplan XXX_3 for subquery SELECT value AS key FROM locally_execute_intermediate_results.table_1 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) +DEBUG: generating subplan XXX_4 for subquery SELECT value AS key FROM locally_execute_intermediate_results.table_2 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_2)) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT foo.key, bar.key FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key text)) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(key text)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key) +DEBUG: Subplan XXX_1 will be written to local file +DEBUG: Subplan XXX_2 will be written to local file +DEBUG: Subplan XXX_3 will be written to local file +DEBUG: Subplan XXX_4 will be written to local file +NOTICE: executing the command locally: SELECT foo.key, bar.key FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key text)) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(key text)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key) + key | key +--------------------------------------------------------------------- +(0 rows) + +-- similar to above, but having pushed down WITH cte_1 AS (SELECT max(value) FROM table_1), cte_2 AS (SELECT max(value) FROM table_2) SELECT * FROM @@ -433,7 +517,8 @@ DEBUG: generating subplan XXX_3 for subquery SELECT key FROM locally_execute_in DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT foo.key, bar.key FROM (SELECT table_1.key FROM locally_execute_intermediate_results.table_1 GROUP BY table_1.key HAVING (max(table_1.value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1))) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key) DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx -DEBUG: Subplan XXX_2 will be written to local file +DEBUG: Subplan XXX_2 will be sent to localhost:xxxxx +DEBUG: Subplan XXX_2 will be sent to localhost:xxxxx DEBUG: Subplan XXX_3 will be sent to localhost:xxxxx DEBUG: Subplan XXX_3 will be sent to localhost:xxxxx key | key @@ -444,19 +529,19 @@ DEBUG: Subplan XXX_3 will be sent to localhost:xxxxx WITH cte_1 AS (SELECT max(value) FROM table_1), cte_2 AS (SELECT max(value) FROM table_2) SELECT * FROM - (SELECT key FROM table_1 GROUP BY key HAVING max(value) > (SELECT * FROM cte_1) LIMIT 1) as foo, - (SELECT key FROM table_2 GROUP BY key HAVING max(value) > (SELECT * FROM cte_2) LIMIT 1) as bar + (SELECT value AS key FROM table_1 GROUP BY value HAVING max(value) > (SELECT * FROM cte_1) LIMIT 1) as foo, + (SELECT value AS key FROM table_2 GROUP BY value HAVING max(value) > (SELECT * FROM cte_2) LIMIT 1) as bar WHERE foo.key != bar.key; DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_2 -DEBUG: generating subplan XXX_3 for subquery SELECT key FROM locally_execute_intermediate_results.table_1 GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) LIMIT 1 -DEBUG: generating subplan XXX_4 for subquery SELECT key FROM locally_execute_intermediate_results.table_2 GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_2)) LIMIT 1 -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT foo.key, bar.key FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key) +DEBUG: generating subplan XXX_3 for subquery SELECT value AS key FROM locally_execute_intermediate_results.table_1 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) LIMIT 1 +DEBUG: generating subplan XXX_4 for subquery SELECT value AS key FROM locally_execute_intermediate_results.table_2 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_2)) LIMIT 1 +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT foo.key, bar.key FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key text)) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(key text)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key) DEBUG: Subplan XXX_1 will be written to local file DEBUG: Subplan XXX_2 will be written to local file DEBUG: Subplan XXX_3 will be written to local file DEBUG: Subplan XXX_4 will be written to local file -NOTICE: executing the command locally: SELECT foo.key, bar.key FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key) +NOTICE: executing the command locally: SELECT foo.key, bar.key FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key text)) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(key text)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key) key | key --------------------------------------------------------------------- (0 rows) @@ -521,15 +606,15 @@ SELECT count(*) FROM table_2 -GROUP BY key +GROUP BY value HAVING max(value) > (SELECT max FROM cte_1); DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) DEBUG: Subplan XXX_1 will be written to local file NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580000 table_1 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580002 table_1 WHERE true -NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_2) AS worker_column_3 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580004 table_2) worker_subquery GROUP BY worker_column_1 -NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_2) AS worker_column_3 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580006 table_2) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_1) AS worker_column_3 FROM (SELECT table_2.value AS worker_column_1 FROM locally_execute_intermediate_results.table_2_1580004 table_2) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_1) AS worker_column_3 FROM (SELECT table_2.value AS worker_column_1 FROM locally_execute_intermediate_results.table_2_1580006 table_2) worker_subquery GROUP BY worker_column_1 count --------------------------------------------------------------------- 1 @@ -546,12 +631,12 @@ FROM table_2 WHERE key > (SELECT key FROM cte_2 ORDER BY 1 LIMIT 1) -GROUP BY key +GROUP BY value HAVING max(value) > (SELECT max FROM cte_1); DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT key, value FROM locally_execute_intermediate_results.table_2 DEBUG: generating subplan XXX_3 for subquery SELECT key FROM (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) cte_2 ORDER BY key LIMIT 1 -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 WHERE (key OPERATOR(pg_catalog.>) (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer))) GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 WHERE (key OPERATOR(pg_catalog.>) (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer))) GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) DEBUG: Subplan XXX_1 will be written to local file NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580000 table_1 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580002 table_1 WHERE true @@ -561,8 +646,8 @@ NOTICE: executing the command locally: SELECT key, value FROM locally_execute_i DEBUG: Subplan XXX_3 will be sent to localhost:xxxxx DEBUG: Subplan XXX_3 will be sent to localhost:xxxxx NOTICE: executing the command locally: SELECT key FROM (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) cte_2 ORDER BY key LIMIT 1 -NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_2) AS worker_column_3 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580004 table_2 WHERE (table_2.key OPERATOR(pg_catalog.>) (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer)))) worker_subquery GROUP BY worker_column_1 -NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_2) AS worker_column_3 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580006 table_2 WHERE (table_2.key OPERATOR(pg_catalog.>) (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer)))) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_1) AS worker_column_3 FROM (SELECT table_2.value AS worker_column_1 FROM locally_execute_intermediate_results.table_2_1580004 table_2 WHERE (table_2.key OPERATOR(pg_catalog.>) (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer)))) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_1) AS worker_column_3 FROM (SELECT table_2.value AS worker_column_1 FROM locally_execute_intermediate_results.table_2_1580006 table_2 WHERE (table_2.key OPERATOR(pg_catalog.>) (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer)))) worker_subquery GROUP BY worker_column_1 count --------------------------------------------------------------------- 1 @@ -584,15 +669,16 @@ HAVING max(value) > (SELECT max FROM cte_1); DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT max(key) AS max FROM locally_execute_intermediate_results.table_2 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 WHERE (key OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max integer)) cte_2)) GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) -DEBUG: Subplan XXX_1 will be written to local file +DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx +DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580000 table_1 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580002 table_1 WHERE true DEBUG: Subplan XXX_2 will be sent to localhost:xxxxx DEBUG: Subplan XXX_2 will be sent to localhost:xxxxx NOTICE: executing the command locally: SELECT max(key) AS max FROM locally_execute_intermediate_results.table_2_1580004 table_2 WHERE true NOTICE: executing the command locally: SELECT max(key) AS max FROM locally_execute_intermediate_results.table_2_1580006 table_2 WHERE true -NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_2) AS worker_column_3 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580004 table_2 WHERE (table_2.key OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max integer)) cte_2))) worker_subquery GROUP BY worker_column_1 -NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_2) AS worker_column_3 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580006 table_2 WHERE (table_2.key OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max integer)) cte_2))) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580004 table_2 WHERE (table_2.key OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max integer)) cte_2))) worker_subquery GROUP BY worker_column_1 HAVING (max(worker_column_2) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) +NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580006 table_2 WHERE (table_2.key OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max integer)) cte_2))) worker_subquery GROUP BY worker_column_1 HAVING (max(worker_column_2) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) count --------------------------------------------------------------------- (0 rows) @@ -636,19 +722,19 @@ SELECT count(*) FROM table_2 -GROUP BY key +GROUP BY value HAVING max(value) > (SELECT max FROM cte_1 JOIN cte_2 USING (max)); DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM ((SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1 JOIN (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_2 USING (max)))) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM ((SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1 JOIN (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_2 USING (max)))) DEBUG: Subplan XXX_1 will be written to local file NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580000 table_1 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580002 table_1 WHERE true DEBUG: Subplan XXX_2 will be written to local file NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580000 table_1 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580002 table_1 WHERE true -NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_2) AS worker_column_3 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580004 table_2) worker_subquery GROUP BY worker_column_1 -NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_2) AS worker_column_3 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580006 table_2) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_1) AS worker_column_3 FROM (SELECT table_2.value AS worker_column_1 FROM locally_execute_intermediate_results.table_2_1580004 table_2) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_1) AS worker_column_3 FROM (SELECT table_2.value AS worker_column_1 FROM locally_execute_intermediate_results.table_2_1580006 table_2) worker_subquery GROUP BY worker_column_1 count --------------------------------------------------------------------- 1 @@ -696,18 +782,18 @@ SELECT count(*) FROM table_2 -GROUP BY key +GROUP BY value HAVING max(value) > (SELECT max(max) FROM cte_1); DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 DEBUG: generating subplan XXX_2 for subquery SELECT max(max) AS max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1 -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text))) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text))) DEBUG: Subplan XXX_1 will be written to local file NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580000 table_1 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580002 table_1 WHERE true DEBUG: Subplan XXX_2 will be written to local file NOTICE: executing the command locally: SELECT max(max) AS max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1 -NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_2) AS worker_column_3 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580004 table_2) worker_subquery GROUP BY worker_column_1 -NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_2) AS worker_column_3 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580006 table_2) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_1) AS worker_column_3 FROM (SELECT table_2.value AS worker_column_1 FROM locally_execute_intermediate_results.table_2_1580004 table_2) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_1) AS worker_column_3 FROM (SELECT table_2.value AS worker_column_1 FROM locally_execute_intermediate_results.table_2_1580006 table_2) worker_subquery GROUP BY worker_column_1 count --------------------------------------------------------------------- 1 @@ -1004,26 +1090,27 @@ NOTICE: executing the command locally: SELECT worker_column_1 AS key, worker_co WITH cte_1 AS (SELECT max(value) FROM table_1), cte_2 AS (SELECT max(value) FROM table_2) SELECT * FROM - (SELECT key FROM table_1 GROUP BY key HAVING max(value) > (SELECT * FROM cte_1)) as foo, - (SELECT key FROM table_2 GROUP BY key HAVING max(value) > (SELECT * FROM cte_2)) as bar + (SELECT value AS key FROM table_1 GROUP BY value HAVING max(value) > (SELECT * FROM cte_1)) as foo, + (SELECT value AS key FROM table_2 GROUP BY value HAVING max(value) > (SELECT * FROM cte_2)) as bar WHERE foo.key != bar.key; DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_2 -DEBUG: generating subplan XXX_3 for subquery SELECT key FROM locally_execute_intermediate_results.table_2 GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_2)) -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT foo.key, bar.key FROM (SELECT table_1.key FROM locally_execute_intermediate_results.table_1 GROUP BY table_1.key HAVING (max(table_1.value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1))) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key) -DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx -DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx +DEBUG: generating subplan XXX_3 for subquery SELECT value AS key FROM locally_execute_intermediate_results.table_1 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) +DEBUG: generating subplan XXX_4 for subquery SELECT value AS key FROM locally_execute_intermediate_results.table_2 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_2)) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT foo.key, bar.key FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key text)) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(key text)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key) +DEBUG: Subplan XXX_1 will be written to local file NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580000 table_1 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580002 table_1 WHERE true DEBUG: Subplan XXX_2 will be written to local file NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_2_1580004 table_2 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_2_1580006 table_2 WHERE true -DEBUG: Subplan XXX_3 will be sent to localhost:xxxxx -DEBUG: Subplan XXX_3 will be sent to localhost:xxxxx -NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_2) AS worker_column_2 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580004 table_2) worker_subquery GROUP BY worker_column_1 -NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_2) AS worker_column_2 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580006 table_2) worker_subquery GROUP BY worker_column_1 -NOTICE: executing the command locally: SELECT worker_column_1 AS key, worker_column_2 AS key FROM (SELECT foo.key AS worker_column_1, bar.key AS worker_column_2 FROM (SELECT table_1.key FROM locally_execute_intermediate_results.table_1_1580000 table_1 GROUP BY table_1.key HAVING (max(table_1.value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1))) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key)) worker_subquery -NOTICE: executing the command locally: SELECT worker_column_1 AS key, worker_column_2 AS key FROM (SELECT foo.key AS worker_column_1, bar.key AS worker_column_2 FROM (SELECT table_1.key FROM locally_execute_intermediate_results.table_1_1580002 table_1 GROUP BY table_1.key HAVING (max(table_1.value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1))) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key)) worker_subquery +DEBUG: Subplan XXX_3 will be written to local file +NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_1) AS worker_column_2 FROM (SELECT table_1.value AS worker_column_1 FROM locally_execute_intermediate_results.table_1_1580000 table_1) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_1) AS worker_column_2 FROM (SELECT table_1.value AS worker_column_1 FROM locally_execute_intermediate_results.table_1_1580002 table_1) worker_subquery GROUP BY worker_column_1 +DEBUG: Subplan XXX_4 will be written to local file +NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_1) AS worker_column_2 FROM (SELECT table_2.value AS worker_column_1 FROM locally_execute_intermediate_results.table_2_1580004 table_2) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_1) AS worker_column_2 FROM (SELECT table_2.value AS worker_column_1 FROM locally_execute_intermediate_results.table_2_1580006 table_2) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT foo.key, bar.key FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key text)) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(key text)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key) key | key --------------------------------------------------------------------- (0 rows) @@ -1032,14 +1119,14 @@ NOTICE: executing the command locally: SELECT worker_column_1 AS key, worker_co WITH cte_1 AS (SELECT max(value) FROM table_1), cte_2 AS (SELECT max(value) FROM table_2) SELECT * FROM - (SELECT key FROM table_1 GROUP BY key HAVING max(value) > (SELECT * FROM cte_1) LIMIT 1) as foo, - (SELECT key FROM table_2 GROUP BY key HAVING max(value) > (SELECT * FROM cte_2) LIMIT 1) as bar + (SELECT value AS key FROM table_1 GROUP BY value HAVING max(value) > (SELECT * FROM cte_1) LIMIT 1) as foo, + (SELECT value AS key FROM table_2 GROUP BY value HAVING max(value) > (SELECT * FROM cte_2) LIMIT 1) as bar WHERE foo.key != bar.key; DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_2 -DEBUG: generating subplan XXX_3 for subquery SELECT key FROM locally_execute_intermediate_results.table_1 GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) LIMIT 1 -DEBUG: generating subplan XXX_4 for subquery SELECT key FROM locally_execute_intermediate_results.table_2 GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_2)) LIMIT 1 -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT foo.key, bar.key FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key) +DEBUG: generating subplan XXX_3 for subquery SELECT value AS key FROM locally_execute_intermediate_results.table_1 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) LIMIT 1 +DEBUG: generating subplan XXX_4 for subquery SELECT value AS key FROM locally_execute_intermediate_results.table_2 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_2)) LIMIT 1 +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT foo.key, bar.key FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key text)) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(key text)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key) DEBUG: Subplan XXX_1 will be written to local file NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580000 table_1 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580002 table_1 WHERE true @@ -1047,12 +1134,12 @@ DEBUG: Subplan XXX_2 will be written to local file NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_2_1580004 table_2 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_2_1580006 table_2 WHERE true DEBUG: Subplan XXX_3 will be written to local file -NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_2) AS worker_column_2 FROM (SELECT table_1.key AS worker_column_1, table_1.value AS worker_column_2 FROM locally_execute_intermediate_results.table_1_1580000 table_1) worker_subquery GROUP BY worker_column_1 -NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_2) AS worker_column_2 FROM (SELECT table_1.key AS worker_column_1, table_1.value AS worker_column_2 FROM locally_execute_intermediate_results.table_1_1580002 table_1) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_1) AS worker_column_2 FROM (SELECT table_1.value AS worker_column_1 FROM locally_execute_intermediate_results.table_1_1580000 table_1) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_1) AS worker_column_2 FROM (SELECT table_1.value AS worker_column_1 FROM locally_execute_intermediate_results.table_1_1580002 table_1) worker_subquery GROUP BY worker_column_1 DEBUG: Subplan XXX_4 will be written to local file -NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_2) AS worker_column_2 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580004 table_2) worker_subquery GROUP BY worker_column_1 -NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_2) AS worker_column_2 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580006 table_2) worker_subquery GROUP BY worker_column_1 -NOTICE: executing the command locally: SELECT foo.key, bar.key FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key) +NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_1) AS worker_column_2 FROM (SELECT table_2.value AS worker_column_1 FROM locally_execute_intermediate_results.table_2_1580004 table_2) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_1) AS worker_column_2 FROM (SELECT table_2.value AS worker_column_1 FROM locally_execute_intermediate_results.table_2_1580006 table_2) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT foo.key, bar.key FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key text)) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(key text)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key) key | key --------------------------------------------------------------------- (0 rows) @@ -1066,15 +1153,15 @@ SELECT count(*) FROM table_2 -GROUP BY key +GROUP BY value HAVING max(value) > (SELECT max FROM cte_1); DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) DEBUG: Subplan XXX_1 will be written to local file NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580000 table_1 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580002 table_1 WHERE true -NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_2) AS worker_column_3 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580004 table_2) worker_subquery GROUP BY worker_column_1 -NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_2) AS worker_column_3 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580006 table_2) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_1) AS worker_column_3 FROM (SELECT table_2.value AS worker_column_1 FROM locally_execute_intermediate_results.table_2_1580004 table_2) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_1) AS worker_column_3 FROM (SELECT table_2.value AS worker_column_1 FROM locally_execute_intermediate_results.table_2_1580006 table_2) worker_subquery GROUP BY worker_column_1 count --------------------------------------------------------------------- 1 @@ -1097,7 +1184,8 @@ DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM lo DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT key, value FROM locally_execute_intermediate_results.table_2 DEBUG: generating subplan XXX_3 for subquery SELECT key FROM (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) cte_2 ORDER BY key LIMIT 1 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 WHERE (key OPERATOR(pg_catalog.>) (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer))) GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) -DEBUG: Subplan XXX_1 will be written to local file +DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx +DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580000 table_1 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580002 table_1 WHERE true DEBUG: Subplan XXX_2 will be sent to localhost:xxxxx @@ -1105,8 +1193,8 @@ NOTICE: executing the command locally: SELECT key, value FROM locally_execute_i NOTICE: executing the command locally: SELECT key, value FROM locally_execute_intermediate_results.table_2_1580006 table_2 WHERE true DEBUG: Subplan XXX_3 will be sent to localhost:xxxxx DEBUG: Subplan XXX_3 will be sent to localhost:xxxxx -NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_2) AS worker_column_3 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580004 table_2 WHERE (table_2.key OPERATOR(pg_catalog.>) (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer)))) worker_subquery GROUP BY worker_column_1 -NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_2) AS worker_column_3 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580006 table_2 WHERE (table_2.key OPERATOR(pg_catalog.>) (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer)))) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580004 table_2 WHERE (table_2.key OPERATOR(pg_catalog.>) (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer)))) worker_subquery GROUP BY worker_column_1 HAVING (max(worker_column_2) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) +NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580006 table_2 WHERE (table_2.key OPERATOR(pg_catalog.>) (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer)))) worker_subquery GROUP BY worker_column_1 HAVING (max(worker_column_2) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) count --------------------------------------------------------------------- 1 @@ -1128,15 +1216,16 @@ HAVING max(value) > (SELECT max FROM cte_1); DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT max(key) AS max FROM locally_execute_intermediate_results.table_2 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 WHERE (key OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max integer)) cte_2)) GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) -DEBUG: Subplan XXX_1 will be written to local file +DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx +DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580000 table_1 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580002 table_1 WHERE true DEBUG: Subplan XXX_2 will be sent to localhost:xxxxx DEBUG: Subplan XXX_2 will be sent to localhost:xxxxx NOTICE: executing the command locally: SELECT max(key) AS max FROM locally_execute_intermediate_results.table_2_1580004 table_2 WHERE true NOTICE: executing the command locally: SELECT max(key) AS max FROM locally_execute_intermediate_results.table_2_1580006 table_2 WHERE true -NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_2) AS worker_column_3 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580004 table_2 WHERE (table_2.key OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max integer)) cte_2))) worker_subquery GROUP BY worker_column_1 -NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_2) AS worker_column_3 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580006 table_2 WHERE (table_2.key OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max integer)) cte_2))) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580004 table_2 WHERE (table_2.key OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max integer)) cte_2))) worker_subquery GROUP BY worker_column_1 HAVING (max(worker_column_2) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) +NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580006 table_2 WHERE (table_2.key OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max integer)) cte_2))) worker_subquery GROUP BY worker_column_1 HAVING (max(worker_column_2) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) count --------------------------------------------------------------------- (0 rows) @@ -1185,14 +1274,16 @@ HAVING max(value) > (SELECT max FROM cte_1 JOIN cte_2 USING (max)); DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM ((SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1 JOIN (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_2 USING (max)))) -DEBUG: Subplan XXX_1 will be written to local file +DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx +DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580000 table_1 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580002 table_1 WHERE true -DEBUG: Subplan XXX_2 will be written to local file +DEBUG: Subplan XXX_2 will be sent to localhost:xxxxx +DEBUG: Subplan XXX_2 will be sent to localhost:xxxxx NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580000 table_1 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580002 table_1 WHERE true -NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_2) AS worker_column_3 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580004 table_2) worker_subquery GROUP BY worker_column_1 -NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_2) AS worker_column_3 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580006 table_2) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580004 table_2) worker_subquery GROUP BY worker_column_1 HAVING (max(worker_column_2) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM ((SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1 JOIN (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_2 USING (max)))) +NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580006 table_2) worker_subquery GROUP BY worker_column_1 HAVING (max(worker_column_2) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM ((SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1 JOIN (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_2 USING (max)))) count --------------------------------------------------------------------- 1 @@ -1209,12 +1300,12 @@ SELECT count(*) FROM cte_3 -GROUP BY key +GROUP BY value HAVING max(value) > (SELECT max FROM cte_1 JOIN cte_2 USING (max)); DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 DEBUG: generating subplan XXX_3 for CTE cte_3: SELECT key, value FROM locally_execute_intermediate_results.table_2 -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) cte_3 GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM ((SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1 JOIN (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_2 USING (max)))) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) cte_3 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM ((SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1 JOIN (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_2 USING (max)))) DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580000 table_1 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580002 table_1 WHERE true @@ -1239,18 +1330,18 @@ SELECT count(*) FROM table_2 -GROUP BY key +GROUP BY value HAVING max(value) > (SELECT max(max) FROM cte_1); DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 DEBUG: generating subplan XXX_2 for subquery SELECT max(max) AS max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1 -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text))) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM locally_execute_intermediate_results.table_2 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text))) DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580000 table_1 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580002 table_1 WHERE true DEBUG: Subplan XXX_2 will be written to local file NOTICE: executing the command locally: SELECT max(max) AS max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1 -NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_2) AS worker_column_3 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580004 table_2) worker_subquery GROUP BY worker_column_1 -NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_2) AS worker_column_3 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580006 table_2) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_1) AS worker_column_3 FROM (SELECT table_2.value AS worker_column_1 FROM locally_execute_intermediate_results.table_2_1580004 table_2) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT count(*) AS count, worker_column_1 AS worker_column_2, max(worker_column_1) AS worker_column_3 FROM (SELECT table_2.value AS worker_column_1 FROM locally_execute_intermediate_results.table_2_1580006 table_2) worker_subquery GROUP BY worker_column_1 count --------------------------------------------------------------------- 1 @@ -1552,26 +1643,26 @@ ERROR: syntax error at or near "-" WITH cte_1 AS (SELECT max(value) FROM table_1), cte_2 AS (SELECT max(value) FROM table_2) SELECT * FROM - (SELECT key FROM table_1 GROUP BY key HAVING max(value) > (SELECT * FROM cte_1)) as foo, - (SELECT key FROM table_2 GROUP BY key HAVING max(value) > (SELECT * FROM cte_2)) as bar + (SELECT value AS key FROM table_1 GROUP BY value HAVING max(value) > (SELECT * FROM cte_1)) as foo, + (SELECT value AS key FROM table_2 GROUP BY value HAVING max(value) > (SELECT * FROM cte_2)) as bar WHERE foo.key != bar.key; DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_2 -DEBUG: generating subplan XXX_3 for subquery SELECT key FROM locally_execute_intermediate_results.table_2 GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_2)) -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT foo.key, bar.key FROM (SELECT table_1.key FROM locally_execute_intermediate_results.table_1 GROUP BY table_1.key HAVING (max(table_1.value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1))) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key) -DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx -DEBUG: Subplan XXX_1 will be sent to localhost:xxxxx +DEBUG: generating subplan XXX_3 for subquery SELECT value AS key FROM locally_execute_intermediate_results.table_1 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) +DEBUG: generating subplan XXX_4 for subquery SELECT value AS key FROM locally_execute_intermediate_results.table_2 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_2)) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT foo.key, bar.key FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key text)) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(key text)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key) +DEBUG: Subplan XXX_1 will be written to local file NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580000 table_1 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580002 table_1 WHERE true DEBUG: Subplan XXX_2 will be written to local file NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_2_1580004 table_2 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_2_1580006 table_2 WHERE true DEBUG: Subplan XXX_3 will be sent to localhost:xxxxx -DEBUG: Subplan XXX_3 will be sent to localhost:xxxxx -NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_2) AS worker_column_2 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580004 table_2) worker_subquery GROUP BY worker_column_1 -NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_2) AS worker_column_2 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580006 table_2) worker_subquery GROUP BY worker_column_1 -NOTICE: executing the command locally: SELECT worker_column_1 AS key, worker_column_2 AS key FROM (SELECT foo.key AS worker_column_1, bar.key AS worker_column_2 FROM (SELECT table_1.key FROM locally_execute_intermediate_results.table_1_1580000 table_1 GROUP BY table_1.key HAVING (max(table_1.value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1))) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key)) worker_subquery -NOTICE: executing the command locally: SELECT worker_column_1 AS key, worker_column_2 AS key FROM (SELECT foo.key AS worker_column_1, bar.key AS worker_column_2 FROM (SELECT table_1.key FROM locally_execute_intermediate_results.table_1_1580002 table_1 GROUP BY table_1.key HAVING (max(table_1.value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1))) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key)) worker_subquery +NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_1) AS worker_column_2 FROM (SELECT table_1.value AS worker_column_1 FROM locally_execute_intermediate_results.table_1_1580000 table_1) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_1) AS worker_column_2 FROM (SELECT table_1.value AS worker_column_1 FROM locally_execute_intermediate_results.table_1_1580002 table_1) worker_subquery GROUP BY worker_column_1 +DEBUG: Subplan XXX_4 will be sent to localhost:xxxxx +NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_1) AS worker_column_2 FROM (SELECT table_2.value AS worker_column_1 FROM locally_execute_intermediate_results.table_2_1580004 table_2) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_1) AS worker_column_2 FROM (SELECT table_2.value AS worker_column_1 FROM locally_execute_intermediate_results.table_2_1580006 table_2) worker_subquery GROUP BY worker_column_1 key | key --------------------------------------------------------------------- (0 rows) @@ -1580,14 +1671,14 @@ NOTICE: executing the command locally: SELECT worker_column_1 AS key, worker_co WITH cte_1 AS (SELECT max(value) FROM table_1), cte_2 AS (SELECT max(value) FROM table_2) SELECT * FROM - (SELECT key FROM table_1 GROUP BY key HAVING max(value) > (SELECT * FROM cte_1) LIMIT 1) as foo, - (SELECT key FROM table_2 GROUP BY key HAVING max(value) > (SELECT * FROM cte_2) LIMIT 1) as bar + (SELECT value AS key FROM table_1 GROUP BY value HAVING max(value) > (SELECT * FROM cte_1) LIMIT 1) as foo, + (SELECT value AS key FROM table_2 GROUP BY value HAVING max(value) > (SELECT * FROM cte_2) LIMIT 1) as bar WHERE foo.key != bar.key; DEBUG: generating subplan XXX_1 for CTE cte_1: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1 DEBUG: generating subplan XXX_2 for CTE cte_2: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_2 -DEBUG: generating subplan XXX_3 for subquery SELECT key FROM locally_execute_intermediate_results.table_1 GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) LIMIT 1 -DEBUG: generating subplan XXX_4 for subquery SELECT key FROM locally_execute_intermediate_results.table_2 GROUP BY key HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_2)) LIMIT 1 -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT foo.key, bar.key FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(key integer)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key) +DEBUG: generating subplan XXX_3 for subquery SELECT value AS key FROM locally_execute_intermediate_results.table_1 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_1.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_1)) LIMIT 1 +DEBUG: generating subplan XXX_4 for subquery SELECT value AS key FROM locally_execute_intermediate_results.table_2 GROUP BY value HAVING (max(value) OPERATOR(pg_catalog.>) (SELECT cte_2.max FROM (SELECT intermediate_result.max FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(max text)) cte_2)) LIMIT 1 +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT foo.key, bar.key FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key text)) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(key text)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key) DEBUG: Subplan XXX_1 will be written to local file NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580000 table_1 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_1_1580002 table_1 WHERE true @@ -1595,11 +1686,12 @@ DEBUG: Subplan XXX_2 will be written to local file NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_2_1580004 table_2 WHERE true NOTICE: executing the command locally: SELECT max(value) AS max FROM locally_execute_intermediate_results.table_2_1580006 table_2 WHERE true DEBUG: Subplan XXX_3 will be sent to localhost:xxxxx -NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_2) AS worker_column_2 FROM (SELECT table_1.key AS worker_column_1, table_1.value AS worker_column_2 FROM locally_execute_intermediate_results.table_1_1580000 table_1) worker_subquery GROUP BY worker_column_1 -NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_2) AS worker_column_2 FROM (SELECT table_1.key AS worker_column_1, table_1.value AS worker_column_2 FROM locally_execute_intermediate_results.table_1_1580002 table_1) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_1) AS worker_column_2 FROM (SELECT table_1.value AS worker_column_1 FROM locally_execute_intermediate_results.table_1_1580000 table_1) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_1) AS worker_column_2 FROM (SELECT table_1.value AS worker_column_1 FROM locally_execute_intermediate_results.table_1_1580002 table_1) worker_subquery GROUP BY worker_column_1 DEBUG: Subplan XXX_4 will be sent to localhost:xxxxx -NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_2) AS worker_column_2 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580004 table_2) worker_subquery GROUP BY worker_column_1 -NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_2) AS worker_column_2 FROM (SELECT table_2.key AS worker_column_1, table_2.value AS worker_column_2 FROM locally_execute_intermediate_results.table_2_1580006 table_2) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_1) AS worker_column_2 FROM (SELECT table_2.value AS worker_column_1 FROM locally_execute_intermediate_results.table_2_1580004 table_2) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT worker_column_1 AS key, max(worker_column_1) AS worker_column_2 FROM (SELECT table_2.value AS worker_column_1 FROM locally_execute_intermediate_results.table_2_1580006 table_2) worker_subquery GROUP BY worker_column_1 +NOTICE: executing the command locally: SELECT foo.key, bar.key FROM (SELECT intermediate_result.key FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(key text)) foo, (SELECT intermediate_result.key FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(key text)) bar WHERE (foo.key OPERATOR(pg_catalog.<>) bar.key) key | key --------------------------------------------------------------------- (0 rows) diff --git a/src/test/regress/expected/multi_explain.out b/src/test/regress/expected/multi_explain.out index c77b91d50..897deaf4c 100644 --- a/src/test/regress/expected/multi_explain.out +++ b/src/test/regress/expected/multi_explain.out @@ -2286,15 +2286,14 @@ Custom Scan (Citus Adaptive) (actual rows=1 loops=1) EXPLAIN :default_analyze_flags SELECT count(distinct a) FROM (SELECT GREATEST(random(), 2) r, a FROM dist_table) t NATURAL JOIN ref_table; Aggregate (actual rows=1 loops=1) - -> Custom Scan (Citus Adaptive) (actual rows=10 loops=1) + -> Custom Scan (Citus Adaptive) (actual rows=4 loops=1) Task Count: 4 - Tuple data received from nodes: 11 bytes + Tuple data received from nodes: 4 bytes Tasks Shown: One of 4 -> Task - Tuple data received from node: 5 bytes + Tuple data received from node: 1 bytes Node: host=localhost port=xxxxx dbname=regression - -> Group (actual rows=4 loops=1) - Group Key: t.a + -> Aggregate (actual rows=1 loops=1) -> Merge Join (actual rows=4 loops=1) Merge Cond: (t.a = ref_table.a) -> Sort (actual rows=4 loops=1) @@ -2310,7 +2309,7 @@ EXPLAIN :default_analyze_flags SELECT count(distinct a) FROM dist_table WHERE EXISTS(SELECT random() < 2 FROM dist_table NATURAL JOIN ref_table); Aggregate (actual rows=1 loops=1) - -> Custom Scan (Citus Adaptive) (actual rows=10 loops=1) + -> Custom Scan (Citus Adaptive) (actual rows=4 loops=1) -> Distributed Subplan XXX_1 Intermediate Data Size: 70 bytes Result destination: Send to 2 nodes @@ -2332,13 +2331,12 @@ Aggregate (actual rows=1 loops=1) Sort Method: quicksort Memory: 25kB -> Seq Scan on ref_table_570021 ref_table (actual rows=10 loops=1) Task Count: 4 - Tuple data received from nodes: 11 bytes + Tuple data received from nodes: 4 bytes Tasks Shown: One of 4 -> Task - Tuple data received from node: 5 bytes + Tuple data received from node: 1 bytes Node: host=localhost port=xxxxx dbname=regression - -> HashAggregate (actual rows=4 loops=1) - Group Key: dist_table.a + -> Aggregate (actual rows=1 loops=1) InitPlan 1 (returns $0) -> Function Scan on read_intermediate_result intermediate_result (actual rows=1 loops=1) -> Result (actual rows=4 loops=1) diff --git a/src/test/regress/expected/multi_insert_select_non_pushable_queries.out b/src/test/regress/expected/multi_insert_select_non_pushable_queries.out index d6c8cc02f..788aeb750 100644 --- a/src/test/regress/expected/multi_insert_select_non_pushable_queries.out +++ b/src/test/regress/expected/multi_insert_select_non_pushable_queries.out @@ -679,17 +679,15 @@ SELECT user_id, event_type FROM events_table WHERE user_id NOT IN (SELECT user_id from events_table WHERE event_type > 500 and event_type < 505) GROUP BY user_id, event_type; $Q$); - coordinator_plan + coordinator_plan --------------------------------------------------------------------- Custom Scan (Citus INSERT ... SELECT) - INSERT/SELECT method: pull to coordinator - -> HashAggregate - Group Key: remote_scan.user_id, remote_scan.value_1_agg - -> Custom Scan (Citus Adaptive) - -> Distributed Subplan XXX_1 - -> Custom Scan (Citus Adaptive) - Task Count: 4 -(8 rows) + INSERT/SELECT method: repartition + -> Custom Scan (Citus Adaptive) + -> Distributed Subplan XXX_1 + -> Custom Scan (Citus Adaptive) + Task Count: 4 +(6 rows) -- not pushable due to not selecting the partition key. Use pull to coordinator. SELECT coordinator_plan($Q$ @@ -699,17 +697,15 @@ SELECT user_id, event_type FROM events_table WHERE user_id IN (SELECT value_2 from events_table WHERE event_type > 500 and event_type < 505) GROUP BY user_id, event_type; $Q$); - coordinator_plan + coordinator_plan --------------------------------------------------------------------- Custom Scan (Citus INSERT ... SELECT) - INSERT/SELECT method: pull to coordinator - -> HashAggregate - Group Key: remote_scan.user_id, remote_scan.value_1_agg - -> Custom Scan (Citus Adaptive) - -> Distributed Subplan XXX_1 - -> Custom Scan (Citus Adaptive) - Task Count: 4 -(8 rows) + INSERT/SELECT method: repartition + -> Custom Scan (Citus Adaptive) + -> Distributed Subplan XXX_1 + -> Custom Scan (Citus Adaptive) + Task Count: 4 +(6 rows) -- not pushable due to not comparing user id from the events table. -- Use pull to coordinator. @@ -720,17 +716,15 @@ SELECT user_id, event_type FROM events_table WHERE event_type IN (SELECT user_id from events_table WHERE event_type > 500 and event_type < 505) GROUP BY user_id, event_type; $Q$); - coordinator_plan + coordinator_plan --------------------------------------------------------------------- Custom Scan (Citus INSERT ... SELECT) - INSERT/SELECT method: pull to coordinator - -> HashAggregate - Group Key: remote_scan.user_id, remote_scan.value_1_agg - -> Custom Scan (Citus Adaptive) - -> Distributed Subplan XXX_1 - -> Custom Scan (Citus Adaptive) - Task Count: 4 -(8 rows) + INSERT/SELECT method: repartition + -> Custom Scan (Citus Adaptive) + -> Distributed Subplan XXX_1 + -> Custom Scan (Citus Adaptive) + Task Count: 4 +(6 rows) --------------------------------------------------------------------- --------------------------------------------------------------------- diff --git a/src/test/regress/expected/multi_limit_clause.out b/src/test/regress/expected/multi_limit_clause.out index b3e0367a3..21432fca1 100644 --- a/src/test/regress/expected/multi_limit_clause.out +++ b/src/test/regress/expected/multi_limit_clause.out @@ -482,6 +482,7 @@ SELECT GROUP BY l_orderkey ORDER BY l_orderkey , 3, 2 LIMIT 5; +DEBUG: push down of limit count: 5 l_orderkey | count | rank --------------------------------------------------------------------- 1 | 6 | 1 diff --git a/src/test/regress/expected/multi_reference_table.out b/src/test/regress/expected/multi_reference_table.out index fcc096c7a..69dbe4d64 100644 --- a/src/test/regress/expected/multi_reference_table.out +++ b/src/test/regress/expected/multi_reference_table.out @@ -1436,7 +1436,7 @@ SELECT master_append_table_to_shard(:a_shard_id, 'append_reference_tmp_table', ERROR: cannot append to shardId 1250019 DETAIL: We currently don't support appending to shards in hash-partitioned, reference and citus local tables SELECT master_get_table_ddl_events('reference_schema.reference_table_ddl'); - master_get_table_ddl_events + master_get_table_ddl_events --------------------------------------------------------------------- CREATE TABLE reference_schema.reference_table_ddl (value_2 double precision DEFAULT 25.0, value_3 text NOT NULL, value_4 timestamp without time zone, value_5 double precision) ALTER TABLE reference_schema.reference_table_ddl OWNER TO postgres @@ -1611,34 +1611,31 @@ ROLLBACK; EXPLAIN (COSTS OFF) SELECT value_1, count(*) FROM colocated_table_test GROUP BY value_1 HAVING (SELECT rt.value_2 FROM reference_table_test rt where rt.value_2 = 2) > 0 ORDER BY 1; - QUERY PLAN + QUERY PLAN --------------------------------------------------------------------- Sort Sort Key: remote_scan.value_1 - InitPlan 1 (returns $0) - -> Function Scan on read_intermediate_result intermediate_result - -> HashAggregate - Group Key: remote_scan.value_1 - -> Result - One-Time Filter: ($0 > '0'::double precision) + -> Custom Scan (Citus Adaptive) + -> Distributed Subplan XXX_1 -> Custom Scan (Citus Adaptive) - Filter: ($0 > '0'::double precision) - -> Distributed Subplan XXX_1 - -> Custom Scan (Citus Adaptive) - Task Count: 1 - Tasks Shown: All - -> Task - Node: host=localhost port=xxxxx dbname=regression - -> Seq Scan on reference_table_test_1250000 rt - Filter: (value_2 = '2'::double precision) - Task Count: 6 - Tasks Shown: One of 6 + Task Count: 1 + Tasks Shown: All -> Task Node: host=localhost port=xxxxx dbname=regression - -> HashAggregate - Group Key: colocated_table_test.value_1 - -> Seq Scan on colocated_table_test_1250005 colocated_table_test -(25 rows) + -> Seq Scan on reference_table_test_1250000 rt + Filter: (value_2 = '2'::double precision) + Task Count: 6 + Tasks Shown: One of 6 + -> Task + Node: host=localhost port=xxxxx dbname=regression + -> HashAggregate + Group Key: colocated_table_test.value_1 + InitPlan 1 (returns $0) + -> Function Scan on read_intermediate_result intermediate_result + -> Result + One-Time Filter: ($0 > '0'::double precision) + -> Seq Scan on colocated_table_test_1250005 colocated_table_test +(22 rows) WITH a as (SELECT rt.value_2 FROM reference_table_test rt where rt.value_2 = 2) SELECT ct.value_1, count(*) FROM colocated_table_test ct join a on ct.value_1 = a.value_2 diff --git a/src/test/regress/expected/multi_subquery.out b/src/test/regress/expected/multi_subquery.out index 1af2b73b0..2261e0f02 100644 --- a/src/test/regress/expected/multi_subquery.out +++ b/src/test/regress/expected/multi_subquery.out @@ -976,97 +976,91 @@ SELECT create_reference_table('keyvalref'); EXPLAIN (COSTS OFF) SELECT count(*) FROM keyval1 GROUP BY key HAVING sum(value) > (SELECT sum(value) FROM keyvalref GROUP BY key); - QUERY PLAN + QUERY PLAN --------------------------------------------------------------------- - HashAggregate - Group Key: remote_scan.worker_column_2 - Filter: ((pg_catalog.sum(remote_scan.worker_column_3))::bigint > $0) - InitPlan 1 (returns $0) - -> Function Scan on read_intermediate_result intermediate_result - -> Custom Scan (Citus Adaptive) - -> Distributed Subplan XXX_1 - -> Custom Scan (Citus Adaptive) - Task Count: 1 - Tasks Shown: All - -> Task - Node: host=localhost port=xxxxx dbname=regression - -> HashAggregate - Group Key: key - -> Seq Scan on keyvalref_xxxxxxx keyvalref - Task Count: 4 - Tasks Shown: One of 4 - -> Task - Node: host=localhost port=xxxxx dbname=regression - -> HashAggregate - Group Key: keyval1.key - -> Seq Scan on keyval1_xxxxxxx keyval1 -(22 rows) + Custom Scan (Citus Adaptive) + -> Distributed Subplan XXX_1 + -> Custom Scan (Citus Adaptive) + Task Count: 1 + Tasks Shown: All + -> Task + Node: host=localhost port=xxxxx dbname=regression + -> HashAggregate + Group Key: key + -> Seq Scan on keyvalref_xxxxxxx keyvalref + Task Count: 4 + Tasks Shown: One of 4 + -> Task + Node: host=localhost port=xxxxx dbname=regression + -> HashAggregate + Group Key: keyval1.key + Filter: (sum(keyval1.value) > $0) + InitPlan 1 (returns $0) + -> Function Scan on read_intermediate_result intermediate_result + -> Seq Scan on keyval1_xxxxxxx keyval1 +(20 rows) -- For some reason 'ORDER BY 1 DESC LIMIT 1' triggers recursive planning EXPLAIN (COSTS OFF) SELECT count(*) FROM keyval1 GROUP BY key HAVING sum(value) > (SELECT sum(value) FROM keyvalref GROUP BY key ORDER BY 1 DESC LIMIT 1); - QUERY PLAN + QUERY PLAN --------------------------------------------------------------------- - HashAggregate - Group Key: remote_scan.worker_column_2 - Filter: ((pg_catalog.sum(remote_scan.worker_column_3))::bigint > $0) - InitPlan 1 (returns $0) - -> Function Scan on read_intermediate_result intermediate_result - -> Custom Scan (Citus Adaptive) - -> Distributed Subplan XXX_1 - -> Custom Scan (Citus Adaptive) - Task Count: 1 - Tasks Shown: All - -> Task - Node: host=localhost port=xxxxx dbname=regression - -> Limit - -> Sort - Sort Key: (sum(value)) DESC - -> HashAggregate - Group Key: key - -> Seq Scan on keyvalref_xxxxxxx keyvalref - Task Count: 4 - Tasks Shown: One of 4 - -> Task - Node: host=localhost port=xxxxx dbname=regression - -> HashAggregate - Group Key: keyval1.key - -> Seq Scan on keyval1_xxxxxxx keyval1 -(25 rows) + Custom Scan (Citus Adaptive) + -> Distributed Subplan XXX_1 + -> Custom Scan (Citus Adaptive) + Task Count: 1 + Tasks Shown: All + -> Task + Node: host=localhost port=xxxxx dbname=regression + -> Limit + -> Sort + Sort Key: (sum(value)) DESC + -> HashAggregate + Group Key: key + -> Seq Scan on keyvalref_xxxxxxx keyvalref + Task Count: 4 + Tasks Shown: One of 4 + -> Task + Node: host=localhost port=xxxxx dbname=regression + -> HashAggregate + Group Key: keyval1.key + Filter: (sum(keyval1.value) > $0) + InitPlan 1 (returns $0) + -> Function Scan on read_intermediate_result intermediate_result + -> Seq Scan on keyval1_xxxxxxx keyval1 +(23 rows) EXPLAIN (COSTS OFF) SELECT count(*) FROM keyval1 GROUP BY key HAVING sum(value) > (SELECT sum(value) FROM keyval2 GROUP BY key ORDER BY 1 DESC LIMIT 1); - QUERY PLAN + QUERY PLAN --------------------------------------------------------------------- - HashAggregate - Group Key: remote_scan.worker_column_2 - Filter: ((pg_catalog.sum(remote_scan.worker_column_3))::bigint > $0) - InitPlan 1 (returns $0) - -> Function Scan on read_intermediate_result intermediate_result - -> Custom Scan (Citus Adaptive) - -> Distributed Subplan XXX_1 - -> Limit - -> Sort - Sort Key: remote_scan.sum DESC - -> Custom Scan (Citus Adaptive) - Task Count: 4 - Tasks Shown: One of 4 - -> Task - Node: host=localhost port=xxxxx dbname=regression - -> Limit - -> Sort - Sort Key: (sum(value)) DESC - -> HashAggregate - Group Key: key - -> Seq Scan on keyval2_xxxxxxx keyval2 - Task Count: 4 - Tasks Shown: One of 4 - -> Task - Node: host=localhost port=xxxxx dbname=regression - -> HashAggregate - Group Key: keyval1.key - -> Seq Scan on keyval1_xxxxxxx keyval1 -(28 rows) + Custom Scan (Citus Adaptive) + -> Distributed Subplan XXX_1 + -> Limit + -> Sort + Sort Key: remote_scan.sum DESC + -> Custom Scan (Citus Adaptive) + Task Count: 4 + Tasks Shown: One of 4 + -> Task + Node: host=localhost port=xxxxx dbname=regression + -> Limit + -> Sort + Sort Key: (sum(value)) DESC + -> HashAggregate + Group Key: key + -> Seq Scan on keyval2_xxxxxxx keyval2 + Task Count: 4 + Tasks Shown: One of 4 + -> Task + Node: host=localhost port=xxxxx dbname=regression + -> HashAggregate + Group Key: keyval1.key + Filter: (sum(keyval1.value) > $0) + InitPlan 1 (returns $0) + -> Function Scan on read_intermediate_result intermediate_result + -> Seq Scan on keyval1_xxxxxxx keyval1 +(26 rows) EXPLAIN (COSTS OFF) SELECT count(*) FROM keyval1 k1 WHERE k1.key = 2 GROUP BY key HAVING sum(value) > (SELECT sum(value) FROM keyval2 k2 WHERE k2.key = 2 GROUP BY key ORDER BY 1 DESC LIMIT 1); diff --git a/src/test/regress/expected/multi_subquery_complex_queries.out b/src/test/regress/expected/multi_subquery_complex_queries.out index dc4e62616..5432f27c4 100644 --- a/src/test/regress/expected/multi_subquery_complex_queries.out +++ b/src/test/regress/expected/multi_subquery_complex_queries.out @@ -1064,6 +1064,7 @@ GROUP BY LIMIT 10; DEBUG: generating subplan XXX_1 for subquery SELECT DISTINCT user_id FROM public.events_table events WHERE (event_type OPERATOR(pg_catalog.=) ANY (ARRAY[0, 6])) GROUP BY user_id DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT user_id, count(*) AS cnt FROM (SELECT first_query.user_id, random() AS random FROM ((SELECT t.user_id, t."time", unnest(t.collected_events) AS event_types FROM (SELECT t1.user_id, min(t1."time") AS "time", array_agg(t1.event ORDER BY t1."time", t1.event DESC) AS collected_events FROM (SELECT events_subquery_1.user_id, events_subquery_1."time", events_subquery_1.event FROM (SELECT events.user_id, events."time", 0 AS event FROM public.events_table events WHERE (events.event_type OPERATOR(pg_catalog.=) ANY (ARRAY[1, 2]))) events_subquery_1 UNION ALL SELECT events_subquery_2.user_id, events_subquery_2."time", events_subquery_2.event FROM (SELECT events.user_id, events."time", 1 AS event FROM public.events_table events WHERE (events.event_type OPERATOR(pg_catalog.=) ANY (ARRAY[3, 4]))) events_subquery_2 UNION ALL SELECT events_subquery_3.user_id, events_subquery_3."time", events_subquery_3.event FROM (SELECT events.user_id, events."time", 2 AS event FROM public.events_table events WHERE (events.event_type OPERATOR(pg_catalog.=) ANY (ARRAY[5, 6]))) events_subquery_3 UNION ALL SELECT events_subquery_4.user_id, events_subquery_4."time", events_subquery_4.event FROM (SELECT events.user_id, events."time", 3 AS event FROM public.events_table events WHERE (events.event_type OPERATOR(pg_catalog.=) ANY (ARRAY[1, 6]))) events_subquery_4) t1 GROUP BY t1.user_id) t) first_query JOIN (SELECT t.user_id FROM ((SELECT users.user_id FROM public.users_table users WHERE ((users.value_1 OPERATOR(pg_catalog.>) 0) AND (users.value_1 OPERATOR(pg_catalog.<) 4))) t LEFT JOIN (SELECT intermediate_result.user_id FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(user_id integer)) t2 ON ((t2.user_id OPERATOR(pg_catalog.>) t.user_id))) WHERE (t2.user_id IS NULL)) second_query ON ((first_query.user_id OPERATOR(pg_catalog.=) second_query.user_id)))) final_query GROUP BY user_id ORDER BY (count(*)) DESC, user_id DESC LIMIT 10 +DEBUG: push down of limit count: 10 user_id | cnt --------------------------------------------------------------------- 5 | 324 diff --git a/src/test/regress/expected/multi_view.out b/src/test/regress/expected/multi_view.out index 926bc5fcf..798108ce4 100644 --- a/src/test/regress/expected/multi_view.out +++ b/src/test/regress/expected/multi_view.out @@ -762,30 +762,28 @@ RESET citus.subquery_pushdown; VACUUM ANALYZE users_table; -- explain tests EXPLAIN (COSTS FALSE) SELECT user_id FROM recent_selected_users GROUP BY 1 ORDER BY 1; - QUERY PLAN + QUERY PLAN --------------------------------------------------------------------- Sort Sort Key: remote_scan.user_id - -> HashAggregate - Group Key: remote_scan.user_id - -> Custom Scan (Citus Adaptive) - Task Count: 4 - Tasks Shown: One of 4 - -> Task - Node: host=localhost port=xxxxx dbname=regression - -> HashAggregate - Group Key: users_table.user_id - -> Nested Loop - Join Filter: (users_table.user_id = users_table_1.user_id) - -> Sort - Sort Key: (max(users_table_1."time")) DESC - -> HashAggregate - Group Key: users_table_1.user_id - Filter: (max(users_table_1."time") > '2017-11-23 16:20:33.264457'::timestamp without time zone) - -> Seq Scan on users_table_1400256 users_table_1 - -> Seq Scan on users_table_1400256 users_table - Filter: ((value_1 >= 1) AND (value_1 < 3)) -(21 rows) + -> Custom Scan (Citus Adaptive) + Task Count: 4 + Tasks Shown: One of 4 + -> Task + Node: host=localhost port=xxxxx dbname=regression + -> HashAggregate + Group Key: users_table.user_id + -> Nested Loop + Join Filter: (users_table.user_id = users_table_1.user_id) + -> Sort + Sort Key: (max(users_table_1."time")) DESC + -> HashAggregate + Group Key: users_table_1.user_id + Filter: (max(users_table_1."time") > '2017-11-23 16:20:33.264457'::timestamp without time zone) + -> Seq Scan on users_table_1400256 users_table_1 + -> Seq Scan on users_table_1400256 users_table + Filter: ((value_1 >= 1) AND (value_1 < 3)) +(19 rows) EXPLAIN (COSTS FALSE) SELECT * FROM ( diff --git a/src/test/regress/expected/subquery_complex_target_list.out b/src/test/regress/expected/subquery_complex_target_list.out index e8296f588..5d44ae5c5 100644 --- a/src/test/regress/expected/subquery_complex_target_list.out +++ b/src/test/regress/expected/subquery_complex_target_list.out @@ -551,19 +551,15 @@ GROUP BY a.key, a.value ||'_append' HAVING length(a.key) + length(a.value) < length(a.value || '_append') ORDER BY 1 $$); - coordinator_plan + coordinator_plan --------------------------------------------------------------------- Sort Output: xxxxxx Sort Key: remote_scan.k1 - -> HashAggregate + -> Custom Scan (Citus Adaptive) Output: xxxxxx - Group Key: remote_scan.k1, remote_scan.va1 - Filter: ((length(remote_scan.worker_column_11) + length(any_value(remote_scan.worker_column_12))) < length((any_value(remote_scan.worker_column_13) || '_append'::text))) - -> Custom Scan (Citus Adaptive) - Output: xxxxxx - Task Count: 4 -(10 rows) + Task Count: 4 +(6 rows) SELECT a FROM items a ORDER BY key; a diff --git a/src/test/regress/expected/subquery_in_targetlist.out b/src/test/regress/expected/subquery_in_targetlist.out index f654af850..395b4dc96 100644 --- a/src/test/regress/expected/subquery_in_targetlist.out +++ b/src/test/regress/expected/subquery_in_targetlist.out @@ -184,6 +184,18 @@ FROM events_table e; 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; + ?column? +--------------------------------------------------------------------- + 19 + 53 + 65 +(3 rows) + +-- correlated subquery outside of a non-pushdownable aggregate +SELECT sum(e.user_id) + (SELECT max(value_3) FROM users_reference_table WHERE value_2 = e.value_2 GROUP BY user_id) +FROM events_table e +GROUP BY e.value_2 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 diff --git a/src/test/regress/expected/window_functions.out b/src/test/regress/expected/window_functions.out index d2eba4811..ff36aa993 100644 --- a/src/test/regress/expected/window_functions.out +++ b/src/test/regress/expected/window_functions.out @@ -1368,7 +1368,7 @@ FROM GROUP BY user_id, value_2 ORDER BY user_id, avg(value_1) DESC LIMIT 5; - QUERY PLAN + QUERY PLAN --------------------------------------------------------------------- Limit -> Sort @@ -1378,13 +1378,17 @@ LIMIT 5; Tasks Shown: One of 4 -> Task Node: host=localhost port=xxxxx dbname=regression - -> WindowAgg - -> Sort - Sort Key: users_table.user_id, (('1'::numeric / ('1'::numeric + avg(users_table.value_1)))) - -> HashAggregate - Group Key: users_table.user_id, users_table.value_2 - -> Seq Scan on users_table_1400256 users_table -(14 rows) + -> Limit + -> Incremental Sort + Sort Key: users_table.user_id, (avg(users_table.value_1)) DESC + Presorted Key: users_table.user_id + -> WindowAgg + -> Sort + Sort Key: users_table.user_id, (('1'::numeric / ('1'::numeric + avg(users_table.value_1)))) + -> HashAggregate + Group Key: users_table.user_id, users_table.value_2 + -> Seq Scan on users_table_1400256 users_table +(18 rows) EXPLAIN (COSTS FALSE) SELECT @@ -1396,7 +1400,7 @@ FROM GROUP BY user_id, value_2 ORDER BY user_id, avg(value_1) DESC LIMIT 5; - QUERY PLAN + QUERY PLAN --------------------------------------------------------------------- Limit -> Sort @@ -1406,13 +1410,17 @@ LIMIT 5; Tasks Shown: One of 4 -> Task Node: host=localhost port=xxxxx dbname=regression - -> WindowAgg - -> Sort - Sort Key: users_table.user_id, (('1'::numeric / ('1'::numeric + avg(users_table.value_1)))) - -> HashAggregate - Group Key: users_table.user_id, users_table.value_2 - -> Seq Scan on users_table_1400256 users_table -(14 rows) + -> Limit + -> Incremental Sort + Sort Key: users_table.user_id, (avg(users_table.value_1)) DESC + Presorted Key: users_table.user_id + -> WindowAgg + -> Sort + Sort Key: users_table.user_id, (('1'::numeric / ('1'::numeric + avg(users_table.value_1)))) + -> HashAggregate + Group Key: users_table.user_id, users_table.value_2 + -> Seq Scan on users_table_1400256 users_table +(18 rows) EXPLAIN (COSTS FALSE) SELECT @@ -1423,6 +1431,38 @@ FROM users_table GROUP BY user_id, value_2 ORDER BY user_id, avg(value_1) DESC +LIMIT 5; + QUERY PLAN +--------------------------------------------------------------------- + Limit + -> Sort + Sort Key: remote_scan.user_id, remote_scan.avg DESC + -> Custom Scan (Citus Adaptive) + Task Count: 4 + Tasks Shown: One of 4 + -> Task + Node: host=localhost port=xxxxx dbname=regression + -> Limit + -> Incremental Sort + Sort Key: users_table.user_id, (avg(users_table.value_1)) DESC + Presorted Key: users_table.user_id + -> WindowAgg + -> Sort + Sort Key: users_table.user_id, ((1 / (1 + sum(users_table.value_2)))) + -> HashAggregate + Group Key: users_table.user_id, users_table.value_2 + -> Seq Scan on users_table_1400256 users_table +(18 rows) + +EXPLAIN (COSTS FALSE) +SELECT + user_id, + avg(value_1), + RANK() OVER (partition by user_id order by sum(value_2)) +FROM + users_table +GROUP BY user_id, value_2 +ORDER BY user_id, avg(value_1) DESC LIMIT 5; QUERY PLAN --------------------------------------------------------------------- @@ -1434,41 +1474,17 @@ LIMIT 5; Tasks Shown: One of 4 -> Task Node: host=localhost port=xxxxx dbname=regression - -> WindowAgg - -> Sort - Sort Key: users_table.user_id, ((1 / (1 + sum(users_table.value_2)))) - -> HashAggregate - Group Key: users_table.user_id, users_table.value_2 - -> Seq Scan on users_table_1400256 users_table -(14 rows) - -EXPLAIN (COSTS FALSE) -SELECT - user_id, - avg(value_1), - RANK() OVER (partition by user_id order by sum(value_2)) -FROM - users_table -GROUP BY user_id, value_2 -ORDER BY user_id, avg(value_1) DESC -LIMIT 5; - QUERY PLAN ---------------------------------------------------------------------- - Limit - -> Sort - Sort Key: remote_scan.user_id, remote_scan.avg DESC - -> Custom Scan (Citus Adaptive) - Task Count: 4 - Tasks Shown: One of 4 - -> Task - Node: host=localhost port=xxxxx dbname=regression - -> WindowAgg - -> Sort - Sort Key: users_table.user_id, (sum(users_table.value_2)) - -> HashAggregate - Group Key: users_table.user_id, users_table.value_2 - -> Seq Scan on users_table_1400256 users_table -(14 rows) + -> Limit + -> Incremental Sort + Sort Key: users_table.user_id, (avg(users_table.value_1)) DESC + Presorted Key: users_table.user_id + -> WindowAgg + -> Sort + Sort Key: users_table.user_id, (sum(users_table.value_2)) + -> HashAggregate + Group Key: users_table.user_id, users_table.value_2 + -> Seq Scan on users_table_1400256 users_table +(18 rows) -- Grouping can be pushed down with aggregates even when window function can't EXPLAIN (COSTS FALSE) @@ -1530,7 +1546,7 @@ HAVING sum(value_2) > 0 ORDER BY commits DESC LIMIT 10; - QUERY PLAN + QUERY PLAN --------------------------------------------------------------------- Limit -> Sort @@ -1540,14 +1556,17 @@ LIMIT 10; Tasks Shown: One of 4 -> Task Node: host=localhost port=xxxxx dbname=regression - -> WindowAgg + -> Limit -> Sort - Sort Key: daily_uniques.user_id, (sum(daily_uniques.value_2)) DESC - -> HashAggregate - Group Key: daily_uniques.user_id - Filter: (sum(daily_uniques.value_2) > '0'::double precision) - -> Seq Scan on daily_uniques_xxxxxxx daily_uniques -(15 rows) + Sort Key: (sum(daily_uniques.value_2)) DESC + -> WindowAgg + -> Sort + Sort Key: daily_uniques.user_id, (sum(daily_uniques.value_2)) DESC + -> HashAggregate + Group Key: daily_uniques.user_id + Filter: (sum(daily_uniques.value_2) > '0'::double precision) + -> Seq Scan on daily_uniques_xxxxxxx daily_uniques +(18 rows) DROP TABLE daily_uniques; -- Partition by reference table column joined to distribution column diff --git a/src/test/regress/expected/window_functions_0.out b/src/test/regress/expected/window_functions_0.out new file mode 100644 index 000000000..51d453427 --- /dev/null +++ b/src/test/regress/expected/window_functions_0.out @@ -0,0 +1,1591 @@ +-- =================================================================== +-- test top level window functions that are pushdownable +-- =================================================================== +-- a very simple window function with an aggregate and a window function +-- distribution column is on the partition by clause +SELECT + user_id, COUNT(*) OVER (PARTITION BY user_id), + rank() OVER (PARTITION BY user_id) +FROM + users_table +ORDER BY + 1 DESC, 2 DESC, 3 DESC +LIMIT 5; + user_id | count | rank +--------------------------------------------------------------------- + 6 | 10 | 1 + 6 | 10 | 1 + 6 | 10 | 1 + 6 | 10 | 1 + 6 | 10 | 1 +(5 rows) + +-- a more complicated window clause, including an aggregate +-- in both the window clause and the target entry +SELECT + user_id, avg(avg(value_3)) OVER (PARTITION BY user_id, MIN(value_2)) +FROM + users_table +GROUP BY + 1 +ORDER BY + 2 DESC NULLS LAST, 1 DESC; + user_id | avg +--------------------------------------------------------------------- + 2 | 3 + 4 | 2.82608695652174 + 3 | 2.70588235294118 + 6 | 2.6 + 1 | 2.57142857142857 + 5 | 2.46153846153846 +(6 rows) + +-- window clause operates on the results of a subquery +SELECT + user_id, max(value_1) OVER (PARTITION BY user_id, MIN(value_2)) +FROM ( + SELECT + DISTINCT us.user_id, us.value_2, value_1, random() as r1 + FROM + users_table as us, events_table + WHERE + us.user_id = events_table.user_id AND event_type IN (1,2) + ORDER BY + user_id, value_2 + ) s +GROUP BY + 1, value_1 +ORDER BY + 2 DESC, 1; + user_id | max +--------------------------------------------------------------------- + 1 | 5 + 3 | 5 + 3 | 5 + 4 | 5 + 5 | 5 + 5 | 5 + 6 | 5 + 6 | 5 + 1 | 4 + 2 | 4 + 3 | 4 + 3 | 4 + 3 | 4 + 4 | 4 + 4 | 4 + 5 | 4 + 5 | 4 + 1 | 3 + 2 | 3 + 2 | 3 + 2 | 3 + 6 | 3 + 2 | 2 + 4 | 2 + 4 | 2 + 4 | 2 + 6 | 2 + 1 | 1 + 3 | 1 + 5 | 1 + 6 | 1 + 5 | 0 +(32 rows) + +-- window function operates on the results of +-- a join +SELECT + us.user_id, + SUM(us.value_1) OVER (PARTITION BY us.user_id) +FROM + users_table us + JOIN + events_table ev + ON (us.user_id = ev.user_id) +GROUP BY + 1, + value_1 +ORDER BY + 1, + 2 +LIMIT 5; + user_id | sum +--------------------------------------------------------------------- + 1 | 13 + 1 | 13 + 1 | 13 + 1 | 13 + 2 | 10 +(5 rows) + +-- the same query, but this time join with an alias +SELECT + user_id, value_1, SUM(j.value_1) OVER (PARTITION BY j.user_id) +FROM + (users_table us + JOIN + events_table ev + USING (user_id ) + ) j +GROUP BY + user_id, + value_1 +ORDER BY + 3 DESC, 2 DESC, 1 DESC +LIMIT 5; + user_id | value_1 | sum +--------------------------------------------------------------------- + 5 | 5 | 15 + 4 | 5 | 15 + 3 | 5 | 15 + 5 | 4 | 15 + 4 | 4 | 15 +(5 rows) + +-- querying views that have window functions should be ok +CREATE VIEW window_view AS +SELECT + DISTINCT user_id, rank() OVER (PARTITION BY user_id ORDER BY value_1) +FROM + users_table +GROUP BY + user_id, value_1 +HAVING count(*) > 1; +-- Window function in View works +SELECT * +FROM + window_view +ORDER BY + 2 DESC, 1 +LIMIT 10; + user_id | rank +--------------------------------------------------------------------- + 5 | 6 + 2 | 5 + 4 | 5 + 5 | 5 + 2 | 4 + 3 | 4 + 4 | 4 + 5 | 4 + 6 | 4 + 2 | 3 +(10 rows) + +-- the other way around also should work fine +-- query a view using window functions +CREATE VIEW users_view AS SELECT * FROM users_table; +SELECT + DISTINCT user_id, rank() OVER (PARTITION BY user_id ORDER BY value_1) +FROM + users_view +GROUP BY + user_id, value_1 +HAVING count(*) > 4 +ORDER BY + 2 DESC, 1; + user_id | rank +--------------------------------------------------------------------- + 4 | 2 + 5 | 2 + 2 | 1 + 3 | 1 + 4 | 1 + 5 | 1 +(6 rows) + +DROP VIEW users_view, window_view; +-- window functions along with subquery in HAVING +SELECT + user_id, count (user_id) OVER (PARTITION BY user_id) +FROM + users_table +GROUP BY + user_id HAVING avg(value_1) < (SELECT min(k_no) FROM users_ref_test_table) +ORDER BY 1 DESC,2 DESC +LIMIT 1; + user_id | count +--------------------------------------------------------------------- + 6 | 1 +(1 row) + +-- window function uses columns from two different tables +SELECT + DISTINCT ON (events_table.user_id, rnk) events_table.user_id, rank() OVER my_win AS rnk +FROM + events_table, users_table +WHERE + users_table.user_id = events_table.user_id +WINDOW + my_win AS (PARTITION BY events_table.user_id, users_table.value_1 ORDER BY events_table.time DESC) +ORDER BY + rnk DESC, 1 DESC +LIMIT 10; + user_id | rnk +--------------------------------------------------------------------- + 3 | 121 + 5 | 118 + 2 | 116 + 3 | 115 + 4 | 113 + 2 | 111 + 5 | 109 + 3 | 109 + 4 | 106 + 2 | 106 +(10 rows) + +-- the same query with reference table column is also on the partition by clause +SELECT + DISTINCT ON (events_table.user_id, rnk) events_table.user_id, rank() OVER my_win AS rnk +FROM + events_table, users_ref_test_table uref +WHERE + uref.id = events_table.user_id +WINDOW + my_win AS (PARTITION BY events_table.user_id, uref.k_no ORDER BY events_table.time DESC) +ORDER BY + rnk DESC, 1 DESC +LIMIT 10; + user_id | rnk +--------------------------------------------------------------------- + 2 | 24 + 2 | 23 + 2 | 22 + 3 | 21 + 2 | 21 + 3 | 20 + 2 | 20 + 3 | 19 + 2 | 19 + 3 | 18 +(10 rows) + +-- similar query with no distribution column on the partition by clause +SELECT + DISTINCT ON (events_table.user_id, rnk) events_table.user_id, rank() OVER my_win AS rnk +FROM + events_table, users_ref_test_table uref +WHERE + uref.id = events_table.user_id +WINDOW + my_win AS (PARTITION BY events_table.value_2, uref.k_no ORDER BY events_table.time DESC) +ORDER BY + rnk DESC, 1 DESC +LIMIT 10; + user_id | rnk +--------------------------------------------------------------------- + 3 | 7 + 2 | 7 + 3 | 6 + 2 | 6 + 4 | 5 + 3 | 5 + 2 | 5 + 1 | 5 + 6 | 4 + 5 | 4 +(10 rows) + +-- ORDER BY in the window function is an aggregate +SELECT + user_id, rank() OVER my_win as rnk, avg(value_2) as avg_val_2 +FROM + events_table +GROUP BY + user_id, date_trunc('day', time) +WINDOW + my_win AS (PARTITION BY user_id ORDER BY avg(event_type) DESC) +ORDER BY + 3 DESC, 2 DESC, 1 DESC; + user_id | rnk | avg_val_2 +--------------------------------------------------------------------- + 1 | 1 | 3.3750000000000000 + 3 | 2 | 3.1666666666666667 + 5 | 1 | 2.6666666666666667 + 6 | 1 | 2.5000000000000000 + 4 | 1 | 2.5000000000000000 + 2 | 1 | 2.4736842105263158 + 4 | 2 | 2.4000000000000000 + 1 | 2 | 2.1428571428571429 + 5 | 2 | 2.0909090909090909 + 6 | 2 | 2.0000000000000000 + 2 | 2 | 2.0000000000000000 + 3 | 1 | 1.8000000000000000 +(12 rows) + +-- lets push the limits of writing complex expressions aling with the window functions +SELECT + COUNT(*) OVER (PARTITION BY user_id, user_id + 1), + rank() OVER (PARTITION BY user_id) as cnt1, + COUNT(*) OVER (PARTITION BY user_id, abs(value_1 - value_2)) as cnt2, + date_trunc('min', lag(time) OVER (PARTITION BY user_id ORDER BY time)) as datee, + rank() OVER my_win as rnnk, + avg(CASE + WHEN user_id > 4 + THEN value_1 + ELSE value_2 + END) FILTER (WHERE user_id > 2) OVER my_win_2 as filtered_count, + sum(user_id * (5.0 / (value_1 + value_2 + 0.1)) * value_3) FILTER (WHERE value_1::text LIKE '%1%') OVER my_win_4 as cnt_with_filter_2 +FROM + users_table +WINDOW + my_win AS (PARTITION BY user_id, (value_1%3)::int ORDER BY time DESC), + my_win_2 AS (PARTITION BY user_id, (value_1)::int ORDER BY time DESC), + my_win_3 AS (PARTITION BY user_id, date_trunc('min', time)), + my_win_4 AS (my_win_3 ORDER BY value_2, value_3) +ORDER BY + cnt_with_filter_2 DESC NULLS LAST, filtered_count DESC NULLS LAST, datee DESC NULLS LAST, rnnk DESC, cnt2 DESC, cnt1 DESC, user_id DESC +LIMIT 5; + count | cnt1 | cnt2 | datee | rnnk | filtered_count | cnt_with_filter_2 +--------------------------------------------------------------------- + 23 | 1 | 7 | Thu Nov 23 02:14:00 2017 | 6 | 0.00000000000000000000 | 72.7272727272727 + 10 | 1 | 3 | Wed Nov 22 23:01:00 2017 | 1 | 1.00000000000000000000 | 57.1428571428571 + 17 | 1 | 5 | Wed Nov 22 23:24:00 2017 | 8 | 3.0000000000000000 | 28.5714285714286 + 17 | 1 | 5 | | 10 | 2.6666666666666667 | 28.5714285714286 + 17 | 1 | 5 | Thu Nov 23 00:15:00 2017 | 7 | 3.6666666666666667 | 24.1935483870968 +(5 rows) + +-- some tests with GROUP BY along with PARTITION BY +SELECT + user_id, + rank() OVER my_win as my_rank, + avg(avg(event_type)) OVER my_win_2 as avg, + max(time) as mx_time +FROM + events_table +GROUP BY + user_id, + value_2 +WINDOW + my_win AS (PARTITION BY user_id, max(event_type) ORDER BY count(*) DESC), + my_win_2 AS (PARTITION BY user_id, avg(user_id) ORDER BY count(*) DESC) +ORDER BY + avg DESC, + mx_time DESC, + my_rank DESC, + user_id DESC; + user_id | my_rank | avg | mx_time +--------------------------------------------------------------------- + 6 | 1 | 3.0000000000000000 | Thu Nov 23 14:00:13.20013 2017 + 6 | 2 | 3.0000000000000000 | Thu Nov 23 11:16:13.106691 2017 + 6 | 1 | 3.0000000000000000 | Thu Nov 23 07:27:32.822068 2017 + 3 | 1 | 2.9857142857142857 | Thu Nov 23 16:31:56.219594 2017 + 4 | 2 | 2.9555555555555556 | Thu Nov 23 14:19:25.765876 2017 + 4 | 1 | 2.9555555555555556 | Thu Nov 23 08:36:53.871919 2017 + 1 | 4 | 2.8633333333333333 | Wed Nov 22 21:06:57.457147 2017 + 1 | 1 | 2.8250000000000000 | Thu Nov 23 21:54:46.924477 2017 + 2 | 2 | 2.7738095238095238 | Thu Nov 23 13:27:37.441959 2017 + 1 | 2 | 2.7722222222222222 | Thu Nov 23 09:23:30.994345 2017 + 3 | 1 | 2.7682539682539682 | Thu Nov 23 01:17:49.040685 2017 + 2 | 1 | 2.7142857142857143 | Thu Nov 23 15:58:49.273421 2017 + 1 | 3 | 2.5791666666666667 | Thu Nov 23 11:09:38.074595 2017 + 3 | 1 | 2.5714285714285714 | Thu Nov 23 16:44:41.903713 2017 + 2 | 1 | 2.5158730158730159 | Thu Nov 23 14:02:47.738901 2017 + 4 | 1 | 2.47777777777777778333 | Thu Nov 23 16:20:33.264457 2017 + 4 | 3 | 2.47777777777777778333 | Thu Nov 23 08:14:18.231273 2017 + 4 | 3 | 2.47777777777777778333 | Thu Nov 23 07:32:45.521278 2017 + 1 | 1 | 2.4000000000000000 | Thu Nov 23 10:23:27.617726 2017 + 2 | 1 | 2.3869047619047619 | Thu Nov 23 17:26:14.563216 2017 + 3 | 1 | 2.3841269841269841 | Thu Nov 23 18:08:26.550729 2017 + 3 | 1 | 2.3841269841269841 | Thu Nov 23 09:38:45.338008 2017 + 3 | 2 | 2.3841269841269841 | Thu Nov 23 06:44:50.887182 2017 + 2 | 2 | 2.3095238095238095 | Thu Nov 23 04:05:16.217731 2017 + 5 | 2 | 2.3000000000000000 | Thu Nov 23 14:28:51.833214 2017 + 5 | 2 | 2.3000000000000000 | Thu Nov 23 14:23:09.889786 2017 + 4 | 1 | 2.2000000000000000 | Thu Nov 23 18:10:21.338399 2017 + 2 | 1 | 2.09126984126984126667 | Thu Nov 23 03:35:04.321504 2017 + 5 | 1 | 2.0000000000000000 | Thu Nov 23 16:11:02.929469 2017 + 5 | 1 | 2.0000000000000000 | Thu Nov 23 14:40:40.467511 2017 + 5 | 1 | 2.0000000000000000 | Thu Nov 23 13:26:45.571108 2017 +(31 rows) + +-- test for range and rows mode and different window functions +-- mostly to make sure that deparsing works fine +SELECT + user_id, + rank() OVER (PARTITION BY user_id ROWS BETWEEN + UNBOUNDED PRECEDING AND CURRENT ROW), + dense_rank() OVER (PARTITION BY user_id RANGE BETWEEN + UNBOUNDED PRECEDING AND CURRENT ROW), + CUME_DIST() OVER (PARTITION BY user_id RANGE BETWEEN + UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), + PERCENT_RANK() OVER (PARTITION BY user_id ORDER BY avg(value_1) RANGE BETWEEN + UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) +FROM + users_table +GROUP BY + 1 +ORDER BY + 4 DESC,3 DESC,2 DESC ,1 DESC; + user_id | rank | dense_rank | cume_dist | percent_rank +--------------------------------------------------------------------- + 6 | 1 | 1 | 1 | 0 + 5 | 1 | 1 | 1 | 0 + 4 | 1 | 1 | 1 | 0 + 3 | 1 | 1 | 1 | 0 + 2 | 1 | 1 | 1 | 0 + 1 | 1 | 1 | 1 | 0 +(6 rows) + +-- test exclude supported +SELECT + user_id, + value_1, + array_agg(value_1) OVER (PARTITION BY user_id ORDER BY value_1 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + array_agg(value_1) OVER (PARTITION BY user_id ORDER BY value_1 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE CURRENT ROW) +FROM + users_table +WHERE + user_id > 2 AND user_id < 6 +ORDER BY + user_id, value_1, 3, 4; + user_id | value_1 | array_agg | array_agg +--------------------------------------------------------------------- + 3 | 0 | {0} | + 3 | 1 | {0,1,1,1,1,1,1} | {0,1,1,1,1,1} + 3 | 1 | {0,1,1,1,1,1,1} | {0,1,1,1,1,1} + 3 | 1 | {0,1,1,1,1,1,1} | {0,1,1,1,1,1} + 3 | 1 | {0,1,1,1,1,1,1} | {0,1,1,1,1,1} + 3 | 1 | {0,1,1,1,1,1,1} | {0,1,1,1,1,1} + 3 | 1 | {0,1,1,1,1,1,1} | {0,1,1,1,1,1} + 3 | 2 | {0,1,1,1,1,1,1,2,2} | {0,1,1,1,1,1,1,2} + 3 | 2 | {0,1,1,1,1,1,1,2,2} | {0,1,1,1,1,1,1,2} + 3 | 3 | {0,1,1,1,1,1,1,2,2,3,3,3} | {0,1,1,1,1,1,1,2,2,3,3} + 3 | 3 | {0,1,1,1,1,1,1,2,2,3,3,3} | {0,1,1,1,1,1,1,2,2,3,3} + 3 | 3 | {0,1,1,1,1,1,1,2,2,3,3,3} | {0,1,1,1,1,1,1,2,2,3,3} + 3 | 4 | {0,1,1,1,1,1,1,2,2,3,3,3,4,4,4,4} | {0,1,1,1,1,1,1,2,2,3,3,3,4,4,4} + 3 | 4 | {0,1,1,1,1,1,1,2,2,3,3,3,4,4,4,4} | {0,1,1,1,1,1,1,2,2,3,3,3,4,4,4} + 3 | 4 | {0,1,1,1,1,1,1,2,2,3,3,3,4,4,4,4} | {0,1,1,1,1,1,1,2,2,3,3,3,4,4,4} + 3 | 4 | {0,1,1,1,1,1,1,2,2,3,3,3,4,4,4,4} | {0,1,1,1,1,1,1,2,2,3,3,3,4,4,4} + 3 | 5 | {0,1,1,1,1,1,1,2,2,3,3,3,4,4,4,4,5} | {0,1,1,1,1,1,1,2,2,3,3,3,4,4,4,4} + 4 | 0 | {0,0,0,0} | {0,0,0} + 4 | 0 | {0,0,0,0} | {0,0,0} + 4 | 0 | {0,0,0,0} | {0,0,0} + 4 | 0 | {0,0,0,0} | {0,0,0} + 4 | 1 | {0,0,0,0,1} | {0,0,0,0} + 4 | 2 | {0,0,0,0,1,2,2,2} | {0,0,0,0,1,2,2} + 4 | 2 | {0,0,0,0,1,2,2,2} | {0,0,0,0,1,2,2} + 4 | 2 | {0,0,0,0,1,2,2,2} | {0,0,0,0,1,2,2} + 4 | 3 | {0,0,0,0,1,2,2,2,3,3,3,3,3,3} | {0,0,0,0,1,2,2,2,3,3,3,3,3} + 4 | 3 | {0,0,0,0,1,2,2,2,3,3,3,3,3,3} | {0,0,0,0,1,2,2,2,3,3,3,3,3} + 4 | 3 | {0,0,0,0,1,2,2,2,3,3,3,3,3,3} | {0,0,0,0,1,2,2,2,3,3,3,3,3} + 4 | 3 | {0,0,0,0,1,2,2,2,3,3,3,3,3,3} | {0,0,0,0,1,2,2,2,3,3,3,3,3} + 4 | 3 | {0,0,0,0,1,2,2,2,3,3,3,3,3,3} | {0,0,0,0,1,2,2,2,3,3,3,3,3} + 4 | 3 | {0,0,0,0,1,2,2,2,3,3,3,3,3,3} | {0,0,0,0,1,2,2,2,3,3,3,3,3} + 4 | 4 | {0,0,0,0,1,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4} | {0,0,0,0,1,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4} + 4 | 4 | {0,0,0,0,1,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4} | {0,0,0,0,1,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4} + 4 | 4 | {0,0,0,0,1,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4} | {0,0,0,0,1,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4} + 4 | 4 | {0,0,0,0,1,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4} | {0,0,0,0,1,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4} + 4 | 4 | {0,0,0,0,1,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4} | {0,0,0,0,1,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4} + 4 | 4 | {0,0,0,0,1,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4} | {0,0,0,0,1,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4} + 4 | 4 | {0,0,0,0,1,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4} | {0,0,0,0,1,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4} + 4 | 5 | {0,0,0,0,1,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5} | {0,0,0,0,1,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,5} + 4 | 5 | {0,0,0,0,1,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5} | {0,0,0,0,1,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,5} + 5 | 0 | {0,0} | {0} + 5 | 0 | {0,0} | {0} + 5 | 1 | {0,0,1,1,1} | {0,0,1,1} + 5 | 1 | {0,0,1,1,1} | {0,0,1,1} + 5 | 1 | {0,0,1,1,1} | {0,0,1,1} + 5 | 2 | {0,0,1,1,1,2,2,2,2,2,2} | {0,0,1,1,1,2,2,2,2,2} + 5 | 2 | {0,0,1,1,1,2,2,2,2,2,2} | {0,0,1,1,1,2,2,2,2,2} + 5 | 2 | {0,0,1,1,1,2,2,2,2,2,2} | {0,0,1,1,1,2,2,2,2,2} + 5 | 2 | {0,0,1,1,1,2,2,2,2,2,2} | {0,0,1,1,1,2,2,2,2,2} + 5 | 2 | {0,0,1,1,1,2,2,2,2,2,2} | {0,0,1,1,1,2,2,2,2,2} + 5 | 2 | {0,0,1,1,1,2,2,2,2,2,2} | {0,0,1,1,1,2,2,2,2,2} + 5 | 3 | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3} | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3} + 5 | 3 | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3} | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3} + 5 | 3 | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3} | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3} + 5 | 3 | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3} | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3} + 5 | 3 | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3} | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3} + 5 | 3 | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3} | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3} + 5 | 3 | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3} | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3} + 5 | 3 | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3} | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3} + 5 | 3 | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3} | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3} + 5 | 4 | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4} | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4} + 5 | 4 | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4} | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4} + 5 | 4 | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4} | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4} + 5 | 5 | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5} | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,5,5} + 5 | 5 | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5} | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,5,5} + 5 | 5 | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,5,5,5} | {0,0,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4,5,5} +(66 rows) + +-- test preceding and following on RANGE window +SELECT + user_id, + value_1, + array_agg(value_1) OVER range_window, + array_agg(value_1) OVER range_window_exclude +FROM + users_table +WHERE + user_id > 2 AND user_id < 6 +WINDOW + range_window as (PARTITION BY user_id ORDER BY value_1 RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING), + range_window_exclude as (PARTITION BY user_id ORDER BY value_1 RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING EXCLUDE CURRENT ROW) +ORDER BY + user_id, value_1, 3, 4; + user_id | value_1 | array_agg | array_agg +--------------------------------------------------------------------- + 3 | 0 | {0,1,1,1,1,1,1} | {1,1,1,1,1,1} + 3 | 1 | {0,1,1,1,1,1,1,2,2} | {0,1,1,1,1,1,2,2} + 3 | 1 | {0,1,1,1,1,1,1,2,2} | {0,1,1,1,1,1,2,2} + 3 | 1 | {0,1,1,1,1,1,1,2,2} | {0,1,1,1,1,1,2,2} + 3 | 1 | {0,1,1,1,1,1,1,2,2} | {0,1,1,1,1,1,2,2} + 3 | 1 | {0,1,1,1,1,1,1,2,2} | {0,1,1,1,1,1,2,2} + 3 | 1 | {0,1,1,1,1,1,1,2,2} | {0,1,1,1,1,1,2,2} + 3 | 2 | {1,1,1,1,1,1,2,2,3,3,3} | {1,1,1,1,1,1,2,3,3,3} + 3 | 2 | {1,1,1,1,1,1,2,2,3,3,3} | {1,1,1,1,1,1,2,3,3,3} + 3 | 3 | {2,2,3,3,3,4,4,4,4} | {2,2,3,3,4,4,4,4} + 3 | 3 | {2,2,3,3,3,4,4,4,4} | {2,2,3,3,4,4,4,4} + 3 | 3 | {2,2,3,3,3,4,4,4,4} | {2,2,3,3,4,4,4,4} + 3 | 4 | {3,3,3,4,4,4,4,5} | {3,3,3,4,4,4,5} + 3 | 4 | {3,3,3,4,4,4,4,5} | {3,3,3,4,4,4,5} + 3 | 4 | {3,3,3,4,4,4,4,5} | {3,3,3,4,4,4,5} + 3 | 4 | {3,3,3,4,4,4,4,5} | {3,3,3,4,4,4,5} + 3 | 5 | {4,4,4,4,5} | {4,4,4,4} + 4 | 0 | {0,0,0,0,1} | {0,0,0,1} + 4 | 0 | {0,0,0,0,1} | {0,0,0,1} + 4 | 0 | {0,0,0,0,1} | {0,0,0,1} + 4 | 0 | {0,0,0,0,1} | {0,0,0,1} + 4 | 1 | {0,0,0,0,1,2,2,2} | {0,0,0,0,2,2,2} + 4 | 2 | {1,2,2,2,3,3,3,3,3,3} | {1,2,2,3,3,3,3,3,3} + 4 | 2 | {1,2,2,2,3,3,3,3,3,3} | {1,2,2,3,3,3,3,3,3} + 4 | 2 | {1,2,2,2,3,3,3,3,3,3} | {1,2,2,3,3,3,3,3,3} + 4 | 3 | {2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4} | {2,2,2,3,3,3,3,3,4,4,4,4,4,4,4} + 4 | 3 | {2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4} | {2,2,2,3,3,3,3,3,4,4,4,4,4,4,4} + 4 | 3 | {2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4} | {2,2,2,3,3,3,3,3,4,4,4,4,4,4,4} + 4 | 3 | {2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4} | {2,2,2,3,3,3,3,3,4,4,4,4,4,4,4} + 4 | 3 | {2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4} | {2,2,2,3,3,3,3,3,4,4,4,4,4,4,4} + 4 | 3 | {2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4} | {2,2,2,3,3,3,3,3,4,4,4,4,4,4,4} + 4 | 4 | {3,3,3,3,3,3,4,4,4,4,4,4,4,5,5} | {3,3,3,3,3,3,4,4,4,4,4,4,5,5} + 4 | 4 | {3,3,3,3,3,3,4,4,4,4,4,4,4,5,5} | {3,3,3,3,3,3,4,4,4,4,4,4,5,5} + 4 | 4 | {3,3,3,3,3,3,4,4,4,4,4,4,4,5,5} | {3,3,3,3,3,3,4,4,4,4,4,4,5,5} + 4 | 4 | {3,3,3,3,3,3,4,4,4,4,4,4,4,5,5} | {3,3,3,3,3,3,4,4,4,4,4,4,5,5} + 4 | 4 | {3,3,3,3,3,3,4,4,4,4,4,4,4,5,5} | {3,3,3,3,3,3,4,4,4,4,4,4,5,5} + 4 | 4 | {3,3,3,3,3,3,4,4,4,4,4,4,4,5,5} | {3,3,3,3,3,3,4,4,4,4,4,4,5,5} + 4 | 4 | {3,3,3,3,3,3,4,4,4,4,4,4,4,5,5} | {3,3,3,3,3,3,4,4,4,4,4,4,5,5} + 4 | 5 | {4,4,4,4,4,4,4,5,5} | {4,4,4,4,4,4,4,5} + 4 | 5 | {4,4,4,4,4,4,4,5,5} | {4,4,4,4,4,4,4,5} + 5 | 0 | {0,0,1,1,1} | {0,1,1,1} + 5 | 0 | {0,0,1,1,1} | {0,1,1,1} + 5 | 1 | {0,0,1,1,1,2,2,2,2,2,2} | {0,0,1,1,2,2,2,2,2,2} + 5 | 1 | {0,0,1,1,1,2,2,2,2,2,2} | {0,0,1,1,2,2,2,2,2,2} + 5 | 1 | {0,0,1,1,1,2,2,2,2,2,2} | {0,0,1,1,2,2,2,2,2,2} + 5 | 2 | {1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3} | {1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3} + 5 | 2 | {1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3} | {1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3} + 5 | 2 | {1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3} | {1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3} + 5 | 2 | {1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3} | {1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3} + 5 | 2 | {1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3} | {1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3} + 5 | 2 | {1,1,1,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3} | {1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,3,3} + 5 | 3 | {2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4} | {2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4} + 5 | 3 | {2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4} | {2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4} + 5 | 3 | {2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4} | {2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4} + 5 | 3 | {2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4} | {2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4} + 5 | 3 | {2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4} | {2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4} + 5 | 3 | {2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4} | {2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4} + 5 | 3 | {2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4} | {2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4} + 5 | 3 | {2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4} | {2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4} + 5 | 3 | {2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,4,4,4} | {2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4} + 5 | 4 | {3,3,3,3,3,3,3,3,3,4,4,4,5,5,5} | {3,3,3,3,3,3,3,3,3,4,4,5,5,5} + 5 | 4 | {3,3,3,3,3,3,3,3,3,4,4,4,5,5,5} | {3,3,3,3,3,3,3,3,3,4,4,5,5,5} + 5 | 4 | {3,3,3,3,3,3,3,3,3,4,4,4,5,5,5} | {3,3,3,3,3,3,3,3,3,4,4,5,5,5} + 5 | 5 | {4,4,4,5,5,5} | {4,4,4,5,5} + 5 | 5 | {4,4,4,5,5,5} | {4,4,4,5,5} + 5 | 5 | {4,4,4,5,5,5} | {4,4,4,5,5} +(66 rows) + +-- test preceding and following on ROW window +SELECT + user_id, + value_1, + array_agg(value_1) OVER row_window, + array_agg(value_1) OVER row_window_exclude +FROM + users_table +WHERE + user_id > 2 and user_id < 6 +WINDOW + row_window as (PARTITION BY user_id ORDER BY value_1 ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING), + row_window_exclude as (PARTITION BY user_id ORDER BY value_1 ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING EXCLUDE CURRENT ROW) +ORDER BY + user_id, value_1, 3, 4; + user_id | value_1 | array_agg | array_agg +--------------------------------------------------------------------- + 3 | 0 | {0,1} | {1} + 3 | 1 | {0,1,1} | {0,1} + 3 | 1 | {1,1,1} | {1,1} + 3 | 1 | {1,1,1} | {1,1} + 3 | 1 | {1,1,1} | {1,1} + 3 | 1 | {1,1,1} | {1,1} + 3 | 1 | {1,1,2} | {1,2} + 3 | 2 | {1,2,2} | {1,2} + 3 | 2 | {2,2,3} | {2,3} + 3 | 3 | {2,3,3} | {2,3} + 3 | 3 | {3,3,3} | {3,3} + 3 | 3 | {3,3,4} | {3,4} + 3 | 4 | {3,4,4} | {3,4} + 3 | 4 | {4,4,4} | {4,4} + 3 | 4 | {4,4,4} | {4,4} + 3 | 4 | {4,4,5} | {4,5} + 3 | 5 | {4,5} | {4} + 4 | 0 | {0,0} | {0} + 4 | 0 | {0,0,0} | {0,0} + 4 | 0 | {0,0,0} | {0,0} + 4 | 0 | {0,0,1} | {0,1} + 4 | 1 | {0,1,2} | {0,2} + 4 | 2 | {1,2,2} | {1,2} + 4 | 2 | {2,2,2} | {2,2} + 4 | 2 | {2,2,3} | {2,3} + 4 | 3 | {2,3,3} | {2,3} + 4 | 3 | {3,3,3} | {3,3} + 4 | 3 | {3,3,3} | {3,3} + 4 | 3 | {3,3,3} | {3,3} + 4 | 3 | {3,3,3} | {3,3} + 4 | 3 | {3,3,4} | {3,4} + 4 | 4 | {3,4,4} | {3,4} + 4 | 4 | {4,4,4} | {4,4} + 4 | 4 | {4,4,4} | {4,4} + 4 | 4 | {4,4,4} | {4,4} + 4 | 4 | {4,4,4} | {4,4} + 4 | 4 | {4,4,4} | {4,4} + 4 | 4 | {4,4,5} | {4,5} + 4 | 5 | {4,5,5} | {4,5} + 4 | 5 | {5,5} | {5} + 5 | 0 | {0,0} | {0} + 5 | 0 | {0,0,1} | {0,1} + 5 | 1 | {0,1,1} | {0,1} + 5 | 1 | {1,1,1} | {1,1} + 5 | 1 | {1,1,2} | {1,2} + 5 | 2 | {1,2,2} | {1,2} + 5 | 2 | {2,2,2} | {2,2} + 5 | 2 | {2,2,2} | {2,2} + 5 | 2 | {2,2,2} | {2,2} + 5 | 2 | {2,2,2} | {2,2} + 5 | 2 | {2,2,3} | {2,3} + 5 | 3 | {2,3,3} | {2,3} + 5 | 3 | {3,3,3} | {3,3} + 5 | 3 | {3,3,3} | {3,3} + 5 | 3 | {3,3,3} | {3,3} + 5 | 3 | {3,3,3} | {3,3} + 5 | 3 | {3,3,3} | {3,3} + 5 | 3 | {3,3,3} | {3,3} + 5 | 3 | {3,3,3} | {3,3} + 5 | 3 | {3,3,4} | {3,4} + 5 | 4 | {3,4,4} | {3,4} + 5 | 4 | {4,4,4} | {4,4} + 5 | 4 | {4,4,5} | {4,5} + 5 | 5 | {4,5,5} | {4,5} + 5 | 5 | {5,5} | {5} + 5 | 5 | {5,5,5} | {5,5} +(66 rows) + +-- repeat above 3 tests without grouping by distribution column +SELECT + value_2, + rank() OVER (PARTITION BY value_2 ROWS BETWEEN + UNBOUNDED PRECEDING AND CURRENT ROW), + dense_rank() OVER (PARTITION BY value_2 RANGE BETWEEN + UNBOUNDED PRECEDING AND CURRENT ROW), + CUME_DIST() OVER (PARTITION BY value_2 RANGE BETWEEN + UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING), + PERCENT_RANK() OVER (PARTITION BY value_2 ORDER BY avg(value_1) RANGE BETWEEN + UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) +FROM + users_table +GROUP BY + 1 +ORDER BY + 4 DESC,3 DESC,2 DESC ,1 DESC; + value_2 | rank | dense_rank | cume_dist | percent_rank +--------------------------------------------------------------------- + 5 | 1 | 1 | 1 | 0 + 4 | 1 | 1 | 1 | 0 + 3 | 1 | 1 | 1 | 0 + 2 | 1 | 1 | 1 | 0 + 1 | 1 | 1 | 1 | 0 + 0 | 1 | 1 | 1 | 0 +(6 rows) + +-- test exclude supported +SELECT + value_2, + value_1, + array_agg(value_1) OVER (PARTITION BY value_2 ORDER BY value_1 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), + array_agg(value_1) OVER (PARTITION BY value_2 ORDER BY value_1 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE CURRENT ROW) +FROM + users_table +WHERE + value_2 > 2 AND value_2 < 6 +ORDER BY + value_2, value_1, 3, 4; + value_2 | value_1 | array_agg | array_agg +--------------------------------------------------------------------- + 3 | 0 | {0,0,0} | {0,0} + 3 | 0 | {0,0,0} | {0,0} + 3 | 0 | {0,0,0} | {0,0} + 3 | 1 | {0,0,0,1,1,1,1} | {0,0,0,1,1,1} + 3 | 1 | {0,0,0,1,1,1,1} | {0,0,0,1,1,1} + 3 | 1 | {0,0,0,1,1,1,1} | {0,0,0,1,1,1} + 3 | 1 | {0,0,0,1,1,1,1} | {0,0,0,1,1,1} + 3 | 2 | {0,0,0,1,1,1,1,2,2} | {0,0,0,1,1,1,1,2} + 3 | 2 | {0,0,0,1,1,1,1,2,2} | {0,0,0,1,1,1,1,2} + 3 | 3 | {0,0,0,1,1,1,1,2,2,3,3} | {0,0,0,1,1,1,1,2,2,3} + 3 | 3 | {0,0,0,1,1,1,1,2,2,3,3} | {0,0,0,1,1,1,1,2,2,3} + 3 | 4 | {0,0,0,1,1,1,1,2,2,3,3,4,4,4,4,4} | {0,0,0,1,1,1,1,2,2,3,3,4,4,4,4} + 3 | 4 | {0,0,0,1,1,1,1,2,2,3,3,4,4,4,4,4} | {0,0,0,1,1,1,1,2,2,3,3,4,4,4,4} + 3 | 4 | {0,0,0,1,1,1,1,2,2,3,3,4,4,4,4,4} | {0,0,0,1,1,1,1,2,2,3,3,4,4,4,4} + 3 | 4 | {0,0,0,1,1,1,1,2,2,3,3,4,4,4,4,4} | {0,0,0,1,1,1,1,2,2,3,3,4,4,4,4} + 3 | 4 | {0,0,0,1,1,1,1,2,2,3,3,4,4,4,4,4} | {0,0,0,1,1,1,1,2,2,3,3,4,4,4,4} + 3 | 5 | {0,0,0,1,1,1,1,2,2,3,3,4,4,4,4,4,5} | {0,0,0,1,1,1,1,2,2,3,3,4,4,4,4,4} + 4 | 0 | {0,0} | {0} + 4 | 0 | {0,0} | {0} + 4 | 1 | {0,0,1,1} | {0,0,1} + 4 | 1 | {0,0,1,1} | {0,0,1} + 4 | 2 | {0,0,1,1,2,2,2} | {0,0,1,1,2,2} + 4 | 2 | {0,0,1,1,2,2,2} | {0,0,1,1,2,2} + 4 | 2 | {0,0,1,1,2,2,2} | {0,0,1,1,2,2} + 4 | 3 | {0,0,1,1,2,2,2,3,3,3,3,3,3,3} | {0,0,1,1,2,2,2,3,3,3,3,3,3} + 4 | 3 | {0,0,1,1,2,2,2,3,3,3,3,3,3,3} | {0,0,1,1,2,2,2,3,3,3,3,3,3} + 4 | 3 | {0,0,1,1,2,2,2,3,3,3,3,3,3,3} | {0,0,1,1,2,2,2,3,3,3,3,3,3} + 4 | 3 | {0,0,1,1,2,2,2,3,3,3,3,3,3,3} | {0,0,1,1,2,2,2,3,3,3,3,3,3} + 4 | 3 | {0,0,1,1,2,2,2,3,3,3,3,3,3,3} | {0,0,1,1,2,2,2,3,3,3,3,3,3} + 4 | 3 | {0,0,1,1,2,2,2,3,3,3,3,3,3,3} | {0,0,1,1,2,2,2,3,3,3,3,3,3} + 4 | 3 | {0,0,1,1,2,2,2,3,3,3,3,3,3,3} | {0,0,1,1,2,2,2,3,3,3,3,3,3} + 4 | 4 | {0,0,1,1,2,2,2,3,3,3,3,3,3,3,4,4,4,4} | {0,0,1,1,2,2,2,3,3,3,3,3,3,3,4,4,4} + 4 | 4 | {0,0,1,1,2,2,2,3,3,3,3,3,3,3,4,4,4,4} | {0,0,1,1,2,2,2,3,3,3,3,3,3,3,4,4,4} + 4 | 4 | {0,0,1,1,2,2,2,3,3,3,3,3,3,3,4,4,4,4} | {0,0,1,1,2,2,2,3,3,3,3,3,3,3,4,4,4} + 4 | 4 | {0,0,1,1,2,2,2,3,3,3,3,3,3,3,4,4,4,4} | {0,0,1,1,2,2,2,3,3,3,3,3,3,3,4,4,4} + 4 | 5 | {0,0,1,1,2,2,2,3,3,3,3,3,3,3,4,4,4,4,5,5} | {0,0,1,1,2,2,2,3,3,3,3,3,3,3,4,4,4,4,5} + 4 | 5 | {0,0,1,1,2,2,2,3,3,3,3,3,3,3,4,4,4,4,5,5} | {0,0,1,1,2,2,2,3,3,3,3,3,3,3,4,4,4,4,5} + 5 | 0 | {0,0} | {0} + 5 | 0 | {0,0} | {0} + 5 | 1 | {0,0,1} | {0,0} + 5 | 2 | {0,0,1,2,2} | {0,0,1,2} + 5 | 2 | {0,0,1,2,2} | {0,0,1,2} + 5 | 3 | {0,0,1,2,2,3,3,3,3} | {0,0,1,2,2,3,3,3} + 5 | 3 | {0,0,1,2,2,3,3,3,3} | {0,0,1,2,2,3,3,3} + 5 | 3 | {0,0,1,2,2,3,3,3,3} | {0,0,1,2,2,3,3,3} + 5 | 3 | {0,0,1,2,2,3,3,3,3} | {0,0,1,2,2,3,3,3} + 5 | 4 | {0,0,1,2,2,3,3,3,3,4,4} | {0,0,1,2,2,3,3,3,3,4} + 5 | 4 | {0,0,1,2,2,3,3,3,3,4,4} | {0,0,1,2,2,3,3,3,3,4} + 5 | 5 | {0,0,1,2,2,3,3,3,3,4,4,5,5} | {0,0,1,2,2,3,3,3,3,4,4,5} + 5 | 5 | {0,0,1,2,2,3,3,3,3,4,4,5,5} | {0,0,1,2,2,3,3,3,3,4,4,5} +(50 rows) + +-- test preceding and following on RANGE window +SELECT + value_2, + value_1, + array_agg(value_1) OVER range_window, + array_agg(value_1) OVER range_window_exclude +FROM + users_table +WHERE + value_2 > 2 AND value_2 < 6 +WINDOW + range_window as (PARTITION BY value_2 ORDER BY value_1 RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING), + range_window_exclude as (PARTITION BY value_2 ORDER BY value_1 RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING EXCLUDE CURRENT ROW) +ORDER BY + value_2, value_1, 3, 4; + value_2 | value_1 | array_agg | array_agg +--------------------------------------------------------------------- + 3 | 0 | {0,0,0,1,1,1,1} | {0,0,1,1,1,1} + 3 | 0 | {0,0,0,1,1,1,1} | {0,0,1,1,1,1} + 3 | 0 | {0,0,0,1,1,1,1} | {0,0,1,1,1,1} + 3 | 1 | {0,0,0,1,1,1,1,2,2} | {0,0,0,1,1,1,2,2} + 3 | 1 | {0,0,0,1,1,1,1,2,2} | {0,0,0,1,1,1,2,2} + 3 | 1 | {0,0,0,1,1,1,1,2,2} | {0,0,0,1,1,1,2,2} + 3 | 1 | {0,0,0,1,1,1,1,2,2} | {0,0,0,1,1,1,2,2} + 3 | 2 | {1,1,1,1,2,2,3,3} | {1,1,1,1,2,3,3} + 3 | 2 | {1,1,1,1,2,2,3,3} | {1,1,1,1,2,3,3} + 3 | 3 | {2,2,3,3,4,4,4,4,4} | {2,2,3,4,4,4,4,4} + 3 | 3 | {2,2,3,3,4,4,4,4,4} | {2,2,3,4,4,4,4,4} + 3 | 4 | {3,3,4,4,4,4,4,5} | {3,3,4,4,4,4,5} + 3 | 4 | {3,3,4,4,4,4,4,5} | {3,3,4,4,4,4,5} + 3 | 4 | {3,3,4,4,4,4,4,5} | {3,3,4,4,4,4,5} + 3 | 4 | {3,3,4,4,4,4,4,5} | {3,3,4,4,4,4,5} + 3 | 4 | {3,3,4,4,4,4,4,5} | {3,3,4,4,4,4,5} + 3 | 5 | {4,4,4,4,4,5} | {4,4,4,4,4} + 4 | 0 | {0,0,1,1} | {0,1,1} + 4 | 0 | {0,0,1,1} | {0,1,1} + 4 | 1 | {0,0,1,1,2,2,2} | {0,0,1,2,2,2} + 4 | 1 | {0,0,1,1,2,2,2} | {0,0,1,2,2,2} + 4 | 2 | {1,1,2,2,2,3,3,3,3,3,3,3} | {1,1,2,2,3,3,3,3,3,3,3} + 4 | 2 | {1,1,2,2,2,3,3,3,3,3,3,3} | {1,1,2,2,3,3,3,3,3,3,3} + 4 | 2 | {1,1,2,2,2,3,3,3,3,3,3,3} | {1,1,2,2,3,3,3,3,3,3,3} + 4 | 3 | {2,2,2,3,3,3,3,3,3,3,4,4,4,4} | {2,2,2,3,3,3,3,3,3,4,4,4,4} + 4 | 3 | {2,2,2,3,3,3,3,3,3,3,4,4,4,4} | {2,2,2,3,3,3,3,3,3,4,4,4,4} + 4 | 3 | {2,2,2,3,3,3,3,3,3,3,4,4,4,4} | {2,2,2,3,3,3,3,3,3,4,4,4,4} + 4 | 3 | {2,2,2,3,3,3,3,3,3,3,4,4,4,4} | {2,2,2,3,3,3,3,3,3,4,4,4,4} + 4 | 3 | {2,2,2,3,3,3,3,3,3,3,4,4,4,4} | {2,2,2,3,3,3,3,3,3,4,4,4,4} + 4 | 3 | {2,2,2,3,3,3,3,3,3,3,4,4,4,4} | {2,2,2,3,3,3,3,3,3,4,4,4,4} + 4 | 3 | {2,2,2,3,3,3,3,3,3,3,4,4,4,4} | {2,2,2,3,3,3,3,3,3,4,4,4,4} + 4 | 4 | {3,3,3,3,3,3,3,4,4,4,4,5,5} | {3,3,3,3,3,3,3,4,4,4,5,5} + 4 | 4 | {3,3,3,3,3,3,3,4,4,4,4,5,5} | {3,3,3,3,3,3,3,4,4,4,5,5} + 4 | 4 | {3,3,3,3,3,3,3,4,4,4,4,5,5} | {3,3,3,3,3,3,3,4,4,4,5,5} + 4 | 4 | {3,3,3,3,3,3,3,4,4,4,4,5,5} | {3,3,3,3,3,3,3,4,4,4,5,5} + 4 | 5 | {4,4,4,4,5,5} | {4,4,4,4,5} + 4 | 5 | {4,4,4,4,5,5} | {4,4,4,4,5} + 5 | 0 | {0,0,1} | {0,1} + 5 | 0 | {0,0,1} | {0,1} + 5 | 1 | {0,0,1,2,2} | {0,0,2,2} + 5 | 2 | {1,2,2,3,3,3,3} | {1,2,3,3,3,3} + 5 | 2 | {1,2,2,3,3,3,3} | {1,2,3,3,3,3} + 5 | 3 | {2,2,3,3,3,3,4,4} | {2,2,3,3,3,4,4} + 5 | 3 | {2,2,3,3,3,3,4,4} | {2,2,3,3,3,4,4} + 5 | 3 | {2,2,3,3,3,3,4,4} | {2,2,3,3,3,4,4} + 5 | 3 | {2,2,3,3,3,3,4,4} | {2,2,3,3,3,4,4} + 5 | 4 | {3,3,3,3,4,4,5,5} | {3,3,3,3,4,5,5} + 5 | 4 | {3,3,3,3,4,4,5,5} | {3,3,3,3,4,5,5} + 5 | 5 | {4,4,5,5} | {4,4,5} + 5 | 5 | {4,4,5,5} | {4,4,5} +(50 rows) + +-- test preceding and following on ROW window +SELECT + value_2, + value_1, + array_agg(value_1) OVER row_window, + array_agg(value_1) OVER row_window_exclude +FROM + users_table +WHERE + value_2 > 2 and value_2 < 6 +WINDOW + row_window as (PARTITION BY value_2 ORDER BY value_1 ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING), + row_window_exclude as (PARTITION BY value_2 ORDER BY value_1 ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING EXCLUDE CURRENT ROW) +ORDER BY + value_2, value_1, 3, 4; + value_2 | value_1 | array_agg | array_agg +--------------------------------------------------------------------- + 3 | 0 | {0,0} | {0} + 3 | 0 | {0,0,0} | {0,0} + 3 | 0 | {0,0,1} | {0,1} + 3 | 1 | {0,1,1} | {0,1} + 3 | 1 | {1,1,1} | {1,1} + 3 | 1 | {1,1,1} | {1,1} + 3 | 1 | {1,1,2} | {1,2} + 3 | 2 | {1,2,2} | {1,2} + 3 | 2 | {2,2,3} | {2,3} + 3 | 3 | {2,3,3} | {2,3} + 3 | 3 | {3,3,4} | {3,4} + 3 | 4 | {3,4,4} | {3,4} + 3 | 4 | {4,4,4} | {4,4} + 3 | 4 | {4,4,4} | {4,4} + 3 | 4 | {4,4,4} | {4,4} + 3 | 4 | {4,4,5} | {4,5} + 3 | 5 | {4,5} | {4} + 4 | 0 | {0,0} | {0} + 4 | 0 | {0,0,1} | {0,1} + 4 | 1 | {0,1,1} | {0,1} + 4 | 1 | {1,1,2} | {1,2} + 4 | 2 | {1,2,2} | {1,2} + 4 | 2 | {2,2,2} | {2,2} + 4 | 2 | {2,2,3} | {2,3} + 4 | 3 | {2,3,3} | {2,3} + 4 | 3 | {3,3,3} | {3,3} + 4 | 3 | {3,3,3} | {3,3} + 4 | 3 | {3,3,3} | {3,3} + 4 | 3 | {3,3,3} | {3,3} + 4 | 3 | {3,3,3} | {3,3} + 4 | 3 | {3,3,4} | {3,4} + 4 | 4 | {3,4,4} | {3,4} + 4 | 4 | {4,4,4} | {4,4} + 4 | 4 | {4,4,4} | {4,4} + 4 | 4 | {4,4,5} | {4,5} + 4 | 5 | {4,5,5} | {4,5} + 4 | 5 | {5,5} | {5} + 5 | 0 | {0,0} | {0} + 5 | 0 | {0,0,1} | {0,1} + 5 | 1 | {0,1,2} | {0,2} + 5 | 2 | {1,2,2} | {1,2} + 5 | 2 | {2,2,3} | {2,3} + 5 | 3 | {2,3,3} | {2,3} + 5 | 3 | {3,3,3} | {3,3} + 5 | 3 | {3,3,3} | {3,3} + 5 | 3 | {3,3,4} | {3,4} + 5 | 4 | {3,4,4} | {3,4} + 5 | 4 | {4,4,5} | {4,5} + 5 | 5 | {4,5,5} | {4,5} + 5 | 5 | {5,5} | {5} +(50 rows) + +-- some tests with GROUP BY, HAVING and LIMIT +SELECT + user_id, sum(event_type) OVER my_win , event_type +FROM + events_table +GROUP BY + user_id, event_type +HAVING count(*) > 2 + WINDOW my_win AS (PARTITION BY user_id, max(event_type) ORDER BY count(*) DESC) +ORDER BY + 2 DESC, 3 DESC, 1 DESC +LIMIT + 5; + user_id | sum | event_type +--------------------------------------------------------------------- + 4 | 4 | 4 + 3 | 4 | 4 + 2 | 4 | 4 + 1 | 4 | 4 + 5 | 3 | 3 +(5 rows) + +-- test PARTITION BY avg(...) ORDER BY avg(...) +SELECT + value_1, + avg(value_3), + dense_rank() OVER (PARTITION BY avg(value_3) ORDER BY avg(value_2)) +FROM + users_table +GROUP BY + 1 +ORDER BY + 1; + value_1 | avg | dense_rank +--------------------------------------------------------------------- + 0 | 3.08333333333333 | 1 + 1 | 2.93333333333333 | 1 + 2 | 2.22222222222222 | 1 + 3 | 2.73076923076923 | 1 + 4 | 2.9047619047619 | 1 + 5 | 2.22222222222222 | 2 +(6 rows) + +-- Group by has more columns than partition by +SELECT + DISTINCT user_id, SUM(value_2) OVER (PARTITION BY user_id) +FROM + users_table +GROUP BY + user_id, value_1, value_2 +HAVING count(*) > 2 +ORDER BY + 2 DESC, 1 +LIMIT + 10; + user_id | sum +--------------------------------------------------------------------- + 5 | 3 + 4 | 2 +(2 rows) + +SELECT + DISTINCT ON (user_id) user_id, SUM(value_2) OVER (PARTITION BY user_id) +FROM + users_table +GROUP BY + user_id, value_1, value_2 +HAVING count(*) > 2 +ORDER BY + 1, 2 DESC +LIMIT + 10; + user_id | sum +--------------------------------------------------------------------- + 4 | 2 + 5 | 3 +(2 rows) + +SELECT + DISTINCT ON (SUM(value_1) OVER (PARTITION BY user_id)) user_id, SUM(value_2) OVER (PARTITION BY user_id) +FROM + users_table +GROUP BY + user_id, value_1, value_2 +HAVING count(*) > 2 +ORDER BY + (SUM(value_1) OVER (PARTITION BY user_id)) , 2 DESC, 1 +LIMIT + 10; + user_id | sum +--------------------------------------------------------------------- + 5 | 3 + 4 | 2 +(2 rows) + +-- not a meaningful query, with interesting syntax +SELECT + user_id, + AVG(avg(value_1)) OVER (PARTITION BY user_id, max(user_id), MIN(value_2)), + AVG(avg(user_id)) OVER (PARTITION BY user_id, min(user_id), AVG(value_1)) +FROM + users_table +GROUP BY + 1 +ORDER BY + 3 DESC, 2 DESC, 1 DESC; + user_id | avg | avg +--------------------------------------------------------------------- + 6 | 2.1000000000000000 | 6.0000000000000000 + 5 | 2.6538461538461538 | 5.0000000000000000 + 4 | 2.7391304347826087 | 4.0000000000000000 + 3 | 2.3529411764705882 | 3.0000000000000000 + 2 | 2.3333333333333333 | 2.0000000000000000 + 1 | 3.2857142857142857 | 1.00000000000000000000 +(6 rows) + +SELECT coordinator_plan($Q$ +EXPLAIN (COSTS FALSE) +SELECT + user_id, + AVG(avg(value_1)) OVER (PARTITION BY user_id, max(user_id), MIN(value_2)), + AVG(avg(user_id)) OVER (PARTITION BY user_id, min(user_id), AVG(value_1)) +FROM + users_table +GROUP BY + 1 +ORDER BY + 3 DESC, 2 DESC, 1 DESC; +$Q$); + coordinator_plan +--------------------------------------------------------------------- + Sort + Sort Key: remote_scan.avg_1 DESC, remote_scan.avg DESC, remote_scan.user_id DESC + -> Custom Scan (Citus Adaptive) + Task Count: 4 +(4 rows) + +SELECT + value_2, + AVG(avg(value_1)) OVER (PARTITION BY value_2, max(value_2), MIN(value_2)), + AVG(avg(value_2)) OVER (PARTITION BY value_2, min(value_2), AVG(value_1)) +FROM + users_table +GROUP BY + 1 +ORDER BY + 3 DESC, 2 DESC, 1 DESC; + value_2 | avg | avg +--------------------------------------------------------------------- + 5 | 2.6923076923076923 | 5.0000000000000000 + 4 | 2.7500000000000000 | 4.0000000000000000 + 3 | 2.2941176470588235 | 3.0000000000000000 + 2 | 2.7619047619047619 | 2.0000000000000000 + 1 | 2.4285714285714286 | 1.00000000000000000000 + 0 | 2.2222222222222222 | 0.00000000000000000000 +(6 rows) + +SELECT + value_2, user_id, + AVG(avg(value_1)) OVER (PARTITION BY value_2, max(value_2), MIN(value_2)), + AVG(avg(value_2)) OVER (PARTITION BY user_id, min(value_2), AVG(value_1)) +FROM + users_table +GROUP BY + 1, 2 +ORDER BY + 3 DESC, 2 DESC, 1 DESC; + value_2 | user_id | avg | avg +--------------------------------------------------------------------- + 5 | 5 | 2.6666666666666667 | 5.0000000000000000 + 5 | 4 | 2.6666666666666667 | 5.0000000000000000 + 5 | 3 | 2.6666666666666667 | 5.0000000000000000 + 5 | 2 | 2.6666666666666667 | 5.0000000000000000 + 2 | 6 | 2.54583333333333333333 | 2.0000000000000000 + 2 | 5 | 2.54583333333333333333 | 2.0000000000000000 + 2 | 4 | 2.54583333333333333333 | 2.0000000000000000 + 2 | 3 | 2.54583333333333333333 | 2.0000000000000000 + 2 | 2 | 2.54583333333333333333 | 2.0000000000000000 + 2 | 1 | 2.54583333333333333333 | 2.0000000000000000 + 0 | 6 | 2.50000000000000000000 | 0.00000000000000000000 + 0 | 5 | 2.50000000000000000000 | 0.00000000000000000000 + 0 | 4 | 2.50000000000000000000 | 0.00000000000000000000 + 0 | 2 | 2.50000000000000000000 | 0.00000000000000000000 + 0 | 1 | 2.50000000000000000000 | 0.00000000000000000000 + 4 | 6 | 2.45555555555555555000 | 4.0000000000000000 + 4 | 5 | 2.45555555555555555000 | 4.0000000000000000 + 4 | 4 | 2.45555555555555555000 | 4.0000000000000000 + 4 | 3 | 2.45555555555555555000 | 4.0000000000000000 + 4 | 2 | 2.45555555555555555000 | 4.0000000000000000 + 4 | 1 | 2.45555555555555555000 | 4.0000000000000000 + 3 | 6 | 2.3500000000000000 | 3.0000000000000000 + 3 | 5 | 2.3500000000000000 | 3.0000000000000000 + 3 | 4 | 2.3500000000000000 | 3.0000000000000000 + 3 | 3 | 2.3500000000000000 | 3.0000000000000000 + 3 | 2 | 2.3500000000000000 | 3.0000000000000000 + 3 | 1 | 2.3500000000000000 | 3.0000000000000000 + 1 | 6 | 1.90666666666666666000 | 1.00000000000000000000 + 1 | 5 | 1.90666666666666666000 | 1.00000000000000000000 + 1 | 4 | 1.90666666666666666000 | 1.00000000000000000000 + 1 | 3 | 1.90666666666666666000 | 1.00000000000000000000 + 1 | 2 | 1.90666666666666666000 | 1.00000000000000000000 +(32 rows) + +SELECT user_id, sum(avg(user_id)) OVER () +FROM users_table +GROUP BY user_id +ORDER BY 1 +LIMIT 10; + user_id | sum +--------------------------------------------------------------------- + 1 | 21.00000000000000000000 + 2 | 21.00000000000000000000 + 3 | 21.00000000000000000000 + 4 | 21.00000000000000000000 + 5 | 21.00000000000000000000 + 6 | 21.00000000000000000000 +(6 rows) + +SELECT + user_id, + 1 + sum(value_1), + 1 + AVG(value_2) OVER (partition by user_id) +FROM + users_table +GROUP BY + user_id, value_2 +ORDER BY + user_id, value_2; + user_id | ?column? | ?column? +--------------------------------------------------------------------- + 1 | 5 | 3.2500000000000000 + 1 | 4 | 3.2500000000000000 + 1 | 6 | 3.2500000000000000 + 1 | 12 | 3.2500000000000000 + 2 | 3 | 3.5000000000000000 + 2 | 5 | 3.5000000000000000 + 2 | 13 | 3.5000000000000000 + 2 | 6 | 3.5000000000000000 + 2 | 17 | 3.5000000000000000 + 2 | 4 | 3.5000000000000000 + 3 | 3 | 4.0000000000000000 + 3 | 13 | 4.0000000000000000 + 3 | 10 | 4.0000000000000000 + 3 | 2 | 4.0000000000000000 + 3 | 17 | 4.0000000000000000 + 4 | 4 | 3.5000000000000000 + 4 | 28 | 3.5000000000000000 + 4 | 1 | 3.5000000000000000 + 4 | 11 | 3.5000000000000000 + 4 | 17 | 3.5000000000000000 + 4 | 8 | 3.5000000000000000 + 5 | 7 | 3.5000000000000000 + 5 | 17 | 3.5000000000000000 + 5 | 24 | 3.5000000000000000 + 5 | 9 | 3.5000000000000000 + 5 | 8 | 3.5000000000000000 + 5 | 10 | 3.5000000000000000 + 6 | 6 | 3.0000000000000000 + 6 | 3 | 3.0000000000000000 + 6 | 9 | 3.0000000000000000 + 6 | 3 | 3.0000000000000000 + 6 | 5 | 3.0000000000000000 +(32 rows) + +SELECT + user_id, + 1 + sum(value_1), + 1 + AVG(value_2) OVER (partition by user_id) +FROM + users_table +GROUP BY + user_id, value_2 +ORDER BY + 2 DESC, 1 +LIMIT 5; + user_id | ?column? | ?column? +--------------------------------------------------------------------- + 4 | 28 | 3.5000000000000000 + 5 | 24 | 3.5000000000000000 + 2 | 17 | 3.5000000000000000 + 3 | 17 | 4.0000000000000000 + 4 | 17 | 3.5000000000000000 +(5 rows) + +-- rank and ordering in the reverse order +SELECT + user_id, + avg(value_1), + RANK() OVER (partition by user_id order by value_2) +FROM + users_table +GROUP BY user_id, value_2 +ORDER BY user_id, value_2 DESC; + user_id | avg | rank +--------------------------------------------------------------------- + 1 | 3.6666666666666667 | 4 + 1 | 2.5000000000000000 | 3 + 1 | 3.0000000000000000 | 2 + 1 | 4.0000000000000000 | 1 + 2 | 1.5000000000000000 | 6 + 2 | 3.2000000000000000 | 5 + 2 | 1.6666666666666667 | 4 + 2 | 3.0000000000000000 | 3 + 2 | 1.3333333333333333 | 2 + 2 | 2.0000000000000000 | 1 + 3 | 2.6666666666666667 | 5 + 3 | 1.00000000000000000000 | 4 + 3 | 3.0000000000000000 | 3 + 3 | 2.4000000000000000 | 2 + 3 | 1.00000000000000000000 | 1 + 4 | 3.5000000000000000 | 6 + 4 | 3.2000000000000000 | 5 + 4 | 3.3333333333333333 | 4 + 4 | 0.00000000000000000000 | 3 + 4 | 3.0000000000000000 | 2 + 4 | 1.00000000000000000000 | 1 + 5 | 3.0000000000000000 | 6 + 5 | 2.3333333333333333 | 5 + 5 | 1.6000000000000000 | 4 + 5 | 2.8750000000000000 | 3 + 5 | 3.2000000000000000 | 2 + 5 | 3.0000000000000000 | 1 + 6 | 1.3333333333333333 | 5 + 6 | 2.0000000000000000 | 4 + 6 | 4.0000000000000000 | 3 + 6 | 1.00000000000000000000 | 2 + 6 | 2.5000000000000000 | 1 +(32 rows) + +-- order by in the window function is same as avg(value_1) DESC +SELECT + user_id, + avg(value_1), + RANK() OVER (partition by user_id order by 1 / (1 + avg(value_1))) +FROM + users_table +GROUP BY user_id, value_2 +ORDER BY user_id, avg(value_1) DESC; + user_id | avg | rank +--------------------------------------------------------------------- + 1 | 4.0000000000000000 | 1 + 1 | 3.6666666666666667 | 2 + 1 | 3.0000000000000000 | 3 + 1 | 2.5000000000000000 | 4 + 2 | 3.2000000000000000 | 1 + 2 | 3.0000000000000000 | 2 + 2 | 2.0000000000000000 | 3 + 2 | 1.6666666666666667 | 4 + 2 | 1.5000000000000000 | 5 + 2 | 1.3333333333333333 | 6 + 3 | 3.0000000000000000 | 1 + 3 | 2.6666666666666667 | 2 + 3 | 2.4000000000000000 | 3 + 3 | 1.00000000000000000000 | 4 + 3 | 1.00000000000000000000 | 4 + 4 | 3.5000000000000000 | 1 + 4 | 3.3333333333333333 | 2 + 4 | 3.2000000000000000 | 3 + 4 | 3.0000000000000000 | 4 + 4 | 1.00000000000000000000 | 5 + 4 | 0.00000000000000000000 | 6 + 5 | 3.2000000000000000 | 1 + 5 | 3.0000000000000000 | 2 + 5 | 3.0000000000000000 | 2 + 5 | 2.8750000000000000 | 4 + 5 | 2.3333333333333333 | 5 + 5 | 1.6000000000000000 | 6 + 6 | 4.0000000000000000 | 1 + 6 | 2.5000000000000000 | 2 + 6 | 2.0000000000000000 | 3 + 6 | 1.3333333333333333 | 4 + 6 | 1.00000000000000000000 | 5 +(32 rows) + +EXPLAIN (COSTS FALSE) +SELECT + user_id, + avg(value_1), + RANK() OVER (partition by user_id order by 1 / (1 + avg(value_1))) +FROM + users_table +GROUP BY user_id, value_2 +ORDER BY user_id, avg(value_1) DESC; + QUERY PLAN +--------------------------------------------------------------------- + Sort + Sort Key: remote_scan.user_id, remote_scan.avg DESC + -> Custom Scan (Citus Adaptive) + Task Count: 4 + Tasks Shown: One of 4 + -> Task + Node: host=localhost port=xxxxx dbname=regression + -> WindowAgg + -> Sort + Sort Key: users_table.user_id, (('1'::numeric / ('1'::numeric + avg(users_table.value_1)))) + -> HashAggregate + Group Key: users_table.user_id, users_table.value_2 + -> Seq Scan on users_table_1400256 users_table +(13 rows) + +-- order by in the window function is same as avg(value_1) DESC +SELECT + user_id, + avg(value_1), + RANK() OVER (partition by user_id order by 1 / (1 + avg(value_1))) +FROM + users_table +GROUP BY user_id, value_2 +ORDER BY user_id, avg(value_1) DESC; + user_id | avg | rank +--------------------------------------------------------------------- + 1 | 4.0000000000000000 | 1 + 1 | 3.6666666666666667 | 2 + 1 | 3.0000000000000000 | 3 + 1 | 2.5000000000000000 | 4 + 2 | 3.2000000000000000 | 1 + 2 | 3.0000000000000000 | 2 + 2 | 2.0000000000000000 | 3 + 2 | 1.6666666666666667 | 4 + 2 | 1.5000000000000000 | 5 + 2 | 1.3333333333333333 | 6 + 3 | 3.0000000000000000 | 1 + 3 | 2.6666666666666667 | 2 + 3 | 2.4000000000000000 | 3 + 3 | 1.00000000000000000000 | 4 + 3 | 1.00000000000000000000 | 4 + 4 | 3.5000000000000000 | 1 + 4 | 3.3333333333333333 | 2 + 4 | 3.2000000000000000 | 3 + 4 | 3.0000000000000000 | 4 + 4 | 1.00000000000000000000 | 5 + 4 | 0.00000000000000000000 | 6 + 5 | 3.2000000000000000 | 1 + 5 | 3.0000000000000000 | 2 + 5 | 3.0000000000000000 | 2 + 5 | 2.8750000000000000 | 4 + 5 | 2.3333333333333333 | 5 + 5 | 1.6000000000000000 | 6 + 6 | 4.0000000000000000 | 1 + 6 | 2.5000000000000000 | 2 + 6 | 2.0000000000000000 | 3 + 6 | 1.3333333333333333 | 4 + 6 | 1.00000000000000000000 | 5 +(32 rows) + +-- limit is not pushed down to worker !! +EXPLAIN (COSTS FALSE) +SELECT + user_id, + avg(value_1), + RANK() OVER (partition by user_id order by 1 / (1 + avg(value_1))) +FROM + users_table +GROUP BY user_id, value_2 +ORDER BY user_id, avg(value_1) DESC +LIMIT 5; + QUERY PLAN +--------------------------------------------------------------------- + Limit + -> Sort + Sort Key: remote_scan.user_id, remote_scan.avg DESC + -> Custom Scan (Citus Adaptive) + Task Count: 4 + Tasks Shown: One of 4 + -> Task + Node: host=localhost port=xxxxx dbname=regression + -> Limit + -> Sort + Sort Key: users_table.user_id, (avg(users_table.value_1)) DESC + -> WindowAgg + -> Sort + Sort Key: users_table.user_id, (('1'::numeric / ('1'::numeric + avg(users_table.value_1)))) + -> HashAggregate + Group Key: users_table.user_id, users_table.value_2 + -> Seq Scan on users_table_1400256 users_table +(17 rows) + +EXPLAIN (COSTS FALSE) +SELECT + user_id, + avg(value_1), + RANK() OVER (partition by user_id order by 1 / (1 + avg(value_1))) +FROM + users_table +GROUP BY user_id, value_2 +ORDER BY user_id, avg(value_1) DESC +LIMIT 5; + QUERY PLAN +--------------------------------------------------------------------- + Limit + -> Sort + Sort Key: remote_scan.user_id, remote_scan.avg DESC + -> Custom Scan (Citus Adaptive) + Task Count: 4 + Tasks Shown: One of 4 + -> Task + Node: host=localhost port=xxxxx dbname=regression + -> Limit + -> Sort + Sort Key: users_table.user_id, (avg(users_table.value_1)) DESC + -> WindowAgg + -> Sort + Sort Key: users_table.user_id, (('1'::numeric / ('1'::numeric + avg(users_table.value_1)))) + -> HashAggregate + Group Key: users_table.user_id, users_table.value_2 + -> Seq Scan on users_table_1400256 users_table +(17 rows) + +EXPLAIN (COSTS FALSE) +SELECT + user_id, + avg(value_1), + RANK() OVER (partition by user_id order by 1 / (1 + sum(value_2))) +FROM + users_table +GROUP BY user_id, value_2 +ORDER BY user_id, avg(value_1) DESC +LIMIT 5; + QUERY PLAN +--------------------------------------------------------------------- + Limit + -> Sort + Sort Key: remote_scan.user_id, remote_scan.avg DESC + -> Custom Scan (Citus Adaptive) + Task Count: 4 + Tasks Shown: One of 4 + -> Task + Node: host=localhost port=xxxxx dbname=regression + -> Limit + -> Sort + Sort Key: users_table.user_id, (avg(users_table.value_1)) DESC + -> WindowAgg + -> Sort + Sort Key: users_table.user_id, ((1 / (1 + sum(users_table.value_2)))) + -> HashAggregate + Group Key: users_table.user_id, users_table.value_2 + -> Seq Scan on users_table_1400256 users_table +(17 rows) + +EXPLAIN (COSTS FALSE) +SELECT + user_id, + avg(value_1), + RANK() OVER (partition by user_id order by sum(value_2)) +FROM + users_table +GROUP BY user_id, value_2 +ORDER BY user_id, avg(value_1) DESC +LIMIT 5; + QUERY PLAN +--------------------------------------------------------------------- + Limit + -> Sort + Sort Key: remote_scan.user_id, remote_scan.avg DESC + -> Custom Scan (Citus Adaptive) + Task Count: 4 + Tasks Shown: One of 4 + -> Task + Node: host=localhost port=xxxxx dbname=regression + -> Limit + -> Sort + Sort Key: users_table.user_id, (avg(users_table.value_1)) DESC + -> WindowAgg + -> Sort + Sort Key: users_table.user_id, (sum(users_table.value_2)) + -> HashAggregate + Group Key: users_table.user_id, users_table.value_2 + -> Seq Scan on users_table_1400256 users_table +(17 rows) + +-- Grouping can be pushed down with aggregates even when window function can't +EXPLAIN (COSTS FALSE) +SELECT user_id, count(value_1), stddev(value_1), count(user_id) OVER (PARTITION BY random()) +FROM users_table GROUP BY user_id HAVING avg(value_1) > 2 LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------- + Limit + -> WindowAgg + -> Sort + Sort Key: remote_scan.worker_column_5 + -> Custom Scan (Citus Adaptive) + Task Count: 4 + Tasks Shown: One of 4 + -> Task + Node: host=localhost port=xxxxx dbname=regression + -> HashAggregate + Group Key: user_id + Filter: (avg(value_1) > '2'::numeric) + -> Seq Scan on users_table_1400256 users_table +(13 rows) + +-- Window function with inlined CTE +WITH cte as ( + SELECT uref.id user_id, events_table.value_2, count(*) c + FROM events_table + JOIN users_ref_test_table uref ON uref.id = events_table.user_id + GROUP BY 1, 2 +) +SELECT DISTINCT cte.value_2, cte.c, sum(cte.value_2) OVER (PARTITION BY cte.c) +FROM cte JOIN events_table et ON et.value_2 = cte.value_2 and et.value_2 = cte.c +ORDER BY 1; + value_2 | c | sum +--------------------------------------------------------------------- + 3 | 3 | 108 + 4 | 4 | 56 +(2 rows) + +-- There was a strange bug where this wouldn't have window functions being pushed down +-- Bug dependent on column ordering +CREATE TABLE daily_uniques (value_2 float, user_id bigint); +SELECT create_distributed_table('daily_uniques', 'user_id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +EXPLAIN (COSTS FALSE) SELECT + user_id, + sum(value_2) AS commits, + RANK () OVER ( + PARTITION BY user_id + ORDER BY + sum(value_2) DESC + ) +FROM daily_uniques +GROUP BY user_id +HAVING + sum(value_2) > 0 +ORDER BY commits DESC +LIMIT 10; + QUERY PLAN +--------------------------------------------------------------------- + Limit + -> Sort + Sort Key: remote_scan.commits DESC + -> Custom Scan (Citus Adaptive) + Task Count: 4 + Tasks Shown: One of 4 + -> Task + Node: host=localhost port=xxxxx dbname=regression + -> Limit + -> Sort + Sort Key: (sum(daily_uniques.value_2)) DESC + -> WindowAgg + -> Sort + Sort Key: daily_uniques.user_id, (sum(daily_uniques.value_2)) DESC + -> HashAggregate + Group Key: daily_uniques.user_id + Filter: (sum(daily_uniques.value_2) > '0'::double precision) + -> Seq Scan on daily_uniques_xxxxxxx daily_uniques +(18 rows) + +DROP TABLE daily_uniques; +-- Partition by reference table column joined to distribution column +SELECT DISTINCT value_2, array_agg(rnk ORDER BY rnk) FROM ( +SELECT events_table.value_2, sum(uref.k_no) OVER (PARTITION BY uref.id) AS rnk +FROM events_table +JOIN users_ref_test_table uref ON uref.id = events_table.user_id) sq +GROUP BY 1 ORDER BY 1; + value_2 | array_agg +--------------------------------------------------------------------- + 0 | {686,686,816,816,987,987,1104} + 1 | {500,500,675,675,675,686,686,816,816,816,987,987,987,987,987,1104,1104,1104,1104,1104,1104,1104} + 2 | {500,500,500,500,675,675,675,675,675,686,686,686,686,816,816,816,816,816,987,987,987,987,987,987,987,1104,1104,1104,1104,1104,1104} + 3 | {500,500,500,500,675,686,686,686,816,816,987,987,987,1104,1104,1104,1104,1104} + 4 | {675,675,675,675,686,686,686,816,816,816,987,987,1104,1104} + 5 | {675,675,816,816,987,987,1104,1104,1104} +(6 rows) + +-- https://github.com/citusdata/citus/issues/3754 +select null = sum(null::int2) over () +from public.users_table as ut limit 1; + ?column? +--------------------------------------------------------------------- + +(1 row) + diff --git a/src/test/regress/sql/locally_execute_intermediate_results.sql b/src/test/regress/sql/locally_execute_intermediate_results.sql index 136cffc2a..bc0c1e04f 100644 --- a/src/test/regress/sql/locally_execute_intermediate_results.sql +++ b/src/test/regress/sql/locally_execute_intermediate_results.sql @@ -39,6 +39,15 @@ SELECT count(*) FROM table_2 +GROUP BY value +HAVING max(value) > (SELECT max FROM cte_1); + +-- in this case, the HAVING Is also pushed down +WITH cte_1 AS (SELECT max(value) FROM table_1) +SELECT +count(*) +FROM +table_2 GROUP BY key HAVING max(value) > (SELECT max FROM cte_1); @@ -88,9 +97,18 @@ SELECT count(*) FROM table_2 -GROUP BY key +GROUP BY value HAVING max(value) > (SELECT max FROM cte_1 JOIN cte_2 USING (max)); +-- same as above, but HAVING pushed down to workers +WITH cte_1 AS (SELECT max(value) FROM table_1), +cte_2 AS (SELECT max(value) FROM table_1) +SELECT +count(*) +FROM +table_2 +GROUP BY key +HAVING max(value) > (SELECT max FROM cte_1 JOIN cte_2 USING (max)); -- multiple CTEs are joined inside HAVING, so written to file -- locally, also the join tree contains only another CTE, so should be @@ -113,9 +131,17 @@ SELECT count(*) FROM table_2 -GROUP BY key +GROUP BY value HAVING max(value) > (SELECT max(max) FROM cte_1); +-- same as above, but with HAVING pushed down +WITH cte_1 AS (SELECT max(value) FROM table_1) +SELECT +count(*) +FROM +table_2 +GROUP BY key +HAVING max(value) > (SELECT max(max) FROM cte_1); -- two ctes are going to be written locally and executed locally WITH cte_1 AS (SELECT max(value) FROM table_1), @@ -221,6 +247,14 @@ SELECT * FROM -- the second subquery needs to be recursively planned due to non-colocated subquery join -- so cte_2 becomes part of master query of that recursive subquery planning +WITH cte_1 AS (SELECT max(value) FROM table_1), + cte_2 AS (SELECT max(value) FROM table_2) +SELECT * FROM + (SELECT value AS key FROM table_1 GROUP BY value HAVING max(value) > (SELECT * FROM cte_1)) as foo, + (SELECT value AS key FROM table_2 GROUP BY value HAVING max(value) > (SELECT * FROM cte_2)) as bar + WHERE foo.key != bar.key; + +-- similar to above, but having pushed down WITH cte_1 AS (SELECT max(value) FROM table_1), cte_2 AS (SELECT max(value) FROM table_2) SELECT * FROM @@ -228,13 +262,12 @@ SELECT * FROM (SELECT key FROM table_2 GROUP BY key HAVING max(value) > (SELECT * FROM cte_2)) as bar WHERE foo.key != bar.key; - -- now, forcing all subqueries to be on the local node WITH cte_1 AS (SELECT max(value) FROM table_1), cte_2 AS (SELECT max(value) FROM table_2) SELECT * FROM - (SELECT key FROM table_1 GROUP BY key HAVING max(value) > (SELECT * FROM cte_1) LIMIT 1) as foo, - (SELECT key FROM table_2 GROUP BY key HAVING max(value) > (SELECT * FROM cte_2) LIMIT 1) as bar + (SELECT value AS key FROM table_1 GROUP BY value HAVING max(value) > (SELECT * FROM cte_1) LIMIT 1) as foo, + (SELECT value AS key FROM table_2 GROUP BY value HAVING max(value) > (SELECT * FROM cte_2) LIMIT 1) as bar WHERE foo.key != bar.key; -- queries in which the last step has only CTEs can use local tables @@ -277,7 +310,7 @@ SELECT count(*) FROM table_2 -GROUP BY key +GROUP BY value HAVING max(value) > (SELECT max FROM cte_1); -- On non-mx case the subquery in the WHERE part of the query can be executed locally @@ -290,7 +323,7 @@ FROM table_2 WHERE key > (SELECT key FROM cte_2 ORDER BY 1 LIMIT 1) -GROUP BY key +GROUP BY value HAVING max(value) > (SELECT max FROM cte_1); -- subquery in the WHERE part of the query should not be executed locally @@ -328,7 +361,7 @@ SELECT count(*) FROM table_2 -GROUP BY key +GROUP BY value HAVING max(value) > (SELECT max FROM cte_1 JOIN cte_2 USING (max)); @@ -354,7 +387,7 @@ SELECT count(*) FROM table_2 -GROUP BY key +GROUP BY value HAVING max(value) > (SELECT max(max) FROM cte_1); @@ -477,8 +510,8 @@ SELECT * FROM WITH cte_1 AS (SELECT max(value) FROM table_1), cte_2 AS (SELECT max(value) FROM table_2) SELECT * FROM - (SELECT key FROM table_1 GROUP BY key HAVING max(value) > (SELECT * FROM cte_1)) as foo, - (SELECT key FROM table_2 GROUP BY key HAVING max(value) > (SELECT * FROM cte_2)) as bar + (SELECT value AS key FROM table_1 GROUP BY value HAVING max(value) > (SELECT * FROM cte_1)) as foo, + (SELECT value AS key FROM table_2 GROUP BY value HAVING max(value) > (SELECT * FROM cte_2)) as bar WHERE foo.key != bar.key; @@ -486,8 +519,8 @@ SELECT * FROM WITH cte_1 AS (SELECT max(value) FROM table_1), cte_2 AS (SELECT max(value) FROM table_2) SELECT * FROM - (SELECT key FROM table_1 GROUP BY key HAVING max(value) > (SELECT * FROM cte_1) LIMIT 1) as foo, - (SELECT key FROM table_2 GROUP BY key HAVING max(value) > (SELECT * FROM cte_2) LIMIT 1) as bar + (SELECT value AS key FROM table_1 GROUP BY value HAVING max(value) > (SELECT * FROM cte_1) LIMIT 1) as foo, + (SELECT value AS key FROM table_2 GROUP BY value HAVING max(value) > (SELECT * FROM cte_2) LIMIT 1) as bar WHERE foo.key != bar.key; -- finally, use round-robin policy on the workers with same set of queries @@ -499,7 +532,7 @@ SELECT count(*) FROM table_2 -GROUP BY key +GROUP BY value HAVING max(value) > (SELECT max FROM cte_1); -- On non-mx case the subquery in the WHERE part of the query can be executed locally @@ -564,7 +597,7 @@ SELECT count(*) FROM cte_3 -GROUP BY key +GROUP BY value HAVING max(value) > (SELECT max FROM cte_1 JOIN cte_2 USING (max)); -- now, the CTE is going to be written locally, @@ -576,7 +609,7 @@ SELECT count(*) FROM table_2 -GROUP BY key +GROUP BY value HAVING max(value) > (SELECT max(max) FROM cte_1); @@ -712,8 +745,8 @@ SELECT * FROM WITH cte_1 AS (SELECT max(value) FROM table_1), cte_2 AS (SELECT max(value) FROM table_2) SELECT * FROM - (SELECT key FROM table_1 GROUP BY key HAVING max(value) > (SELECT * FROM cte_1)) as foo, - (SELECT key FROM table_2 GROUP BY key HAVING max(value) > (SELECT * FROM cte_2)) as bar + (SELECT value AS key FROM table_1 GROUP BY value HAVING max(value) > (SELECT * FROM cte_1)) as foo, + (SELECT value AS key FROM table_2 GROUP BY value HAVING max(value) > (SELECT * FROM cte_2)) as bar WHERE foo.key != bar.key; @@ -721,8 +754,8 @@ SELECT * FROM WITH cte_1 AS (SELECT max(value) FROM table_1), cte_2 AS (SELECT max(value) FROM table_2) SELECT * FROM - (SELECT key FROM table_1 GROUP BY key HAVING max(value) > (SELECT * FROM cte_1) LIMIT 1) as foo, - (SELECT key FROM table_2 GROUP BY key HAVING max(value) > (SELECT * FROM cte_2) LIMIT 1) as bar + (SELECT value AS key FROM table_1 GROUP BY value HAVING max(value) > (SELECT * FROM cte_1) LIMIT 1) as foo, + (SELECT value AS key FROM table_2 GROUP BY value HAVING max(value) > (SELECT * FROM cte_2) LIMIT 1) as bar WHERE foo.key != bar.key; \c - - - :master_port diff --git a/src/test/regress/sql/subquery_in_targetlist.sql b/src/test/regress/sql/subquery_in_targetlist.sql index 8245c1a2a..a434e50f3 100644 --- a/src/test/regress/sql/subquery_in_targetlist.sql +++ b/src/test/regress/sql/subquery_in_targetlist.sql @@ -123,6 +123,12 @@ FROM events_table e GROUP BY e.user_id ORDER BY 1 LIMIT 3; +-- correlated subquery outside of a non-pushdownable aggregate +SELECT sum(e.user_id) + (SELECT max(value_3) FROM users_reference_table WHERE value_2 = e.value_2 GROUP BY user_id) +FROM events_table e +GROUP BY e.value_2 +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;