From 3bd53a24a329dd1b6cf0aa382f49965fe3fa68b6 Mon Sep 17 00:00:00 2001 From: Sait Talha Nisanci Date: Wed, 2 Dec 2020 16:54:15 +0300 Subject: [PATCH] Support update on postgres table from citus local table --- .../distributed/planner/multi_router_planner.c | 12 ++++++++---- src/backend/distributed/planner/recursive_planning.c | 2 -- src/test/regress/expected/local_table_join.out | 2 ++ src/test/regress/sql/local_table_join.sql | 4 ++++ 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/backend/distributed/planner/multi_router_planner.c b/src/backend/distributed/planner/multi_router_planner.c index dec40c41a..257c6d24c 100644 --- a/src/backend/distributed/planner/multi_router_planner.c +++ b/src/backend/distributed/planner/multi_router_planner.c @@ -1940,10 +1940,12 @@ SingleShardTaskList(Query *query, uint64 jobId, List *relationShardList, RangeTblEntry *updateOrDeleteRTE = ExtractResultRelationRTE(query); Assert(updateOrDeleteRTE != NULL); - CitusTableCacheEntry *modificationTableCacheEntry = GetCitusTableCacheEntry( - updateOrDeleteRTE->relid); + CitusTableCacheEntry *modificationTableCacheEntry = NULL; + if (IsCitusTable(updateOrDeleteRTE->relid)) { + modificationTableCacheEntry = GetCitusTableCacheEntry(updateOrDeleteRTE->relid); + } - if (IsCitusTableTypeCacheEntry(modificationTableCacheEntry, REFERENCE_TABLE) && + if (IsCitusTableType(updateOrDeleteRTE->relid, REFERENCE_TABLE) && SelectsFromDistributedTable(rangeTableList, query)) { ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -1952,7 +1954,9 @@ SingleShardTaskList(Query *query, uint64 jobId, List *relationShardList, } taskType = MODIFY_TASK; - replicationModel = modificationTableCacheEntry->replicationModel; + if (modificationTableCacheEntry) { + replicationModel = modificationTableCacheEntry->replicationModel; + } } if (taskType == READ_TASK && query->hasModifyingCTE) diff --git a/src/backend/distributed/planner/recursive_planning.c b/src/backend/distributed/planner/recursive_planning.c index 5f85df5cc..581635576 100644 --- a/src/backend/distributed/planner/recursive_planning.c +++ b/src/backend/distributed/planner/recursive_planning.c @@ -1453,11 +1453,9 @@ ContainsTableToBeConvertedToSubquery(List *rangeTableList, Oid resultRelationId) { return true; } - return false; } - /* * AllDataLocallyAccessible return true if all data for the relations in the * rangeTableList is locally accessible. diff --git a/src/test/regress/expected/local_table_join.out b/src/test/regress/expected/local_table_join.out index 4f9ae31c8..2deab459c 100644 --- a/src/test/regress/expected/local_table_join.out +++ b/src/test/regress/expected/local_table_join.out @@ -1080,6 +1080,8 @@ 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; diff --git a/src/test/regress/sql/local_table_join.sql b/src/test/regress/sql/local_table_join.sql index 1b5593061..10c5fdcd9 100644 --- a/src/test/regress/sql/local_table_join.sql +++ b/src/test/regress/sql/local_table_join.sql @@ -418,6 +418,10 @@ SELECT count(*) FROM postgres_table JOIN (SELECT * FROM (SELECT * FROM distribut 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;