From b566c4815cfe58cdcdb915b856d13566419cf9aa Mon Sep 17 00:00:00 2001 From: Marco Slot Date: Fri, 11 Nov 2016 07:14:08 +0100 Subject: [PATCH] Pass down the correct type for null parameters --- .../distributed/executor/multi_router_executor.c | 16 ++++++++++++++-- .../regress/expected/multi_prepare_plsql.out | 15 +++++++++++++++ src/test/regress/sql/multi_prepare_plsql.sql | 11 +++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/backend/distributed/executor/multi_router_executor.c b/src/backend/distributed/executor/multi_router_executor.c index a4b958559..aee7e09a5 100644 --- a/src/backend/distributed/executor/multi_router_executor.c +++ b/src/backend/distributed/executor/multi_router_executor.c @@ -1383,12 +1383,12 @@ ExtractParametersFromParamListInfo(ParamListInfo paramListInfo, Oid **parameterT } /* - * If the parameter is NULL, or is not referenced / used (ptype == 0 + * If the parameter is not referenced / used (ptype == 0) and * would otherwise have errored out inside standard_planner()), * don't pass a value to the remote side, and pass text oid to prevent * undetermined data type errors on workers. */ - if (parameterData->isnull || parameterData->ptype == 0) + if (parameterData->ptype == 0) { (*parameterValues)[parameterIndex] = NULL; (*parameterTypes)[parameterIndex] = TEXTOID; @@ -1396,8 +1396,20 @@ ExtractParametersFromParamListInfo(ParamListInfo paramListInfo, Oid **parameterT continue; } + /* + * If the parameter is NULL then we preserve its type, but + * don't need to evaluate its value. + */ + if (parameterData->isnull) + { + (*parameterValues)[parameterIndex] = NULL; + + continue; + } + getTypeOutputInfo(parameterData->ptype, &typeOutputFunctionId, &variableLengthType); + (*parameterValues)[parameterIndex] = OidOutputFunctionCall(typeOutputFunctionId, parameterData->value); } diff --git a/src/test/regress/expected/multi_prepare_plsql.out b/src/test/regress/expected/multi_prepare_plsql.out index 6f41b00f3..5cc965ab2 100644 --- a/src/test/regress/expected/multi_prepare_plsql.out +++ b/src/test/regress/expected/multi_prepare_plsql.out @@ -1041,6 +1041,21 @@ SELECT * FROM plpgsql_table ORDER BY key, value; 0 | (6 rows) +-- check whether we can handle execute parameters +CREATE TABLE execute_parameter_test (key int, val date); +SELECT create_distributed_table('execute_parameter_test', 'key'); + create_distributed_table +-------------------------- + +(1 row) + +DO $$ +BEGIN + EXECUTE 'INSERT INTO execute_parameter_test VALUES (3, $1)' USING date '2000-01-01'; + EXECUTE 'INSERT INTO execute_parameter_test VALUES (3, $1)' USING NULL::date; +END; +$$; +DROP TABLE execute_parameter_test; -- clean-up functions DROP FUNCTION plpgsql_test_1(); DROP FUNCTION plpgsql_test_2(); diff --git a/src/test/regress/sql/multi_prepare_plsql.sql b/src/test/regress/sql/multi_prepare_plsql.sql index b7ee32d6e..cb1bab581 100644 --- a/src/test/regress/sql/multi_prepare_plsql.sql +++ b/src/test/regress/sql/multi_prepare_plsql.sql @@ -497,6 +497,17 @@ SELECT non_partition_parameter_delete(62); -- check table after deletes SELECT * FROM plpgsql_table ORDER BY key, value; +-- check whether we can handle execute parameters +CREATE TABLE execute_parameter_test (key int, val date); +SELECT create_distributed_table('execute_parameter_test', 'key'); +DO $$ +BEGIN + EXECUTE 'INSERT INTO execute_parameter_test VALUES (3, $1)' USING date '2000-01-01'; + EXECUTE 'INSERT INTO execute_parameter_test VALUES (3, $1)' USING NULL::date; +END; +$$; +DROP TABLE execute_parameter_test; + -- clean-up functions DROP FUNCTION plpgsql_test_1(); DROP FUNCTION plpgsql_test_2();