diff --git a/src/backend/distributed/commands/index.c b/src/backend/distributed/commands/index.c index cf68b90f6..81a037abc 100644 --- a/src/backend/distributed/commands/index.c +++ b/src/backend/distributed/commands/index.c @@ -249,51 +249,6 @@ CreateIndexStmtGetSchemaId(IndexStmt *createIndexStatement) return namespaceId; } - -/* - * ExecuteFunctionOnEachTableIndex executes the given indexProcessor function on each - * index of the given relation. - * It returns a list that is filled by the indexProcessor. - */ -List * -ExecuteFunctionOnEachTableIndex(Oid relationId, IndexProcesor indexProcessor) -{ - List *result = NIL; - ScanKeyData scanKey[1]; - int scanKeyCount = 1; - - PushOverrideEmptySearchPath(CurrentMemoryContext); - - /* open system catalog and scan all indexes that belong to this table */ - Relation pgIndex = table_open(IndexRelationId, AccessShareLock); - - ScanKeyInit(&scanKey[0], Anum_pg_index_indrelid, - BTEqualStrategyNumber, F_OIDEQ, relationId); - - SysScanDesc scanDescriptor = systable_beginscan(pgIndex, - IndexIndrelidIndexId, true, /* indexOK */ - NULL, scanKeyCount, scanKey); - - HeapTuple heapTuple = systable_getnext(scanDescriptor); - while (HeapTupleIsValid(heapTuple)) - { - Form_pg_index indexForm = (Form_pg_index) GETSTRUCT(heapTuple); - indexProcessor(indexForm, &result); - - heapTuple = systable_getnext(scanDescriptor); - } - - /* clean up scan and close system catalog */ - systable_endscan(scanDescriptor); - table_close(pgIndex, AccessShareLock); - - /* revert back to original search_path */ - PopOverrideSearchPath(); - - return result; -} - - /* * ExecuteFunctionOnEachTableIndex executes the given pgIndexProcessor function on each * index of the given relation. diff --git a/src/backend/distributed/executor/citus_custom_scan.c b/src/backend/distributed/executor/citus_custom_scan.c index 4a59512f2..106f47cbe 100644 --- a/src/backend/distributed/executor/citus_custom_scan.c +++ b/src/backend/distributed/executor/citus_custom_scan.c @@ -326,6 +326,7 @@ CitusBeginModifyScan(CustomScanState *node, EState *estate, int eflags) scanState->distributedPlan = currentPlan; Job *workerJob = currentPlan->workerJob; + Query *jobQuery = workerJob->jobQuery; if (ModifyJobNeedsEvaluation(workerJob)) @@ -367,6 +368,11 @@ CitusBeginModifyScan(CustomScanState *node, EState *estate, int eflags) RebuildQueryStrings(workerJob); } + if (workerJob->onDummyPlacement) { + /* if this job is on a dummy placement, then it doesn't operate on + an actual shard placement */ + return; + } /* * Now that we know the shard ID(s) we can acquire the necessary shard metadata * locks. Once we have the locks it's safe to load the placement metadata. @@ -375,6 +381,7 @@ CitusBeginModifyScan(CustomScanState *node, EState *estate, int eflags) /* prevent concurrent placement changes */ AcquireMetadataLocks(workerJob->taskList); + /* modify tasks are always assigned using first-replica policy */ workerJob->taskList = FirstReplicaAssignTaskList(workerJob->taskList); diff --git a/src/backend/distributed/planner/local_distributed_join_planner.c b/src/backend/distributed/planner/local_distributed_join_planner.c index e819ada8b..7fdf97af6 100644 --- a/src/backend/distributed/planner/local_distributed_join_planner.c +++ b/src/backend/distributed/planner/local_distributed_join_planner.c @@ -250,6 +250,8 @@ ShouldConvertLocalTableJoinsToSubqueries(Query *query, List *rangeTableList, plannerRestrictionContext, query); if (IsRouterPlannable(query, plannerRestrictionContext)) { + ereport(DEBUG1, (errmsg("local-distributed table joins will not be converted, " + "as the query is router plannable"))); return false; } return true; diff --git a/src/backend/distributed/planner/multi_router_planner.c b/src/backend/distributed/planner/multi_router_planner.c index 2b97da267..537091359 100644 --- a/src/backend/distributed/planner/multi_router_planner.c +++ b/src/backend/distributed/planner/multi_router_planner.c @@ -1754,6 +1754,7 @@ RouterJob(Query *originalQuery, PlannerRestrictionContext *plannerRestrictionCon Job *job = CreateJob(originalQuery); job->partitionKeyValue = partitionKeyValue; + job->onDummyPlacement = replacePrunedQueryWithDummy; if (originalQuery->resultRelation > 0) { @@ -1828,7 +1829,7 @@ GenerateSingleShardRouterTaskList(Job *job, List *relationShardList, placementList); } } - else if (shardId == INVALID_SHARD_ID) + else if (shardId == INVALID_SHARD_ID && !job->onDummyPlacement) { /* modification that prunes to 0 shards */ job->taskList = NIL; diff --git a/src/backend/distributed/utils/citus_copyfuncs.c b/src/backend/distributed/utils/citus_copyfuncs.c index 24caf6a8d..698e96449 100644 --- a/src/backend/distributed/utils/citus_copyfuncs.c +++ b/src/backend/distributed/utils/citus_copyfuncs.c @@ -101,6 +101,7 @@ copyJobInfo(Job *newnode, Job *from) COPY_NODE_FIELD(partitionKeyValue); COPY_NODE_FIELD(localPlannedStatements); COPY_SCALAR_FIELD(parametersInJobQueryResolved); + COPY_SCALAR_FIELD(onDummyPlacement); } diff --git a/src/include/distributed/commands.h b/src/include/distributed/commands.h index e24b47757..3461e2246 100644 --- a/src/include/distributed/commands.h +++ b/src/include/distributed/commands.h @@ -186,13 +186,8 @@ extern List * PostprocessIndexStmt(Node *node, const char *queryString); extern void ErrorIfUnsupportedAlterIndexStmt(AlterTableStmt *alterTableStatement); extern void MarkIndexValid(IndexStmt *indexStmt); -<<<<<<< HEAD extern List * ExecuteFunctionOnEachTableIndex(Oid relationId, PGIndexProcessor pgIndexProcessor); -======= -extern List * ExecuteFunctionOnEachTableIndex(Oid relationId, IndexProcesor - indexProcessor); ->>>>>>> Increase readability of the current structure /* objectaddress.c - forward declarations */ extern ObjectAddress CreateExtensionStmtObjectAddress(Node *stmt, bool missing_ok); diff --git a/src/include/distributed/multi_physical_planner.h b/src/include/distributed/multi_physical_planner.h index 24e60facd..c15c6bcf9 100644 --- a/src/include/distributed/multi_physical_planner.h +++ b/src/include/distributed/multi_physical_planner.h @@ -163,6 +163,7 @@ typedef struct Job * query. */ bool parametersInJobQueryResolved; + bool onDummyPlacement; } Job; diff --git a/src/test/regress/expected/citus_local_dist_joins.out b/src/test/regress/expected/citus_local_dist_joins.out new file mode 100644 index 000000000..dbbf37bfe --- /dev/null +++ b/src/test/regress/expected/citus_local_dist_joins.out @@ -0,0 +1,469 @@ +CREATE SCHEMA citus_local_dist_joins; +SET search_path TO citus_local_dist_joins; +SET client_min_messages to ERROR; +SELECT master_add_node('localhost', :master_port, groupId => 0); + master_add_node +--------------------------------------------------------------------- + 5 +(1 row) + +CREATE TABLE citus_local(key int, value text); +SELECT create_citus_local_table('citus_local'); + create_citus_local_table +--------------------------------------------------------------------- + +(1 row) + +CREATE TABLE postgres_table (key int, value text, value_2 jsonb); +CREATE TABLE reference_table (key int, value text, value_2 jsonb); +SELECT create_reference_table('reference_table'); + create_reference_table +--------------------------------------------------------------------- + +(1 row) + +CREATE TABLE distributed_table (key int, value text, value_2 jsonb); +SELECT create_distributed_table('distributed_table', 'key'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +CREATE TABLE distributed_table_pkey (key int primary key, value text, value_2 jsonb); +SELECT create_distributed_table('distributed_table_pkey', 'key'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +CREATE TABLE distributed_table_windex (key int primary key, value text, value_2 jsonb); +SELECT create_distributed_table('distributed_table_windex', 'key'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +CREATE UNIQUE INDEX key_index ON distributed_table_windex (key); +CREATE TABLE distributed_partitioned_table(key int, value text) PARTITION BY RANGE (key); +CREATE TABLE distributed_partitioned_table_1 PARTITION OF distributed_partitioned_table FOR VALUES FROM (0) TO (50); +CREATE TABLE distributed_partitioned_table_2 PARTITION OF distributed_partitioned_table FOR VALUES FROM (50) TO (200); +SELECT create_distributed_table('distributed_partitioned_table', 'key'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +CREATE TABLE local_partitioned_table(key int, value text) PARTITION BY RANGE (key); +CREATE TABLE local_partitioned_table_1 PARTITION OF local_partitioned_table FOR VALUES FROM (0) TO (50); +CREATE TABLE local_partitioned_table_2 PARTITION OF local_partitioned_table FOR VALUES FROM (50) TO (200); +CREATE TABLE distributed_table_composite (key int, value text, value_2 jsonb, primary key (key, value)); +SELECT create_distributed_table('distributed_table_composite', 'key'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +CREATE MATERIALIZED VIEW mv1 AS SELECT * FROM postgres_table; +CREATE MATERIALIZED VIEW mv2 AS SELECT * FROM distributed_table; +-- set log messages to debug1 so that we can see which tables are recursively planned. +SET client_min_messages TO DEBUG1; +INSERT INTO postgres_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO reference_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +DEBUG: distributed INSERT ... SELECT can only select from distributed tables +DEBUG: Collecting INSERT ... SELECT results on coordinator +INSERT INTO distributed_table_windex SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +DEBUG: distributed INSERT ... SELECT can only select from distributed tables +DEBUG: Collecting INSERT ... SELECT results on coordinator +INSERT INTO distributed_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +DEBUG: distributed INSERT ... SELECT can only select from distributed tables +DEBUG: Collecting INSERT ... SELECT results on coordinator +INSERT INTO distributed_table_pkey SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +DEBUG: distributed INSERT ... SELECT can only select from distributed tables +DEBUG: Collecting INSERT ... SELECT results on coordinator +INSERT INTO distributed_partitioned_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +DEBUG: distributed INSERT ... SELECT can only select from distributed tables +DEBUG: Collecting INSERT ... SELECT results on coordinator +INSERT INTO distributed_table_composite SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +DEBUG: distributed INSERT ... SELECT can only select from distributed tables +DEBUG: Collecting INSERT ... SELECT results on coordinator +INSERT INTO local_partitioned_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO citus_local SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +DEBUG: distributed INSERT ... SELECT can only select from distributed tables +DEBUG: Collecting INSERT ... SELECT results on coordinator +-- a unique index on key so dist table should be recursively planned +SELECT count(*) FROM citus_local JOIN distributed_table_windex USING(key); +DEBUG: Wrapping relation "citus_local" to a subquery: SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +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_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local JOIN citus_local_dist_joins.distributed_table_windex USING (key)) + count +--------------------------------------------------------------------- + 100 +(1 row) + +SELECT count(*) FROM citus_local JOIN distributed_table_windex USING(value); +DEBUG: Wrapping relation "citus_local" to a subquery: SELECT NULL::integer AS key, value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value FROM citus_local_dist_joins.citus_local WHERE true +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_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local JOIN citus_local_dist_joins.distributed_table_windex USING (value)) + count +--------------------------------------------------------------------- + 100 +(1 row) + +SELECT count(*) FROM citus_local JOIN distributed_table_windex ON citus_local.key = distributed_table_windex.key; +DEBUG: Wrapping relation "citus_local" to a subquery: SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +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_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local JOIN citus_local_dist_joins.distributed_table_windex ON ((citus_local.key OPERATOR(pg_catalog.=) distributed_table_windex.key))) + count +--------------------------------------------------------------------- + 100 +(1 row) + +SELECT count(*) FROM citus_local JOIN distributed_table_windex ON distributed_table_windex.key = 10; +DEBUG: Wrapping relation "distributed_table_windex" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM citus_local_dist_joins.distributed_table_windex WHERE (key OPERATOR(pg_catalog.=) 10) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM citus_local_dist_joins.distributed_table_windex WHERE (key OPERATOR(pg_catalog.=) 10) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (citus_local_dist_joins.citus_local JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table_windex ON ((distributed_table_windex.key OPERATOR(pg_catalog.=) 10))) + count +--------------------------------------------------------------------- + 100 +(1 row) + +-- no unique index, citus local table should be recursively planned +SELECT count(*) FROM citus_local JOIN distributed_table USING(key); +DEBUG: Wrapping relation "citus_local" to a subquery: SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +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_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local JOIN citus_local_dist_joins.distributed_table USING (key)) + count +--------------------------------------------------------------------- + 100 +(1 row) + +SELECT count(*) FROM citus_local JOIN distributed_table USING(value); +DEBUG: Wrapping relation "citus_local" to a subquery: SELECT NULL::integer AS key, value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value FROM citus_local_dist_joins.citus_local WHERE true +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_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local JOIN citus_local_dist_joins.distributed_table USING (value)) + count +--------------------------------------------------------------------- + 100 +(1 row) + +SELECT count(*) FROM citus_local JOIN distributed_table ON citus_local.key = distributed_table.key; +DEBUG: Wrapping relation "citus_local" to a subquery: SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +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_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local JOIN citus_local_dist_joins.distributed_table ON ((citus_local.key OPERATOR(pg_catalog.=) distributed_table.key))) + count +--------------------------------------------------------------------- + 100 +(1 row) + +SELECT count(*) FROM citus_local JOIN distributed_table ON distributed_table.key = 10; +DEBUG: Wrapping relation "citus_local" to a subquery: SELECT NULL::integer AS key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +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_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local JOIN citus_local_dist_joins.distributed_table ON ((distributed_table.key OPERATOR(pg_catalog.=) 10))) + count +--------------------------------------------------------------------- + 100 +(1 row) + +SELECT count(*) FROM citus_local JOIN distributed_table USING(key) JOIN postgres_table USING (key) JOIN reference_table USING(key); +DEBUG: Wrapping relation "citus_local" to a subquery: SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM citus_local_dist_joins.postgres_table WHERE true +DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM citus_local_dist_joins.postgres_table WHERE true +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_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local JOIN citus_local_dist_joins.distributed_table USING (key)) JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table USING (key)) JOIN citus_local_dist_joins.reference_table USING (key)) + count +--------------------------------------------------------------------- + 100 +(1 row) + +SELECT count(*) FROM distributed_partitioned_table JOIN postgres_table USING(key) JOIN reference_table USING (key) + JOIN citus_local USING(key) WHERE distributed_partitioned_table.key > 10 and distributed_partitioned_table.key = 10; +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM citus_local_dist_joins.postgres_table WHERE (key OPERATOR(pg_catalog.=) 10) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM citus_local_dist_joins.postgres_table WHERE (key OPERATOR(pg_catalog.=) 10) +DEBUG: Wrapping relation "citus_local" to a subquery: SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE (key OPERATOR(pg_catalog.=) 10) +DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE (key OPERATOR(pg_catalog.=) 10) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (((citus_local_dist_joins.distributed_partitioned_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table USING (key)) JOIN citus_local_dist_joins.reference_table USING (key)) JOIN (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local USING (key)) WHERE ((distributed_partitioned_table.key OPERATOR(pg_catalog.>) 10) AND (distributed_partitioned_table.key OPERATOR(pg_catalog.=) 10)) + count +--------------------------------------------------------------------- + 0 +(1 row) + +-- update +BEGIN; +SELECT COUNT(DISTINCT value) FROM citus_local; + count +--------------------------------------------------------------------- + 100 +(1 row) + +UPDATE + citus_local +SET + value = 'test' +FROM + distributed_table +WHERE + distributed_table.key = citus_local.key; +DEBUG: Wrapping relation "distributed_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM citus_local_dist_joins.distributed_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM citus_local_dist_joins.distributed_table WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE citus_local_dist_joins.citus_local SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table WHERE (distributed_table.key OPERATOR(pg_catalog.=) citus_local.key) +SELECT COUNT(DISTINCT value) FROM citus_local; + count +--------------------------------------------------------------------- + 1 +(1 row) + +ROLLBACK; +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table; + count +--------------------------------------------------------------------- + 100 +(1 row) + +UPDATE + distributed_table +SET + value = 'test' +FROM + citus_local +WHERE + distributed_table.key = citus_local.key; +DEBUG: Wrapping relation "citus_local" to a subquery: SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE citus_local_dist_joins.distributed_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local WHERE (distributed_table.key OPERATOR(pg_catalog.=) citus_local.key) +SELECT COUNT(DISTINCT value) FROM distributed_table; + count +--------------------------------------------------------------------- + 1 +(1 row) + +ROLLBACK; +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; + count +--------------------------------------------------------------------- + 100 +(1 row) + +UPDATE + distributed_table_pkey +SET + value = 'test' +FROM + citus_local +WHERE + distributed_table_pkey.key = citus_local.key; +DEBUG: Wrapping relation "citus_local" to a subquery: SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE citus_local_dist_joins.distributed_table_pkey SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local WHERE (distributed_table_pkey.key OPERATOR(pg_catalog.=) citus_local.key) +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; + count +--------------------------------------------------------------------- + 1 +(1 row) + +ROLLBACK; +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; + count +--------------------------------------------------------------------- + 100 +(1 row) + +UPDATE + distributed_table_windex +SET + value = 'test' +FROM + citus_local +WHERE + distributed_table_windex.key = citus_local.key; +DEBUG: Wrapping relation "citus_local" to a subquery: SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE citus_local_dist_joins.distributed_table_windex SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local WHERE (distributed_table_windex.key OPERATOR(pg_catalog.=) citus_local.key) +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; + count +--------------------------------------------------------------------- + 1 +(1 row) + +ROLLBACK; +BEGIN; +UPDATE + mv1 +SET + value = 'test' +FROM + citus_local +WHERE + mv1.key = citus_local.key; +ERROR: materialized views in modify queries are not supported +ROLLBACK; +BEGIN; +UPDATE + citus_local +SET + value = 'test' +FROM + mv1 +WHERE + mv1.key = citus_local.key; +ERROR: materialized views in modify queries are not supported +ROLLBACK; +BEGIN; +UPDATE + citus_local +SET + value = 'test' +FROM + mv2 +WHERE + mv2.key = citus_local.key; +ERROR: materialized views in modify queries are not supported +ROLLBACK; +-- DELETE operations +BEGIN; +SELECT COUNT(DISTINCT value) FROM citus_local; + count +--------------------------------------------------------------------- + 100 +(1 row) + +DELETE FROM + citus_local +USING + distributed_table +WHERE + distributed_table.key = citus_local.key; +DEBUG: Wrapping relation "distributed_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM citus_local_dist_joins.distributed_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM citus_local_dist_joins.distributed_table WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: DELETE FROM citus_local_dist_joins.citus_local USING (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table WHERE (distributed_table.key OPERATOR(pg_catalog.=) citus_local.key) +SELECT COUNT(DISTINCT value) FROM citus_local; + count +--------------------------------------------------------------------- + 0 +(1 row) + +ROLLBACK; +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table; + count +--------------------------------------------------------------------- + 100 +(1 row) + +DELETE FROM + distributed_table +USING + citus_local +WHERE + distributed_table.key = citus_local.key; +DEBUG: Wrapping relation "citus_local" to a subquery: SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: DELETE FROM citus_local_dist_joins.distributed_table USING (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local WHERE (distributed_table.key OPERATOR(pg_catalog.=) citus_local.key) +SELECT COUNT(DISTINCT value) FROM distributed_table; + count +--------------------------------------------------------------------- + 0 +(1 row) + +ROLLBACK; +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; + count +--------------------------------------------------------------------- + 100 +(1 row) + +DELETE FROM + distributed_table_pkey +USING + citus_local +WHERE + distributed_table_pkey.key = citus_local.key; +DEBUG: Wrapping relation "citus_local" to a subquery: SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: DELETE FROM citus_local_dist_joins.distributed_table_pkey USING (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local WHERE (distributed_table_pkey.key OPERATOR(pg_catalog.=) citus_local.key) +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; + count +--------------------------------------------------------------------- + 0 +(1 row) + +ROLLBACK; +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; + count +--------------------------------------------------------------------- + 100 +(1 row) + +DELETE FROM + distributed_table_windex +USING + citus_local +WHERE + distributed_table_windex.key = citus_local.key; +DEBUG: Wrapping relation "citus_local" to a subquery: SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM citus_local_dist_joins.citus_local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: DELETE FROM citus_local_dist_joins.distributed_table_windex USING (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local WHERE (distributed_table_windex.key OPERATOR(pg_catalog.=) citus_local.key) +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; + count +--------------------------------------------------------------------- + 0 +(1 row) + +ROLLBACK; +DELETE FROM + mv1 +USING + citus_local +WHERE + mv1.key = citus_local.key; +ERROR: materialized views in modify queries are not supported +DELETE FROM + citus_local +USING + mv1 +WHERE + mv1.key = citus_local.key; +ERROR: materialized views in modify queries are not supported +DELETE FROM + citus_local +USING + mv2 +WHERE + mv2.key = citus_local.key; +ERROR: materialized views in modify queries are not supported +SELECT count(*) FROM postgres_table JOIN (SELECT * FROM (SELECT * FROM distributed_table LIMIT 1) d1) d2 using (key) JOIN reference_table USING(key) JOIN citus_local USING (key) JOIN (SELECT * FROM citus_local) c1 USING (key) WHERE d2.key > 10 AND d2.key = 10; +DEBUG: push down of limit count: 1 +DEBUG: generating subplan XXX_1 for subquery SELECT key, value, value_2 FROM citus_local_dist_joins.distributed_table LIMIT 1 +DEBUG: generating subplan XXX_2 for subquery SELECT key, value FROM citus_local_dist_joins.citus_local +DEBUG: local-distributed table joins will not be converted, as the query is router plannable +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((((citus_local_dist_joins.postgres_table JOIN (SELECT d1.key, d1.value, d1.value_2 FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) d1) d2 USING (key)) JOIN citus_local_dist_joins.reference_table USING (key)) JOIN citus_local_dist_joins.citus_local USING (key)) JOIN (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) c1 USING (key)) WHERE ((d2.key OPERATOR(pg_catalog.>) 10) AND (d2.key OPERATOR(pg_catalog.=) 10)) + count +--------------------------------------------------------------------- + 0 +(1 row) + +SELECT count(*) FROM postgres_table JOIN (SELECT * FROM (SELECT * FROM distributed_table LIMIT 1) d1) d2 using (key) JOIN reference_table USING(key) JOIN citus_local USING (key) JOIN (SELECT * FROM citus_local) c1 USING (key) WHERE d2.key > 10 AND d2.key = 10; +DEBUG: push down of limit count: 1 +DEBUG: generating subplan XXX_1 for subquery SELECT key, value, value_2 FROM citus_local_dist_joins.distributed_table LIMIT 1 +DEBUG: generating subplan XXX_2 for subquery SELECT key, value FROM citus_local_dist_joins.citus_local +DEBUG: local-distributed table joins will not be converted, as the query is router plannable +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((((citus_local_dist_joins.postgres_table JOIN (SELECT d1.key, d1.value, d1.value_2 FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) d1) d2 USING (key)) JOIN citus_local_dist_joins.reference_table USING (key)) JOIN citus_local_dist_joins.citus_local USING (key)) JOIN (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) c1 USING (key)) WHERE ((d2.key OPERATOR(pg_catalog.>) 10) AND (d2.key OPERATOR(pg_catalog.=) 10)) + count +--------------------------------------------------------------------- + 0 +(1 row) + +SET client_min_messages to ERROR; +DROP TABLE citus_local; +SELECT master_remove_node('localhost', :master_port); + master_remove_node +--------------------------------------------------------------------- + +(1 row) + +\set VERBOSITY terse +DROP SCHEMA citus_local_dist_joins CASCADE; diff --git a/src/test/regress/expected/citus_local_tables_queries.out b/src/test/regress/expected/citus_local_tables_queries.out index 0529d6f02..6ccc25bf9 100644 --- a/src/test/regress/expected/citus_local_tables_queries.out +++ b/src/test/regress/expected/citus_local_tables_queries.out @@ -154,7 +154,7 @@ SELECT count(*) FROM ( SELECT *, random() FROM (SELECT *, random() FROM citus_local_table, distributed_table) as subquery_inner ) as subquery_top; -NOTICE: executing the command locally: SELECT NULL::integer AS a, NULL::integer AS b FROM citus_local_table_queries.citus_local_table_1509000 citus_local_table WHERE true OFFSET 0 +NOTICE: executing the command locally: SELECT NULL::integer AS a, NULL::integer AS b FROM citus_local_table_queries.citus_local_table_1509000 citus_local_table WHERE true count --------------------------------------------------------------------- 36 @@ -167,7 +167,7 @@ SELECT count(*) FROM FROM ( WITH cte_1 AS (SELECT *, random() FROM citus_local_table, distributed_table) SELECT * FROM cte_1) as subquery_inner ) as subquery_top; -NOTICE: executing the command locally: SELECT a, b FROM citus_local_table_queries.citus_local_table_1509000 citus_local_table WHERE true OFFSET 0 +NOTICE: executing the command locally: SELECT a, b FROM citus_local_table_queries.citus_local_table_1509000 citus_local_table WHERE true NOTICE: executing the command locally: SELECT count(*) AS count FROM (SELECT subquery_inner.a, subquery_inner.b, subquery_inner.a_1 AS a, subquery_inner.b_1 AS b, subquery_inner.random, random() AS random FROM (SELECT cte_1.a, cte_1.b, cte_1.a_1 AS a, cte_1.b_1 AS b, cte_1.random FROM (SELECT intermediate_result.a, intermediate_result.b, intermediate_result.a_1 AS a, intermediate_result.b_1 AS b, intermediate_result.random FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer, b integer, a_1 integer, b_1 integer, random double precision)) cte_1(a, b, a_1, b_1, random)) subquery_inner(a, b, a_1, b_1, random)) subquery_top(a, b, a_1, b_1, random, random_1) count --------------------------------------------------------------------- @@ -527,7 +527,7 @@ NOTICE: executing the command locally: SELECT a, b FROM citus_local_table_queri -- join between citus local tables and distributed tables would fail SELECT count(*) FROM citus_local_table, distributed_table; -NOTICE: executing the command locally: SELECT NULL::integer AS a, NULL::integer AS b FROM citus_local_table_queries.citus_local_table_1509000 citus_local_table WHERE true OFFSET 0 +NOTICE: executing the command locally: SELECT NULL::integer AS a, NULL::integer AS b FROM citus_local_table_queries.citus_local_table_1509000 citus_local_table WHERE true count --------------------------------------------------------------------- 36 @@ -654,7 +654,7 @@ NOTICE: executing the copy locally for shard xxxxx INSERT INTO citus_local_table SELECT distributed_table.* FROM distributed_table JOIN citus_local_table ON (true); -NOTICE: executing the command locally: SELECT NULL::integer AS a, NULL::integer AS b FROM citus_local_table_queries.citus_local_table_1509000 citus_local_table WHERE true OFFSET 0 +NOTICE: executing the command locally: SELECT NULL::integer AS a, NULL::integer AS b FROM citus_local_table_queries.citus_local_table_1509000 citus_local_table WHERE true NOTICE: executing the copy locally for shard xxxxx -- .. but when wrapped into a CTE, join works fine INSERT INTO citus_local_table @@ -699,12 +699,12 @@ UPDATE distributed_table SET b = 6 FROM citus_local_table WHERE citus_local_table.a = distributed_table.a; -NOTICE: executing the command locally: SELECT a, NULL::integer AS b FROM citus_local_table_queries.citus_local_table_1509000 citus_local_table WHERE true OFFSET 0 +NOTICE: executing the command locally: SELECT a, NULL::integer AS b FROM citus_local_table_queries.citus_local_table_1509000 citus_local_table WHERE true UPDATE reference_table SET b = 6 FROM citus_local_table WHERE citus_local_table.a = reference_table.a; -NOTICE: executing the command locally: SELECT a, NULL::integer AS b FROM citus_local_table_queries.citus_local_table_1509000 citus_local_table WHERE true OFFSET 0 +NOTICE: executing the command locally: SELECT a, NULL::integer AS b FROM citus_local_table_queries.citus_local_table_1509000 citus_local_table WHERE true NOTICE: executing the command locally: UPDATE citus_local_table_queries.reference_table_1509002 reference_table SET b = 6 FROM (SELECT intermediate_result.a, intermediate_result.b FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer, b integer)) citus_local_table WHERE (citus_local_table.a OPERATOR(pg_catalog.=) reference_table.a) -- should not work, add HINT use CTEs UPDATE citus_local_table @@ -717,13 +717,13 @@ UPDATE citus_local_table SET b = 6 FROM reference_table WHERE citus_local_table.a = reference_table.a; -NOTICE: executing the command locally: SELECT a, NULL::integer AS b FROM citus_local_table_queries.reference_table_1509002 reference_table WHERE true OFFSET 0 +NOTICE: executing the command locally: SELECT a, NULL::integer AS b FROM citus_local_table_queries.reference_table_1509002 reference_table WHERE true NOTICE: executing the command locally: UPDATE citus_local_table_queries.citus_local_table_1509000 citus_local_table SET b = 6 FROM (SELECT intermediate_result.a, intermediate_result.b FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer, b integer)) reference_table WHERE (citus_local_table.a OPERATOR(pg_catalog.=) reference_table.a) -- should not work, add HINT use CTEs DELETE FROM distributed_table USING citus_local_table WHERE citus_local_table.a = distributed_table.a; -NOTICE: executing the command locally: SELECT a, NULL::integer AS b FROM citus_local_table_queries.citus_local_table_1509000 citus_local_table WHERE true OFFSET 0 +NOTICE: executing the command locally: SELECT a, NULL::integer AS b FROM citus_local_table_queries.citus_local_table_1509000 citus_local_table WHERE true -- should not work, add HINT use CTEs DELETE FROM citus_local_table USING distributed_table @@ -732,13 +732,13 @@ NOTICE: executing the command locally: DELETE FROM citus_local_table_queries.ci DELETE FROM reference_table USING citus_local_table WHERE citus_local_table.a = reference_table.a; -NOTICE: executing the command locally: SELECT a, NULL::integer AS b FROM citus_local_table_queries.citus_local_table_1509000 citus_local_table WHERE true OFFSET 0 +NOTICE: executing the command locally: SELECT a, NULL::integer AS b FROM citus_local_table_queries.citus_local_table_1509000 citus_local_table WHERE true NOTICE: executing the command locally: DELETE FROM citus_local_table_queries.reference_table_1509002 reference_table USING (SELECT intermediate_result.a, intermediate_result.b FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer, b integer)) citus_local_table WHERE (citus_local_table.a OPERATOR(pg_catalog.=) reference_table.a) -- should work, add HINT use CTEs DELETE FROM citus_local_table USING reference_table WHERE citus_local_table.a = reference_table.a; -NOTICE: executing the command locally: SELECT a, NULL::integer AS b FROM citus_local_table_queries.reference_table_1509002 reference_table WHERE true OFFSET 0 +NOTICE: executing the command locally: SELECT a, NULL::integer AS b FROM citus_local_table_queries.reference_table_1509002 reference_table WHERE true NOTICE: executing the command locally: DELETE FROM citus_local_table_queries.citus_local_table_1509000 citus_local_table USING (SELECT intermediate_result.a, intermediate_result.b FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer, b integer)) reference_table WHERE (citus_local_table.a OPERATOR(pg_catalog.=) reference_table.a) -- just works DELETE FROM citus_local_table @@ -795,8 +795,8 @@ JOIN citus_local_table_2 USING (a) JOIN distributed_table USING (a); -- should fail as view contains direct local dist join SELECT count(*) FROM view_2; -NOTICE: executing the command locally: SELECT a, NULL::integer AS b FROM citus_local_table_queries.citus_local_table_1509000 citus_local_table WHERE true OFFSET 0 -NOTICE: executing the command locally: SELECT a, NULL::integer AS b FROM citus_local_table_queries.citus_local_table_2_1509001 citus_local_table_2 WHERE true OFFSET 0 +NOTICE: executing the command locally: SELECT a, NULL::integer AS b FROM citus_local_table_queries.citus_local_table_1509000 citus_local_table WHERE true +NOTICE: executing the command locally: SELECT a, NULL::integer AS b FROM citus_local_table_queries.citus_local_table_2_1509001 citus_local_table_2 WHERE true NOTICE: executing the command locally: SELECT count(*) AS count FROM (SELECT intermediate_result.count FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(count bigint)) view_2 count --------------------------------------------------------------------- diff --git a/src/test/regress/expected/dml_recursive.out b/src/test/regress/expected/dml_recursive.out index ff75e6277..304e53218 100644 --- a/src/test/regress/expected/dml_recursive.out +++ b/src/test/regress/expected/dml_recursive.out @@ -352,8 +352,8 @@ FROM distributed_table WHERE distributed_table.tenant_id = local_table.id; -DEBUG: Wrapping relation "distributed_table" to a subquery: SELECT tenant_id, NULL::integer AS dept, NULL::jsonb AS info FROM recursive_dml_queries.distributed_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT tenant_id, NULL::integer AS dept, NULL::jsonb AS info FROM recursive_dml_queries.distributed_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "distributed_table" to a subquery: SELECT tenant_id, NULL::integer AS dept, NULL::jsonb AS info FROM recursive_dml_queries.distributed_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT tenant_id, NULL::integer AS dept, NULL::jsonb AS info FROM recursive_dml_queries.distributed_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE recursive_dml_queries.local_table SET id = 'citus_test'::text FROM (SELECT intermediate_result.tenant_id, intermediate_result.dept, intermediate_result.info FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(tenant_id text, dept integer, info jsonb)) distributed_table WHERE (distributed_table.tenant_id OPERATOR(pg_catalog.=) local_table.id) RESET client_min_messages; DROP SCHEMA recursive_dml_queries CASCADE; diff --git a/src/test/regress/expected/local_dist_join_mixed.out b/src/test/regress/expected/local_dist_join_mixed.out new file mode 100644 index 000000000..95cf94ff9 --- /dev/null +++ b/src/test/regress/expected/local_dist_join_mixed.out @@ -0,0 +1,1532 @@ +CREATE SCHEMA local_dist_join_mixed; +SET search_path TO local_dist_join_mixed; +CREATE TABLE distributed (id bigserial PRIMARY KEY, + name text, + created_at timestamptz DEFAULT now()); +CREATE TABLE reference (id bigserial PRIMARY KEY, + title text); +CREATE TABLE local (id bigserial PRIMARY KEY, + title text); +-- these above restrictions brought us to the following schema +SELECT create_reference_table('reference'); + create_reference_table +--------------------------------------------------------------------- + +(1 row) + +SELECT create_distributed_table('distributed', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +INSERT INTO distributed SELECT i, i::text, now() FROM generate_series(0,100)i; +INSERT INTO reference SELECT i, i::text FROM generate_series(0,100)i; +INSERT INTO local SELECT i, i::text FROM generate_series(0,100)i; +SET client_min_messages to DEBUG1; +-- very simple 1-1 Joins +SELECT count(*) FROM distributed JOIN local USING (id); +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_dist_join_mixed.distributed JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) + count +--------------------------------------------------------------------- + 101 +(1 row) + +SELECT count(*) FROM distributed JOIN local ON (name = title); +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_dist_join_mixed.distributed JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON ((distributed.name OPERATOR(pg_catalog.=) local.title))) + count +--------------------------------------------------------------------- + 101 +(1 row) + +SELECT count(*) FROM distributed d1 JOIN local ON (name = d1.id::text); +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_dist_join_mixed.distributed d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON ((d1.name OPERATOR(pg_catalog.=) (d1.id)::text))) + count +--------------------------------------------------------------------- + 10201 +(1 row) + +SELECT count(*) FROM distributed d1 JOIN local ON (name = d1.id::text AND d1.id < local.title::int); +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_dist_join_mixed.distributed d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON (((d1.name OPERATOR(pg_catalog.=) (d1.id)::text) AND (d1.id OPERATOR(pg_catalog.<) (local.title)::integer)))) + count +--------------------------------------------------------------------- + 5050 +(1 row) + +SELECT count(*) FROM distributed d1 JOIN local ON (name = d1.id::text AND d1.id < local.title::int) WHERE d1.id = 1; +DEBUG: Wrapping relation "distributed" to a subquery: SELECT id, name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed d1 WHERE ((name OPERATOR(pg_catalog.=) (id)::text) AND (id OPERATOR(pg_catalog.=) 1)) +DEBUG: generating subplan XXX_1 for subquery SELECT id, name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed d1 WHERE ((name OPERATOR(pg_catalog.=) (id)::text) AND (id OPERATOR(pg_catalog.=) 1)) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.id, intermediate_result.name, intermediate_result.created_at FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, name text, created_at timestamp with time zone)) d1 JOIN local_dist_join_mixed.local ON (((d1.name OPERATOR(pg_catalog.=) (d1.id)::text) AND (d1.id OPERATOR(pg_catalog.<) (local.title)::integer)))) WHERE (d1.id OPERATOR(pg_catalog.=) 1) + count +--------------------------------------------------------------------- + 99 +(1 row) + +SELECT count(*) FROM distributed JOIN local USING (id) WHERE false; +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE false +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE false +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_dist_join_mixed.distributed JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) WHERE false + count +--------------------------------------------------------------------- + 0 +(1 row) + +SELECT count(*) FROM distributed d1 JOIN local ON (name = d1.id::text AND d1.id < local.title::int) WHERE d1.id = 1 OR True; +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_dist_join_mixed.distributed d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON (((d1.name OPERATOR(pg_catalog.=) (d1.id)::text) AND (d1.id OPERATOR(pg_catalog.<) (local.title)::integer)))) WHERE ((d1.id OPERATOR(pg_catalog.=) 1) OR true) + count +--------------------------------------------------------------------- + 5050 +(1 row) + +SELECT count(*) FROM distributed d1 JOIN local ON (name::int + local.id > d1.id AND d1.id < local.title::int) WHERE d1.id = 1; +DEBUG: Wrapping relation "distributed" to a subquery: SELECT id, name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed d1 WHERE (id OPERATOR(pg_catalog.=) 1) +DEBUG: generating subplan XXX_1 for subquery SELECT id, name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed d1 WHERE (id OPERATOR(pg_catalog.=) 1) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.id, intermediate_result.name, intermediate_result.created_at FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, name text, created_at timestamp with time zone)) d1 JOIN local_dist_join_mixed.local ON (((((d1.name)::integer OPERATOR(pg_catalog.+) local.id) OPERATOR(pg_catalog.>) d1.id) AND (d1.id OPERATOR(pg_catalog.<) (local.title)::integer)))) WHERE (d1.id OPERATOR(pg_catalog.=) 1) + count +--------------------------------------------------------------------- + 99 +(1 row) + +SELECT count(*) FROM distributed JOIN local ON (hashtext(name) = hashtext(title)); +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_dist_join_mixed.distributed JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON ((hashtext(distributed.name) OPERATOR(pg_catalog.=) hashtext(local.title)))) + count +--------------------------------------------------------------------- + 101 +(1 row) + +SELECT hashtext(local.id::text) FROM distributed JOIN local ON (hashtext(name) = hashtext(title)) ORDER BY 1 LIMIT 4; +DEBUG: Wrapping relation "local" to a subquery: SELECT id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT hashtext((local.id)::text) AS hashtext FROM (local_dist_join_mixed.distributed JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON ((hashtext(distributed.name) OPERATOR(pg_catalog.=) hashtext(local.title)))) ORDER BY (hashtext((local.id)::text)) LIMIT 4 +DEBUG: push down of limit count: 4 + hashtext +--------------------------------------------------------------------- + -2114455578 + -2097988278 + -1997006946 + -1985772843 +(4 rows) + +SELECT '' as "xxx", local.*, 'xxx' as "test" FROM distributed JOIN local ON (hashtext(name) = hashtext(title)) ORDER BY 1,2,3 LIMIT 4; +DEBUG: Wrapping relation "local" to a subquery: SELECT id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT ''::text AS xxx, local.id, local.title, 'xxx'::text AS test FROM (local_dist_join_mixed.distributed JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON ((hashtext(distributed.name) OPERATOR(pg_catalog.=) hashtext(local.title)))) ORDER BY ''::text, local.id, local.title LIMIT 4 +DEBUG: push down of limit count: 4 + xxx | id | title | test +--------------------------------------------------------------------- + | 0 | 0 | xxx + | 1 | 1 | xxx + | 2 | 2 | xxx + | 3 | 3 | xxx +(4 rows) + +SELECT local.title, count(*) FROM distributed JOIN local USING (id) GROUP BY 1 ORDER BY 1, 2 DESC LIMIT 5; +DEBUG: Wrapping relation "local" to a subquery: SELECT id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT local.title, count(*) AS count FROM (local_dist_join_mixed.distributed JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) GROUP BY local.title ORDER BY local.title, (count(*)) DESC LIMIT 5 + title | count +--------------------------------------------------------------------- + 0 | 1 + 1 | 1 + 10 | 1 + 100 | 1 + 11 | 1 +(5 rows) + +SELECT distributed.id as id1, local.id as id2 FROM distributed JOIN local USING(id) ORDER BY distributed.id + local.id LIMIT 5; +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT distributed.id AS id1, local.id AS id2 FROM (local_dist_join_mixed.distributed JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) ORDER BY (distributed.id OPERATOR(pg_catalog.+) local.id) LIMIT 5 +DEBUG: push down of limit count: 5 + id1 | id2 +--------------------------------------------------------------------- + 0 | 0 + 1 | 1 + 2 | 2 + 3 | 3 + 4 | 4 +(5 rows) + +SELECT distributed.id as id1, local.id as id2, count(*) FROM distributed JOIN local USING(id) GROUP BY distributed.id, local.id ORDER BY 1,2 LIMIT 5; +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT distributed.id AS id1, local.id AS id2, count(*) AS count FROM (local_dist_join_mixed.distributed JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) GROUP BY distributed.id, local.id ORDER BY distributed.id, local.id LIMIT 5 +DEBUG: push down of limit count: 5 + id1 | id2 | count +--------------------------------------------------------------------- + 0 | 0 | 1 + 1 | 1 | 1 + 2 | 2 | 1 + 3 | 3 | 1 + 4 | 4 | 1 +(5 rows) + +-- basic subqueries that cannot be pulled up +SELECT count(*) FROM (SELECT *, random() FROM distributed) as d1 JOIN local USING (id); +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed.id, distributed.name, distributed.created_at, random() AS random FROM local_dist_join_mixed.distributed) d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) + count +--------------------------------------------------------------------- + 101 +(1 row) + +SELECT count(*) FROM (SELECT *, random() FROM distributed) as d1 JOIN local ON (name = title); +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed.id, distributed.name, distributed.created_at, random() AS random FROM local_dist_join_mixed.distributed) d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON ((d1.name OPERATOR(pg_catalog.=) local.title))) + count +--------------------------------------------------------------------- + 101 +(1 row) + +SELECT count(*) FROM (SELECT *, random() FROM distributed) as d1 JOIN local ON (name = d1.id::text); +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed.id, distributed.name, distributed.created_at, random() AS random FROM local_dist_join_mixed.distributed) d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON ((d1.name OPERATOR(pg_catalog.=) (d1.id)::text))) + count +--------------------------------------------------------------------- + 10201 +(1 row) + +SELECT count(*) FROM (SELECT *, random() FROM distributed) as d1 JOIN local ON (name = d1.id::text AND d1.id < local.title::int); +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed.id, distributed.name, distributed.created_at, random() AS random FROM local_dist_join_mixed.distributed) d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON (((d1.name OPERATOR(pg_catalog.=) (d1.id)::text) AND (d1.id OPERATOR(pg_catalog.<) (local.title)::integer)))) + count +--------------------------------------------------------------------- + 5050 +(1 row) + +SELECT count(*) FROM (SELECT *, random() FROM distributed) as d1 JOIN local ON (name = d1.id::text AND d1.id < local.title::int) WHERE d1.id = 1; +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed.id, distributed.name, distributed.created_at, random() AS random FROM local_dist_join_mixed.distributed) d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON (((d1.name OPERATOR(pg_catalog.=) (d1.id)::text) AND (d1.id OPERATOR(pg_catalog.<) (local.title)::integer)))) WHERE (d1.id OPERATOR(pg_catalog.=) 1) + count +--------------------------------------------------------------------- + 99 +(1 row) + +SELECT count(*) FROM (SELECT *, random() FROM distributed) as d1 JOIN local ON (name = d1.id::text AND d1.id < local.title::int) WHERE d1.id = 1 AND false; +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE ((id OPERATOR(pg_catalog.<) (title)::integer) AND false) +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE ((id OPERATOR(pg_catalog.<) (title)::integer) AND false) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed.id, distributed.name, distributed.created_at, random() AS random FROM local_dist_join_mixed.distributed) d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON (((d1.name OPERATOR(pg_catalog.=) (d1.id)::text) AND (d1.id OPERATOR(pg_catalog.<) (local.title)::integer)))) WHERE ((d1.id OPERATOR(pg_catalog.=) 1) AND false) + count +--------------------------------------------------------------------- + 0 +(1 row) + +SELECT count(*) FROM (SELECT *, random() FROM distributed) as d1 JOIN local ON (name = d1.id::text AND d1.id < local.title::int) WHERE d1.id = 1 OR true; +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed.id, distributed.name, distributed.created_at, random() AS random FROM local_dist_join_mixed.distributed) d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON (((d1.name OPERATOR(pg_catalog.=) (d1.id)::text) AND (d1.id OPERATOR(pg_catalog.<) (local.title)::integer)))) WHERE ((d1.id OPERATOR(pg_catalog.=) 1) OR true) + count +--------------------------------------------------------------------- + 5050 +(1 row) + +-- pull up subqueries as they are pretty simple, local table should be recursively planned +SELECT count(*) FROM (SELECT * FROM distributed) as d1 JOIN local USING (id); +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed.id, distributed.name, distributed.created_at FROM local_dist_join_mixed.distributed) d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) + count +--------------------------------------------------------------------- + 101 +(1 row) + +SELECT count(*) FROM (SELECT * FROM distributed) as d1 JOIN local ON (name = title); +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed.id, distributed.name, distributed.created_at FROM local_dist_join_mixed.distributed) d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON ((d1.name OPERATOR(pg_catalog.=) local.title))) + count +--------------------------------------------------------------------- + 101 +(1 row) + +SELECT count(*) FROM (SELECT * FROM distributed) as d1 JOIN local ON (name = d1.id::text); +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed.id, distributed.name, distributed.created_at FROM local_dist_join_mixed.distributed) d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON ((d1.name OPERATOR(pg_catalog.=) (d1.id)::text))) + count +--------------------------------------------------------------------- + 10201 +(1 row) + +SELECT count(*) FROM (SELECT * FROM distributed) as d1 JOIN local ON (name = d1.id::text AND d1.id < local.title::int); +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed.id, distributed.name, distributed.created_at FROM local_dist_join_mixed.distributed) d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON (((d1.name OPERATOR(pg_catalog.=) (d1.id)::text) AND (d1.id OPERATOR(pg_catalog.<) (local.title)::integer)))) + count +--------------------------------------------------------------------- + 5050 +(1 row) + +SELECT count(*) FROM (SELECT * FROM distributed) as d1 JOIN local ON (name = d1.id::text AND d1.id < local.title::int) WHERE d1.id = 1; +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed.id, distributed.name, distributed.created_at FROM local_dist_join_mixed.distributed) d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON (((d1.name OPERATOR(pg_catalog.=) (d1.id)::text) AND (d1.id OPERATOR(pg_catalog.<) (local.title)::integer)))) WHERE (d1.id OPERATOR(pg_catalog.=) 1) + count +--------------------------------------------------------------------- + 99 +(1 row) + +SELECT count(*) FROM (SELECT * FROM distributed) as d1 JOIN local ON (name = d1.id::text AND d1.id < local.title::int) WHERE d1.id = 1 AND false; +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE ((id OPERATOR(pg_catalog.<) (title)::integer) AND false) +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE ((id OPERATOR(pg_catalog.<) (title)::integer) AND false) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed.id, distributed.name, distributed.created_at FROM local_dist_join_mixed.distributed) d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON (((d1.name OPERATOR(pg_catalog.=) (d1.id)::text) AND (d1.id OPERATOR(pg_catalog.<) (local.title)::integer)))) WHERE ((d1.id OPERATOR(pg_catalog.=) 1) AND false) + count +--------------------------------------------------------------------- + 0 +(1 row) + +SELECT count(*) FROM (SELECT * FROM distributed) as d1 JOIN local ON (name = d1.id::text AND d1.id < local.title::int) WHERE d1.id = 1 OR true; +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed.id, distributed.name, distributed.created_at FROM local_dist_join_mixed.distributed) d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON (((d1.name OPERATOR(pg_catalog.=) (d1.id)::text) AND (d1.id OPERATOR(pg_catalog.<) (local.title)::integer)))) WHERE ((d1.id OPERATOR(pg_catalog.=) 1) OR true) + count +--------------------------------------------------------------------- + 5050 +(1 row) + +SELECT count(*) FROM (SELECT * FROM distributed WHERE id = 2) as d1 JOIN local ON (name = d1.id::text AND d1.id < local.title::int) WHERE d1.id = 1; +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE ((id OPERATOR(pg_catalog.<) (title)::integer) AND false) +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE ((id OPERATOR(pg_catalog.<) (title)::integer) AND false) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed.id, distributed.name, distributed.created_at FROM local_dist_join_mixed.distributed WHERE (distributed.id OPERATOR(pg_catalog.=) 2)) d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON (((d1.name OPERATOR(pg_catalog.=) (d1.id)::text) AND (d1.id OPERATOR(pg_catalog.<) (local.title)::integer)))) WHERE (d1.id OPERATOR(pg_catalog.=) 1) + count +--------------------------------------------------------------------- + 0 +(1 row) + +SELECT count(*) FROM (SELECT * FROM distributed WHERE false) as d1 JOIN local ON (name = d1.id::text AND d1.id < local.title::int) WHERE d1.id = 1; +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE (false AND (id OPERATOR(pg_catalog.<) (title)::integer)) +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, title FROM local_dist_join_mixed.local WHERE (false AND (id OPERATOR(pg_catalog.<) (title)::integer)) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed.id, distributed.name, distributed.created_at FROM local_dist_join_mixed.distributed WHERE false) d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local ON (((d1.name OPERATOR(pg_catalog.=) (d1.id)::text) AND (d1.id OPERATOR(pg_catalog.<) (local.title)::integer)))) WHERE (d1.id OPERATOR(pg_catalog.=) 1) + count +--------------------------------------------------------------------- + 0 +(1 row) + +-- TEMPORARY table +CREATE TEMPORARY TABLE temp_local AS SELECT * FROM local; +SELECT count(*) FROM distributed JOIN temp_local USING (id); +DEBUG: Wrapping relation "temp_local" to a subquery: SELECT id, NULL::text AS title FROM temp_local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM temp_local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_dist_join_mixed.distributed JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) temp_local USING (id)) + count +--------------------------------------------------------------------- + 101 +(1 row) + +-- UNLOGGED table +CREATE UNLOGGED TABLE unlogged_local AS SELECT * FROM local; +SELECT count(*) FROM distributed JOIN unlogged_local USING (id); +DEBUG: Wrapping relation "unlogged_local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.unlogged_local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.unlogged_local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_dist_join_mixed.distributed JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) unlogged_local USING (id)) + count +--------------------------------------------------------------------- + 101 +(1 row) + +-- mat view +CREATE MATERIALIZED VIEW mat_view AS SELECT * FROM local; +SELECT count(*) FROM distributed JOIN mat_view USING (id); +DEBUG: Wrapping relation "mat_view" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.mat_view WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.mat_view WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_dist_join_mixed.distributed JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) mat_view USING (id)) + count +--------------------------------------------------------------------- + 101 +(1 row) + +CREATE VIEW local_regular_view AS SELECT * FROM local; +CREATE VIEW dist_regular_view AS SELECT * FROM distributed; +SELECT count(*) FROM distributed JOIN local_regular_view USING (id); +DEBUG: generating subplan XXX_1 for subquery SELECT local.id, local.title FROM local_dist_join_mixed.local +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_dist_join_mixed.distributed JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local_regular_view USING (id)) + count +--------------------------------------------------------------------- + 101 +(1 row) + +SELECT count(*) FROM local JOIN dist_regular_view USING (id); +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local JOIN (SELECT distributed.id, distributed.name, distributed.created_at FROM local_dist_join_mixed.distributed) dist_regular_view USING (id)) + count +--------------------------------------------------------------------- + 101 +(1 row) + +SELECT count(*) FROM dist_regular_view JOIN local_regular_view USING (id); +DEBUG: generating subplan XXX_1 for subquery SELECT local.id, local.title FROM local_dist_join_mixed.local +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed.id, distributed.name, distributed.created_at FROM local_dist_join_mixed.distributed) dist_regular_view JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local_regular_view USING (id)) + count +--------------------------------------------------------------------- + 101 +(1 row) + +-- join alias/table alias +SELECT COUNT(*) FROM (distributed JOIN local USING (id)) AS t(a,b,c,d) ORDER BY d,c,a,b LIMIT 3; +ERROR: column "local.title" must appear in the GROUP BY clause or be used in an aggregate function +SELECT COUNT(*) FROM (distributed d1(x,y,y1) JOIN local l1(x,t) USING (x)) AS t(a,b,c,d) ORDER BY d,c,a,b LIMIT 3; +ERROR: column "l1.t" must appear in the GROUP BY clause or be used in an aggregate function +-- final queries are pushdown queries +SELECT sum(d1.id + local.id) FROM distributed d1 JOIN local USING (id); +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT sum((d1.id OPERATOR(pg_catalog.+) local.id)) AS sum FROM (local_dist_join_mixed.distributed d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) + sum +--------------------------------------------------------------------- + 10100 +(1 row) + +SELECT sum(d1.id + local.id) OVER (PARTITION BY d1.id) FROM distributed d1 JOIN local USING (id) ORDER BY 1 DESC LIMIT 4; +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT sum((d1.id OPERATOR(pg_catalog.+) local.id)) OVER (PARTITION BY d1.id) AS sum FROM (local_dist_join_mixed.distributed d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) ORDER BY (sum((d1.id OPERATOR(pg_catalog.+) local.id)) OVER (PARTITION BY d1.id)) DESC LIMIT 4 +DEBUG: push down of limit count: 4 + sum +--------------------------------------------------------------------- + 200 + 198 + 196 + 194 +(4 rows) + +SELECT count(*) FROM distributed d1 JOIN local USING (id) LEFT JOIN distributed d2 USING (id) ORDER BY 1 DESC LIMIT 4; +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((local_dist_join_mixed.distributed d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) LEFT JOIN local_dist_join_mixed.distributed d2 USING (id)) ORDER BY (count(*)) DESC LIMIT 4 +DEBUG: push down of limit count: 4 + count +--------------------------------------------------------------------- + 101 +(1 row) + +SELECT count(DISTINCT d1.name::int * local.id) FROM distributed d1 JOIN local USING (id); +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(DISTINCT ((d1.name)::integer OPERATOR(pg_catalog.*) local.id)) AS count FROM (local_dist_join_mixed.distributed d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) + count +--------------------------------------------------------------------- + 101 +(1 row) + +-- final queries are router queries +SELECT sum(d1.id + local.id) FROM distributed d1 JOIN local USING (id) WHERE d1.id = 1; +DEBUG: Wrapping relation "distributed" to a subquery: SELECT id, NULL::text AS name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed d1 WHERE (id OPERATOR(pg_catalog.=) 1) +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed d1 WHERE (id OPERATOR(pg_catalog.=) 1) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT sum((d1.id OPERATOR(pg_catalog.+) local.id)) AS sum FROM ((SELECT intermediate_result.id, intermediate_result.name, intermediate_result.created_at FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, name text, created_at timestamp with time zone)) d1 JOIN local_dist_join_mixed.local USING (id)) WHERE (d1.id OPERATOR(pg_catalog.=) 1) + sum +--------------------------------------------------------------------- + 2 +(1 row) + +SELECT sum(d1.id + local.id) OVER (PARTITION BY d1.id) FROM distributed d1 JOIN local USING (id) WHERE d1.id = 1 ORDER BY 1 DESC LIMIT 4; +DEBUG: Wrapping relation "distributed" to a subquery: SELECT id, NULL::text AS name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed d1 WHERE (id OPERATOR(pg_catalog.=) 1) +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed d1 WHERE (id OPERATOR(pg_catalog.=) 1) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT sum((d1.id OPERATOR(pg_catalog.+) local.id)) OVER (PARTITION BY d1.id) AS sum FROM ((SELECT intermediate_result.id, intermediate_result.name, intermediate_result.created_at FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, name text, created_at timestamp with time zone)) d1 JOIN local_dist_join_mixed.local USING (id)) WHERE (d1.id OPERATOR(pg_catalog.=) 1) ORDER BY (sum((d1.id OPERATOR(pg_catalog.+) local.id)) OVER (PARTITION BY d1.id)) DESC LIMIT 4 + sum +--------------------------------------------------------------------- + 2 +(1 row) + +SELECT count(*) FROM distributed d1 JOIN local USING (id) LEFT JOIN distributed d2 USING (id) WHERE d2.id = 1 ORDER BY 1 DESC LIMIT 4; +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE (id OPERATOR(pg_catalog.=) 1) +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE (id OPERATOR(pg_catalog.=) 1) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((local_dist_join_mixed.distributed d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) LEFT JOIN local_dist_join_mixed.distributed d2 USING (id)) WHERE (d2.id OPERATOR(pg_catalog.=) 1) ORDER BY (count(*)) DESC LIMIT 4 + count +--------------------------------------------------------------------- + 1 +(1 row) + +-- final queries are pull to coordinator queries +SELECT sum(d1.id + local.id) OVER (PARTITION BY d1.id + local.id) FROM distributed d1 JOIN local USING (id) ORDER BY 1 DESC LIMIT 4; +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT sum((d1.id OPERATOR(pg_catalog.+) local.id)) OVER (PARTITION BY (d1.id OPERATOR(pg_catalog.+) local.id)) AS sum FROM (local_dist_join_mixed.distributed d1 JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) ORDER BY (sum((d1.id OPERATOR(pg_catalog.+) local.id)) OVER (PARTITION BY (d1.id OPERATOR(pg_catalog.+) local.id))) DESC LIMIT 4 + sum +--------------------------------------------------------------------- + 200 + 198 + 196 + 194 +(4 rows) + +-- nested subqueries +SELECT + count(*) +FROM + (SELECT * FROM (SELECT * FROM distributed) as foo) as bar + JOIN + local + USING(id); +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT foo.id, foo.name, foo.created_at FROM (SELECT distributed.id, distributed.name, distributed.created_at FROM local_dist_join_mixed.distributed) foo) bar JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) + count +--------------------------------------------------------------------- + 101 +(1 row) + +SELECT + count(*) +FROM + (SELECT *, random() FROM (SELECT *, random() FROM distributed) as foo) as bar + JOIN + local + USING(id); +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT foo.id, foo.name, foo.created_at, foo.random, random() AS random FROM (SELECT distributed.id, distributed.name, distributed.created_at, random() AS random FROM local_dist_join_mixed.distributed) foo) bar(id, name, created_at, random, random_1) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) + count +--------------------------------------------------------------------- + 101 +(1 row) + +SELECT + count(*) +FROM + (SELECT *, random() FROM (SELECT *, random() FROM distributed) as foo) as bar + JOIN + local + USING(id); +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT foo.id, foo.name, foo.created_at, foo.random, random() AS random FROM (SELECT distributed.id, distributed.name, distributed.created_at, random() AS random FROM local_dist_join_mixed.distributed) foo) bar(id, name, created_at, random, random_1) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) + count +--------------------------------------------------------------------- + 101 +(1 row) + +SELECT + count(*) +FROM + (SELECT *, random() FROM (SELECT *, random() FROM distributed) as foo) as bar + JOIN + (SELECT *, random() FROM (SELECT *,random() FROM local) as foo2) as bar2 + USING(id); +DEBUG: generating subplan XXX_1 for subquery SELECT id, title, random() AS random FROM local_dist_join_mixed.local +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT foo.id, foo.name, foo.created_at, foo.random, random() AS random FROM (SELECT distributed.id, distributed.name, distributed.created_at, random() AS random FROM local_dist_join_mixed.distributed) foo) bar(id, name, created_at, random, random_1) JOIN (SELECT foo2.id, foo2.title, foo2.random, random() AS random FROM (SELECT intermediate_result.id, intermediate_result.title, intermediate_result.random FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text, random double precision)) foo2) bar2(id, title, random, random_1) USING (id)) + count +--------------------------------------------------------------------- + 101 +(1 row) + +-- TODO: Unnecessary recursive planning for local +SELECT + count(*) +FROM + (SELECT *, random() FROM (SELECT *, random() FROM distributed LIMIT 1) as foo) as bar + JOIN + (SELECT *, random() FROM (SELECT *,random() FROM local) as foo2) as bar2 + USING(id); +DEBUG: push down of limit count: 1 +DEBUG: generating subplan XXX_1 for subquery SELECT id, name, created_at, random() AS random FROM local_dist_join_mixed.distributed LIMIT 1 +DEBUG: generating subplan XXX_2 for subquery SELECT id, title, random() AS random FROM local_dist_join_mixed.local +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT foo.id, foo.name, foo.created_at, foo.random, random() AS random FROM (SELECT intermediate_result.id, intermediate_result.name, intermediate_result.created_at, intermediate_result.random FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, name text, created_at timestamp with time zone, random double precision)) foo) bar(id, name, created_at, random, random_1) JOIN (SELECT foo2.id, foo2.title, foo2.random, random() AS random FROM (SELECT intermediate_result.id, intermediate_result.title, intermediate_result.random FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text, random double precision)) foo2) bar2(id, title, random, random_1) USING (id)) + count +--------------------------------------------------------------------- + 1 +(1 row) + +-- subqueries in WHERE clause +-- is not colocated, and the JOIN inside as well. +-- so should be recursively planned twice +SELECT + count(*) +FROM + distributed +WHERE + id > (SELECT + count(*) + FROM + (SELECT *, random() FROM (SELECT *, random() FROM distributed) as foo) as bar + JOIN + (SELECT *, random() FROM (SELECT *,random() FROM local) as foo2) as bar2 + USING(id) + ); +DEBUG: generating subplan XXX_1 for subquery SELECT id, title, random() AS random FROM local_dist_join_mixed.local +DEBUG: generating subplan XXX_2 for subquery SELECT count(*) AS count FROM ((SELECT foo.id, foo.name, foo.created_at, foo.random, random() AS random FROM (SELECT distributed.id, distributed.name, distributed.created_at, random() AS random FROM local_dist_join_mixed.distributed) foo) bar(id, name, created_at, random, random_1) JOIN (SELECT foo2.id, foo2.title, foo2.random, random() AS random FROM (SELECT intermediate_result.id, intermediate_result.title, intermediate_result.random FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text, random double precision)) foo2) bar2(id, title, random, random_1) USING (id)) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM local_dist_join_mixed.distributed WHERE (id OPERATOR(pg_catalog.>) (SELECT intermediate_result.count FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(count bigint))) + count +--------------------------------------------------------------------- + 0 +(1 row) + +-- two distributed tables are co-located and JOINed on distribution +-- key, so should be fine to pushdown +SELECT + count(*) +FROM + distributed d_upper +WHERE + (SELECT + bar.id + FROM + (SELECT *, random() FROM (SELECT *, random() FROM distributed WHERE distributed.id = d_upper.id) as foo) as bar + JOIN + (SELECT *, random() FROM (SELECT *,random() FROM local) as foo2) as bar2 + USING(id) + ) IS NOT NULL; +DEBUG: generating subplan XXX_1 for subquery SELECT id, title, random() AS random FROM local_dist_join_mixed.local +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM local_dist_join_mixed.distributed d_upper WHERE ((SELECT bar.id FROM ((SELECT foo.id, foo.name, foo.created_at, foo.random, random() AS random FROM (SELECT distributed.id, distributed.name, distributed.created_at, random() AS random FROM local_dist_join_mixed.distributed WHERE (distributed.id OPERATOR(pg_catalog.=) d_upper.id)) foo) bar(id, name, created_at, random, random_1) JOIN (SELECT foo2.id, foo2.title, foo2.random, random() AS random FROM (SELECT intermediate_result.id, intermediate_result.title, intermediate_result.random FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text, random double precision)) foo2) bar2(id, title, random, random_1) USING (id))) IS NOT NULL) + count +--------------------------------------------------------------------- + 101 +(1 row) + +SELECT + count(*) +FROM + distributed d_upper +WHERE + (SELECT + bar.id + FROM + (SELECT *, random() FROM (SELECT *, random() FROM distributed WHERE distributed.id = d_upper.id) as foo) as bar + JOIN + local as foo + USING(id) + ) IS NOT NULL; +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local foo WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local foo WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM local_dist_join_mixed.distributed d_upper WHERE ((SELECT bar.id FROM ((SELECT foo_1.id, foo_1.name, foo_1.created_at, foo_1.random, random() AS random FROM (SELECT distributed.id, distributed.name, distributed.created_at, random() AS random FROM local_dist_join_mixed.distributed WHERE (distributed.id OPERATOR(pg_catalog.=) d_upper.id)) foo_1) bar(id, name, created_at, random, random_1) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) foo USING (id))) IS NOT NULL) + count +--------------------------------------------------------------------- + 101 +(1 row) + +SELECT + count(*) +FROM + distributed d_upper +WHERE d_upper.id > + (SELECT + bar.id + FROM + (SELECT *, random() FROM (SELECT *, random() FROM distributed WHERE distributed.id = d_upper.id) as foo) as bar + JOIN + local as foo + USING(id) + ); +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local foo WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local foo WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM local_dist_join_mixed.distributed d_upper WHERE (id OPERATOR(pg_catalog.>) (SELECT bar.id FROM ((SELECT foo_1.id, foo_1.name, foo_1.created_at, foo_1.random, random() AS random FROM (SELECT distributed.id, distributed.name, distributed.created_at, random() AS random FROM local_dist_join_mixed.distributed WHERE (distributed.id OPERATOR(pg_catalog.=) d_upper.id)) foo_1) bar(id, name, created_at, random, random_1) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) foo USING (id)))) + count +--------------------------------------------------------------------- + 0 +(1 row) + +SELECT + count(*) +FROM + distributed d_upper +WHERE + (SELECT + bar.id + FROM + (SELECT *, random() FROM (SELECT *, random() FROM distributed WHERE distributed.id = d_upper.id) as foo) as bar + JOIN + (SELECT *, random() FROM (SELECT *,random() FROM local WHERE d_upper.id = id) as foo2) as bar2 + USING(id) + ) IS NOT NULL; +ERROR: direct joins between distributed and local tables are not supported +HINT: Use CTE's or subqueries to select from local tables and use them in joins +-- subqueries in the target list +-- router, should work +select (SELECT local.id) FROM local, distributed WHERE distributed.id = 1 LIMIT 1; +DEBUG: Wrapping relation "distributed" to a subquery: SELECT id, NULL::text AS name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed WHERE (id OPERATOR(pg_catalog.=) 1) +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed WHERE (id OPERATOR(pg_catalog.=) 1) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT (SELECT local.id) AS id FROM local_dist_join_mixed.local, (SELECT intermediate_result.id, intermediate_result.name, intermediate_result.created_at FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, name text, created_at timestamp with time zone)) distributed WHERE (distributed.id OPERATOR(pg_catalog.=) 1) LIMIT 1 + id +--------------------------------------------------------------------- + 0 +(1 row) + +-- should fail +select (SELECT local.id) FROM local, distributed WHERE distributed.id != 1 LIMIT 1; +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT (SELECT local.id) AS id FROM (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local, local_dist_join_mixed.distributed WHERE (distributed.id OPERATOR(pg_catalog.<>) 1) LIMIT 1 +ERROR: could not run distributed query with subquery outside the FROM, WHERE and HAVING clauses +HINT: Consider using an equality filter on the distributed table's partition column. +-- currently not supported, but should work with https://github.com/citusdata/citus/pull/4360/files +SELECT + name, (SELECT id FROM local WHERE id = e.id) +FROM + distributed e +ORDER BY 1,2 LIMIT 1; +ERROR: could not run distributed query with subquery outside the FROM, WHERE and HAVING clauses +HINT: Consider using an equality filter on the distributed table's partition column. +-- set operations +SELECT local.* FROM distributed JOIN local USING (id) + EXCEPT +SELECT local.* FROM distributed JOIN local USING (id); +DEBUG: Wrapping relation "local" to a subquery: SELECT id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_2 for subquery SELECT id, title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_3 for subquery SELECT local.id, local.title FROM (local_dist_join_mixed.distributed JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) +DEBUG: generating subplan XXX_4 for subquery SELECT local.id, local.title FROM (local_dist_join_mixed.distributed JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text) EXCEPT SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text) + id | title +--------------------------------------------------------------------- +(0 rows) + +SELECT distributed.* FROM distributed JOIN local USING (id) + EXCEPT +SELECT distributed.* FROM distributed JOIN local USING (id); +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_2 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_3 for subquery SELECT distributed.id, distributed.name, distributed.created_at FROM (local_dist_join_mixed.distributed JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) +DEBUG: generating subplan XXX_4 for subquery SELECT distributed.id, distributed.name, distributed.created_at FROM (local_dist_join_mixed.distributed JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT intermediate_result.id, intermediate_result.name, intermediate_result.created_at FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, name text, created_at timestamp with time zone) EXCEPT SELECT intermediate_result.id, intermediate_result.name, intermediate_result.created_at FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, name text, created_at timestamp with time zone) + id | name | created_at +--------------------------------------------------------------------- +(0 rows) + +SELECT count(*) FROM +( + (SELECT * FROM (SELECT * FROM local) as f JOIN distributed USING (id)) + UNION ALL + (SELECT * FROM (SELECT * FROM local) as f2 JOIN distributed USING (id)) +) bar; +DEBUG: generating subplan XXX_1 for subquery SELECT id, title FROM local_dist_join_mixed.local +DEBUG: generating subplan XXX_2 for subquery SELECT id, title FROM local_dist_join_mixed.local +DEBUG: generating subplan XXX_3 for subquery SELECT f.id, f.title, distributed.name, distributed.created_at FROM ((SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) f JOIN local_dist_join_mixed.distributed USING (id)) +DEBUG: generating subplan XXX_4 for subquery SELECT f2.id, f2.title, distributed.name, distributed.created_at FROM ((SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) f2 JOIN local_dist_join_mixed.distributed USING (id)) +DEBUG: generating subplan XXX_5 for subquery SELECT intermediate_result.id, intermediate_result.title, intermediate_result.name, intermediate_result.created_at FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text, name text, created_at timestamp with time zone) UNION ALL SELECT intermediate_result.id, intermediate_result.title, intermediate_result.name, intermediate_result.created_at FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text, name text, created_at timestamp with time zone) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.id, intermediate_result.title, intermediate_result.name, intermediate_result.created_at FROM read_intermediate_result('XXX_5'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text, name text, created_at timestamp with time zone)) bar + count +--------------------------------------------------------------------- + 202 +(1 row) + +SELECT count(*) FROM +( + (SELECT * FROM (SELECT distributed.* FROM local JOIN distributed USING (id)) as fo) + UNION ALL + (SELECT * FROM (SELECT distributed.* FROM local JOIN distributed USING (id)) as ba) +) bar; +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_2 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_3 for subquery SELECT id, name, created_at FROM (SELECT distributed.id, distributed.name, distributed.created_at FROM ((SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local JOIN local_dist_join_mixed.distributed USING (id))) fo +DEBUG: generating subplan XXX_4 for subquery SELECT id, name, created_at FROM (SELECT distributed.id, distributed.name, distributed.created_at FROM ((SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local JOIN local_dist_join_mixed.distributed USING (id))) ba +DEBUG: generating subplan XXX_5 for subquery SELECT intermediate_result.id, intermediate_result.name, intermediate_result.created_at FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, name text, created_at timestamp with time zone) UNION ALL SELECT intermediate_result.id, intermediate_result.name, intermediate_result.created_at FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, name text, created_at timestamp with time zone) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (SELECT intermediate_result.id, intermediate_result.name, intermediate_result.created_at FROM read_intermediate_result('XXX_5'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, name text, created_at timestamp with time zone)) bar + count +--------------------------------------------------------------------- + 202 +(1 row) + +select count(DISTINCT id) +FROM +( + (SELECT * FROM (SELECT distributed.* FROM local JOIN distributed USING (id)) as fo) + UNION ALL + (SELECT * FROM (SELECT distributed.* FROM local JOIN distributed USING (id)) as ba) +) bar; +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_2 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(DISTINCT id) AS count FROM (SELECT fo.id, fo.name, fo.created_at FROM (SELECT distributed.id, distributed.name, distributed.created_at FROM ((SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local JOIN local_dist_join_mixed.distributed USING (id))) fo UNION ALL SELECT ba.id, ba.name, ba.created_at FROM (SELECT distributed.id, distributed.name, distributed.created_at FROM ((SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local JOIN local_dist_join_mixed.distributed USING (id))) ba) bar + count +--------------------------------------------------------------------- + 101 +(1 row) + +-- 25 Joins +select ' select count(*) from distributed ' || string_Agg('INNER +JOIN local u'|| x::text || ' USING (id)',' ') from +generate_Series(1,25)x; + ?column? +--------------------------------------------------------------------- + select count(*) from distributed INNER+ + JOIN local u1 USING (id) INNER + + JOIN local u2 USING (id) INNER + + JOIN local u3 USING (id) INNER + + JOIN local u4 USING (id) INNER + + JOIN local u5 USING (id) INNER + + JOIN local u6 USING (id) INNER + + JOIN local u7 USING (id) INNER + + JOIN local u8 USING (id) INNER + + JOIN local u9 USING (id) INNER + + JOIN local u10 USING (id) INNER + + JOIN local u11 USING (id) INNER + + JOIN local u12 USING (id) INNER + + JOIN local u13 USING (id) INNER + + JOIN local u14 USING (id) INNER + + JOIN local u15 USING (id) INNER + + JOIN local u16 USING (id) INNER + + JOIN local u17 USING (id) INNER + + JOIN local u18 USING (id) INNER + + JOIN local u19 USING (id) INNER + + JOIN local u20 USING (id) INNER + + JOIN local u21 USING (id) INNER + + JOIN local u22 USING (id) INNER + + JOIN local u23 USING (id) INNER + + JOIN local u24 USING (id) INNER + + JOIN local u25 USING (id) +(1 row) + +\gexec + select count(*) from distributed INNER +JOIN local u1 USING (id) INNER +JOIN local u2 USING (id) INNER +JOIN local u3 USING (id) INNER +JOIN local u4 USING (id) INNER +JOIN local u5 USING (id) INNER +JOIN local u6 USING (id) INNER +JOIN local u7 USING (id) INNER +JOIN local u8 USING (id) INNER +JOIN local u9 USING (id) INNER +JOIN local u10 USING (id) INNER +JOIN local u11 USING (id) INNER +JOIN local u12 USING (id) INNER +JOIN local u13 USING (id) INNER +JOIN local u14 USING (id) INNER +JOIN local u15 USING (id) INNER +JOIN local u16 USING (id) INNER +JOIN local u17 USING (id) INNER +JOIN local u18 USING (id) INNER +JOIN local u19 USING (id) INNER +JOIN local u20 USING (id) INNER +JOIN local u21 USING (id) INNER +JOIN local u22 USING (id) INNER +JOIN local u23 USING (id) INNER +JOIN local u24 USING (id) INNER +JOIN local u25 USING (id) +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u1 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u1 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u2 WHERE true +DEBUG: generating subplan XXX_2 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u2 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u3 WHERE true +DEBUG: generating subplan XXX_3 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u3 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u4 WHERE true +DEBUG: generating subplan XXX_4 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u4 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u5 WHERE true +DEBUG: generating subplan XXX_5 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u5 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u6 WHERE true +DEBUG: generating subplan XXX_6 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u6 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u7 WHERE true +DEBUG: generating subplan XXX_7 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u7 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u8 WHERE true +DEBUG: generating subplan XXX_8 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u8 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u9 WHERE true +DEBUG: generating subplan XXX_9 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u9 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u10 WHERE true +DEBUG: generating subplan XXX_10 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u10 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u11 WHERE true +DEBUG: generating subplan XXX_11 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u11 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u12 WHERE true +DEBUG: generating subplan XXX_12 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u12 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u13 WHERE true +DEBUG: generating subplan XXX_13 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u13 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u14 WHERE true +DEBUG: generating subplan XXX_14 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u14 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u15 WHERE true +DEBUG: generating subplan XXX_15 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u15 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u16 WHERE true +DEBUG: generating subplan XXX_16 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u16 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u17 WHERE true +DEBUG: generating subplan XXX_17 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u17 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u18 WHERE true +DEBUG: generating subplan XXX_18 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u18 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u19 WHERE true +DEBUG: generating subplan XXX_19 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u19 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u20 WHERE true +DEBUG: generating subplan XXX_20 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u20 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u21 WHERE true +DEBUG: generating subplan XXX_21 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u21 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u22 WHERE true +DEBUG: generating subplan XXX_22 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u22 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u23 WHERE true +DEBUG: generating subplan XXX_23 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u23 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u24 WHERE true +DEBUG: generating subplan XXX_24 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u24 WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u25 WHERE true +DEBUG: generating subplan XXX_25 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local u25 WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (((((((((((((((((((((((((local_dist_join_mixed.distributed JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u1 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u2 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u3 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u4 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_5'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u5 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_6'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u6 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_7'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u7 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_8'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u8 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_9'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u9 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_10'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u10 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_11'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u11 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_12'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u12 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_13'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u13 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_14'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u14 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_15'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u15 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_16'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u16 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_17'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u17 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_18'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u18 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_19'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u19 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_20'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u20 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_21'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u21 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_22'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u22 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_23'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u23 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_24'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u24 USING (id)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_25'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u25 USING (id)) + count +--------------------------------------------------------------------- + 101 +(1 row) + +select ' select count(*) from distributed ' || string_Agg('INNER +JOIN local u'|| x::text || ' ON (false)',' ') from +generate_Series(1,25)x; + ?column? +--------------------------------------------------------------------- + select count(*) from distributed INNER+ + JOIN local u1 ON (false) INNER + + JOIN local u2 ON (false) INNER + + JOIN local u3 ON (false) INNER + + JOIN local u4 ON (false) INNER + + JOIN local u5 ON (false) INNER + + JOIN local u6 ON (false) INNER + + JOIN local u7 ON (false) INNER + + JOIN local u8 ON (false) INNER + + JOIN local u9 ON (false) INNER + + JOIN local u10 ON (false) INNER + + JOIN local u11 ON (false) INNER + + JOIN local u12 ON (false) INNER + + JOIN local u13 ON (false) INNER + + JOIN local u14 ON (false) INNER + + JOIN local u15 ON (false) INNER + + JOIN local u16 ON (false) INNER + + JOIN local u17 ON (false) INNER + + JOIN local u18 ON (false) INNER + + JOIN local u19 ON (false) INNER + + JOIN local u20 ON (false) INNER + + JOIN local u21 ON (false) INNER + + JOIN local u22 ON (false) INNER + + JOIN local u23 ON (false) INNER + + JOIN local u24 ON (false) INNER + + JOIN local u25 ON (false) +(1 row) + +\gexec + select count(*) from distributed INNER +JOIN local u1 ON (false) INNER +JOIN local u2 ON (false) INNER +JOIN local u3 ON (false) INNER +JOIN local u4 ON (false) INNER +JOIN local u5 ON (false) INNER +JOIN local u6 ON (false) INNER +JOIN local u7 ON (false) INNER +JOIN local u8 ON (false) INNER +JOIN local u9 ON (false) INNER +JOIN local u10 ON (false) INNER +JOIN local u11 ON (false) INNER +JOIN local u12 ON (false) INNER +JOIN local u13 ON (false) INNER +JOIN local u14 ON (false) INNER +JOIN local u15 ON (false) INNER +JOIN local u16 ON (false) INNER +JOIN local u17 ON (false) INNER +JOIN local u18 ON (false) INNER +JOIN local u19 ON (false) INNER +JOIN local u20 ON (false) INNER +JOIN local u21 ON (false) INNER +JOIN local u22 ON (false) INNER +JOIN local u23 ON (false) INNER +JOIN local u24 ON (false) INNER +JOIN local u25 ON (false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u1 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u1 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u2 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_2 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u2 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u3 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_3 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u3 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u4 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_4 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u4 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u5 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_5 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u5 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u6 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_6 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u6 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u7 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_7 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u7 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u8 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_8 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u8 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u9 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_9 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u9 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u10 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_10 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u10 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u11 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_11 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u11 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u12 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_12 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u12 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u13 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_13 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u13 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u14 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_14 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u14 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u15 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_15 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u15 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u16 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_16 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u16 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u17 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_17 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u17 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u18 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_18 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u18 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u19 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_19 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u19 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u20 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_20 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u20 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u21 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_21 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u21 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u22 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_22 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u22 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u23 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_23 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u23 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u24 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_24 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u24 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u25 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_25 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local u25 WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (((((((((((((((((((((((((local_dist_join_mixed.distributed JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u1 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u2 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u3 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u4 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_5'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u5 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_6'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u6 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_7'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u7 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_8'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u8 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_9'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u9 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_10'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u10 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_11'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u11 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_12'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u12 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_13'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u13 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_14'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u14 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_15'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u15 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_16'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u16 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_17'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u17 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_18'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u18 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_19'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u19 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_20'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u20 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_21'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u21 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_22'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u22 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_23'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u23 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_24'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u24 ON (false)) JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_25'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) u25 ON (false)) + count +--------------------------------------------------------------------- + 0 +(1 row) + +select ' select count(*) from local ' || string_Agg('INNER +JOIN distributed u'|| x::text || ' USING (id)',' ') from +generate_Series(1,25)x; + ?column? +--------------------------------------------------------------------- + select count(*) from local INNER + + JOIN distributed u1 USING (id) INNER + + JOIN distributed u2 USING (id) INNER + + JOIN distributed u3 USING (id) INNER + + JOIN distributed u4 USING (id) INNER + + JOIN distributed u5 USING (id) INNER + + JOIN distributed u6 USING (id) INNER + + JOIN distributed u7 USING (id) INNER + + JOIN distributed u8 USING (id) INNER + + JOIN distributed u9 USING (id) INNER + + JOIN distributed u10 USING (id) INNER+ + JOIN distributed u11 USING (id) INNER+ + JOIN distributed u12 USING (id) INNER+ + JOIN distributed u13 USING (id) INNER+ + JOIN distributed u14 USING (id) INNER+ + JOIN distributed u15 USING (id) INNER+ + JOIN distributed u16 USING (id) INNER+ + JOIN distributed u17 USING (id) INNER+ + JOIN distributed u18 USING (id) INNER+ + JOIN distributed u19 USING (id) INNER+ + JOIN distributed u20 USING (id) INNER+ + JOIN distributed u21 USING (id) INNER+ + JOIN distributed u22 USING (id) INNER+ + JOIN distributed u23 USING (id) INNER+ + JOIN distributed u24 USING (id) INNER+ + JOIN distributed u25 USING (id) +(1 row) + +\gexec + select count(*) from local INNER +JOIN distributed u1 USING (id) INNER +JOIN distributed u2 USING (id) INNER +JOIN distributed u3 USING (id) INNER +JOIN distributed u4 USING (id) INNER +JOIN distributed u5 USING (id) INNER +JOIN distributed u6 USING (id) INNER +JOIN distributed u7 USING (id) INNER +JOIN distributed u8 USING (id) INNER +JOIN distributed u9 USING (id) INNER +JOIN distributed u10 USING (id) INNER +JOIN distributed u11 USING (id) INNER +JOIN distributed u12 USING (id) INNER +JOIN distributed u13 USING (id) INNER +JOIN distributed u14 USING (id) INNER +JOIN distributed u15 USING (id) INNER +JOIN distributed u16 USING (id) INNER +JOIN distributed u17 USING (id) INNER +JOIN distributed u18 USING (id) INNER +JOIN distributed u19 USING (id) INNER +JOIN distributed u20 USING (id) INNER +JOIN distributed u21 USING (id) INNER +JOIN distributed u22 USING (id) INNER +JOIN distributed u23 USING (id) INNER +JOIN distributed u24 USING (id) INNER +JOIN distributed u25 USING (id) +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((((((((((((((((((((((((((SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local JOIN local_dist_join_mixed.distributed u1 USING (id)) JOIN local_dist_join_mixed.distributed u2 USING (id)) JOIN local_dist_join_mixed.distributed u3 USING (id)) JOIN local_dist_join_mixed.distributed u4 USING (id)) JOIN local_dist_join_mixed.distributed u5 USING (id)) JOIN local_dist_join_mixed.distributed u6 USING (id)) JOIN local_dist_join_mixed.distributed u7 USING (id)) JOIN local_dist_join_mixed.distributed u8 USING (id)) JOIN local_dist_join_mixed.distributed u9 USING (id)) JOIN local_dist_join_mixed.distributed u10 USING (id)) JOIN local_dist_join_mixed.distributed u11 USING (id)) JOIN local_dist_join_mixed.distributed u12 USING (id)) JOIN local_dist_join_mixed.distributed u13 USING (id)) JOIN local_dist_join_mixed.distributed u14 USING (id)) JOIN local_dist_join_mixed.distributed u15 USING (id)) JOIN local_dist_join_mixed.distributed u16 USING (id)) JOIN local_dist_join_mixed.distributed u17 USING (id)) JOIN local_dist_join_mixed.distributed u18 USING (id)) JOIN local_dist_join_mixed.distributed u19 USING (id)) JOIN local_dist_join_mixed.distributed u20 USING (id)) JOIN local_dist_join_mixed.distributed u21 USING (id)) JOIN local_dist_join_mixed.distributed u22 USING (id)) JOIN local_dist_join_mixed.distributed u23 USING (id)) JOIN local_dist_join_mixed.distributed u24 USING (id)) JOIN local_dist_join_mixed.distributed u25 USING (id)) + count +--------------------------------------------------------------------- + 101 +(1 row) + +select ' select count(*) from local ' || string_Agg('INNER +JOIN distributed u'|| x::text || ' ON (false)',' ') from +generate_Series(1,25)x; + ?column? +--------------------------------------------------------------------- + select count(*) from local INNER + + JOIN distributed u1 ON (false) INNER + + JOIN distributed u2 ON (false) INNER + + JOIN distributed u3 ON (false) INNER + + JOIN distributed u4 ON (false) INNER + + JOIN distributed u5 ON (false) INNER + + JOIN distributed u6 ON (false) INNER + + JOIN distributed u7 ON (false) INNER + + JOIN distributed u8 ON (false) INNER + + JOIN distributed u9 ON (false) INNER + + JOIN distributed u10 ON (false) INNER+ + JOIN distributed u11 ON (false) INNER+ + JOIN distributed u12 ON (false) INNER+ + JOIN distributed u13 ON (false) INNER+ + JOIN distributed u14 ON (false) INNER+ + JOIN distributed u15 ON (false) INNER+ + JOIN distributed u16 ON (false) INNER+ + JOIN distributed u17 ON (false) INNER+ + JOIN distributed u18 ON (false) INNER+ + JOIN distributed u19 ON (false) INNER+ + JOIN distributed u20 ON (false) INNER+ + JOIN distributed u21 ON (false) INNER+ + JOIN distributed u22 ON (false) INNER+ + JOIN distributed u23 ON (false) INNER+ + JOIN distributed u24 ON (false) INNER+ + JOIN distributed u25 ON (false) +(1 row) + +\gexec + select count(*) from local INNER +JOIN distributed u1 ON (false) INNER +JOIN distributed u2 ON (false) INNER +JOIN distributed u3 ON (false) INNER +JOIN distributed u4 ON (false) INNER +JOIN distributed u5 ON (false) INNER +JOIN distributed u6 ON (false) INNER +JOIN distributed u7 ON (false) INNER +JOIN distributed u8 ON (false) INNER +JOIN distributed u9 ON (false) INNER +JOIN distributed u10 ON (false) INNER +JOIN distributed u11 ON (false) INNER +JOIN distributed u12 ON (false) INNER +JOIN distributed u13 ON (false) INNER +JOIN distributed u14 ON (false) INNER +JOIN distributed u15 ON (false) INNER +JOIN distributed u16 ON (false) INNER +JOIN distributed u17 ON (false) INNER +JOIN distributed u18 ON (false) INNER +JOIN distributed u19 ON (false) INNER +JOIN distributed u20 ON (false) INNER +JOIN distributed u21 ON (false) INNER +JOIN distributed u22 ON (false) INNER +JOIN distributed u23 ON (false) INNER +JOIN distributed u24 ON (false) INNER +JOIN distributed u25 ON (false) +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local WHERE (false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false AND false) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((((((((((((((((((((((((((SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local JOIN local_dist_join_mixed.distributed u1 ON (false)) JOIN local_dist_join_mixed.distributed u2 ON (false)) JOIN local_dist_join_mixed.distributed u3 ON (false)) JOIN local_dist_join_mixed.distributed u4 ON (false)) JOIN local_dist_join_mixed.distributed u5 ON (false)) JOIN local_dist_join_mixed.distributed u6 ON (false)) JOIN local_dist_join_mixed.distributed u7 ON (false)) JOIN local_dist_join_mixed.distributed u8 ON (false)) JOIN local_dist_join_mixed.distributed u9 ON (false)) JOIN local_dist_join_mixed.distributed u10 ON (false)) JOIN local_dist_join_mixed.distributed u11 ON (false)) JOIN local_dist_join_mixed.distributed u12 ON (false)) JOIN local_dist_join_mixed.distributed u13 ON (false)) JOIN local_dist_join_mixed.distributed u14 ON (false)) JOIN local_dist_join_mixed.distributed u15 ON (false)) JOIN local_dist_join_mixed.distributed u16 ON (false)) JOIN local_dist_join_mixed.distributed u17 ON (false)) JOIN local_dist_join_mixed.distributed u18 ON (false)) JOIN local_dist_join_mixed.distributed u19 ON (false)) JOIN local_dist_join_mixed.distributed u20 ON (false)) JOIN local_dist_join_mixed.distributed u21 ON (false)) JOIN local_dist_join_mixed.distributed u22 ON (false)) JOIN local_dist_join_mixed.distributed u23 ON (false)) JOIN local_dist_join_mixed.distributed u24 ON (false)) JOIN local_dist_join_mixed.distributed u25 ON (false)) + count +--------------------------------------------------------------------- + 0 +(1 row) + +-- lateral joins +SELECT COUNT(*) FROM (VALUES (1), (2), (3)) as f(x) LATERAL JOIN (SELECT * FROM local WHERE id = x) as bar; +ERROR: syntax error at or near "LATERAL" +SELECT COUNT(*) FROM local JOIN LATERAL (SELECT * FROM distributed WHERE local.id = distributed.id) as foo ON (true); +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local JOIN LATERAL (SELECT distributed.id, distributed.name, distributed.created_at FROM local_dist_join_mixed.distributed WHERE (local.id OPERATOR(pg_catalog.=) distributed.id)) foo ON (true)) + count +--------------------------------------------------------------------- + 101 +(1 row) + +SELECT COUNT(*) FROM local JOIN LATERAL (SELECT * FROM distributed WHERE local.id > distributed.id) as foo ON (true); +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local JOIN LATERAL (SELECT distributed.id, distributed.name, distributed.created_at FROM local_dist_join_mixed.distributed WHERE (local.id OPERATOR(pg_catalog.>) distributed.id)) foo ON (true)) + count +--------------------------------------------------------------------- + 5050 +(1 row) + +SELECT COUNT(*) FROM distributed JOIN LATERAL (SELECT * FROM local WHERE local.id = distributed.id) as foo ON (true); +ERROR: direct joins between distributed and local tables are not supported +HINT: Use CTE's or subqueries to select from local tables and use them in joins +SELECT COUNT(*) FROM distributed JOIN LATERAL (SELECT * FROM local WHERE local.id > distributed.id) as foo ON (true); +ERROR: direct joins between distributed and local tables are not supported +HINT: Use CTE's or subqueries to select from local tables and use them in joins +SELECT count(*) FROM distributed CROSS JOIN local; +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_dist_join_mixed.distributed CROSS JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local) + count +--------------------------------------------------------------------- + 10201 +(1 row) + +SELECT count(*) FROM distributed CROSS JOIN local WHERE distributed.id = 1; +DEBUG: Wrapping relation "distributed" to a subquery: SELECT id, NULL::text AS name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed WHERE (id OPERATOR(pg_catalog.=) 1) +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed WHERE (id OPERATOR(pg_catalog.=) 1) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.id, intermediate_result.name, intermediate_result.created_at FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, name text, created_at timestamp with time zone)) distributed CROSS JOIN local_dist_join_mixed.local) WHERE (distributed.id OPERATOR(pg_catalog.=) 1) + count +--------------------------------------------------------------------- + 101 +(1 row) + +-- w count(*) it works fine as PG ignores the inner tables +SELECT count(*) FROM distributed LEFT JOIN local USING (id); +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_dist_join_mixed.distributed LEFT JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) + count +--------------------------------------------------------------------- + 101 +(1 row) + +SELECT count(*) FROM local LEFT JOIN distributed USING (id); +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local LEFT JOIN local_dist_join_mixed.distributed USING (id)) + count +--------------------------------------------------------------------- + 101 +(1 row) + +SELECT id, name FROM distributed LEFT JOIN local USING (id) LIMIT 1; +DEBUG: Wrapping relation "local" to a subquery: SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::bigint AS id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT distributed.id, distributed.name FROM (local_dist_join_mixed.distributed LEFT JOIN (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local USING (id)) LIMIT 1 +DEBUG: push down of limit count: 1 + id | name +--------------------------------------------------------------------- + 1 | 1 +(1 row) + +SELECT id, name FROM local LEFT JOIN distributed USING (id) LIMIT 1; +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT local.id, distributed.name FROM ((SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local LEFT JOIN local_dist_join_mixed.distributed USING (id)) LIMIT 1 +ERROR: cannot pushdown the subquery +DETAIL: Complex subqueries and CTEs cannot be in the outer part of the outer join + SELECT + foo1.id + FROM + (SELECT local.id, local.title FROM local, distributed WHERE local.id = distributed.id ) as foo9, + (SELECT local.id, local.title FROM local, distributed WHERE local.id = distributed.id ) as foo8, + (SELECT local.id, local.title FROM local, distributed WHERE local.id = distributed.id ) as foo7, + (SELECT local.id, local.title FROM local, distributed WHERE local.id = distributed.id ) as foo6, + (SELECT local.id, local.title FROM local, distributed WHERE local.id = distributed.id ) as foo5, + (SELECT local.id, local.title FROM local, distributed WHERE local.id = distributed.id ) as foo4, + (SELECT local.id, local.title FROM local, distributed WHERE local.id = distributed.id ) as foo3, + (SELECT local.id, local.title FROM local, distributed WHERE local.id = distributed.id ) as foo2, + (SELECT local.id, local.title FROM local, distributed WHERE local.id = distributed.id ) as foo10, + (SELECT local.id, local.title FROM local, distributed WHERE local.id = distributed.id ) as foo1 + WHERE + foo1.id = foo9.id AND + foo1.id = foo8.id AND + foo1.id = foo7.id AND + foo1.id = foo6.id AND + foo1.id = foo5.id AND + foo1.id = foo4.id AND + foo1.id = foo3.id AND + foo1.id = foo2.id AND + foo1.id = foo10.id AND + foo1.id = foo1.id +ORDER BY 1; +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_2 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_3 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_4 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_5 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_6 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_7 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_8 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_9 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE (id IS NOT NULL) +DEBUG: generating subplan XXX_10 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE (id IS NOT NULL) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT foo1.id FROM (SELECT local.id, local.title FROM (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local, local_dist_join_mixed.distributed WHERE (local.id OPERATOR(pg_catalog.=) distributed.id)) foo9, (SELECT local.id, local.title FROM (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local, local_dist_join_mixed.distributed WHERE (local.id OPERATOR(pg_catalog.=) distributed.id)) foo8, (SELECT local.id, local.title FROM (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local, local_dist_join_mixed.distributed WHERE (local.id OPERATOR(pg_catalog.=) distributed.id)) foo7, (SELECT local.id, local.title FROM (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local, local_dist_join_mixed.distributed WHERE (local.id OPERATOR(pg_catalog.=) distributed.id)) foo6, (SELECT local.id, local.title FROM (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_5'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local, local_dist_join_mixed.distributed WHERE (local.id OPERATOR(pg_catalog.=) distributed.id)) foo5, (SELECT local.id, local.title FROM (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_6'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local, local_dist_join_mixed.distributed WHERE (local.id OPERATOR(pg_catalog.=) distributed.id)) foo4, (SELECT local.id, local.title FROM (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_7'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local, local_dist_join_mixed.distributed WHERE (local.id OPERATOR(pg_catalog.=) distributed.id)) foo3, (SELECT local.id, local.title FROM (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_8'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local, local_dist_join_mixed.distributed WHERE (local.id OPERATOR(pg_catalog.=) distributed.id)) foo2, (SELECT local.id, local.title FROM (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_9'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local, local_dist_join_mixed.distributed WHERE (local.id OPERATOR(pg_catalog.=) distributed.id)) foo10, (SELECT local.id, local.title FROM (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_10'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local, local_dist_join_mixed.distributed WHERE (local.id OPERATOR(pg_catalog.=) distributed.id)) foo1 WHERE ((foo1.id OPERATOR(pg_catalog.=) foo9.id) AND (foo1.id OPERATOR(pg_catalog.=) foo8.id) AND (foo1.id OPERATOR(pg_catalog.=) foo7.id) AND (foo1.id OPERATOR(pg_catalog.=) foo6.id) AND (foo1.id OPERATOR(pg_catalog.=) foo5.id) AND (foo1.id OPERATOR(pg_catalog.=) foo4.id) AND (foo1.id OPERATOR(pg_catalog.=) foo3.id) AND (foo1.id OPERATOR(pg_catalog.=) foo2.id) AND (foo1.id OPERATOR(pg_catalog.=) foo10.id) AND (foo1.id OPERATOR(pg_catalog.=) foo1.id)) ORDER BY foo1.id + id +--------------------------------------------------------------------- + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 + 100 +(101 rows) + +SELECT + foo1.id +FROM + (SELECT local.id FROM distributed, local WHERE local.id = distributed.id ) as foo1, + (SELECT local.id FROM distributed, local WHERE local.id = distributed.id ) as foo2, + (SELECT local.id FROM distributed, local WHERE local.id = distributed.id ) as foo3, + (SELECT local.id FROM distributed, local WHERE local.id = distributed.id ) as foo4, + (SELECT local.id FROM distributed, local WHERE local.id = distributed.id ) as foo5 +WHERE + foo1.id = foo4.id AND + foo1.id = foo2.id AND + foo1.id = foo3.id AND + foo1.id = foo4.id AND + foo1.id = foo5.id +ORDER BY 1; +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_2 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_3 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_4 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Wrapping relation "local" to a subquery: SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: generating subplan XXX_5 for subquery SELECT id, NULL::text AS title FROM local_dist_join_mixed.local WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT foo1.id FROM (SELECT local.id FROM local_dist_join_mixed.distributed, (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local WHERE (local.id OPERATOR(pg_catalog.=) distributed.id)) foo1, (SELECT local.id FROM local_dist_join_mixed.distributed, (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local WHERE (local.id OPERATOR(pg_catalog.=) distributed.id)) foo2, (SELECT local.id FROM local_dist_join_mixed.distributed, (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local WHERE (local.id OPERATOR(pg_catalog.=) distributed.id)) foo3, (SELECT local.id FROM local_dist_join_mixed.distributed, (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local WHERE (local.id OPERATOR(pg_catalog.=) distributed.id)) foo4, (SELECT local.id FROM local_dist_join_mixed.distributed, (SELECT intermediate_result.id, intermediate_result.title FROM read_intermediate_result('XXX_5'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, title text)) local WHERE (local.id OPERATOR(pg_catalog.=) distributed.id)) foo5 WHERE ((foo1.id OPERATOR(pg_catalog.=) foo4.id) AND (foo1.id OPERATOR(pg_catalog.=) foo2.id) AND (foo1.id OPERATOR(pg_catalog.=) foo3.id) AND (foo1.id OPERATOR(pg_catalog.=) foo4.id) AND (foo1.id OPERATOR(pg_catalog.=) foo5.id)) ORDER BY foo1.id + id +--------------------------------------------------------------------- + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 + 100 +(101 rows) + +SELECT + foo1.id +FROM + (SELECT local.id FROM distributed, local WHERE local.id = distributed.id AND distributed.id = 1) as foo1, + (SELECT local.id FROM distributed, local WHERE local.id = distributed.id AND distributed.id = 2) as foo2, + (SELECT local.id FROM distributed, local WHERE local.id = distributed.id AND distributed.id = 3) as foo3, + (SELECT local.id FROM distributed, local WHERE local.id = distributed.id AND distributed.id = 4) as foo4, + (SELECT local.id FROM distributed, local WHERE local.id = distributed.id AND distributed.id = 5) as foo5 +WHERE + foo1.id = foo4.id AND + foo1.id = foo2.id AND + foo1.id = foo3.id AND + foo1.id = foo4.id AND + foo1.id = foo5.id +ORDER BY 1; +DEBUG: Wrapping relation "distributed" to a subquery: SELECT id, NULL::text AS name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed WHERE (false AND false AND false AND false) +DEBUG: generating subplan XXX_1 for subquery SELECT id, NULL::text AS name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed WHERE (false AND false AND false AND false) +DEBUG: generating subplan XXX_2 for subquery SELECT local.id FROM (SELECT intermediate_result.id, intermediate_result.name, intermediate_result.created_at FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, name text, created_at timestamp with time zone)) distributed, local_dist_join_mixed.local WHERE ((local.id OPERATOR(pg_catalog.=) distributed.id) AND (distributed.id OPERATOR(pg_catalog.=) 1)) +DEBUG: Wrapping relation "distributed" to a subquery: SELECT id, NULL::text AS name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed WHERE (false AND false AND false AND false) +DEBUG: generating subplan XXX_3 for subquery SELECT id, NULL::text AS name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed WHERE (false AND false AND false AND false) +DEBUG: generating subplan XXX_4 for subquery SELECT local.id FROM (SELECT intermediate_result.id, intermediate_result.name, intermediate_result.created_at FROM read_intermediate_result('XXX_3'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, name text, created_at timestamp with time zone)) distributed, local_dist_join_mixed.local WHERE ((local.id OPERATOR(pg_catalog.=) distributed.id) AND (distributed.id OPERATOR(pg_catalog.=) 2)) +DEBUG: Wrapping relation "distributed" to a subquery: SELECT id, NULL::text AS name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed WHERE (false AND false AND false AND false) +DEBUG: generating subplan XXX_5 for subquery SELECT id, NULL::text AS name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed WHERE (false AND false AND false AND false) +DEBUG: generating subplan XXX_6 for subquery SELECT local.id FROM (SELECT intermediate_result.id, intermediate_result.name, intermediate_result.created_at FROM read_intermediate_result('XXX_5'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, name text, created_at timestamp with time zone)) distributed, local_dist_join_mixed.local WHERE ((local.id OPERATOR(pg_catalog.=) distributed.id) AND (distributed.id OPERATOR(pg_catalog.=) 3)) +DEBUG: Wrapping relation "distributed" to a subquery: SELECT id, NULL::text AS name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed WHERE (false AND false AND false AND false) +DEBUG: generating subplan XXX_7 for subquery SELECT id, NULL::text AS name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed WHERE (false AND false AND false AND false) +DEBUG: generating subplan XXX_8 for subquery SELECT local.id FROM (SELECT intermediate_result.id, intermediate_result.name, intermediate_result.created_at FROM read_intermediate_result('XXX_7'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, name text, created_at timestamp with time zone)) distributed, local_dist_join_mixed.local WHERE ((local.id OPERATOR(pg_catalog.=) distributed.id) AND (distributed.id OPERATOR(pg_catalog.=) 4)) +DEBUG: Wrapping relation "distributed" to a subquery: SELECT id, NULL::text AS name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed WHERE (false AND false AND false AND false) +DEBUG: generating subplan XXX_9 for subquery SELECT id, NULL::text AS name, NULL::timestamp with time zone AS created_at FROM local_dist_join_mixed.distributed WHERE (false AND false AND false AND false) +DEBUG: generating subplan XXX_10 for subquery SELECT local.id FROM (SELECT intermediate_result.id, intermediate_result.name, intermediate_result.created_at FROM read_intermediate_result('XXX_9'::text, 'binary'::citus_copy_format) intermediate_result(id bigint, name text, created_at timestamp with time zone)) distributed, local_dist_join_mixed.local WHERE ((local.id OPERATOR(pg_catalog.=) distributed.id) AND (distributed.id OPERATOR(pg_catalog.=) 5)) +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT foo1.id FROM (SELECT intermediate_result.id FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(id bigint)) foo1, (SELECT intermediate_result.id FROM read_intermediate_result('XXX_4'::text, 'binary'::citus_copy_format) intermediate_result(id bigint)) foo2, (SELECT intermediate_result.id FROM read_intermediate_result('XXX_6'::text, 'binary'::citus_copy_format) intermediate_result(id bigint)) foo3, (SELECT intermediate_result.id FROM read_intermediate_result('XXX_8'::text, 'binary'::citus_copy_format) intermediate_result(id bigint)) foo4, (SELECT intermediate_result.id FROM read_intermediate_result('XXX_10'::text, 'binary'::citus_copy_format) intermediate_result(id bigint)) foo5 WHERE ((foo1.id OPERATOR(pg_catalog.=) foo4.id) AND (foo1.id OPERATOR(pg_catalog.=) foo2.id) AND (foo1.id OPERATOR(pg_catalog.=) foo3.id) AND (foo1.id OPERATOR(pg_catalog.=) foo4.id) AND (foo1.id OPERATOR(pg_catalog.=) foo5.id)) ORDER BY foo1.id + id +--------------------------------------------------------------------- +(0 rows) + +DROP SCHEMA local_dist_join_mixed CASCADE; +NOTICE: drop cascades to 7 other objects +DETAIL: drop cascades to table distributed +drop cascades to table reference +drop cascades to table local +drop cascades to table unlogged_local +drop cascades to materialized view mat_view +drop cascades to view local_regular_view +drop cascades to view dist_regular_view diff --git a/src/test/regress/expected/local_dist_join_modifications.out b/src/test/regress/expected/local_dist_join_modifications.out new file mode 100644 index 000000000..a42de58bf --- /dev/null +++ b/src/test/regress/expected/local_dist_join_modifications.out @@ -0,0 +1,597 @@ +CREATE SCHEMA local_dist_join_modifications; +SET search_path TO local_dist_join_modifications; +CREATE TABLE postgres_table (key int, value text, value_2 jsonb); +CREATE TABLE reference_table (key int, value text, value_2 jsonb); +SELECT create_reference_table('reference_table'); + create_reference_table +--------------------------------------------------------------------- + +(1 row) + +CREATE TABLE distributed_table (key int, value text, value_2 jsonb); +SELECT create_distributed_table('distributed_table', 'key'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +CREATE TABLE distributed_table_pkey (key int primary key, value text, value_2 jsonb); +SELECT create_distributed_table('distributed_table_pkey', 'key'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +CREATE TABLE distributed_table_windex (key int primary key, value text, value_2 jsonb); +SELECT create_distributed_table('distributed_table_windex', 'key'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +CREATE UNIQUE INDEX key_index ON distributed_table_windex (key); +CREATE TABLE distributed_partitioned_table(key int, value text) PARTITION BY RANGE (key); +CREATE TABLE distributed_partitioned_table_1 PARTITION OF distributed_partitioned_table FOR VALUES FROM (0) TO (50); +CREATE TABLE distributed_partitioned_table_2 PARTITION OF distributed_partitioned_table FOR VALUES FROM (50) TO (200); +SELECT create_distributed_table('distributed_partitioned_table', 'key'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +CREATE TABLE local_partitioned_table(key int, value text) PARTITION BY RANGE (key); +CREATE TABLE local_partitioned_table_1 PARTITION OF local_partitioned_table FOR VALUES FROM (0) TO (50); +CREATE TABLE local_partitioned_table_2 PARTITION OF local_partitioned_table FOR VALUES FROM (50) TO (200); +CREATE TABLE distributed_table_composite (key int, value text, value_2 jsonb, primary key (key, value)); +SELECT create_distributed_table('distributed_table_composite', 'key'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +CREATE MATERIALIZED VIEW mv1 AS SELECT * FROM postgres_table; +CREATE MATERIALIZED VIEW mv2 AS SELECT * FROM distributed_table; +-- set log messages to debug1 so that we can see which tables are recursively planned. +SET client_min_messages TO DEBUG1; +INSERT INTO postgres_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO reference_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +DEBUG: distributed INSERT ... SELECT can only select from distributed tables +DEBUG: Collecting INSERT ... SELECT results on coordinator +INSERT INTO distributed_table_windex SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +DEBUG: distributed INSERT ... SELECT can only select from distributed tables +DEBUG: Collecting INSERT ... SELECT results on coordinator +INSERT INTO distributed_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +DEBUG: distributed INSERT ... SELECT can only select from distributed tables +DEBUG: Collecting INSERT ... SELECT results on coordinator +INSERT INTO distributed_table_pkey SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +DEBUG: distributed INSERT ... SELECT can only select from distributed tables +DEBUG: Collecting INSERT ... SELECT results on coordinator +INSERT INTO distributed_partitioned_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +DEBUG: distributed INSERT ... SELECT can only select from distributed tables +DEBUG: Collecting INSERT ... SELECT results on coordinator +INSERT INTO distributed_table_composite SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +DEBUG: distributed INSERT ... SELECT can only select from distributed tables +DEBUG: Collecting INSERT ... SELECT results on coordinator +INSERT INTO local_partitioned_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +SET citus.local_table_join_policy to 'auto'; +-- we can support modification queries as well +BEGIN; +SELECT COUNT(DISTINCT value) FROM postgres_table; + count +--------------------------------------------------------------------- + 100 +(1 row) + +UPDATE + postgres_table +SET + value = 'test' +FROM + distributed_table +WHERE + distributed_table.key = postgres_table.key; +DEBUG: Wrapping relation "distributed_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.distributed_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.distributed_table WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_dist_join_modifications.postgres_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table WHERE (distributed_table.key OPERATOR(pg_catalog.=) postgres_table.key) +SELECT COUNT(DISTINCT value) FROM postgres_table; + count +--------------------------------------------------------------------- + 1 +(1 row) + +ROLLBACK; +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table; + count +--------------------------------------------------------------------- + 100 +(1 row) + +UPDATE + distributed_table +SET + value = 'test' +FROM + postgres_table +WHERE + distributed_table.key = postgres_table.key; +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_dist_join_modifications.distributed_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table.key OPERATOR(pg_catalog.=) postgres_table.key) +SELECT COUNT(DISTINCT value) FROM distributed_table; + count +--------------------------------------------------------------------- + 1 +(1 row) + +ROLLBACK; +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; + count +--------------------------------------------------------------------- + 100 +(1 row) + +UPDATE + distributed_table_pkey +SET + value = 'test' +FROM + postgres_table +WHERE + distributed_table_pkey.key = postgres_table.key; +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_dist_join_modifications.distributed_table_pkey SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table_pkey.key OPERATOR(pg_catalog.=) postgres_table.key) +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; + count +--------------------------------------------------------------------- + 1 +(1 row) + +ROLLBACK; +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; + count +--------------------------------------------------------------------- + 100 +(1 row) + +UPDATE + distributed_table_windex +SET + value = 'test' +FROM + postgres_table +WHERE + distributed_table_windex.key = postgres_table.key; +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_dist_join_modifications.distributed_table_windex SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table_windex.key OPERATOR(pg_catalog.=) postgres_table.key) +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; + count +--------------------------------------------------------------------- + 1 +(1 row) + +ROLLBACK; +BEGIN; +UPDATE + mv1 +SET + value = 'test' +FROM + postgres_table +WHERE + mv1.key = postgres_table.key; +ERROR: cannot change materialized view "mv1" +ROLLBACK; +BEGIN; +UPDATE + postgres_table +SET + value = 'test' +FROM + mv1 +WHERE + mv1.key = postgres_table.key; +ROLLBACK; +BEGIN; +UPDATE + postgres_table +SET + value = 'test' +FROM + mv2 +WHERE + mv2.key = postgres_table.key; +ROLLBACK; +-- in case of update/delete we always recursively plan +-- the tables other than target table no matter what the policy is +SET citus.local_table_join_policy TO 'prefer-local'; +BEGIN; +SELECT COUNT(DISTINCT value) FROM postgres_table; + count +--------------------------------------------------------------------- + 100 +(1 row) + +UPDATE + postgres_table +SET + value = 'test' +FROM + distributed_table +WHERE + distributed_table.key = postgres_table.key; +DEBUG: Wrapping relation "distributed_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.distributed_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.distributed_table WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_dist_join_modifications.postgres_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table WHERE (distributed_table.key OPERATOR(pg_catalog.=) postgres_table.key) +SELECT COUNT(DISTINCT value) FROM postgres_table; + count +--------------------------------------------------------------------- + 1 +(1 row) + +ROLLBACK; +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table; + count +--------------------------------------------------------------------- + 100 +(1 row) + +UPDATE + distributed_table +SET + value = 'test' +FROM + postgres_table +WHERE + distributed_table.key = postgres_table.key; +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_dist_join_modifications.distributed_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table.key OPERATOR(pg_catalog.=) postgres_table.key) +SELECT COUNT(DISTINCT value) FROM distributed_table; + count +--------------------------------------------------------------------- + 1 +(1 row) + +ROLLBACK; +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; + count +--------------------------------------------------------------------- + 100 +(1 row) + +UPDATE + distributed_table_pkey +SET + value = 'test' +FROM + postgres_table +WHERE + distributed_table_pkey.key = postgres_table.key; +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_dist_join_modifications.distributed_table_pkey SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table_pkey.key OPERATOR(pg_catalog.=) postgres_table.key) +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; + count +--------------------------------------------------------------------- + 1 +(1 row) + +ROLLBACK; +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; + count +--------------------------------------------------------------------- + 100 +(1 row) + +UPDATE + distributed_table_windex +SET + value = 'test' +FROM + postgres_table +WHERE + distributed_table_windex.key = postgres_table.key; +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_dist_join_modifications.distributed_table_windex SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table_windex.key OPERATOR(pg_catalog.=) postgres_table.key) +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; + count +--------------------------------------------------------------------- + 1 +(1 row) + +ROLLBACK; +SET citus.local_table_join_policy TO 'prefer-distributed'; +BEGIN; +SELECT COUNT(DISTINCT value) FROM postgres_table; + count +--------------------------------------------------------------------- + 100 +(1 row) + +UPDATE + postgres_table +SET + value = 'test' +FROM + distributed_table +WHERE + distributed_table.key = postgres_table.key; +DEBUG: Wrapping relation "distributed_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.distributed_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.distributed_table WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_dist_join_modifications.postgres_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table WHERE (distributed_table.key OPERATOR(pg_catalog.=) postgres_table.key) +SELECT COUNT(DISTINCT value) FROM postgres_table; + count +--------------------------------------------------------------------- + 1 +(1 row) + +ROLLBACK; +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table; + count +--------------------------------------------------------------------- + 100 +(1 row) + +UPDATE + distributed_table +SET + value = 'test' +FROM + postgres_table +WHERE + distributed_table.key = postgres_table.key; +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_dist_join_modifications.distributed_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table.key OPERATOR(pg_catalog.=) postgres_table.key) +SELECT COUNT(DISTINCT value) FROM distributed_table; + count +--------------------------------------------------------------------- + 1 +(1 row) + +ROLLBACK; +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; + count +--------------------------------------------------------------------- + 100 +(1 row) + +UPDATE + distributed_table_pkey +SET + value = 'test' +FROM + postgres_table +WHERE + distributed_table_pkey.key = postgres_table.key; +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_dist_join_modifications.distributed_table_pkey SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table_pkey.key OPERATOR(pg_catalog.=) postgres_table.key) +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; + count +--------------------------------------------------------------------- + 1 +(1 row) + +ROLLBACK; +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; + count +--------------------------------------------------------------------- + 100 +(1 row) + +UPDATE + distributed_table_windex +SET + value = 'test' +FROM + postgres_table +WHERE + distributed_table_windex.key = postgres_table.key; +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_dist_join_modifications.distributed_table_windex SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table_windex.key OPERATOR(pg_catalog.=) postgres_table.key) +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; + count +--------------------------------------------------------------------- + 1 +(1 row) + +ROLLBACK; +SET citus.local_table_join_policy TO 'auto'; +-- modifications with multiple tables +BEGIN; +UPDATE + distributed_table +SET + value = 'test' +FROM + postgres_table p1, postgres_table p2 +WHERE + distributed_table.key = p1.key AND p1.key = p2.key; +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table p1 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table p1 WHERE true +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table p2 WHERE true +DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table p2 WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_dist_join_modifications.distributed_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) p1, (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) p2 WHERE ((distributed_table.key OPERATOR(pg_catalog.=) p1.key) AND (p1.key OPERATOR(pg_catalog.=) p2.key)) +ROLLBACK; +BEGIN; +UPDATE + postgres_table +SET + value = 'test' +FROM + (SELECT * FROM distributed_table) d1 +WHERE + d1.key = postgres_table.key; +ERROR: relation postgres_table is not distributed +ROLLBACK; +BEGIN; +UPDATE + postgres_table +SET + value = 'test' +FROM + (SELECT * FROM distributed_table LIMIT 1) d1 +WHERE + d1.key = postgres_table.key; +DEBUG: push down of limit count: 1 +DEBUG: generating subplan XXX_1 for subquery SELECT key, value, value_2 FROM local_dist_join_modifications.distributed_table LIMIT 1 +DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_dist_join_modifications.postgres_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) d1 WHERE (d1.key OPERATOR(pg_catalog.=) postgres_table.key) +ROLLBACK; +BEGIN; +UPDATE + distributed_table +SET + value = 'test' +FROM + postgres_table p1, distributed_table d2 +WHERE + distributed_table.key = p1.key AND p1.key = d2.key; +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table p1 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table p1 WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_dist_join_modifications.distributed_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) p1, local_dist_join_modifications.distributed_table d2 WHERE ((distributed_table.key OPERATOR(pg_catalog.=) p1.key) AND (p1.key OPERATOR(pg_catalog.=) d2.key)) +ROLLBACK; +-- pretty inefficient plan as it requires +-- recursive planninng of 2 distributed tables +BEGIN; +UPDATE + postgres_table +SET + value = 'test' +FROM + distributed_table d1, distributed_table d2 +WHERE + postgres_table.key = d1.key AND d1.key = d2.key; +DEBUG: Wrapping relation "distributed_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.distributed_table d1 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.distributed_table d1 WHERE true +DEBUG: Wrapping relation "distributed_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.distributed_table d2 WHERE true +DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.distributed_table d2 WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_dist_join_modifications.postgres_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) d1, (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) d2 WHERE ((postgres_table.key OPERATOR(pg_catalog.=) d1.key) AND (d1.key OPERATOR(pg_catalog.=) d2.key)) +ROLLBACK; +-- DELETE operations +BEGIN; +SELECT COUNT(DISTINCT value) FROM postgres_table; + count +--------------------------------------------------------------------- + 100 +(1 row) + +DELETE FROM + postgres_table +USING + distributed_table +WHERE + distributed_table.key = postgres_table.key; +DEBUG: Wrapping relation "distributed_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.distributed_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.distributed_table WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: DELETE FROM local_dist_join_modifications.postgres_table USING (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table WHERE (distributed_table.key OPERATOR(pg_catalog.=) postgres_table.key) +SELECT COUNT(DISTINCT value) FROM postgres_table; + count +--------------------------------------------------------------------- + 0 +(1 row) + +ROLLBACK; +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table; + count +--------------------------------------------------------------------- + 100 +(1 row) + +DELETE FROM + distributed_table +USING + postgres_table +WHERE + distributed_table.key = postgres_table.key; +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: DELETE FROM local_dist_join_modifications.distributed_table USING (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table.key OPERATOR(pg_catalog.=) postgres_table.key) +SELECT COUNT(DISTINCT value) FROM distributed_table; + count +--------------------------------------------------------------------- + 0 +(1 row) + +ROLLBACK; +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; + count +--------------------------------------------------------------------- + 100 +(1 row) + +DELETE FROM + distributed_table_pkey +USING + postgres_table +WHERE + distributed_table_pkey.key = postgres_table.key; +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: DELETE FROM local_dist_join_modifications.distributed_table_pkey USING (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table_pkey.key OPERATOR(pg_catalog.=) postgres_table.key) +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; + count +--------------------------------------------------------------------- + 0 +(1 row) + +ROLLBACK; +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; + count +--------------------------------------------------------------------- + 100 +(1 row) + +DELETE FROM + distributed_table_windex +USING + postgres_table +WHERE + distributed_table_windex.key = postgres_table.key; +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_dist_join_modifications.postgres_table WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: DELETE FROM local_dist_join_modifications.distributed_table_windex USING (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table_windex.key OPERATOR(pg_catalog.=) postgres_table.key) +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; + count +--------------------------------------------------------------------- + 0 +(1 row) + +ROLLBACK; +DELETE FROM + mv1 +USING + postgres_table +WHERE + mv1.key = postgres_table.key; +ERROR: cannot change materialized view "mv1" +DELETE FROM + postgres_table +USING + mv1 +WHERE + mv1.key = postgres_table.key; +DELETE FROM + postgres_table +USING + mv2 +WHERE + mv2.key = postgres_table.key; +SET client_min_messages to ERROR; +DROP SCHEMA local_dist_join_modifications CASCADE; diff --git a/src/test/regress/expected/local_distributed_table_join.out b/src/test/regress/expected/local_distributed_table_join.out deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/test/regress/expected/local_table_join.out b/src/test/regress/expected/local_table_join.out index 7710453ed..647c1609e 100644 --- a/src/test/regress/expected/local_table_join.out +++ b/src/test/regress/expected/local_table_join.out @@ -31,8 +31,8 @@ SELECT create_distributed_table('distributed_table_windex', 'key'); CREATE UNIQUE INDEX key_index ON distributed_table_windex (key); CREATE TABLE distributed_partitioned_table(key int, value text) PARTITION BY RANGE (key); -CREATE TABLE distributed_partitioned_table_1 PARTITION OF distributed_partitioned_table FOR VALUES FROM (0) TO (10); -CREATE TABLE distributed_partitioned_table_2 PARTITION OF distributed_partitioned_table FOR VALUES FROM (10) TO (20); +CREATE TABLE distributed_partitioned_table_1 PARTITION OF distributed_partitioned_table FOR VALUES FROM (0) TO (50); +CREATE TABLE distributed_partitioned_table_2 PARTITION OF distributed_partitioned_table FOR VALUES FROM (50) TO (200); SELECT create_distributed_table('distributed_partitioned_table', 'key'); create_distributed_table --------------------------------------------------------------------- @@ -40,8 +40,8 @@ SELECT create_distributed_table('distributed_partitioned_table', 'key'); (1 row) CREATE TABLE local_partitioned_table(key int, value text) PARTITION BY RANGE (key); -CREATE TABLE local_partitioned_table_1 PARTITION OF local_partitioned_table FOR VALUES FROM (0) TO (10); -CREATE TABLE local_partitioned_table_2 PARTITION OF local_partitioned_table FOR VALUES FROM (10) TO (20); +CREATE TABLE local_partitioned_table_1 PARTITION OF local_partitioned_table FOR VALUES FROM (0) TO (50); +CREATE TABLE local_partitioned_table_2 PARTITION OF local_partitioned_table FOR VALUES FROM (50) TO (200); CREATE TABLE distributed_table_composite (key int, value text, value_2 jsonb, primary key (key, value)); SELECT create_distributed_table('distributed_table_composite', 'key'); create_distributed_table @@ -49,6 +49,14 @@ SELECT create_distributed_table('distributed_table_composite', 'key'); (1 row) +INSERT INTO postgres_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO reference_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO distributed_table_windex SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO distributed_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO distributed_table_pkey SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO distributed_partitioned_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO distributed_table_composite SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO local_partitioned_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; CREATE FUNCTION fake_fdw_handler() RETURNS fdw_handler AS 'citus' @@ -73,181 +81,180 @@ HINT: Use CTE's or subqueries to select from local tables and use them in joins -- the user prefers local table recursively planned SET citus.local_table_join_policy TO 'prefer-local'; SELECT count(*) FROM postgres_table JOIN distributed_table USING(key); -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table JOIN local_table_join.distributed_table USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM postgres_table JOIN reference_table USING(key); -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table JOIN local_table_join.reference_table USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) -- the user prefers distributed table recursively planned SET citus.local_table_join_policy TO 'prefer-distributed'; SELECT count(*) FROM postgres_table JOIN distributed_table USING(key); -DEBUG: Wrapping relation "distributed_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "distributed_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.postgres_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM postgres_table JOIN reference_table USING(key); -DEBUG: Wrapping relation "reference_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.reference_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.reference_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "reference_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.reference_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.reference_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.postgres_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) reference_table USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) --- update/delete -- auto tests -- switch back to the default policy, which is auto SET citus.local_table_join_policy to 'auto'; -- on the auto mode, the local tables should be recursively planned -- unless a unique index exists in a column for distributed table SELECT count(*) FROM distributed_table JOIN postgres_table USING(key); -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.distributed_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM reference_table JOIN postgres_table USING(key); -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.reference_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM distributed_table JOIN postgres_table USING(key) JOIN reference_table USING (key); -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((local_table_join.distributed_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table USING (key)) JOIN local_table_join.reference_table USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) -- partititoned local tables should work as well SELECT count(*) FROM distributed_table JOIN local_partitioned_table USING(key); -DEBUG: Wrapping relation "local_partitioned_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "local_partitioned_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.distributed_table JOIN (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) local_partitioned_table USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM reference_table JOIN local_partitioned_table USING(key); -DEBUG: Wrapping relation "local_partitioned_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "local_partitioned_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.reference_table JOIN (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) local_partitioned_table USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM distributed_table JOIN local_partitioned_table USING(key) JOIN reference_table USING (key); -DEBUG: Wrapping relation "local_partitioned_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "local_partitioned_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((local_table_join.distributed_table JOIN (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) local_partitioned_table USING (key)) JOIN local_table_join.reference_table USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) -- materialized views should work too SELECT count(*) FROM distributed_table JOIN mv1 USING(key); -DEBUG: Wrapping relation "mv1" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true OFFSET 0 +DEBUG: Wrapping relation "mv1" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.distributed_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) mv1 USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM (SELECT * FROM distributed_table) d1 JOIN mv1 USING(key); -DEBUG: Wrapping relation "mv1" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true OFFSET 0 +DEBUG: Wrapping relation "mv1" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed_table.key, distributed_table.value, distributed_table.value_2 FROM local_table_join.distributed_table) d1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) mv1 USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM reference_table JOIN mv1 USING(key); -DEBUG: Wrapping relation "mv1" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true OFFSET 0 +DEBUG: Wrapping relation "mv1" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.reference_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) mv1 USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM distributed_table JOIN mv1 USING(key) JOIN reference_table USING (key); -DEBUG: Wrapping relation "mv1" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true OFFSET 0 +DEBUG: Wrapping relation "mv1" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv1 WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((local_table_join.distributed_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) mv1 USING (key)) JOIN local_table_join.reference_table USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM distributed_table JOIN mv2 USING(key); -DEBUG: Wrapping relation "mv2" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true OFFSET 0 +DEBUG: Wrapping relation "mv2" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.distributed_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) mv2 USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM (SELECT * FROM distributed_table) d1 JOIN mv2 USING(key); -DEBUG: Wrapping relation "mv2" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true OFFSET 0 +DEBUG: Wrapping relation "mv2" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed_table.key, distributed_table.value, distributed_table.value_2 FROM local_table_join.distributed_table) d1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) mv2 USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM reference_table JOIN mv2 USING(key); -DEBUG: Wrapping relation "mv2" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true OFFSET 0 +DEBUG: Wrapping relation "mv2" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.reference_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) mv2 USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM distributed_table JOIN mv2 USING(key) JOIN reference_table USING (key); -DEBUG: Wrapping relation "mv2" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true OFFSET 0 +DEBUG: Wrapping relation "mv2" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.mv2 WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((local_table_join.distributed_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) mv2 USING (key)) JOIN local_table_join.reference_table USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) -- foreign tables should work too SELECT count(*) FROM foreign_table JOIN distributed_table USING(key); -DEBUG: Wrapping relation "foreign_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.foreign_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM local_table_join.foreign_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "foreign_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.foreign_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM local_table_join.foreign_table WHERE true 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_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) foreign_table JOIN local_table_join.distributed_table USING (key)) count --------------------------------------------------------------------- @@ -256,107 +263,107 @@ DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS c -- partitioned tables should work as well SELECT count(*) FROM distributed_partitioned_table JOIN postgres_table USING(key); -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.distributed_partitioned_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM distributed_partitioned_table JOIN postgres_table USING(key) WHERE distributed_partitioned_table.key = 10; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 10) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 10) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.distributed_partitioned_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table USING (key)) WHERE (distributed_partitioned_table.key OPERATOR(pg_catalog.=) 10) count --------------------------------------------------------------------- - 0 + 1 (1 row) SELECT count(*) FROM distributed_partitioned_table JOIN postgres_table USING(key) JOIN reference_table USING (key); -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((local_table_join.distributed_partitioned_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table USING (key)) JOIN local_table_join.reference_table USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM distributed_partitioned_table JOIN local_partitioned_table USING(key); -DEBUG: Wrapping relation "local_partitioned_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "local_partitioned_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.distributed_partitioned_table JOIN (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) local_partitioned_table USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM distributed_partitioned_table JOIN local_partitioned_table USING(key) WHERE distributed_partitioned_table.key = 10; -DEBUG: Wrapping relation "local_partitioned_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 +DEBUG: Wrapping relation "local_partitioned_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE (key OPERATOR(pg_catalog.=) 10) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE (key OPERATOR(pg_catalog.=) 10) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.distributed_partitioned_table JOIN (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) local_partitioned_table USING (key)) WHERE (distributed_partitioned_table.key OPERATOR(pg_catalog.=) 10) count --------------------------------------------------------------------- - 0 + 1 (1 row) SELECT count(*) FROM distributed_partitioned_table JOIN local_partitioned_table USING(key) JOIN reference_table USING (key); -DEBUG: Wrapping relation "local_partitioned_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "local_partitioned_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((local_table_join.distributed_partitioned_table JOIN (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) local_partitioned_table USING (key)) JOIN local_table_join.reference_table USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) -- the conversions should be independent from the order of table entries in the query SELECT COUNT(*) FROM postgres_table join distributed_table_pkey using(key) join local_partitioned_table using(key) join distributed_table using(key) where distributed_table_pkey.key = 5; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 5) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 5) OFFSET 0 -DEBUG: Wrapping relation "local_partitioned_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE (key OPERATOR(pg_catalog.=) 5) OFFSET 0 -DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE (key OPERATOR(pg_catalog.=) 5) OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 5) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 5) +DEBUG: Wrapping relation "local_partitioned_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE (key OPERATOR(pg_catalog.=) 5) +DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE (key OPERATOR(pg_catalog.=) 5) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table JOIN local_table_join.distributed_table_pkey USING (key)) JOIN (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) local_partitioned_table USING (key)) JOIN local_table_join.distributed_table USING (key)) WHERE (distributed_table_pkey.key OPERATOR(pg_catalog.=) 5) count --------------------------------------------------------------------- - 0 + 1 (1 row) SELECT COUNT(*) FROM postgres_table join local_partitioned_table using(key) join distributed_table_pkey using(key) join distributed_table using(key) where distributed_table_pkey.key = 5; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 5) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 5) OFFSET 0 -DEBUG: Wrapping relation "local_partitioned_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE (key OPERATOR(pg_catalog.=) 5) OFFSET 0 -DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE (key OPERATOR(pg_catalog.=) 5) OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 5) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 5) +DEBUG: Wrapping relation "local_partitioned_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE (key OPERATOR(pg_catalog.=) 5) +DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE (key OPERATOR(pg_catalog.=) 5) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table JOIN (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) local_partitioned_table USING (key)) JOIN local_table_join.distributed_table_pkey USING (key)) JOIN local_table_join.distributed_table USING (key)) WHERE (distributed_table_pkey.key OPERATOR(pg_catalog.=) 5) count --------------------------------------------------------------------- - 0 + 1 (1 row) SELECT COUNT(*) FROM postgres_table join distributed_table using(key) join local_partitioned_table using(key) join distributed_table_pkey using(key) where distributed_table_pkey.key = 5; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 5) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 5) OFFSET 0 -DEBUG: Wrapping relation "local_partitioned_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE (key OPERATOR(pg_catalog.=) 5) OFFSET 0 -DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE (key OPERATOR(pg_catalog.=) 5) OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 5) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 5) +DEBUG: Wrapping relation "local_partitioned_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE (key OPERATOR(pg_catalog.=) 5) +DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE (key OPERATOR(pg_catalog.=) 5) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table JOIN local_table_join.distributed_table USING (key)) JOIN (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) local_partitioned_table USING (key)) JOIN local_table_join.distributed_table_pkey USING (key)) WHERE (distributed_table_pkey.key OPERATOR(pg_catalog.=) 5) count --------------------------------------------------------------------- - 0 + 1 (1 row) SELECT COUNT(*) FROM distributed_table_pkey join distributed_table using(key) join postgres_table using(key) join local_partitioned_table using(key) where distributed_table_pkey.key = 5; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 5) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 5) OFFSET 0 -DEBUG: Wrapping relation "local_partitioned_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE (key OPERATOR(pg_catalog.=) 5) OFFSET 0 -DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE (key OPERATOR(pg_catalog.=) 5) OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 5) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 5) +DEBUG: Wrapping relation "local_partitioned_table" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE (key OPERATOR(pg_catalog.=) 5) +DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value FROM local_table_join.local_partitioned_table WHERE (key OPERATOR(pg_catalog.=) 5) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (((local_table_join.distributed_table_pkey JOIN local_table_join.distributed_table USING (key)) JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table USING (key)) JOIN (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) local_partitioned_table USING (key)) WHERE (distributed_table_pkey.key OPERATOR(pg_catalog.=) 5) count --------------------------------------------------------------------- - 0 + 1 (1 row) SELECT count(*) FROM (SELECT *, random() FROM distributed_table) as d1 JOIN postgres_table ON (postgres_table.key = d1.key AND d1.key < postgres_table.key) WHERE d1.key = 1 AND false; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE ((key OPERATOR(pg_catalog.<) key) AND false) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE ((key OPERATOR(pg_catalog.<) key) AND false) OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE ((key OPERATOR(pg_catalog.<) key) AND false) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE ((key OPERATOR(pg_catalog.<) key) AND false) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed_table.key, distributed_table.value, distributed_table.value_2, random() AS random FROM local_table_join.distributed_table) d1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table ON (((postgres_table.key OPERATOR(pg_catalog.=) d1.key) AND (d1.key OPERATOR(pg_catalog.<) postgres_table.key)))) WHERE ((d1.key OPERATOR(pg_catalog.=) 1) AND false) count --------------------------------------------------------------------- @@ -364,8 +371,8 @@ DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS c (1 row) SELECT count(*) FROM (SELECT *, random() FROM distributed_table_pkey) as d1 JOIN postgres_table ON (postgres_table.key = d1.key AND d1.key < postgres_table.key) WHERE d1.key = 1 AND false; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE ((key OPERATOR(pg_catalog.<) key) AND false) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE ((key OPERATOR(pg_catalog.<) key) AND false) OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE ((key OPERATOR(pg_catalog.<) key) AND false) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE ((key OPERATOR(pg_catalog.<) key) AND false) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed_table_pkey.key, distributed_table_pkey.value, distributed_table_pkey.value_2, random() AS random FROM local_table_join.distributed_table_pkey) d1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table ON (((postgres_table.key OPERATOR(pg_catalog.=) d1.key) AND (d1.key OPERATOR(pg_catalog.<) postgres_table.key)))) WHERE ((d1.key OPERATOR(pg_catalog.=) 1) AND false) count --------------------------------------------------------------------- @@ -373,8 +380,8 @@ DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS c (1 row) SELECT count(*) FROM (SELECT *, random() FROM distributed_partitioned_table) as d1 JOIN postgres_table ON (postgres_table.key = d1.key AND d1.key < postgres_table.key) WHERE d1.key = 1 AND false; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE ((key OPERATOR(pg_catalog.<) key) AND false) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE ((key OPERATOR(pg_catalog.<) key) AND false) OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE ((key OPERATOR(pg_catalog.<) key) AND false) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE ((key OPERATOR(pg_catalog.<) key) AND false) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed_partitioned_table.key, distributed_partitioned_table.value, random() AS random FROM local_table_join.distributed_partitioned_table) d1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table ON (((postgres_table.key OPERATOR(pg_catalog.=) d1.key) AND (d1.key OPERATOR(pg_catalog.<) postgres_table.key)))) WHERE ((d1.key OPERATOR(pg_catalog.=) 1) AND false) count --------------------------------------------------------------------- @@ -382,8 +389,8 @@ DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS c (1 row) SELECT count(*) FROM (SELECT *, random() FROM distributed_partitioned_table) as d1 JOIN postgres_table ON (postgres_table.key::int = d1.key::int AND d1.key < postgres_table.key) WHERE d1.key::int = 1 AND false; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE ((key OPERATOR(pg_catalog.<) key) AND false) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE ((key OPERATOR(pg_catalog.<) key) AND false) OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE ((key OPERATOR(pg_catalog.<) key) AND false) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE ((key OPERATOR(pg_catalog.<) key) AND false) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT distributed_partitioned_table.key, distributed_partitioned_table.value, random() AS random FROM local_table_join.distributed_partitioned_table) d1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table ON (((postgres_table.key OPERATOR(pg_catalog.=) d1.key) AND (d1.key OPERATOR(pg_catalog.<) postgres_table.key)))) WHERE ((d1.key OPERATOR(pg_catalog.=) 1) AND false) count --------------------------------------------------------------------- @@ -392,82 +399,82 @@ DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS c -- TODO:: We should probably recursively plan postgres table here because primary key is on key,value not key. SELECT count(*) FROM distributed_table_composite JOIN postgres_table USING(key) WHERE distributed_table_composite.key = 10; -DEBUG: Wrapping relation "distributed_table_composite" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_composite WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_composite WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 +DEBUG: Wrapping relation "distributed_table_composite" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_composite WHERE (key OPERATOR(pg_catalog.=) 10) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_composite WHERE (key OPERATOR(pg_catalog.=) 10) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table_composite JOIN local_table_join.postgres_table USING (key)) WHERE (distributed_table_composite.key OPERATOR(pg_catalog.=) 10) count --------------------------------------------------------------------- - 0 + 1 (1 row) -- a unique index on key so dist table should be recursively planned SELECT count(*) FROM postgres_table JOIN distributed_table_pkey USING(key); -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table JOIN local_table_join.distributed_table_pkey USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM postgres_table JOIN distributed_table_pkey USING(value); -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT NULL::integer AS key, value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT NULL::integer AS key, value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table JOIN local_table_join.distributed_table_pkey USING (value)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM postgres_table JOIN distributed_table_pkey ON postgres_table.key = distributed_table_pkey.key; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table JOIN local_table_join.distributed_table_pkey ON ((postgres_table.key OPERATOR(pg_catalog.=) distributed_table_pkey.key))) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM postgres_table JOIN distributed_table_pkey ON distributed_table_pkey.key = 10; -DEBUG: Wrapping relation "distributed_table_pkey" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 +DEBUG: Wrapping relation "distributed_table_pkey" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE (key OPERATOR(pg_catalog.=) 10) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE (key OPERATOR(pg_catalog.=) 10) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.postgres_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table_pkey ON ((distributed_table_pkey.key OPERATOR(pg_catalog.=) 10))) count --------------------------------------------------------------------- - 0 + 100 (1 row) -- it should favor distributed table only if it has equality on the unique column SELECT count(*) FROM postgres_table JOIN distributed_table_pkey ON distributed_table_pkey.key > 10; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table JOIN local_table_join.distributed_table_pkey ON ((distributed_table_pkey.key OPERATOR(pg_catalog.>) 10))) count --------------------------------------------------------------------- - 0 + 9000 (1 row) SELECT count(*) FROM postgres_table JOIN distributed_table_pkey ON distributed_table_pkey.key < 10; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table JOIN local_table_join.distributed_table_pkey ON ((distributed_table_pkey.key OPERATOR(pg_catalog.<) 10))) count --------------------------------------------------------------------- - 0 + 900 (1 row) SELECT count(*) FROM postgres_table JOIN distributed_table_pkey ON distributed_table_pkey.key = 10; -DEBUG: Wrapping relation "distributed_table_pkey" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 +DEBUG: Wrapping relation "distributed_table_pkey" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE (key OPERATOR(pg_catalog.=) 10) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE (key OPERATOR(pg_catalog.=) 10) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.postgres_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table_pkey ON ((distributed_table_pkey.key OPERATOR(pg_catalog.=) 10))) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM postgres_table JOIN distributed_table_pkey ON distributed_table_pkey.key = 10 AND distributed_table_pkey.key > 10 ; -DEBUG: Wrapping relation "distributed_table_pkey" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.>) 10) AND (key OPERATOR(pg_catalog.=) 10)) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.>) 10) AND (key OPERATOR(pg_catalog.=) 10)) OFFSET 0 +DEBUG: Wrapping relation "distributed_table_pkey" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.>) 10) AND (key OPERATOR(pg_catalog.=) 10)) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.>) 10) AND (key OPERATOR(pg_catalog.=) 10)) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.postgres_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table_pkey ON (((distributed_table_pkey.key OPERATOR(pg_catalog.=) 10) AND (distributed_table_pkey.key OPERATOR(pg_catalog.>) 10)))) count --------------------------------------------------------------------- @@ -475,8 +482,8 @@ DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS c (1 row) SELECT count(*) FROM postgres_table JOIN distributed_table_pkey ON distributed_table_pkey.key = 10 AND distributed_table_pkey.key > 10 ; -DEBUG: Wrapping relation "distributed_table_pkey" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.>) 10) AND (key OPERATOR(pg_catalog.=) 10)) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.>) 10) AND (key OPERATOR(pg_catalog.=) 10)) OFFSET 0 +DEBUG: Wrapping relation "distributed_table_pkey" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.>) 10) AND (key OPERATOR(pg_catalog.=) 10)) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.>) 10) AND (key OPERATOR(pg_catalog.=) 10)) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.postgres_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table_pkey ON (((distributed_table_pkey.key OPERATOR(pg_catalog.=) 10) AND (distributed_table_pkey.key OPERATOR(pg_catalog.>) 10)))) count --------------------------------------------------------------------- @@ -484,8 +491,8 @@ DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS c (1 row) SELECT count(*) FROM postgres_table JOIN distributed_table_pkey ON distributed_table_pkey.key = 10 AND distributed_table_pkey.key > 10 AND postgres_table.key = 5; -DEBUG: Wrapping relation "distributed_table_pkey" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.>) 10) AND (key OPERATOR(pg_catalog.=) 10)) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.>) 10) AND (key OPERATOR(pg_catalog.=) 10)) OFFSET 0 +DEBUG: Wrapping relation "distributed_table_pkey" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.>) 10) AND (key OPERATOR(pg_catalog.=) 10)) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.>) 10) AND (key OPERATOR(pg_catalog.=) 10)) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.postgres_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table_pkey ON (((distributed_table_pkey.key OPERATOR(pg_catalog.=) 10) AND (distributed_table_pkey.key OPERATOR(pg_catalog.>) 10) AND (postgres_table.key OPERATOR(pg_catalog.=) 5)))) count --------------------------------------------------------------------- @@ -493,96 +500,114 @@ DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS c (1 row) SELECT count(*) FROM postgres_table JOIN distributed_table_pkey ON distributed_table_pkey.key = 10 OR distributed_table_pkey.key > 10; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table JOIN local_table_join.distributed_table_pkey ON (((distributed_table_pkey.key OPERATOR(pg_catalog.=) 10) OR (distributed_table_pkey.key OPERATOR(pg_catalog.>) 10)))) count --------------------------------------------------------------------- - 0 + 9100 (1 row) SELECT count(*) FROM postgres_table JOIN distributed_table_pkey ON distributed_table_pkey.key = 10 OR distributed_table_pkey.key = 20; -DEBUG: Wrapping relation "distributed_table_pkey" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.=) 10) OR (key OPERATOR(pg_catalog.=) 20)) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.=) 10) OR (key OPERATOR(pg_catalog.=) 20)) OFFSET 0 +DEBUG: Wrapping relation "distributed_table_pkey" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.=) 10) OR (key OPERATOR(pg_catalog.=) 20)) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.=) 10) OR (key OPERATOR(pg_catalog.=) 20)) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.postgres_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table_pkey ON (((distributed_table_pkey.key OPERATOR(pg_catalog.=) 10) OR (distributed_table_pkey.key OPERATOR(pg_catalog.=) 20)))) count --------------------------------------------------------------------- - 0 + 200 (1 row) SELECT count(*) FROM postgres_table JOIN distributed_table_pkey ON distributed_table_pkey.key = 10 OR distributed_table_pkey.key = 20 OR distributed_table_pkey.key = 30; -DEBUG: Wrapping relation "distributed_table_pkey" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.=) 10) OR (key OPERATOR(pg_catalog.=) 20) OR (key OPERATOR(pg_catalog.=) 30)) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.=) 10) OR (key OPERATOR(pg_catalog.=) 20) OR (key OPERATOR(pg_catalog.=) 30)) OFFSET 0 +DEBUG: Wrapping relation "distributed_table_pkey" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.=) 10) OR (key OPERATOR(pg_catalog.=) 20) OR (key OPERATOR(pg_catalog.=) 30)) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.=) 10) OR (key OPERATOR(pg_catalog.=) 20) OR (key OPERATOR(pg_catalog.=) 30)) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.postgres_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table_pkey ON (((distributed_table_pkey.key OPERATOR(pg_catalog.=) 10) OR (distributed_table_pkey.key OPERATOR(pg_catalog.=) 20) OR (distributed_table_pkey.key OPERATOR(pg_catalog.=) 30)))) count --------------------------------------------------------------------- - 0 + 300 (1 row) SELECT count(*) FROM postgres_table JOIN distributed_table_pkey ON distributed_table_pkey.key = 10 OR distributed_table_pkey.key = ( SELECT count(*) FROM distributed_table_pkey ); DEBUG: generating subplan XXX_1 for subquery SELECT count(*) AS count FROM local_table_join.distributed_table_pkey -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_2 for subquery SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_2 for subquery SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table JOIN local_table_join.distributed_table_pkey ON (((distributed_table_pkey.key OPERATOR(pg_catalog.=) 10) OR (distributed_table_pkey.key OPERATOR(pg_catalog.=) (SELECT intermediate_result.count FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(count bigint)))))) count --------------------------------------------------------------------- - 0 + 200 (1 row) SELECT count(*) FROM postgres_table JOIN distributed_table_pkey ON distributed_table_pkey.key = 10 OR (distributed_table_pkey.key = 5 and distributed_table_pkey.key > 15); -DEBUG: Wrapping relation "distributed_table_pkey" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.=) 10) OR ((key OPERATOR(pg_catalog.=) 5) AND (key OPERATOR(pg_catalog.>) 15))) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.=) 10) OR ((key OPERATOR(pg_catalog.=) 5) AND (key OPERATOR(pg_catalog.>) 15))) OFFSET 0 +DEBUG: Wrapping relation "distributed_table_pkey" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.=) 10) OR ((key OPERATOR(pg_catalog.=) 5) AND (key OPERATOR(pg_catalog.>) 15))) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.=) 10) OR ((key OPERATOR(pg_catalog.=) 5) AND (key OPERATOR(pg_catalog.>) 15))) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.postgres_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table_pkey ON (((distributed_table_pkey.key OPERATOR(pg_catalog.=) 10) OR ((distributed_table_pkey.key OPERATOR(pg_catalog.=) 5) AND (distributed_table_pkey.key OPERATOR(pg_catalog.>) 15))))) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM postgres_table JOIN distributed_table_pkey ON distributed_table_pkey.key = 10 OR (distributed_table_pkey.key > 10 and distributed_table_pkey.key > 15); -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table JOIN local_table_join.distributed_table_pkey ON (((distributed_table_pkey.key OPERATOR(pg_catalog.=) 10) OR ((distributed_table_pkey.key OPERATOR(pg_catalog.>) 10) AND (distributed_table_pkey.key OPERATOR(pg_catalog.>) 15))))) count --------------------------------------------------------------------- - 0 + 8600 (1 row) SELECT count(*) FROM postgres_table JOIN distributed_table_pkey ON distributed_table_pkey.key = 10 OR (distributed_table_pkey.key > 10 and distributed_table_pkey.value = 'notext'); -DEBUG: Wrapping relation "distributed_table_pkey" to a subquery: SELECT key, value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.=) 10) OR ((key OPERATOR(pg_catalog.>) 10) AND (value OPERATOR(pg_catalog.=) 'notext'::text))) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.=) 10) OR ((key OPERATOR(pg_catalog.>) 10) AND (value OPERATOR(pg_catalog.=) 'notext'::text))) OFFSET 0 +DEBUG: Wrapping relation "distributed_table_pkey" to a subquery: SELECT key, value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.=) 10) OR ((key OPERATOR(pg_catalog.>) 10) AND (value OPERATOR(pg_catalog.=) 'notext'::text))) +DEBUG: generating subplan XXX_1 for subquery SELECT key, value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE ((key OPERATOR(pg_catalog.=) 10) OR ((key OPERATOR(pg_catalog.>) 10) AND (value OPERATOR(pg_catalog.=) 'notext'::text))) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.postgres_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table_pkey ON (((distributed_table_pkey.key OPERATOR(pg_catalog.=) 10) OR ((distributed_table_pkey.key OPERATOR(pg_catalog.>) 10) AND (distributed_table_pkey.value OPERATOR(pg_catalog.=) 'notext'::text))))) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM postgres_table JOIN distributed_table_pkey ON distributed_table_pkey.key = 10 OR (distributed_table_pkey.key = 10 and distributed_table_pkey.value = 'notext'); -DEBUG: Wrapping relation "distributed_table_pkey" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 +DEBUG: Wrapping relation "distributed_table_pkey" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE (key OPERATOR(pg_catalog.=) 10) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_pkey WHERE (key OPERATOR(pg_catalog.=) 10) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.postgres_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table_pkey ON (((distributed_table_pkey.key OPERATOR(pg_catalog.=) 10) OR ((distributed_table_pkey.key OPERATOR(pg_catalog.=) 10) AND (distributed_table_pkey.value OPERATOR(pg_catalog.=) 'notext'::text))))) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM postgres_table JOIN distributed_table_pkey ON postgres_table.key = 10; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 10) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 10) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table JOIN local_table_join.distributed_table_pkey ON ((postgres_table.key OPERATOR(pg_catalog.=) 10))) count --------------------------------------------------------------------- - 0 + 100 +(1 row) + +select count(*) FROM postgres_table JOIN (SELECT a.key,random() FROM distributed_table a JOIN distributed_table b USING(key)) as foo USING(key); +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table JOIN (SELECT a.key, random() AS random FROM (local_table_join.distributed_table a JOIN local_table_join.distributed_table b USING (key))) foo USING (key)) + count +--------------------------------------------------------------------- + 100 +(1 row) + +select count(*) FROM (SELECT a.key, random() FROM distributed_table a JOIN distributed_table b USING(key)) as foo JOIN postgres_table USING(key); +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT a.key, random() AS random FROM (local_table_join.distributed_table a JOIN local_table_join.distributed_table b USING (key))) foo JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table USING (key)) + count +--------------------------------------------------------------------- + 100 (1 row) SELECT count(*) FROM postgres_table JOIN (SELECT * FROM distributed_table) d1 USING(key); -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table JOIN (SELECT distributed_table.key, distributed_table.value, distributed_table.value_2 FROM local_table_join.distributed_table) d1 USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) -- since this is already router plannable, we don't recursively plan the postgres table @@ -592,50 +617,50 @@ DEBUG: generating subplan XXX_1 for subquery SELECT key, value, value_2 FROM lo DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.postgres_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) d1 USING (key)) count --------------------------------------------------------------------- - 0 + 1 (1 row) -- a unique index on key so dist table should be recursively planned SELECT count(*) FROM postgres_table JOIN distributed_table_windex USING(key); -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table JOIN local_table_join.distributed_table_windex USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM postgres_table JOIN distributed_table_windex USING(value); -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT NULL::integer AS key, value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT NULL::integer AS key, value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table JOIN local_table_join.distributed_table_windex USING (value)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM postgres_table JOIN distributed_table_windex ON postgres_table.key = distributed_table_windex.key; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table JOIN local_table_join.distributed_table_windex ON ((postgres_table.key OPERATOR(pg_catalog.=) distributed_table_windex.key))) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT count(*) FROM postgres_table JOIN distributed_table_windex ON distributed_table_windex.key = 10; -DEBUG: Wrapping relation "distributed_table_windex" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_windex WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_windex WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 +DEBUG: Wrapping relation "distributed_table_windex" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_windex WHERE (key OPERATOR(pg_catalog.=) 10) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_windex WHERE (key OPERATOR(pg_catalog.=) 10) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.postgres_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table_windex ON ((distributed_table_windex.key OPERATOR(pg_catalog.=) 10))) count --------------------------------------------------------------------- - 0 + 100 (1 row) -- no unique index on value so local table should be recursively planned. SELECT count(*) FROM distributed_table JOIN postgres_table USING(key) WHERE distributed_table.value = 'test'; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.distributed_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table USING (key)) WHERE (distributed_table.value OPERATOR(pg_catalog.=) 'test'::text) count --------------------------------------------------------------------- @@ -643,18 +668,18 @@ DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS c (1 row) SELECT count(*) FROM distributed_table JOIN postgres_table USING(key) WHERE distributed_table.key = 1; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 1) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 1) OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 1) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 1) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.distributed_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table USING (key)) WHERE (distributed_table.key OPERATOR(pg_catalog.=) 1) count --------------------------------------------------------------------- - 0 + 1 (1 row) -- if both local and distributed tables have a filter, we prefer local unless distributed table has unique indexes on any equality filter SELECT count(*) FROM distributed_table JOIN postgres_table USING(key) WHERE distributed_table.value = 'test' AND postgres_table.value = 'test'; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (value OPERATOR(pg_catalog.=) 'test'::text) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (value OPERATOR(pg_catalog.=) 'test'::text) OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (value OPERATOR(pg_catalog.=) 'test'::text) +DEBUG: generating subplan XXX_1 for subquery SELECT key, value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (value OPERATOR(pg_catalog.=) 'test'::text) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.distributed_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table USING (key)) WHERE ((distributed_table.value OPERATOR(pg_catalog.=) 'test'::text) AND (postgres_table.value OPERATOR(pg_catalog.=) 'test'::text)) count --------------------------------------------------------------------- @@ -662,8 +687,8 @@ DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS c (1 row) SELECT count(*) FROM distributed_table JOIN postgres_table USING(key) WHERE distributed_table.value = 'test' OR postgres_table.value = 'test'; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.distributed_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table USING (key)) WHERE ((distributed_table.value OPERATOR(pg_catalog.=) 'test'::text) OR (postgres_table.value OPERATOR(pg_catalog.=) 'test'::text)) count --------------------------------------------------------------------- @@ -673,14 +698,14 @@ DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS c -- multiple local/distributed tables -- only local tables are recursively planned SELECT count(*) FROM distributed_table d1 JOIN postgres_table p1 USING(key) JOIN distributed_table d2 USING(key) JOIN postgres_table p2 USING(key); -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p1 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p1 WHERE true OFFSET 0 -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p2 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p2 WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p1 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p1 WHERE true +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p2 WHERE true +DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p2 WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (((local_table_join.distributed_table d1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) p1 USING (key)) JOIN local_table_join.distributed_table d2 USING (key)) JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) p2 USING (key)) count --------------------------------------------------------------------- - 0 + 100 (1 row) SELECT @@ -689,14 +714,14 @@ FROM distributed_table d1 JOIN postgres_table p1 USING(key) JOIN distributed_table d2 USING(key) JOIN postgres_table p2 USING(key) WHERE d1.value = '1'; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p1 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p1 WHERE true OFFSET 0 -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p2 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p2 WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p1 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p1 WHERE true +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p2 WHERE true +DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p2 WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (((local_table_join.distributed_table d1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) p1 USING (key)) JOIN local_table_join.distributed_table d2 USING (key)) JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) p2 USING (key)) WHERE (d1.value OPERATOR(pg_catalog.=) '1'::text) count --------------------------------------------------------------------- - 0 + 1 (1 row) -- if the filter is on the JOIN key, we can recursively plan the local @@ -707,419 +732,50 @@ FROM distributed_table d1 JOIN postgres_table p1 USING(key) JOIN distributed_table d2 USING(key) JOIN postgres_table p2 USING(key) WHERE d1.key = 1; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p1 WHERE (key OPERATOR(pg_catalog.=) 1) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p1 WHERE (key OPERATOR(pg_catalog.=) 1) OFFSET 0 -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p2 WHERE (key OPERATOR(pg_catalog.=) 1) OFFSET 0 -DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p2 WHERE (key OPERATOR(pg_catalog.=) 1) OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p1 WHERE (key OPERATOR(pg_catalog.=) 1) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p1 WHERE (key OPERATOR(pg_catalog.=) 1) +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p2 WHERE (key OPERATOR(pg_catalog.=) 1) +DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p2 WHERE (key OPERATOR(pg_catalog.=) 1) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (((local_table_join.distributed_table d1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) p1 USING (key)) JOIN local_table_join.distributed_table d2 USING (key)) JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) p2 USING (key)) WHERE (d1.key OPERATOR(pg_catalog.=) 1) count --------------------------------------------------------------------- - 0 + 1 (1 row) -SET citus.local_table_join_policy to 'auto'; --- we can support modification queries as well -UPDATE - postgres_table -SET - value = 'test' -FROM - distributed_table -WHERE - distributed_table.key = postgres_table.key; -DEBUG: Wrapping relation "distributed_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table WHERE true OFFSET 0 -DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_table_join.postgres_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table WHERE (distributed_table.key OPERATOR(pg_catalog.=) postgres_table.key) -UPDATE - distributed_table -SET - value = 'test' -FROM - postgres_table -WHERE - distributed_table.key = postgres_table.key; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_table_join.distributed_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table.key OPERATOR(pg_catalog.=) postgres_table.key) -UPDATE - distributed_table_pkey -SET - value = 'test' -FROM - postgres_table -WHERE - distributed_table_pkey.key = postgres_table.key; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_table_join.distributed_table_pkey SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table_pkey.key OPERATOR(pg_catalog.=) postgres_table.key) -UPDATE - distributed_table_windex -SET - value = 'test' -FROM - postgres_table -WHERE - distributed_table_windex.key = postgres_table.key; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_table_join.distributed_table_windex SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table_windex.key OPERATOR(pg_catalog.=) postgres_table.key) --- in case of update/delete we always recursively plan --- the tables other than target table no matter what the policy is -SET citus.local_table_join_policy TO 'prefer-local'; -UPDATE - postgres_table -SET - value = 'test' -FROM - distributed_table -WHERE - distributed_table.key = postgres_table.key; -DEBUG: Wrapping relation "distributed_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table WHERE true OFFSET 0 -DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_table_join.postgres_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table WHERE (distributed_table.key OPERATOR(pg_catalog.=) postgres_table.key) -UPDATE - distributed_table -SET - value = 'test' -FROM - postgres_table -WHERE - distributed_table.key = postgres_table.key; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_table_join.distributed_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table.key OPERATOR(pg_catalog.=) postgres_table.key) -UPDATE - distributed_table_pkey -SET - value = 'test' -FROM - postgres_table -WHERE - distributed_table_pkey.key = postgres_table.key; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_table_join.distributed_table_pkey SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table_pkey.key OPERATOR(pg_catalog.=) postgres_table.key) -UPDATE - distributed_table_windex -SET - value = 'test' -FROM - postgres_table -WHERE - distributed_table_windex.key = postgres_table.key; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_table_join.distributed_table_windex SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table_windex.key OPERATOR(pg_catalog.=) postgres_table.key) -SET citus.local_table_join_policy TO 'prefer-distributed'; -UPDATE - postgres_table -SET - value = 'test' -FROM - distributed_table -WHERE - distributed_table.key = postgres_table.key; -DEBUG: Wrapping relation "distributed_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table WHERE true OFFSET 0 -DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_table_join.postgres_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table WHERE (distributed_table.key OPERATOR(pg_catalog.=) postgres_table.key) -UPDATE - distributed_table -SET - value = 'test' -FROM - postgres_table -WHERE - distributed_table.key = postgres_table.key; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_table_join.distributed_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table.key OPERATOR(pg_catalog.=) postgres_table.key) -UPDATE - distributed_table_pkey -SET - value = 'test' -FROM - postgres_table -WHERE - distributed_table_pkey.key = postgres_table.key; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_table_join.distributed_table_pkey SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table_pkey.key OPERATOR(pg_catalog.=) postgres_table.key) -UPDATE - distributed_table_windex -SET - value = 'test' -FROM - postgres_table -WHERE - distributed_table_windex.key = postgres_table.key; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_table_join.distributed_table_windex SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (distributed_table_windex.key OPERATOR(pg_catalog.=) postgres_table.key) -SET citus.local_table_join_policy TO 'auto'; --- modifications with multiple tables -UPDATE - distributed_table -SET - value = 'test' -FROM - postgres_table p1, postgres_table p2 -WHERE - distributed_table.key = p1.key AND p1.key = p2.key; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p1 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p1 WHERE true OFFSET 0 -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p2 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p2 WHERE true OFFSET 0 -DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_table_join.distributed_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) p1, (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) p2 WHERE ((distributed_table.key OPERATOR(pg_catalog.=) p1.key) AND (p1.key OPERATOR(pg_catalog.=) p2.key)) -UPDATE - postgres_table -SET - value = 'test' -FROM - (SELECT * FROM distributed_table) d1 -WHERE - d1.key = postgres_table.key; -ERROR: relation postgres_table is not distributed -UPDATE - postgres_table -SET - value = 'test' -FROM - (SELECT * FROM distributed_table LIMIT 1) d1 -WHERE - d1.key = postgres_table.key; -DEBUG: push down of limit count: 1 -DEBUG: generating subplan XXX_1 for subquery SELECT key, value, value_2 FROM local_table_join.distributed_table LIMIT 1 -DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_table_join.postgres_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) d1 WHERE (d1.key OPERATOR(pg_catalog.=) postgres_table.key) -UPDATE - distributed_table -SET - value = 'test' -FROM - postgres_table p1, distributed_table d2 -WHERE - distributed_table.key = p1.key AND p1.key = d2.key; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p1 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table p1 WHERE true OFFSET 0 -DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_table_join.distributed_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) p1, local_table_join.distributed_table d2 WHERE ((distributed_table.key OPERATOR(pg_catalog.=) p1.key) AND (p1.key OPERATOR(pg_catalog.=) d2.key)) --- pretty inefficient plan as it requires --- recursive planninng of 2 distributed tables -UPDATE - postgres_table -SET - value = 'test' -FROM - distributed_table d1, distributed_table d2 -WHERE - postgres_table.key = d1.key AND d1.key = d2.key; -DEBUG: Wrapping relation "distributed_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table d1 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table d1 WHERE true OFFSET 0 -DEBUG: Wrapping relation "distributed_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table d2 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table d2 WHERE true OFFSET 0 -DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_table_join.postgres_table SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) d1, (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) d2 WHERE ((postgres_table.key OPERATOR(pg_catalog.=) d1.key) AND (d1.key OPERATOR(pg_catalog.=) d2.key)) --- currently can't plan subquery-local table join SELECT count(*) FROM (SELECT * FROM (SELECT * FROM distributed_table) d1) d2 JOIN postgres_table USING(key); -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT d1.key, d1.value, d1.value_2 FROM (SELECT distributed_table.key, distributed_table.value, distributed_table.value_2 FROM local_table_join.distributed_table) d1) d2 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table USING (key)) count --------------------------------------------------------------------- - 0 -(1 row) - ---------------------------------------------------------------------- -SET client_min_messages to ERROR; -SELECT master_add_node('localhost', :master_port, groupId => 0); - master_add_node ---------------------------------------------------------------------- - 5 -(1 row) - -CREATE TABLE citus_local(key int, value text); -SELECT create_citus_local_table('citus_local'); - create_citus_local_table ---------------------------------------------------------------------- - -(1 row) - -SET client_min_messages TO DEBUG1; --- same for citus local table - distributed table joins --- a unique index on key so dist table should be recursively planned -SELECT count(*) FROM citus_local JOIN distributed_table_windex USING(key); -DEBUG: Wrapping relation "citus_local" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.citus_local WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM local_table_join.citus_local WHERE true OFFSET 0 -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_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local JOIN local_table_join.distributed_table_windex USING (key)) - count ---------------------------------------------------------------------- - 0 -(1 row) - -SELECT count(*) FROM citus_local JOIN distributed_table_windex USING(value); -DEBUG: Wrapping relation "citus_local" to a subquery: SELECT NULL::integer AS key, value FROM local_table_join.citus_local WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value FROM local_table_join.citus_local WHERE true OFFSET 0 -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_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local JOIN local_table_join.distributed_table_windex USING (value)) - count ---------------------------------------------------------------------- - 0 -(1 row) - -SELECT count(*) FROM citus_local JOIN distributed_table_windex ON citus_local.key = distributed_table_windex.key; -DEBUG: Wrapping relation "citus_local" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.citus_local WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM local_table_join.citus_local WHERE true OFFSET 0 -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_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local JOIN local_table_join.distributed_table_windex ON ((citus_local.key OPERATOR(pg_catalog.=) distributed_table_windex.key))) - count ---------------------------------------------------------------------- - 0 -(1 row) - -SELECT count(*) FROM citus_local JOIN distributed_table_windex ON distributed_table_windex.key = 10; -DEBUG: Wrapping relation "distributed_table_windex" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_windex WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_windex WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (local_table_join.citus_local JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table_windex ON ((distributed_table_windex.key OPERATOR(pg_catalog.=) 10))) - count ---------------------------------------------------------------------- - 0 -(1 row) - --- no unique index, citus local table should be recursively planned -SELECT count(*) FROM citus_local JOIN distributed_table USING(key); -DEBUG: Wrapping relation "citus_local" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.citus_local WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM local_table_join.citus_local WHERE true OFFSET 0 -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_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local JOIN local_table_join.distributed_table USING (key)) - count ---------------------------------------------------------------------- - 0 -(1 row) - -SELECT count(*) FROM citus_local JOIN distributed_table USING(value); -DEBUG: Wrapping relation "citus_local" to a subquery: SELECT NULL::integer AS key, value FROM local_table_join.citus_local WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value FROM local_table_join.citus_local WHERE true OFFSET 0 -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_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local JOIN local_table_join.distributed_table USING (value)) - count ---------------------------------------------------------------------- - 0 -(1 row) - -SELECT count(*) FROM citus_local JOIN distributed_table ON citus_local.key = distributed_table.key; -DEBUG: Wrapping relation "citus_local" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.citus_local WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM local_table_join.citus_local WHERE true OFFSET 0 -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_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local JOIN local_table_join.distributed_table ON ((citus_local.key OPERATOR(pg_catalog.=) distributed_table.key))) - count ---------------------------------------------------------------------- - 0 -(1 row) - -SELECT count(*) FROM citus_local JOIN distributed_table ON distributed_table.key = 10; -DEBUG: Wrapping relation "citus_local" to a subquery: SELECT NULL::integer AS key, NULL::text AS value FROM local_table_join.citus_local WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, NULL::text AS value FROM local_table_join.citus_local WHERE true OFFSET 0 -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_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local JOIN local_table_join.distributed_table ON ((distributed_table.key OPERATOR(pg_catalog.=) 10))) - count ---------------------------------------------------------------------- - 0 -(1 row) - -SELECT count(*) FROM citus_local JOIN distributed_table USING(key) JOIN postgres_table USING (key) JOIN reference_table USING(key); -DEBUG: Wrapping relation "citus_local" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.citus_local WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM local_table_join.citus_local WHERE true OFFSET 0 -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE true OFFSET 0 -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_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local JOIN local_table_join.distributed_table USING (key)) JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table USING (key)) JOIN local_table_join.reference_table USING (key)) - count ---------------------------------------------------------------------- - 0 -(1 row) - -SELECT count(*) FROM distributed_partitioned_table JOIN postgres_table USING(key) JOIN reference_table USING (key) - JOIN citus_local USING(key) WHERE distributed_partitioned_table.key > 10 and distributed_partitioned_table.key = 10; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 -DEBUG: Wrapping relation "citus_local" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.citus_local WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 -DEBUG: generating subplan XXX_2 for subquery SELECT key, NULL::text AS value FROM local_table_join.citus_local WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (((local_table_join.distributed_partitioned_table JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table USING (key)) JOIN local_table_join.reference_table USING (key)) JOIN (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local USING (key)) WHERE ((distributed_partitioned_table.key OPERATOR(pg_catalog.>) 10) AND (distributed_partitioned_table.key OPERATOR(pg_catalog.=) 10)) - count ---------------------------------------------------------------------- - 0 -(1 row) - --- update -UPDATE - distributed_table_windex -SET - value = 'test' -FROM - citus_local -WHERE - distributed_table_windex.key = citus_local.key; -DEBUG: Wrapping relation "citus_local" to a subquery: SELECT key, NULL::text AS value FROM local_table_join.citus_local WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value FROM local_table_join.citus_local WHERE true OFFSET 0 -DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_table_join.distributed_table_windex SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) citus_local WHERE (distributed_table_windex.key OPERATOR(pg_catalog.=) citus_local.key) -UPDATE - citus_local -SET - value = 'test' -FROM - distributed_table_windex -WHERE - distributed_table_windex.key = citus_local.key; -DEBUG: Wrapping relation "distributed_table_windex" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_windex WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.distributed_table_windex WHERE true OFFSET 0 -DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_table_join.citus_local SET value = 'test'::text FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) distributed_table_windex WHERE (distributed_table_windex.key OPERATOR(pg_catalog.=) citus_local.key) --- complex queries -SELECT count(*) FROM postgres_table JOIN (SELECT * FROM (SELECT * FROM distributed_table LIMIT 1) d1) d2 using (key) JOIN reference_table USING(key) JOIN citus_local USING (key) JOIN (SELECT * FROM citus_local) c1 USING (key) WHERE d2.key > 10 AND d2.key = 10; -DEBUG: push down of limit count: 1 -DEBUG: generating subplan XXX_1 for subquery SELECT key, value, value_2 FROM local_table_join.distributed_table LIMIT 1 -DEBUG: generating subplan XXX_2 for subquery SELECT key, value FROM local_table_join.citus_local -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((((local_table_join.postgres_table JOIN (SELECT d1.key, d1.value, d1.value_2 FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) d1) d2 USING (key)) JOIN local_table_join.reference_table USING (key)) JOIN local_table_join.citus_local USING (key)) JOIN (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) c1 USING (key)) WHERE ((d2.key OPERATOR(pg_catalog.>) 10) AND (d2.key OPERATOR(pg_catalog.=) 10)) - count ---------------------------------------------------------------------- - 0 -(1 row) - -SELECT count(*) FROM postgres_table JOIN (SELECT * FROM (SELECT * FROM distributed_table LIMIT 1) d1) d2 using (key) JOIN reference_table USING(key) JOIN citus_local USING (key) JOIN (SELECT * FROM citus_local) c1 USING (key) WHERE d2.key > 10 AND d2.key = 10; -DEBUG: push down of limit count: 1 -DEBUG: generating subplan XXX_1 for subquery SELECT key, value, value_2 FROM local_table_join.distributed_table LIMIT 1 -DEBUG: generating subplan XXX_2 for subquery SELECT key, value FROM local_table_join.citus_local -DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((((local_table_join.postgres_table JOIN (SELECT d1.key, d1.value, d1.value_2 FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) d1) d2 USING (key)) JOIN local_table_join.reference_table USING (key)) JOIN local_table_join.citus_local USING (key)) JOIN (SELECT intermediate_result.key, intermediate_result.value FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text)) c1 USING (key)) WHERE ((d2.key OPERATOR(pg_catalog.>) 10) AND (d2.key OPERATOR(pg_catalog.=) 10)) - count ---------------------------------------------------------------------- - 0 + 100 (1 row) -- TODO:: we should support this? UPDATE reference_table SET key = 1 FROM postgres_table WHERE postgres_table.key = 10; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 10) OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 10) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE (key OPERATOR(pg_catalog.=) 10) DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_table_join.reference_table SET key = 1 FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table WHERE (postgres_table.key OPERATOR(pg_catalog.=) 10) ERROR: relation postgres_table is not distributed UPDATE reference_table SET key = 1 FROM (SELECT * FROM postgres_table) l WHERE l.key = 10; DEBUG: generating subplan XXX_1 for subquery SELECT key, value, value_2 FROM local_table_join.postgres_table DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE local_table_join.reference_table SET key = 1 FROM (SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) l WHERE (l.key OPERATOR(pg_catalog.=) 10) -UPDATE citus_local SET key = 1 FROM postgres_table WHERE citus_local.key = 10; -UPDATE postgres_table SET key = 1 FROM citus_local WHERE citus_local.key = 10; -- TODO:: we should probably not wrap postgres_table here as there is a WHERE FALSE? -- though then the planner could give an error SELECT count(*) FROM postgres_table JOIN distributed_table USING(key) WHERE FALSE; -DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE false OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE false OFFSET 0 +DEBUG: Wrapping relation "postgres_table" to a subquery: SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE false +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::text AS value, NULL::jsonb AS value_2 FROM local_table_join.postgres_table WHERE false DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.key, intermediate_result.value, intermediate_result.value_2 FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value text, value_2 jsonb)) postgres_table JOIN local_table_join.distributed_table USING (key)) WHERE false count --------------------------------------------------------------------- 0 (1 row) -DROP TABLE citus_local; -CONTEXT: SQL statement "SELECT master_drop_all_shards(v_obj.objid, v_obj.schema_name, v_obj.object_name)" -PL/pgSQL function citus_drop_trigger() line 15 at PERFORM RESET client_min_messages; -SELECT master_remove_node('localhost', :master_port); - master_remove_node ---------------------------------------------------------------------- - -(1 row) - \set VERBOSITY terse DROP SCHEMA local_table_join CASCADE; -NOTICE: drop cascades to 15 other objects +NOTICE: drop cascades to 14 other objects diff --git a/src/test/regress/expected/mixed_relkind_tests.out b/src/test/regress/expected/mixed_relkind_tests.out index 65a6d6045..0c40cc1a2 100644 --- a/src/test/regress/expected/mixed_relkind_tests.out +++ b/src/test/regress/expected/mixed_relkind_tests.out @@ -320,8 +320,8 @@ $$); SET client_min_messages TO DEBUG1; SELECT COUNT(*) FROM partitioned_postgres_local_table JOIN distributed_table ON (true); -DEBUG: Wrapping relation "partitioned_postgres_local_table" to a subquery: SELECT NULL::integer AS a FROM mixed_relkind_tests.partitioned_postgres_local_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS a FROM mixed_relkind_tests.partitioned_postgres_local_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "partitioned_postgres_local_table" to a subquery: SELECT NULL::integer AS a FROM mixed_relkind_tests.partitioned_postgres_local_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS a FROM mixed_relkind_tests.partitioned_postgres_local_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.a FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer)) partitioned_postgres_local_table JOIN mixed_relkind_tests.distributed_table ON (true)) count --------------------------------------------------------------------- @@ -329,8 +329,8 @@ DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS c (1 row) SELECT COUNT(*) FROM partitioned_postgres_local_table JOIN partitioned_distributed_table ON (true); -DEBUG: Wrapping relation "partitioned_postgres_local_table" to a subquery: SELECT NULL::integer AS a FROM mixed_relkind_tests.partitioned_postgres_local_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS a FROM mixed_relkind_tests.partitioned_postgres_local_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "partitioned_postgres_local_table" to a subquery: SELECT NULL::integer AS a FROM mixed_relkind_tests.partitioned_postgres_local_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS a FROM mixed_relkind_tests.partitioned_postgres_local_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((SELECT intermediate_result.a FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer)) partitioned_postgres_local_table JOIN mixed_relkind_tests.partitioned_distributed_table ON (true)) count --------------------------------------------------------------------- @@ -338,8 +338,8 @@ DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS c (1 row) SELECT COUNT(*) FROM distributed_table JOIN partitioned_postgres_local_table ON (true); -DEBUG: Wrapping relation "partitioned_postgres_local_table" to a subquery: SELECT NULL::integer AS a FROM mixed_relkind_tests.partitioned_postgres_local_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS a FROM mixed_relkind_tests.partitioned_postgres_local_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "partitioned_postgres_local_table" to a subquery: SELECT NULL::integer AS a FROM mixed_relkind_tests.partitioned_postgres_local_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS a FROM mixed_relkind_tests.partitioned_postgres_local_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (mixed_relkind_tests.distributed_table JOIN (SELECT intermediate_result.a FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer)) partitioned_postgres_local_table ON (true)) count --------------------------------------------------------------------- @@ -348,20 +348,20 @@ DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS c INSERT INTO partitioned_distributed_table SELECT foo.* FROM partitioned_distributed_table AS foo JOIN citus_local_table ON (true); DEBUG: distributed INSERT ... SELECT cannot select from distributed tables and local tables at the same time -DEBUG: Wrapping relation "citus_local_table" to a subquery: SELECT NULL::integer AS a FROM mixed_relkind_tests.citus_local_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS a FROM mixed_relkind_tests.citus_local_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "citus_local_table" to a subquery: SELECT NULL::integer AS a FROM mixed_relkind_tests.citus_local_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS a FROM mixed_relkind_tests.citus_local_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT foo.a, foo.b FROM (mixed_relkind_tests.partitioned_distributed_table foo JOIN (SELECT intermediate_result.a FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer)) citus_local_table ON (true)) DEBUG: performing repartitioned INSERT ... SELECT INSERT INTO partitioned_distributed_table SELECT foo.* FROM distributed_table AS foo JOIN citus_local_table ON (true); DEBUG: distributed INSERT ... SELECT cannot select from distributed tables and local tables at the same time -DEBUG: Wrapping relation "citus_local_table" to a subquery: SELECT NULL::integer AS a FROM mixed_relkind_tests.citus_local_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS a FROM mixed_relkind_tests.citus_local_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "citus_local_table" to a subquery: SELECT NULL::integer AS a FROM mixed_relkind_tests.citus_local_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS a FROM mixed_relkind_tests.citus_local_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT foo.a FROM (mixed_relkind_tests.distributed_table foo JOIN (SELECT intermediate_result.a FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer)) citus_local_table ON (true)) DEBUG: performing repartitioned INSERT ... SELECT INSERT INTO distributed_table SELECT foo.a FROM partitioned_distributed_table AS foo JOIN citus_local_table ON (true); DEBUG: distributed INSERT ... SELECT cannot select from distributed tables and local tables at the same time -DEBUG: Wrapping relation "citus_local_table" to a subquery: SELECT NULL::integer AS a FROM mixed_relkind_tests.citus_local_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS a FROM mixed_relkind_tests.citus_local_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "citus_local_table" to a subquery: SELECT NULL::integer AS a FROM mixed_relkind_tests.citus_local_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS a FROM mixed_relkind_tests.citus_local_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT foo.a FROM (mixed_relkind_tests.partitioned_distributed_table foo JOIN (SELECT intermediate_result.a FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer)) citus_local_table ON (true)) DEBUG: performing repartitioned INSERT ... SELECT -- should fail @@ -392,25 +392,25 @@ DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS c (1 row) UPDATE partitioned_distributed_table SET b = foo.a FROM citus_local_table AS foo; -DEBUG: Wrapping relation "citus_local_table" to a subquery: SELECT a FROM mixed_relkind_tests.citus_local_table foo WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT a FROM mixed_relkind_tests.citus_local_table foo WHERE true OFFSET 0 +DEBUG: Wrapping relation "citus_local_table" to a subquery: SELECT a FROM mixed_relkind_tests.citus_local_table foo WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT a FROM mixed_relkind_tests.citus_local_table foo WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE mixed_relkind_tests.partitioned_distributed_table SET b = foo.a FROM (SELECT intermediate_result.a FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer)) foo UPDATE partitioned_distributed_table SET b = foo.a FROM postgres_local_table AS foo; -DEBUG: Wrapping relation "postgres_local_table" to a subquery: SELECT a FROM mixed_relkind_tests.postgres_local_table foo WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT a FROM mixed_relkind_tests.postgres_local_table foo WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_local_table" to a subquery: SELECT a FROM mixed_relkind_tests.postgres_local_table foo WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT a FROM mixed_relkind_tests.postgres_local_table foo WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE mixed_relkind_tests.partitioned_distributed_table SET b = foo.a FROM (SELECT intermediate_result.a FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer)) foo UPDATE partitioned_distributed_table SET a = foo.a FROM postgres_local_table AS foo WHERE foo.a = partitioned_distributed_table.a; -DEBUG: Wrapping relation "postgres_local_table" to a subquery: SELECT a FROM mixed_relkind_tests.postgres_local_table foo WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT a FROM mixed_relkind_tests.postgres_local_table foo WHERE true OFFSET 0 +DEBUG: Wrapping relation "postgres_local_table" to a subquery: SELECT a FROM mixed_relkind_tests.postgres_local_table foo WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT a FROM mixed_relkind_tests.postgres_local_table foo WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE mixed_relkind_tests.partitioned_distributed_table SET a = foo.a FROM (SELECT intermediate_result.a FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer)) foo WHERE (foo.a OPERATOR(pg_catalog.=) partitioned_distributed_table.a) UPDATE partitioned_distributed_table SET a = foo.a FROM citus_local_table AS foo WHERE foo.a = partitioned_distributed_table.a; -DEBUG: Wrapping relation "citus_local_table" to a subquery: SELECT a FROM mixed_relkind_tests.citus_local_table foo WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT a FROM mixed_relkind_tests.citus_local_table foo WHERE true OFFSET 0 +DEBUG: Wrapping relation "citus_local_table" to a subquery: SELECT a FROM mixed_relkind_tests.citus_local_table foo WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT a FROM mixed_relkind_tests.citus_local_table foo WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE mixed_relkind_tests.partitioned_distributed_table SET a = foo.a FROM (SELECT intermediate_result.a FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer)) foo WHERE (foo.a OPERATOR(pg_catalog.=) partitioned_distributed_table.a) -- should fail UPDATE partitioned_distributed_table SET a = foo.a FROM mat_view_on_part_dist AS foo WHERE foo.a = partitioned_distributed_table.a; -DEBUG: Wrapping relation "mat_view_on_part_dist" to a subquery: SELECT a, NULL::integer AS b FROM mixed_relkind_tests.mat_view_on_part_dist foo WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT a, NULL::integer AS b FROM mixed_relkind_tests.mat_view_on_part_dist foo WHERE true OFFSET 0 +DEBUG: Wrapping relation "mat_view_on_part_dist" to a subquery: SELECT a, NULL::integer AS b FROM mixed_relkind_tests.mat_view_on_part_dist foo WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT a, NULL::integer AS b FROM mixed_relkind_tests.mat_view_on_part_dist foo WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: UPDATE mixed_relkind_tests.partitioned_distributed_table SET a = foo.a FROM (SELECT intermediate_result.a, intermediate_result.b FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(a integer, b integer)) foo WHERE (foo.a OPERATOR(pg_catalog.=) partitioned_distributed_table.a) UPDATE partitioned_distributed_table SET a = foo.a FROM partitioned_distributed_table AS foo WHERE foo.a < partitioned_distributed_table.a; ERROR: complex joins are only supported when all distributed tables are co-located and joined on their distribution columns diff --git a/src/test/regress/expected/multi_partitioning.out b/src/test/regress/expected/multi_partitioning.out index 2e177214e..a31711fe7 100644 --- a/src/test/regress/expected/multi_partitioning.out +++ b/src/test/regress/expected/multi_partitioning.out @@ -1430,7 +1430,7 @@ COMMIT; BEGIN; TRUNCATE partitioning_locks; SELECT relation::regclass, locktype, mode FROM pg_locks WHERE relation::regclass::text LIKE 'partitioning_locks%' AND pid = pg_backend_pid() ORDER BY 1, 2, 3; - relation | locktype | mode + relation | locktype | mode --------------------------------------------------------------------- partitioning_locks | relation | AccessExclusiveLock partitioning_locks | relation | AccessShareLock @@ -1471,29 +1471,17 @@ BEGIN; UPDATE partitioning_locks_2009 SET time = '2009-03-01'; -- see the locks on parent table SELECT * FROM lockinfo; - logicalrelid | locktype | mode + logicalrelid | locktype | mode --------------------------------------------------------------------- - partitioning_locks | colocated_shards_metadata | ShareLock - partitioning_locks | colocated_shards_metadata | ShareLock - partitioning_locks | colocated_shards_metadata | ShareLock - partitioning_locks | colocated_shards_metadata | ShareLock - partitioning_locks | shard | ShareUpdateExclusiveLock - partitioning_locks | shard | ShareUpdateExclusiveLock - partitioning_locks | shard | ShareUpdateExclusiveLock - partitioning_locks | shard | ShareUpdateExclusiveLock - partitioning_locks_2009 | colocated_shards_metadata | ShareLock - partitioning_locks_2009 | colocated_shards_metadata | ShareLock - partitioning_locks_2009 | colocated_shards_metadata | ShareLock - partitioning_locks_2009 | colocated_shards_metadata | ShareLock - partitioning_locks_2009 | shard | ShareUpdateExclusiveLock - partitioning_locks_2009 | shard | ShareUpdateExclusiveLock - partitioning_locks_2009 | shard | ShareUpdateExclusiveLock - partitioning_locks_2009 | shard | ShareUpdateExclusiveLock - partitioning_locks_2010 | colocated_shards_metadata | ShareLock - partitioning_locks_2010 | colocated_shards_metadata | ShareLock - partitioning_locks_2010 | colocated_shards_metadata | ShareLock - partitioning_locks_2010 | colocated_shards_metadata | ShareLock -(20 rows) + partitioning_locks | shard | ShareUpdateExclusiveLock + partitioning_locks | shard | ShareUpdateExclusiveLock + partitioning_locks | shard | ShareUpdateExclusiveLock + partitioning_locks | shard | ShareUpdateExclusiveLock + partitioning_locks_2009 | shard | ShareUpdateExclusiveLock + partitioning_locks_2009 | shard | ShareUpdateExclusiveLock + partitioning_locks_2009 | shard | ShareUpdateExclusiveLock + partitioning_locks_2009 | shard | ShareUpdateExclusiveLock +(8 rows) COMMIT; -- test shard resource locks with TRUNCATE diff --git a/src/test/regress/expected/recursive_relation_planning_restirction_pushdown.out b/src/test/regress/expected/recursive_relation_planning_restirction_pushdown.out index 20788d6fe..adfe0bf26 100644 --- a/src/test/regress/expected/recursive_relation_planning_restirction_pushdown.out +++ b/src/test/regress/expected/recursive_relation_planning_restirction_pushdown.out @@ -31,8 +31,8 @@ SELECT count(*) FROM distributed_table u1 JOIN distributed_table u2 USING(key) JOIN local_table USING (key); -DEBUG: Wrapping relation "local_table" to a subquery: SELECT key, NULL::integer AS value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::integer AS value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table WHERE true OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT key, NULL::integer AS value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::integer AS value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((push_down_filters.distributed_table u1 JOIN push_down_filters.distributed_table u2 USING (key)) JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) local_table USING (key)) count --------------------------------------------------------------------- @@ -44,8 +44,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING (key) WHERE u2.key > ANY(ARRAY[2, 1, 6]); -DEBUG: Wrapping relation "local_table" to a subquery: SELECT key, NULL::integer AS value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (key OPERATOR(pg_catalog.>) ANY ('{2,1,6}'::integer[])) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::integer AS value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (key OPERATOR(pg_catalog.>) ANY ('{2,1,6}'::integer[])) OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT key, NULL::integer AS value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (key OPERATOR(pg_catalog.>) ANY ('{2,1,6}'::integer[])) +DEBUG: generating subplan XXX_1 for subquery SELECT key, NULL::integer AS value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (key OPERATOR(pg_catalog.>) ANY ('{2,1,6}'::integer[])) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (key)) WHERE (u2.key OPERATOR(pg_catalog.>) ANY (ARRAY[2, 1, 6])) count --------------------------------------------------------------------- @@ -57,8 +57,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(key) WHERE ARRAY[u2.key, u2.value] @> (ARRAY[2, 3]); -DEBUG: Wrapping relation "local_table" to a subquery: SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (ARRAY[key, value] OPERATOR(pg_catalog.@>) '{2,3}'::integer[]) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (ARRAY[key, value] OPERATOR(pg_catalog.@>) '{2,3}'::integer[]) OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (ARRAY[key, value] OPERATOR(pg_catalog.@>) '{2,3}'::integer[]) +DEBUG: generating subplan XXX_1 for subquery SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (ARRAY[key, value] OPERATOR(pg_catalog.@>) '{2,3}'::integer[]) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (key)) WHERE (ARRAY[u2.key, u2.value] OPERATOR(pg_catalog.@>) ARRAY[2, 3]) count --------------------------------------------------------------------- @@ -70,8 +70,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE ARRAY[u2.value, u1.value] @> (ARRAY[2, 3]); -DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE (ARRAY[u2.value, u1.value] OPERATOR(pg_catalog.@>) ARRAY[2, 3]) count --------------------------------------------------------------------- @@ -83,8 +83,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE (u2.value/2.0 > 2)::int::bool::text::bool; -DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (((((((value)::numeric OPERATOR(pg_catalog./) 2.0) OPERATOR(pg_catalog.>) '2'::numeric))::integer)::boolean)::text)::boolean OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (((((((value)::numeric OPERATOR(pg_catalog./) 2.0) OPERATOR(pg_catalog.>) '2'::numeric))::integer)::boolean)::text)::boolean OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (((((((value)::numeric OPERATOR(pg_catalog./) 2.0) OPERATOR(pg_catalog.>) '2'::numeric))::integer)::boolean)::text)::boolean +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (((((((value)::numeric OPERATOR(pg_catalog./) 2.0) OPERATOR(pg_catalog.>) '2'::numeric))::integer)::boolean)::text)::boolean DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE (((((((u2.value)::numeric OPERATOR(pg_catalog./) 2.0) OPERATOR(pg_catalog.>) (2)::numeric))::integer)::boolean)::text)::boolean count --------------------------------------------------------------------- @@ -96,8 +96,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE (CASE WHEN u2.value > 3 THEN u2.value > 2 ELSE false END); -DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE CASE WHEN (value OPERATOR(pg_catalog.>) 3) THEN (value OPERATOR(pg_catalog.>) 2) ELSE false END OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE CASE WHEN (value OPERATOR(pg_catalog.>) 3) THEN (value OPERATOR(pg_catalog.>) 2) ELSE false END OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE CASE WHEN (value OPERATOR(pg_catalog.>) 3) THEN (value OPERATOR(pg_catalog.>) 2) ELSE false END +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE CASE WHEN (value OPERATOR(pg_catalog.>) 3) THEN (value OPERATOR(pg_catalog.>) 2) ELSE false END DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE CASE WHEN (u2.value OPERATOR(pg_catalog.>) 3) THEN (u2.value OPERATOR(pg_catalog.>) 2) ELSE false END count --------------------------------------------------------------------- @@ -109,8 +109,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE (CASE WHEN u1.value > 4000 THEN u2.value / 100 > 1 ELSE false END); -DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE CASE WHEN (u1.value OPERATOR(pg_catalog.>) 4000) THEN ((u2.value OPERATOR(pg_catalog./) 100) OPERATOR(pg_catalog.>) 1) ELSE false END count --------------------------------------------------------------------- @@ -122,8 +122,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE COALESCE((u2.key/5.0)::int::bool, false); -DEBUG: Wrapping relation "local_table" to a subquery: SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE COALESCE(((((key)::numeric OPERATOR(pg_catalog./) 5.0))::integer)::boolean, false) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE COALESCE(((((key)::numeric OPERATOR(pg_catalog./) 5.0))::integer)::boolean, false) OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE COALESCE(((((key)::numeric OPERATOR(pg_catalog./) 5.0))::integer)::boolean, false) +DEBUG: generating subplan XXX_1 for subquery SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE COALESCE(((((key)::numeric OPERATOR(pg_catalog./) 5.0))::integer)::boolean, false) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE COALESCE(((((u2.key)::numeric OPERATOR(pg_catalog./) 5.0))::integer)::boolean, false) count --------------------------------------------------------------------- @@ -135,8 +135,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE NULLIF((u2.value/5.0)::int::bool, false); -DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE NULLIF(((((value)::numeric OPERATOR(pg_catalog./) 5.0))::integer)::boolean, false) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE NULLIF(((((value)::numeric OPERATOR(pg_catalog./) 5.0))::integer)::boolean, false) OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE NULLIF(((((value)::numeric OPERATOR(pg_catalog./) 5.0))::integer)::boolean, false) +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE NULLIF(((((value)::numeric OPERATOR(pg_catalog./) 5.0))::integer)::boolean, false) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE NULLIF(((((u2.value)::numeric OPERATOR(pg_catalog./) 5.0))::integer)::boolean, false) count --------------------------------------------------------------------- @@ -148,8 +148,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE u2.value IS NOT NULL; -DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (value IS NOT NULL) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (value IS NOT NULL) OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (value IS NOT NULL) +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (value IS NOT NULL) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE (u2.value IS NOT NULL) count --------------------------------------------------------------------- @@ -161,8 +161,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE isfinite(u2.time); -DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, "time" FROM push_down_filters.local_table u2 WHERE isfinite("time") OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, "time" FROM push_down_filters.local_table u2 WHERE isfinite("time") OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, "time" FROM push_down_filters.local_table u2 WHERE isfinite("time") +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, "time" FROM push_down_filters.local_table u2 WHERE isfinite("time") DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE isfinite(u2."time") count --------------------------------------------------------------------- @@ -174,8 +174,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE int4smaller(u2.value, u1.value) = 55; -DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE (int4smaller(u2.value, u1.value) OPERATOR(pg_catalog.=) 55) count --------------------------------------------------------------------- @@ -187,8 +187,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE int4smaller(u2.key, u2.value) = u2.key; -DEBUG: Wrapping relation "local_table" to a subquery: SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (int4smaller(key, value) OPERATOR(pg_catalog.=) key) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (int4smaller(key, value) OPERATOR(pg_catalog.=) key) OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (int4smaller(key, value) OPERATOR(pg_catalog.=) key) +DEBUG: generating subplan XXX_1 for subquery SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (int4smaller(key, value) OPERATOR(pg_catalog.=) key) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE (int4smaller(u2.key, u2.value) OPERATOR(pg_catalog.=) u2.key) count --------------------------------------------------------------------- @@ -200,8 +200,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE row(u2.value, 2, 3) > row(u2.value, 2, 3); -DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (ROW(value, 2, 3) OPERATOR(pg_catalog.>) ROW(value, 2, 3)) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (ROW(value, 2, 3) OPERATOR(pg_catalog.>) ROW(value, 2, 3)) OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (ROW(value, 2, 3) OPERATOR(pg_catalog.>) ROW(value, 2, 3)) +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (ROW(value, 2, 3) OPERATOR(pg_catalog.>) ROW(value, 2, 3)) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE (ROW(u2.value, 2, 3) OPERATOR(pg_catalog.>) ROW(u2.value, 2, 3)) count --------------------------------------------------------------------- @@ -220,8 +220,8 @@ JOIN local_table u2 USING(value) isfinite(u2.time) AND u2.value IS DISTINCT FROM 50040 AND row(u2.value, 2, 3) > row(2000, 2, 3); -DEBUG: Wrapping relation "local_table" to a subquery: SELECT key, value, "time" FROM push_down_filters.local_table u2 WHERE (((((((key)::numeric OPERATOR(pg_catalog./) 1.0))::integer)::boolean)::text)::boolean AND CASE WHEN (key OPERATOR(pg_catalog.>) 4000) THEN ((value OPERATOR(pg_catalog./) 100) OPERATOR(pg_catalog.>) 1) ELSE false END AND COALESCE(((key OPERATOR(pg_catalog./) 50000))::boolean, false) AND NULLIF(((value OPERATOR(pg_catalog./) 50000))::boolean, false) AND isfinite("time") AND (value IS DISTINCT FROM 50040) AND (ROW(value, 2, 3) OPERATOR(pg_catalog.>) ROW(2000, 2, 3))) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, value, "time" FROM push_down_filters.local_table u2 WHERE (((((((key)::numeric OPERATOR(pg_catalog./) 1.0))::integer)::boolean)::text)::boolean AND CASE WHEN (key OPERATOR(pg_catalog.>) 4000) THEN ((value OPERATOR(pg_catalog./) 100) OPERATOR(pg_catalog.>) 1) ELSE false END AND COALESCE(((key OPERATOR(pg_catalog./) 50000))::boolean, false) AND NULLIF(((value OPERATOR(pg_catalog./) 50000))::boolean, false) AND isfinite("time") AND (value IS DISTINCT FROM 50040) AND (ROW(value, 2, 3) OPERATOR(pg_catalog.>) ROW(2000, 2, 3))) OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT key, value, "time" FROM push_down_filters.local_table u2 WHERE (((((((key)::numeric OPERATOR(pg_catalog./) 1.0))::integer)::boolean)::text)::boolean AND CASE WHEN (key OPERATOR(pg_catalog.>) 4000) THEN ((value OPERATOR(pg_catalog./) 100) OPERATOR(pg_catalog.>) 1) ELSE false END AND COALESCE(((key OPERATOR(pg_catalog./) 50000))::boolean, false) AND NULLIF(((value OPERATOR(pg_catalog./) 50000))::boolean, false) AND isfinite("time") AND (value IS DISTINCT FROM 50040) AND (ROW(value, 2, 3) OPERATOR(pg_catalog.>) ROW(2000, 2, 3))) +DEBUG: generating subplan XXX_1 for subquery SELECT key, value, "time" FROM push_down_filters.local_table u2 WHERE (((((((key)::numeric OPERATOR(pg_catalog./) 1.0))::integer)::boolean)::text)::boolean AND CASE WHEN (key OPERATOR(pg_catalog.>) 4000) THEN ((value OPERATOR(pg_catalog./) 100) OPERATOR(pg_catalog.>) 1) ELSE false END AND COALESCE(((key OPERATOR(pg_catalog./) 50000))::boolean, false) AND NULLIF(((value OPERATOR(pg_catalog./) 50000))::boolean, false) AND isfinite("time") AND (value IS DISTINCT FROM 50040) AND (ROW(value, 2, 3) OPERATOR(pg_catalog.>) ROW(2000, 2, 3))) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE (((((((u2.key)::numeric OPERATOR(pg_catalog./) 1.0))::integer)::boolean)::text)::boolean AND CASE WHEN (u2.key OPERATOR(pg_catalog.>) 4000) THEN ((u2.value OPERATOR(pg_catalog./) 100) OPERATOR(pg_catalog.>) 1) ELSE false END AND COALESCE(((u2.key OPERATOR(pg_catalog./) 50000))::boolean, false) AND NULLIF(((u2.value OPERATOR(pg_catalog./) 50000))::boolean, false) AND isfinite(u2."time") AND (u2.value IS DISTINCT FROM 50040) AND (ROW(u2.value, 2, 3) OPERATOR(pg_catalog.>) ROW(2000, 2, 3))) count --------------------------------------------------------------------- @@ -236,8 +236,8 @@ WHERE u2.value > (SELECT avg(key) FROM distributed_table); DEBUG: generating subplan XXX_1 for subquery SELECT avg(key) AS avg FROM push_down_filters.distributed_table -DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_2 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true +DEBUG: generating subplan XXX_2 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_2'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE ((u2.value)::numeric OPERATOR(pg_catalog.>) (SELECT intermediate_result.avg FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(avg numeric))) count --------------------------------------------------------------------- @@ -249,8 +249,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE u2.value > (SELECT 5); -DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE (u2.value OPERATOR(pg_catalog.>) (SELECT 5)) count --------------------------------------------------------------------- @@ -262,8 +262,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE u2.value * u1.key > 25; -DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE ((u2.value OPERATOR(pg_catalog.*) u1.key) OPERATOR(pg_catalog.>) 25) count --------------------------------------------------------------------- @@ -277,8 +277,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE u1.value = 3; -DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (value OPERATOR(pg_catalog.=) 3) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (value OPERATOR(pg_catalog.=) 3) OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (value OPERATOR(pg_catalog.=) 3) +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE (value OPERATOR(pg_catalog.=) 3) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE (u1.value OPERATOR(pg_catalog.=) 3) count --------------------------------------------------------------------- @@ -290,8 +290,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE u1.value > 3; -DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE (u1.value OPERATOR(pg_catalog.>) 3) count --------------------------------------------------------------------- @@ -304,8 +304,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE u1.key = 3; -DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE (u1.key OPERATOR(pg_catalog.=) 3) count --------------------------------------------------------------------- @@ -317,8 +317,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE u2.value > 4 OR u2.value = 4; -DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE ((value OPERATOR(pg_catalog.>) 4) OR (value OPERATOR(pg_catalog.=) 4)) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE ((value OPERATOR(pg_catalog.>) 4) OR (value OPERATOR(pg_catalog.=) 4)) OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE ((value OPERATOR(pg_catalog.>) 4) OR (value OPERATOR(pg_catalog.=) 4)) +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE ((value OPERATOR(pg_catalog.>) 4) OR (value OPERATOR(pg_catalog.=) 4)) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE ((u2.value OPERATOR(pg_catalog.>) 4) OR (u2.value OPERATOR(pg_catalog.=) 4)) count --------------------------------------------------------------------- @@ -330,8 +330,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE u2.value > 2 and u2.time IS NULL; -DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, "time" FROM push_down_filters.local_table u2 WHERE ((value OPERATOR(pg_catalog.>) 2) AND ("time" IS NULL)) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, "time" FROM push_down_filters.local_table u2 WHERE ((value OPERATOR(pg_catalog.>) 2) AND ("time" IS NULL)) OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, "time" FROM push_down_filters.local_table u2 WHERE ((value OPERATOR(pg_catalog.>) 2) AND ("time" IS NULL)) +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, "time" FROM push_down_filters.local_table u2 WHERE ((value OPERATOR(pg_catalog.>) 2) AND ("time" IS NULL)) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE ((u2.value OPERATOR(pg_catalog.>) 2) AND (u2."time" IS NULL)) count --------------------------------------------------------------------- @@ -344,8 +344,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE (u2.value > 2 OR u2.value IS NULL) AND (u2.key > 4 OR u1.key > 3); -DEBUG: Wrapping relation "local_table" to a subquery: SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE ((value OPERATOR(pg_catalog.>) 2) OR (value IS NULL)) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE ((value OPERATOR(pg_catalog.>) 2) OR (value IS NULL)) OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE ((value OPERATOR(pg_catalog.>) 2) OR (value IS NULL)) +DEBUG: generating subplan XXX_1 for subquery SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE ((value OPERATOR(pg_catalog.>) 2) OR (value IS NULL)) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE (((u2.value OPERATOR(pg_catalog.>) 2) OR (u2.value IS NULL)) AND ((u2.key OPERATOR(pg_catalog.>) 4) OR (u1.key OPERATOR(pg_catalog.>) 3))) count --------------------------------------------------------------------- @@ -358,8 +358,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE (u2.value > 2 OR u2.value IS NULL) OR (u2.key > 4 OR u1.key > 3); -DEBUG: Wrapping relation "local_table" to a subquery: SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE ((u2.value OPERATOR(pg_catalog.>) 2) OR (u2.value IS NULL) OR ((u2.key OPERATOR(pg_catalog.>) 4) OR (u1.key OPERATOR(pg_catalog.>) 3))) count --------------------------------------------------------------------- @@ -372,8 +372,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE (u2.value > 2 OR u2.value IS NULL) AND (u2.key > 4 OR u1.key > 3); -DEBUG: Wrapping relation "local_table" to a subquery: SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE ((value OPERATOR(pg_catalog.>) 2) OR (value IS NULL)) OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE ((value OPERATOR(pg_catalog.>) 2) OR (value IS NULL)) OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE ((value OPERATOR(pg_catalog.>) 2) OR (value IS NULL)) +DEBUG: generating subplan XXX_1 for subquery SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE ((value OPERATOR(pg_catalog.>) 2) OR (value IS NULL)) DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE (((u2.value OPERATOR(pg_catalog.>) 2) OR (u2.value IS NULL)) AND ((u2.key OPERATOR(pg_catalog.>) 4) OR (u1.key OPERATOR(pg_catalog.>) 3))) count --------------------------------------------------------------------- @@ -385,8 +385,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE (u2.value > 2 OR u1.value IS NULL) AND (u2.key = 10000 * random() OR u1.key > 3); -DEBUG: Wrapping relation "local_table" to a subquery: SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true +DEBUG: generating subplan XXX_1 for subquery SELECT key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE true DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE (((u2.value OPERATOR(pg_catalog.>) 2) OR (u1.value IS NULL)) AND (((u2.key)::double precision OPERATOR(pg_catalog.=) ((10000)::double precision OPERATOR(pg_catalog.*) random())) OR (u1.key OPERATOR(pg_catalog.>) 3))) count --------------------------------------------------------------------- @@ -398,8 +398,8 @@ SELECT count(*) FROM distributed_table u1 JOIN local_table u2 USING(value) WHERE (u2.value > 2 AND false); -DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE false OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE false OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE false +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE false DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM (push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) WHERE ((u2.value OPERATOR(pg_catalog.>) 2) AND false) count --------------------------------------------------------------------- @@ -418,8 +418,8 @@ JOIN LATERAL WHERE u2.value = 15) AS u3 USING (value) WHERE (u2.value > 2 AND FALSE); -DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE false OFFSET 0 -DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE false OFFSET 0 +DEBUG: Wrapping relation "local_table" to a subquery: SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE false +DEBUG: generating subplan XXX_1 for subquery SELECT NULL::integer AS key, value, NULL::timestamp with time zone AS "time" FROM push_down_filters.local_table u2 WHERE false DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT count(*) AS count FROM ((push_down_filters.distributed_table u1 JOIN (SELECT intermediate_result.key, intermediate_result.value, intermediate_result."time" FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(key integer, value integer, "time" timestamp with time zone)) u2 USING (value)) JOIN LATERAL (SELECT distributed_table.value, random() AS random FROM push_down_filters.distributed_table WHERE (u2.value OPERATOR(pg_catalog.=) 15)) u3 USING (value)) WHERE ((u2.value OPERATOR(pg_catalog.>) 2) AND false) ERROR: complex joins are only supported when all distributed tables are co-located and joined on their distribution columns \set VERBOSITY terse diff --git a/src/test/regress/multi_schedule b/src/test/regress/multi_schedule index 3c5cb0175..80cf392a5 100644 --- a/src/test/regress/multi_schedule +++ b/src/test/regress/multi_schedule @@ -222,7 +222,10 @@ test: multi_modifying_xacts test: multi_repartition_udt multi_repartitioned_subquery_udf multi_subtransactions test: multi_transaction_recovery +test: local_dist_join_modifications test: local_table_join +test: local_dist_join_mixed +test: citus_local_dist_joins # --------- # multi_copy creates hash and range-partitioned tables and performs COPY diff --git a/src/test/regress/sql/citus_local_dist_joins.sql b/src/test/regress/sql/citus_local_dist_joins.sql new file mode 100644 index 000000000..34523eec2 --- /dev/null +++ b/src/test/regress/sql/citus_local_dist_joins.sql @@ -0,0 +1,232 @@ +CREATE SCHEMA citus_local_dist_joins; +SET search_path TO citus_local_dist_joins; + +SET client_min_messages to ERROR; +SELECT master_add_node('localhost', :master_port, groupId => 0); + + +CREATE TABLE citus_local(key int, value text); +SELECT create_citus_local_table('citus_local'); + +CREATE TABLE postgres_table (key int, value text, value_2 jsonb); +CREATE TABLE reference_table (key int, value text, value_2 jsonb); +SELECT create_reference_table('reference_table'); +CREATE TABLE distributed_table (key int, value text, value_2 jsonb); +SELECT create_distributed_table('distributed_table', 'key'); + +CREATE TABLE distributed_table_pkey (key int primary key, value text, value_2 jsonb); +SELECT create_distributed_table('distributed_table_pkey', 'key'); + +CREATE TABLE distributed_table_windex (key int primary key, value text, value_2 jsonb); +SELECT create_distributed_table('distributed_table_windex', 'key'); +CREATE UNIQUE INDEX key_index ON distributed_table_windex (key); + +CREATE TABLE distributed_partitioned_table(key int, value text) PARTITION BY RANGE (key); +CREATE TABLE distributed_partitioned_table_1 PARTITION OF distributed_partitioned_table FOR VALUES FROM (0) TO (50); +CREATE TABLE distributed_partitioned_table_2 PARTITION OF distributed_partitioned_table FOR VALUES FROM (50) TO (200); +SELECT create_distributed_table('distributed_partitioned_table', 'key'); + +CREATE TABLE local_partitioned_table(key int, value text) PARTITION BY RANGE (key); +CREATE TABLE local_partitioned_table_1 PARTITION OF local_partitioned_table FOR VALUES FROM (0) TO (50); +CREATE TABLE local_partitioned_table_2 PARTITION OF local_partitioned_table FOR VALUES FROM (50) TO (200); + +CREATE TABLE distributed_table_composite (key int, value text, value_2 jsonb, primary key (key, value)); +SELECT create_distributed_table('distributed_table_composite', 'key'); + +CREATE MATERIALIZED VIEW mv1 AS SELECT * FROM postgres_table; +CREATE MATERIALIZED VIEW mv2 AS SELECT * FROM distributed_table; + +-- set log messages to debug1 so that we can see which tables are recursively planned. +SET client_min_messages TO DEBUG1; + +INSERT INTO postgres_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO reference_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO distributed_table_windex SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO distributed_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO distributed_table_pkey SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO distributed_partitioned_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO distributed_table_composite SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO local_partitioned_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO citus_local SELECT i, i::varchar(256) FROM generate_series(1, 100) i; + + +-- a unique index on key so dist table should be recursively planned +SELECT count(*) FROM citus_local JOIN distributed_table_windex USING(key); +SELECT count(*) FROM citus_local JOIN distributed_table_windex USING(value); +SELECT count(*) FROM citus_local JOIN distributed_table_windex ON citus_local.key = distributed_table_windex.key; +SELECT count(*) FROM citus_local JOIN distributed_table_windex ON distributed_table_windex.key = 10; + +-- no unique index, citus local table should be recursively planned +SELECT count(*) FROM citus_local JOIN distributed_table USING(key); +SELECT count(*) FROM citus_local JOIN distributed_table USING(value); +SELECT count(*) FROM citus_local JOIN distributed_table ON citus_local.key = distributed_table.key; +SELECT count(*) FROM citus_local JOIN distributed_table ON distributed_table.key = 10; + +SELECT count(*) FROM citus_local JOIN distributed_table USING(key) JOIN postgres_table USING (key) JOIN reference_table USING(key); + +SELECT count(*) FROM distributed_partitioned_table JOIN postgres_table USING(key) JOIN reference_table USING (key) + JOIN citus_local USING(key) WHERE distributed_partitioned_table.key > 10 and distributed_partitioned_table.key = 10; + +-- update +BEGIN; +SELECT COUNT(DISTINCT value) FROM citus_local; +UPDATE + citus_local +SET + value = 'test' +FROM + distributed_table +WHERE + distributed_table.key = citus_local.key; +SELECT COUNT(DISTINCT value) FROM citus_local; +ROLLBACK; + +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table; +UPDATE + distributed_table +SET + value = 'test' +FROM + citus_local +WHERE + distributed_table.key = citus_local.key; +SELECT COUNT(DISTINCT value) FROM distributed_table; +ROLLBACK; + +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; +UPDATE + distributed_table_pkey +SET + value = 'test' +FROM + citus_local +WHERE + distributed_table_pkey.key = citus_local.key; +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; +ROLLBACK; + +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; +UPDATE + distributed_table_windex +SET + value = 'test' +FROM + citus_local +WHERE + distributed_table_windex.key = citus_local.key; +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; +ROLLBACK; + +BEGIN; +UPDATE + mv1 +SET + value = 'test' +FROM + citus_local +WHERE + mv1.key = citus_local.key; +ROLLBACK; + +BEGIN; +UPDATE + citus_local +SET + value = 'test' +FROM + mv1 +WHERE + mv1.key = citus_local.key; +ROLLBACK; + +BEGIN; +UPDATE + citus_local +SET + value = 'test' +FROM + mv2 +WHERE + mv2.key = citus_local.key; +ROLLBACK; + +-- DELETE operations + +BEGIN; +SELECT COUNT(DISTINCT value) FROM citus_local; +DELETE FROM + citus_local +USING + distributed_table +WHERE + distributed_table.key = citus_local.key; +SELECT COUNT(DISTINCT value) FROM citus_local; +ROLLBACK; + +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table; +DELETE FROM + distributed_table +USING + citus_local +WHERE + distributed_table.key = citus_local.key; +SELECT COUNT(DISTINCT value) FROM distributed_table; +ROLLBACK; + +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; +DELETE FROM + distributed_table_pkey +USING + citus_local +WHERE + distributed_table_pkey.key = citus_local.key; +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; +ROLLBACK; + +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; +DELETE FROM + distributed_table_windex +USING + citus_local +WHERE + distributed_table_windex.key = citus_local.key; +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; +ROLLBACK; + +DELETE FROM + mv1 +USING + citus_local +WHERE + mv1.key = citus_local.key; + +DELETE FROM + citus_local +USING + mv1 +WHERE + mv1.key = citus_local.key; + +DELETE FROM + citus_local +USING + mv2 +WHERE + mv2.key = citus_local.key; + +SELECT count(*) FROM postgres_table JOIN (SELECT * FROM (SELECT * FROM distributed_table LIMIT 1) d1) d2 using (key) JOIN reference_table USING(key) JOIN citus_local USING (key) JOIN (SELECT * FROM citus_local) c1 USING (key) WHERE d2.key > 10 AND d2.key = 10; +SELECT count(*) FROM postgres_table JOIN (SELECT * FROM (SELECT * FROM distributed_table LIMIT 1) d1) d2 using (key) JOIN reference_table USING(key) JOIN citus_local USING (key) JOIN (SELECT * FROM citus_local) c1 USING (key) WHERE d2.key > 10 AND d2.key = 10; + + + +SET client_min_messages to ERROR; +DROP TABLE citus_local; +SELECT master_remove_node('localhost', :master_port); +\set VERBOSITY terse +DROP SCHEMA citus_local_dist_joins CASCADE; \ No newline at end of file diff --git a/src/test/regress/sql/local_distributed_table_join.sql b/src/test/regress/sql/local_dist_join_mixed.sql similarity index 88% rename from src/test/regress/sql/local_distributed_table_join.sql rename to src/test/regress/sql/local_dist_join_mixed.sql index 78ff90614..1a00c4f22 100644 --- a/src/test/regress/sql/local_distributed_table_join.sql +++ b/src/test/regress/sql/local_dist_join_mixed.sql @@ -1,5 +1,5 @@ -CREATE SCHEMA local_distributed_table_join; -SET search_path TO local_distributed_table_join; +CREATE SCHEMA local_dist_join_mixed; +SET search_path TO local_dist_join_mixed; @@ -20,6 +20,7 @@ INSERT INTO distributed SELECT i, i::text, now() FROM generate_series(0,100)i; INSERT INTO reference SELECT i, i::text FROM generate_series(0,100)i; INSERT INTO local SELECT i, i::text FROM generate_series(0,100)i; +SET client_min_messages to DEBUG1; -- very simple 1-1 Joins SELECT count(*) FROM distributed JOIN local USING (id); @@ -308,11 +309,11 @@ SELECT count(*) FROM distributed CROSS JOIN local WHERE distributed.id = 1; SELECT count(*) FROM distributed LEFT JOIN local USING (id); SELECT count(*) FROM local LEFT JOIN distributed USING (id); -SELECT * FROM distributed LEFT JOIN local USING (id) LIMIT 1; -SELECT * FROM local LEFT JOIN distributed USING (id) LIMIT 1; +SELECT id, name FROM distributed LEFT JOIN local USING (id) LIMIT 1; +SELECT id, name FROM local LEFT JOIN distributed USING (id) LIMIT 1; SELECT - foo1.id, random() + foo1.id FROM (SELECT local.id, local.title FROM local, distributed WHERE local.id = distributed.id ) as foo9, (SELECT local.id, local.title FROM local, distributed WHERE local.id = distributed.id ) as foo8, @@ -334,38 +335,41 @@ SELECT * FROM local LEFT JOIN distributed USING (id) LIMIT 1; foo1.id = foo3.id AND foo1.id = foo2.id AND foo1.id = foo10.id AND - foo1.id = foo1.id ; + foo1.id = foo1.id +ORDER BY 1; - SELECT - foo1.id - FROM - (SELECT local.id FROM distributed, local WHERE local.id = distributed.id ) as foo1, - (SELECT local.id FROM distributed, local WHERE local.id = distributed.id ) as foo2, - (SELECT local.id FROM distributed, local WHERE local.id = distributed.id ) as foo3, - (SELECT local.id FROM distributed, local WHERE local.id = distributed.id ) as foo4, - (SELECT local.id FROM distributed, local WHERE local.id = distributed.id ) as foo5 - WHERE - foo1.id = foo4.id AND - foo1.id = foo2.id AND - foo1.id = foo3.id AND - foo1.id = foo4.id AND - foo1.id = foo5.id; +SELECT + foo1.id +FROM + (SELECT local.id FROM distributed, local WHERE local.id = distributed.id ) as foo1, + (SELECT local.id FROM distributed, local WHERE local.id = distributed.id ) as foo2, + (SELECT local.id FROM distributed, local WHERE local.id = distributed.id ) as foo3, + (SELECT local.id FROM distributed, local WHERE local.id = distributed.id ) as foo4, + (SELECT local.id FROM distributed, local WHERE local.id = distributed.id ) as foo5 +WHERE + foo1.id = foo4.id AND + foo1.id = foo2.id AND + foo1.id = foo3.id AND + foo1.id = foo4.id AND + foo1.id = foo5.id +ORDER BY 1; - SELECT - foo1.id - FROM - (SELECT local.id FROM distributed, local WHERE local.id = distributed.id AND distributed.id = 1) as foo1, - (SELECT local.id FROM distributed, local WHERE local.id = distributed.id AND distributed.id = 2) as foo2, - (SELECT local.id FROM distributed, local WHERE local.id = distributed.id AND distributed.id = 3) as foo3, - (SELECT local.id FROM distributed, local WHERE local.id = distributed.id AND distributed.id = 4) as foo4, - (SELECT local.id FROM distributed, local WHERE local.id = distributed.id AND distributed.id = 5) as foo5 - WHERE - foo1.id = foo4.id AND - foo1.id = foo2.id AND - foo1.id = foo3.id AND - foo1.id = foo4.id AND - foo1.id = foo5.id; +SELECT + foo1.id +FROM + (SELECT local.id FROM distributed, local WHERE local.id = distributed.id AND distributed.id = 1) as foo1, + (SELECT local.id FROM distributed, local WHERE local.id = distributed.id AND distributed.id = 2) as foo2, + (SELECT local.id FROM distributed, local WHERE local.id = distributed.id AND distributed.id = 3) as foo3, + (SELECT local.id FROM distributed, local WHERE local.id = distributed.id AND distributed.id = 4) as foo4, + (SELECT local.id FROM distributed, local WHERE local.id = distributed.id AND distributed.id = 5) as foo5 +WHERE + foo1.id = foo4.id AND + foo1.id = foo2.id AND + foo1.id = foo3.id AND + foo1.id = foo4.id AND + foo1.id = foo5.id +ORDER BY 1; -DROP SCHEMA local_distributed_table_join CASCADE; \ No newline at end of file +DROP SCHEMA local_dist_join_mixed CASCADE; \ No newline at end of file diff --git a/src/test/regress/sql/local_dist_join_modifications.sql b/src/test/regress/sql/local_dist_join_modifications.sql new file mode 100644 index 000000000..f8c8ee886 --- /dev/null +++ b/src/test/regress/sql/local_dist_join_modifications.sql @@ -0,0 +1,372 @@ +CREATE SCHEMA local_dist_join_modifications; +SET search_path TO local_dist_join_modifications; + +CREATE TABLE postgres_table (key int, value text, value_2 jsonb); +CREATE TABLE reference_table (key int, value text, value_2 jsonb); +SELECT create_reference_table('reference_table'); +CREATE TABLE distributed_table (key int, value text, value_2 jsonb); +SELECT create_distributed_table('distributed_table', 'key'); + +CREATE TABLE distributed_table_pkey (key int primary key, value text, value_2 jsonb); +SELECT create_distributed_table('distributed_table_pkey', 'key'); + +CREATE TABLE distributed_table_windex (key int primary key, value text, value_2 jsonb); +SELECT create_distributed_table('distributed_table_windex', 'key'); +CREATE UNIQUE INDEX key_index ON distributed_table_windex (key); + +CREATE TABLE distributed_partitioned_table(key int, value text) PARTITION BY RANGE (key); +CREATE TABLE distributed_partitioned_table_1 PARTITION OF distributed_partitioned_table FOR VALUES FROM (0) TO (50); +CREATE TABLE distributed_partitioned_table_2 PARTITION OF distributed_partitioned_table FOR VALUES FROM (50) TO (200); +SELECT create_distributed_table('distributed_partitioned_table', 'key'); + +CREATE TABLE local_partitioned_table(key int, value text) PARTITION BY RANGE (key); +CREATE TABLE local_partitioned_table_1 PARTITION OF local_partitioned_table FOR VALUES FROM (0) TO (50); +CREATE TABLE local_partitioned_table_2 PARTITION OF local_partitioned_table FOR VALUES FROM (50) TO (200); + +CREATE TABLE distributed_table_composite (key int, value text, value_2 jsonb, primary key (key, value)); +SELECT create_distributed_table('distributed_table_composite', 'key'); + +CREATE MATERIALIZED VIEW mv1 AS SELECT * FROM postgres_table; +CREATE MATERIALIZED VIEW mv2 AS SELECT * FROM distributed_table; + +-- set log messages to debug1 so that we can see which tables are recursively planned. +SET client_min_messages TO DEBUG1; + +INSERT INTO postgres_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO reference_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO distributed_table_windex SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO distributed_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO distributed_table_pkey SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO distributed_partitioned_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO distributed_table_composite SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO local_partitioned_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; + +SET citus.local_table_join_policy to 'auto'; + +-- we can support modification queries as well +BEGIN; +SELECT COUNT(DISTINCT value) FROM postgres_table; +UPDATE + postgres_table +SET + value = 'test' +FROM + distributed_table +WHERE + distributed_table.key = postgres_table.key; +SELECT COUNT(DISTINCT value) FROM postgres_table; +ROLLBACK; + +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table; +UPDATE + distributed_table +SET + value = 'test' +FROM + postgres_table +WHERE + distributed_table.key = postgres_table.key; +SELECT COUNT(DISTINCT value) FROM distributed_table; +ROLLBACK; + +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; +UPDATE + distributed_table_pkey +SET + value = 'test' +FROM + postgres_table +WHERE + distributed_table_pkey.key = postgres_table.key; +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; +ROLLBACK; + +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; +UPDATE + distributed_table_windex +SET + value = 'test' +FROM + postgres_table +WHERE + distributed_table_windex.key = postgres_table.key; +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; +ROLLBACK; + +BEGIN; +UPDATE + mv1 +SET + value = 'test' +FROM + postgres_table +WHERE + mv1.key = postgres_table.key; +ROLLBACK; + +BEGIN; +UPDATE + postgres_table +SET + value = 'test' +FROM + mv1 +WHERE + mv1.key = postgres_table.key; +ROLLBACK; + +BEGIN; +UPDATE + postgres_table +SET + value = 'test' +FROM + mv2 +WHERE + mv2.key = postgres_table.key; +ROLLBACK; + +-- in case of update/delete we always recursively plan +-- the tables other than target table no matter what the policy is + +SET citus.local_table_join_policy TO 'prefer-local'; + +BEGIN; +SELECT COUNT(DISTINCT value) FROM postgres_table; +UPDATE + postgres_table +SET + value = 'test' +FROM + distributed_table +WHERE + distributed_table.key = postgres_table.key; +SELECT COUNT(DISTINCT value) FROM postgres_table; +ROLLBACK; + +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table; +UPDATE + distributed_table +SET + value = 'test' +FROM + postgres_table +WHERE + distributed_table.key = postgres_table.key; +SELECT COUNT(DISTINCT value) FROM distributed_table; +ROLLBACK; + +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; +UPDATE + distributed_table_pkey +SET + value = 'test' +FROM + postgres_table +WHERE + distributed_table_pkey.key = postgres_table.key; +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; +ROLLBACK; + +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; +UPDATE + distributed_table_windex +SET + value = 'test' +FROM + postgres_table +WHERE + distributed_table_windex.key = postgres_table.key; +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; +ROLLBACK; + +SET citus.local_table_join_policy TO 'prefer-distributed'; + +BEGIN; +SELECT COUNT(DISTINCT value) FROM postgres_table; +UPDATE + postgres_table +SET + value = 'test' +FROM + distributed_table +WHERE + distributed_table.key = postgres_table.key; +SELECT COUNT(DISTINCT value) FROM postgres_table; +ROLLBACK; + +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table; +UPDATE + distributed_table +SET + value = 'test' +FROM + postgres_table +WHERE + distributed_table.key = postgres_table.key; +SELECT COUNT(DISTINCT value) FROM distributed_table; +ROLLBACK; + +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; +UPDATE + distributed_table_pkey +SET + value = 'test' +FROM + postgres_table +WHERE + distributed_table_pkey.key = postgres_table.key; +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; +ROLLBACK; + + +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; +UPDATE + distributed_table_windex +SET + value = 'test' +FROM + postgres_table +WHERE + distributed_table_windex.key = postgres_table.key; +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; +ROLLBACK; + +SET citus.local_table_join_policy TO 'auto'; + +-- modifications with multiple tables +BEGIN; +UPDATE + distributed_table +SET + value = 'test' +FROM + postgres_table p1, postgres_table p2 +WHERE + distributed_table.key = p1.key AND p1.key = p2.key; +ROLLBACK; + +BEGIN; +UPDATE + postgres_table +SET + value = 'test' +FROM + (SELECT * FROM distributed_table) d1 +WHERE + d1.key = postgres_table.key; +ROLLBACK; + +BEGIN; +UPDATE + postgres_table +SET + value = 'test' +FROM + (SELECT * FROM distributed_table LIMIT 1) d1 +WHERE + d1.key = postgres_table.key; +ROLLBACK; + +BEGIN; +UPDATE + distributed_table +SET + value = 'test' +FROM + postgres_table p1, distributed_table d2 +WHERE + distributed_table.key = p1.key AND p1.key = d2.key; +ROLLBACK; + +-- pretty inefficient plan as it requires +-- recursive planninng of 2 distributed tables +BEGIN; +UPDATE + postgres_table +SET + value = 'test' +FROM + distributed_table d1, distributed_table d2 +WHERE + postgres_table.key = d1.key AND d1.key = d2.key; +ROLLBACK; +-- DELETE operations + +BEGIN; +SELECT COUNT(DISTINCT value) FROM postgres_table; +DELETE FROM + postgres_table +USING + distributed_table +WHERE + distributed_table.key = postgres_table.key; +SELECT COUNT(DISTINCT value) FROM postgres_table; +ROLLBACK; + +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table; +DELETE FROM + distributed_table +USING + postgres_table +WHERE + distributed_table.key = postgres_table.key; +SELECT COUNT(DISTINCT value) FROM distributed_table; +ROLLBACK; + +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; +DELETE FROM + distributed_table_pkey +USING + postgres_table +WHERE + distributed_table_pkey.key = postgres_table.key; +SELECT COUNT(DISTINCT value) FROM distributed_table_pkey; +ROLLBACK; + +BEGIN; +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; +DELETE FROM + distributed_table_windex +USING + postgres_table +WHERE + distributed_table_windex.key = postgres_table.key; +SELECT COUNT(DISTINCT value) FROM distributed_table_windex; +ROLLBACK; + +DELETE FROM + mv1 +USING + postgres_table +WHERE + mv1.key = postgres_table.key; + +DELETE FROM + postgres_table +USING + mv1 +WHERE + mv1.key = postgres_table.key; + +DELETE FROM + postgres_table +USING + mv2 +WHERE + mv2.key = postgres_table.key; + + +SET client_min_messages to ERROR; +DROP SCHEMA local_dist_join_modifications CASCADE; \ No newline at end of file diff --git a/src/test/regress/sql/local_table_join.sql b/src/test/regress/sql/local_table_join.sql index c3786cc4f..dad8459f1 100644 --- a/src/test/regress/sql/local_table_join.sql +++ b/src/test/regress/sql/local_table_join.sql @@ -15,17 +15,26 @@ SELECT create_distributed_table('distributed_table_windex', 'key'); CREATE UNIQUE INDEX key_index ON distributed_table_windex (key); CREATE TABLE distributed_partitioned_table(key int, value text) PARTITION BY RANGE (key); -CREATE TABLE distributed_partitioned_table_1 PARTITION OF distributed_partitioned_table FOR VALUES FROM (0) TO (10); -CREATE TABLE distributed_partitioned_table_2 PARTITION OF distributed_partitioned_table FOR VALUES FROM (10) TO (20); +CREATE TABLE distributed_partitioned_table_1 PARTITION OF distributed_partitioned_table FOR VALUES FROM (0) TO (50); +CREATE TABLE distributed_partitioned_table_2 PARTITION OF distributed_partitioned_table FOR VALUES FROM (50) TO (200); SELECT create_distributed_table('distributed_partitioned_table', 'key'); CREATE TABLE local_partitioned_table(key int, value text) PARTITION BY RANGE (key); -CREATE TABLE local_partitioned_table_1 PARTITION OF local_partitioned_table FOR VALUES FROM (0) TO (10); -CREATE TABLE local_partitioned_table_2 PARTITION OF local_partitioned_table FOR VALUES FROM (10) TO (20); +CREATE TABLE local_partitioned_table_1 PARTITION OF local_partitioned_table FOR VALUES FROM (0) TO (50); +CREATE TABLE local_partitioned_table_2 PARTITION OF local_partitioned_table FOR VALUES FROM (50) TO (200); CREATE TABLE distributed_table_composite (key int, value text, value_2 jsonb, primary key (key, value)); SELECT create_distributed_table('distributed_table_composite', 'key'); +INSERT INTO postgres_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO reference_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO distributed_table_windex SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO distributed_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO distributed_table_pkey SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO distributed_partitioned_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO distributed_table_composite SELECT i, i::varchar(256) FROM generate_series(1, 100) i; +INSERT INTO local_partitioned_table SELECT i, i::varchar(256) FROM generate_series(1, 100) i; + CREATE FUNCTION fake_fdw_handler() RETURNS fdw_handler AS 'citus' @@ -61,7 +70,6 @@ SET citus.local_table_join_policy TO 'prefer-distributed'; SELECT count(*) FROM postgres_table JOIN distributed_table USING(key); SELECT count(*) FROM postgres_table JOIN reference_table USING(key); --- update/delete -- auto tests -- switch back to the default policy, which is auto @@ -187,179 +195,6 @@ WHERE d1.key = 1; -SET citus.local_table_join_policy to 'auto'; - --- we can support modification queries as well -UPDATE - postgres_table -SET - value = 'test' -FROM - distributed_table -WHERE - distributed_table.key = postgres_table.key; - - -UPDATE - distributed_table -SET - value = 'test' -FROM - postgres_table -WHERE - distributed_table.key = postgres_table.key; - -UPDATE - distributed_table_pkey -SET - value = 'test' -FROM - postgres_table -WHERE - distributed_table_pkey.key = postgres_table.key; - -UPDATE - distributed_table_windex -SET - value = 'test' -FROM - postgres_table -WHERE - distributed_table_windex.key = postgres_table.key; - --- in case of update/delete we always recursively plan --- the tables other than target table no matter what the policy is - -SET citus.local_table_join_policy TO 'prefer-local'; - -UPDATE - postgres_table -SET - value = 'test' -FROM - distributed_table -WHERE - distributed_table.key = postgres_table.key; - - -UPDATE - distributed_table -SET - value = 'test' -FROM - postgres_table -WHERE - distributed_table.key = postgres_table.key; - -UPDATE - distributed_table_pkey -SET - value = 'test' -FROM - postgres_table -WHERE - distributed_table_pkey.key = postgres_table.key; - -UPDATE - distributed_table_windex -SET - value = 'test' -FROM - postgres_table -WHERE - distributed_table_windex.key = postgres_table.key; - - -SET citus.local_table_join_policy TO 'prefer-distributed'; - -UPDATE - postgres_table -SET - value = 'test' -FROM - distributed_table -WHERE - distributed_table.key = postgres_table.key; - - -UPDATE - distributed_table -SET - value = 'test' -FROM - postgres_table -WHERE - distributed_table.key = postgres_table.key; - -UPDATE - distributed_table_pkey -SET - value = 'test' -FROM - postgres_table -WHERE - distributed_table_pkey.key = postgres_table.key; - -UPDATE - distributed_table_windex -SET - value = 'test' -FROM - postgres_table -WHERE - distributed_table_windex.key = postgres_table.key; - -SET citus.local_table_join_policy TO 'auto'; - --- modifications with multiple tables -UPDATE - distributed_table -SET - value = 'test' -FROM - postgres_table p1, postgres_table p2 -WHERE - distributed_table.key = p1.key AND p1.key = p2.key; - -UPDATE - postgres_table -SET - value = 'test' -FROM - (SELECT * FROM distributed_table) d1 -WHERE - d1.key = postgres_table.key; - -UPDATE - postgres_table -SET - value = 'test' -FROM - (SELECT * FROM distributed_table LIMIT 1) d1 -WHERE - d1.key = postgres_table.key; - -UPDATE - distributed_table -SET - value = 'test' -FROM - postgres_table p1, distributed_table d2 -WHERE - distributed_table.key = p1.key AND p1.key = d2.key; - --- pretty inefficient plan as it requires --- recursive planninng of 2 distributed tables -UPDATE - postgres_table -SET - value = 'test' -FROM - distributed_table d1, distributed_table d2 -WHERE - postgres_table.key = d1.key AND d1.key = d2.key; - --- currently can't plan subquery-local table join SELECT count(*) FROM (SELECT * FROM (SELECT * FROM distributed_table) d1) d2 @@ -367,72 +202,15 @@ JOIN postgres_table USING(key); - ---------------------------------------------------------- - -SET client_min_messages to ERROR; -SELECT master_add_node('localhost', :master_port, groupId => 0); - - -CREATE TABLE citus_local(key int, value text); -SELECT create_citus_local_table('citus_local'); -SET client_min_messages TO DEBUG1; - --- same for citus local table - distributed table joins --- a unique index on key so dist table should be recursively planned -SELECT count(*) FROM citus_local JOIN distributed_table_windex USING(key); -SELECT count(*) FROM citus_local JOIN distributed_table_windex USING(value); -SELECT count(*) FROM citus_local JOIN distributed_table_windex ON citus_local.key = distributed_table_windex.key; -SELECT count(*) FROM citus_local JOIN distributed_table_windex ON distributed_table_windex.key = 10; - --- no unique index, citus local table should be recursively planned -SELECT count(*) FROM citus_local JOIN distributed_table USING(key); -SELECT count(*) FROM citus_local JOIN distributed_table USING(value); -SELECT count(*) FROM citus_local JOIN distributed_table ON citus_local.key = distributed_table.key; -SELECT count(*) FROM citus_local JOIN distributed_table ON distributed_table.key = 10; - -SELECT count(*) FROM citus_local JOIN distributed_table USING(key) JOIN postgres_table USING (key) JOIN reference_table USING(key); - -SELECT count(*) FROM distributed_partitioned_table JOIN postgres_table USING(key) JOIN reference_table USING (key) - JOIN citus_local USING(key) WHERE distributed_partitioned_table.key > 10 and distributed_partitioned_table.key = 10; - --- update -UPDATE - distributed_table_windex -SET - value = 'test' -FROM - citus_local -WHERE - distributed_table_windex.key = citus_local.key; - -UPDATE - citus_local -SET - value = 'test' -FROM - distributed_table_windex -WHERE - distributed_table_windex.key = citus_local.key; - --- complex queries -SELECT count(*) FROM postgres_table JOIN (SELECT * FROM (SELECT * FROM distributed_table LIMIT 1) d1) d2 using (key) JOIN reference_table USING(key) JOIN citus_local USING (key) JOIN (SELECT * FROM citus_local) c1 USING (key) WHERE d2.key > 10 AND d2.key = 10; -SELECT count(*) FROM postgres_table JOIN (SELECT * FROM (SELECT * FROM distributed_table LIMIT 1) d1) d2 using (key) JOIN reference_table USING(key) JOIN citus_local USING (key) JOIN (SELECT * FROM citus_local) c1 USING (key) WHERE d2.key > 10 AND d2.key = 10; - -- TODO:: we should support this? UPDATE reference_table SET key = 1 FROM postgres_table WHERE postgres_table.key = 10; UPDATE reference_table SET key = 1 FROM (SELECT * FROM postgres_table) l WHERE l.key = 10; -UPDATE citus_local SET key = 1 FROM postgres_table WHERE citus_local.key = 10; -UPDATE postgres_table SET key = 1 FROM citus_local WHERE citus_local.key = 10; - -- TODO:: we should probably not wrap postgres_table here as there is a WHERE FALSE? -- though then the planner could give an error SELECT count(*) FROM postgres_table JOIN distributed_table USING(key) WHERE FALSE; -DROP TABLE citus_local; RESET client_min_messages; -SELECT master_remove_node('localhost', :master_port); \set VERBOSITY terse DROP SCHEMA local_table_join CASCADE;