diff --git a/src/backend/distributed/executor/adaptive_executor.c b/src/backend/distributed/executor/adaptive_executor.c index 895f01ae7..c3e7d3167 100644 --- a/src/backend/distributed/executor/adaptive_executor.c +++ b/src/backend/distributed/executor/adaptive_executor.c @@ -815,8 +815,11 @@ AdaptiveExecutor(CitusScanState *scanState) * be part of the same transaction. */ UseCoordinatedTransaction(); + + ParamListInfo boundParams = copyParamList(paramListInfo); + taskList = ExplainAnalyzeTaskList(taskList, defaultTupleDest, tupleDescriptor, - paramListInfo); + boundParams); /* * Multiple queries per task is not supported with local execution. See the Assert in diff --git a/src/backend/distributed/planner/multi_explain.c b/src/backend/distributed/planner/multi_explain.c index 370e487b4..643c95235 100644 --- a/src/backend/distributed/planner/multi_explain.c +++ b/src/backend/distributed/planner/multi_explain.c @@ -919,7 +919,11 @@ FetchRemoteExplainFromWorkers(Task *task, ExplainState *es, ParamListInfo params if (params) { - ExtractParametersFromParamList(params, ¶mTypes, ¶mValues, false); + /* force evaluation of bound params */ + params = copyParamList(params); + + ExtractParametersForRemoteExecution(params, ¶mTypes, + ¶mValues); } int sendStatus = SendRemoteCommandParams(connection, explainQuery->data, @@ -1890,6 +1894,7 @@ FetchPlanQueryForExplainAnalyze(const char *queryString, ParamListInfo params) ParameterResolutionSubquery(params)); } + appendStringInfoString(fetchQuery, "SELECT explain_analyze_output, execution_duration " "FROM worker_last_saved_explain_analyze()"); @@ -1913,6 +1918,12 @@ ParameterResolutionSubquery(ParamListInfo params) for (int paramIndex = 0; paramIndex < params->numParams; paramIndex++) { ParamExternData *param = ¶ms->params[paramIndex]; + + if (param->ptype == 0) + { + continue; + } + char *typeName = format_type_extended(param->ptype, -1, FORMAT_TYPE_FORCE_QUALIFY); diff --git a/src/test/regress/expected/multi_explain.out b/src/test/regress/expected/multi_explain.out index bfcf29c4d..c47346dd2 100644 --- a/src/test/regress/expected/multi_explain.out +++ b/src/test/regress/expected/multi_explain.out @@ -3239,6 +3239,19 @@ SET auto_explain.log_min_duration = 0; set auto_explain.log_analyze to true; -- the following should not be locally executed since explain analyze is on select * from test_ref_table; +CREATE TABLE test_auto_explain.test_params +( coll1 int8 NULL, + coll2 int4 NOT NULL); +SELECT create_distributed_table('test_auto_explain.test_params', 'coll1'); + +CREATE OR REPLACE PROCEDURE test_auto_explain.test_delete_from(p_coll2 int) +LANGUAGE plpgsql +AS $$ +BEGIN +DELETE FROM test_auto_explain.test_params +WHERE coll2 = p_coll2; +END;$$; +CALL test_auto_explain.test_delete_from(20240401); DROP SCHEMA test_auto_explain CASCADE; SET client_min_messages TO ERROR; DROP SCHEMA multi_explain CASCADE; diff --git a/src/test/regress/expected/multi_explain_0.out b/src/test/regress/expected/multi_explain_0.out index 4d3acd14d..6a34e4cc7 100644 --- a/src/test/regress/expected/multi_explain_0.out +++ b/src/test/regress/expected/multi_explain_0.out @@ -3228,6 +3228,19 @@ SET auto_explain.log_min_duration = 0; set auto_explain.log_analyze to true; -- the following should not be locally executed since explain analyze is on select * from test_ref_table; +CREATE TABLE test_auto_explain.test_params +( coll1 int8 NULL, + coll2 int4 NOT NULL); +SELECT create_distributed_table('test_auto_explain.test_params', 'coll1'); + +CREATE OR REPLACE PROCEDURE test_auto_explain.test_delete_from(p_coll2 int) +LANGUAGE plpgsql +AS $$ +BEGIN +DELETE FROM test_auto_explain.test_params +WHERE coll2 = p_coll2; +END;$$; +CALL test_auto_explain.test_delete_from(20240401); DROP SCHEMA test_auto_explain CASCADE; SET client_min_messages TO ERROR; DROP SCHEMA multi_explain CASCADE; diff --git a/src/test/regress/sql/multi_explain.sql b/src/test/regress/sql/multi_explain.sql index 65ca6f5da..888818c12 100644 --- a/src/test/regress/sql/multi_explain.sql +++ b/src/test/regress/sql/multi_explain.sql @@ -1180,6 +1180,22 @@ set auto_explain.log_analyze to true; -- the following should not be locally executed since explain analyze is on select * from test_ref_table; +CREATE TABLE test_auto_explain.test_params +( coll1 int8 NULL, + coll2 int4 NOT NULL); + +SELECT create_distributed_table('test_auto_explain.test_params', 'coll1'); + +CREATE OR REPLACE PROCEDURE test_auto_explain.test_delete_from(p_coll2 int) +LANGUAGE plpgsql +AS $$ +BEGIN +DELETE FROM test_auto_explain.test_params +WHERE coll2 = p_coll2; +END;$$; + +CALL test_auto_explain.test_delete_from(20240401); + DROP SCHEMA test_auto_explain CASCADE; SET client_min_messages TO ERROR;