From 38a59b47672edd539b0486ea6dd7b44b12129775 Mon Sep 17 00:00:00 2001 From: Onur Tirtir Date: Thu, 13 Feb 2020 15:41:58 +0300 Subject: [PATCH] change ErrorIfTransactionAccessedPlacementsLocally logic & usages --- .../distributed/executor/adaptive_executor.c | 8 +++-- .../distributed/executor/local_executor.c | 36 +++++++++++++++++++ src/include/distributed/local_executor.h | 1 + 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/backend/distributed/executor/adaptive_executor.c b/src/backend/distributed/executor/adaptive_executor.c index 3b9f7d531..76ce3d330 100644 --- a/src/backend/distributed/executor/adaptive_executor.c +++ b/src/backend/distributed/executor/adaptive_executor.c @@ -936,10 +936,12 @@ ExecuteTaskListExtended(RowModifyLevel modLevel, List *taskList, ParamListInfo paramListInfo = NULL; /* - * The code-paths that rely on this function do not know how to execute - * commands locally. + * If current transaction accessed local placements and task list includes + * tasks that should be executed locally (accessing any of the local placements), + * then we should error out as it would cause inconsistencies across the + * remote connection and local execution */ - ErrorIfTransactionAccessedPlacementsLocally(); + ErrorIfRemoteTaskExecutionOnLocallyAccessedNode(taskList); if (MultiShardConnectionType == SEQUENTIAL_CONNECTION) { diff --git a/src/backend/distributed/executor/local_executor.c b/src/backend/distributed/executor/local_executor.c index cf81ee4ee..2a418927e 100644 --- a/src/backend/distributed/executor/local_executor.c +++ b/src/backend/distributed/executor/local_executor.c @@ -592,6 +592,27 @@ ShouldExecuteTasksLocally(List *taskList) } +/* + * AnyTaskAccessesLocalNode returns true if a task within the task list accesses + * to the local node. + */ +bool +AnyTaskAccessesLocalNode(List *taskList) +{ + Task *task = NULL; + + foreach_ptr(task, taskList) + { + if (TaskAccessesLocalNode(task)) + { + return true; + } + } + + return false; +} + + /* * TaskAccessesLocalNode returns true if any placements of the task reside on * the node that we're executing the query. @@ -614,6 +635,21 @@ TaskAccessesLocalNode(Task *task) } +/* + * ErrorIfRemoteTaskExecutionOnLocallyAccessedNode errors out if the current + * transaction already accessed local placements in the current session(locally) + * and any of the given remote tasks will access a local placement. + */ +void +ErrorIfRemoteTaskExecutionOnLocallyAccessedNode(List *remoteTaskList) +{ + if (AnyTaskAccessesLocalNode(remoteTaskList)) + { + ErrorIfTransactionAccessedPlacementsLocally(); + } +} + + /* * ErrorIfTransactionAccessedPlacementsLocally errors out if a local query * on any shard has already been executed in the same transaction. diff --git a/src/include/distributed/local_executor.h b/src/include/distributed/local_executor.h index 8b11e096c..691c2804b 100644 --- a/src/include/distributed/local_executor.h +++ b/src/include/distributed/local_executor.h @@ -28,6 +28,7 @@ extern void ExtractLocalAndRemoteTasks(bool readOnlyPlan, List *taskList, extern bool ShouldExecuteTasksLocally(List *taskList); extern bool AnyTaskAccessesLocalNode(List *taskList); extern bool TaskAccessesLocalNode(Task *task); +extern void ErrorIfRemoteTaskExecutionOnLocallyAccessedNode(List *taskList); extern void ErrorIfTransactionAccessedPlacementsLocally(void); extern void DisableLocalExecution(void);