From fd89760a29eebbbf6ea88cf25f8084ce9ee94f0c Mon Sep 17 00:00:00 2001 From: Onder Kalaci Date: Tue, 3 Mar 2020 19:48:23 +0100 Subject: [PATCH] For composite types, add cast to the parameter to ease remote node detect the type. --- .../distributed/deparser/ruleutils_11.c | 15 ++- .../distributed/deparser/ruleutils_12.c | 15 ++- .../regress/expected/multi_prepare_sql.out | 103 ++++++++++++++++++ src/test/regress/sql/multi_prepare_sql.sql | 35 ++++++ 4 files changed, 164 insertions(+), 4 deletions(-) diff --git a/src/backend/distributed/deparser/ruleutils_11.c b/src/backend/distributed/deparser/ruleutils_11.c index 816803ff8..b027723dd 100644 --- a/src/backend/distributed/deparser/ruleutils_11.c +++ b/src/backend/distributed/deparser/ruleutils_11.c @@ -4419,9 +4419,20 @@ get_parameter(Param *param, deparse_context *context) } /* - * Not PARAM_EXEC, or couldn't find referent: just print $N. + * Not PARAM_EXEC, or couldn't find referent: for base types just print $N. + * For composite types, add cast to the parameter to ease remote node detect + * the type. */ - appendStringInfo(context->buf, "$%d", param->paramid); + if (param->paramtype >= FirstNormalObjectId) + { + char *typeName = format_type_with_typemod(param->paramtype, param->paramtypmod); + + appendStringInfo(context->buf, "$%d::%s", param->paramid, typeName); + } + else + { + appendStringInfo(context->buf, "$%d", param->paramid); + } } /* diff --git a/src/backend/distributed/deparser/ruleutils_12.c b/src/backend/distributed/deparser/ruleutils_12.c index 2bca08845..6b9a1c56d 100644 --- a/src/backend/distributed/deparser/ruleutils_12.c +++ b/src/backend/distributed/deparser/ruleutils_12.c @@ -4433,9 +4433,20 @@ get_parameter(Param *param, deparse_context *context) } /* - * Not PARAM_EXEC, or couldn't find referent: just print $N. + * Not PARAM_EXEC, or couldn't find referent: for base types just print $N. + * For composite types, add cast to the parameter to ease remote node detect + * the type. */ - appendStringInfo(context->buf, "$%d", param->paramid); + if (param->paramtype >= FirstNormalObjectId) + { + char *typeName = format_type_with_typemod(param->paramtype, param->paramtypmod); + + appendStringInfo(context->buf, "$%d::%s", param->paramid, typeName); + } + else + { + appendStringInfo(context->buf, "$%d", param->paramid); + } } /* diff --git a/src/test/regress/expected/multi_prepare_sql.out b/src/test/regress/expected/multi_prepare_sql.out index 8338ee3f9..02fd99ae1 100644 --- a/src/test/regress/expected/multi_prepare_sql.out +++ b/src/test/regress/expected/multi_prepare_sql.out @@ -275,6 +275,109 @@ EXECUTE prepared_insert('comment-3', '(3, 30)'); EXECUTE prepared_insert('comment-4', '(4, 40)'); EXECUTE prepared_insert('comment-5', '(5, 50)'); EXECUTE prepared_insert('comment-6', '(6, 60)'); +-- to make this work, Citus adds the type casting for composite keys +-- during the deparsing +PREPARE prepared_custom_type_select(test_composite_type) AS + SELECT count(*) FROM router_executor_table WHERE id = 1 AND stats = $1; +EXECUTE prepared_custom_type_select('(1,1)'); + count +--------------------------------------------------------------------- + 0 +(1 row) + +EXECUTE prepared_custom_type_select('(1,1)'); + count +--------------------------------------------------------------------- + 0 +(1 row) + +EXECUTE prepared_custom_type_select('(1,1)'); + count +--------------------------------------------------------------------- + 0 +(1 row) + +EXECUTE prepared_custom_type_select('(1,1)'); + count +--------------------------------------------------------------------- + 0 +(1 row) + +EXECUTE prepared_custom_type_select('(1,1)'); + count +--------------------------------------------------------------------- + 0 +(1 row) + +EXECUTE prepared_custom_type_select('(1,1)'); + count +--------------------------------------------------------------------- + 0 +(1 row) + +EXECUTE prepared_custom_type_select('(1,1)'); + count +--------------------------------------------------------------------- + 0 +(1 row) + +CREATE SCHEMA internal_test_schema; +SET search_path TO internal_test_schema; +-- to make this work, Citus adds the type casting for composite keys +-- during the deparsing +PREPARE prepared_custom_type_select_with_search_path(public.test_composite_type) AS + SELECT count(*) FROM public.router_executor_table WHERE id = 1 AND stats = $1; +EXECUTE prepared_custom_type_select_with_search_path('(1,1)'); + count +--------------------------------------------------------------------- + 0 +(1 row) + +EXECUTE prepared_custom_type_select_with_search_path('(1,1)'); + count +--------------------------------------------------------------------- + 0 +(1 row) + +EXECUTE prepared_custom_type_select_with_search_path('(1,1)'); + count +--------------------------------------------------------------------- + 0 +(1 row) + +EXECUTE prepared_custom_type_select_with_search_path('(1,1)'); + count +--------------------------------------------------------------------- + 0 +(1 row) + +EXECUTE prepared_custom_type_select_with_search_path('(1,1)'); + count +--------------------------------------------------------------------- + 0 +(1 row) + +EXECUTE prepared_custom_type_select_with_search_path('(1,1)'); + count +--------------------------------------------------------------------- + 0 +(1 row) + +EXECUTE prepared_custom_type_select_with_search_path('(1,1)'); + count +--------------------------------------------------------------------- + 0 +(1 row) + +-- also show that it works even if we explicitly cast the type +EXECUTE prepared_custom_type_select_with_search_path('(1,1)'::public.test_composite_type); + count +--------------------------------------------------------------------- + 0 +(1 row) + +DROP SCHEMA internal_test_schema CASCADE; +SET search_path TO public; SELECT * FROM router_executor_table ORDER BY comment; id | comment | stats --------------------------------------------------------------------- diff --git a/src/test/regress/sql/multi_prepare_sql.sql b/src/test/regress/sql/multi_prepare_sql.sql index 13c7a999f..d6c1762b8 100644 --- a/src/test/regress/sql/multi_prepare_sql.sql +++ b/src/test/regress/sql/multi_prepare_sql.sql @@ -179,6 +179,41 @@ EXECUTE prepared_insert('comment-4', '(4, 40)'); EXECUTE prepared_insert('comment-5', '(5, 50)'); EXECUTE prepared_insert('comment-6', '(6, 60)'); +-- to make this work, Citus adds the type casting for composite keys +-- during the deparsing +PREPARE prepared_custom_type_select(test_composite_type) AS + SELECT count(*) FROM router_executor_table WHERE id = 1 AND stats = $1; + +EXECUTE prepared_custom_type_select('(1,1)'); +EXECUTE prepared_custom_type_select('(1,1)'); +EXECUTE prepared_custom_type_select('(1,1)'); +EXECUTE prepared_custom_type_select('(1,1)'); +EXECUTE prepared_custom_type_select('(1,1)'); +EXECUTE prepared_custom_type_select('(1,1)'); +EXECUTE prepared_custom_type_select('(1,1)'); + +CREATE SCHEMA internal_test_schema; +SET search_path TO internal_test_schema; + +-- to make this work, Citus adds the type casting for composite keys +-- during the deparsing +PREPARE prepared_custom_type_select_with_search_path(public.test_composite_type) AS + SELECT count(*) FROM public.router_executor_table WHERE id = 1 AND stats = $1; + +EXECUTE prepared_custom_type_select_with_search_path('(1,1)'); +EXECUTE prepared_custom_type_select_with_search_path('(1,1)'); +EXECUTE prepared_custom_type_select_with_search_path('(1,1)'); +EXECUTE prepared_custom_type_select_with_search_path('(1,1)'); +EXECUTE prepared_custom_type_select_with_search_path('(1,1)'); +EXECUTE prepared_custom_type_select_with_search_path('(1,1)'); +EXECUTE prepared_custom_type_select_with_search_path('(1,1)'); + +-- also show that it works even if we explicitly cast the type +EXECUTE prepared_custom_type_select_with_search_path('(1,1)'::public.test_composite_type); + +DROP SCHEMA internal_test_schema CASCADE; +SET search_path TO public; + SELECT * FROM router_executor_table ORDER BY comment; -- test parameterized selects