From 087f6eb4c0a17cc14f539ea0b482f46e7e7416aa Mon Sep 17 00:00:00 2001 From: Onder Kalaci Date: Tue, 3 Mar 2020 19:48:23 +0100 Subject: [PATCH 1/2] 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 From 27f23d2c8966e37b93be56e196d5b7c242cc4bc3 Mon Sep 17 00:00:00 2001 From: Marco Slot Date: Wed, 4 Mar 2020 05:01:43 +0100 Subject: [PATCH 2/2] Add some distribution column = composite type prepared statement tests --- .../regress/expected/multi_data_types.out | 44 +++++++++++++++++++ src/test/regress/sql/multi_data_types.sql | 17 +++++++ 2 files changed, 61 insertions(+) diff --git a/src/test/regress/expected/multi_data_types.out b/src/test/regress/expected/multi_data_types.out index 5c44cb1eb..124b04c74 100644 --- a/src/test/regress/expected/multi_data_types.out +++ b/src/test/regress/expected/multi_data_types.out @@ -85,6 +85,50 @@ INSERT INTO composite_type_partitioned_table VALUES (2, '(3, 4)'::test_composit INSERT INTO composite_type_partitioned_table VALUES (3, '(5, 6)'::test_composite_type); INSERT INTO composite_type_partitioned_table VALUES (4, '(7, 8)'::test_composite_type); INSERT INTO composite_type_partitioned_table VALUES (5, '(9, 10)'::test_composite_type); +PREPARE do_insert(int,test_composite_type) AS INSERT INTO composite_type_partitioned_table VALUES ($1,$2); +EXECUTE do_insert(5, '(9,10)'); +EXECUTE do_insert(5, '(9,10)'); +EXECUTE do_insert(5, '(9,10)'); +EXECUTE do_insert(5, '(9,10)'); +EXECUTE do_insert(5, '(9,10)'); +EXECUTE do_insert(5, '(9,10)'); +PREPARE get_id(test_composite_type) AS SELECT min(id) FROM composite_type_partitioned_table WHERE col = $1; +EXECUTE get_id('(9,10)'); + min +--------------------------------------------------------------------- + 5 +(1 row) + +EXECUTE get_id('(9,10)'); + min +--------------------------------------------------------------------- + 5 +(1 row) + +EXECUTE get_id('(9,10)'); + min +--------------------------------------------------------------------- + 5 +(1 row) + +EXECUTE get_id('(9,10)'); + min +--------------------------------------------------------------------- + 5 +(1 row) + +EXECUTE get_id('(9,10)'); + min +--------------------------------------------------------------------- + 5 +(1 row) + +EXECUTE get_id('(9,10)'); + min +--------------------------------------------------------------------- + 5 +(1 row) + SELECT * FROM composite_type_partitioned_table WHERE col = '(7, 8)'::test_composite_type; id | col --------------------------------------------------------------------- diff --git a/src/test/regress/sql/multi_data_types.sql b/src/test/regress/sql/multi_data_types.sql index 9a5ac4038..9ae4ce1d8 100644 --- a/src/test/regress/sql/multi_data_types.sql +++ b/src/test/regress/sql/multi_data_types.sql @@ -80,6 +80,23 @@ INSERT INTO composite_type_partitioned_table VALUES (3, '(5, 6)'::test_composit INSERT INTO composite_type_partitioned_table VALUES (4, '(7, 8)'::test_composite_type); INSERT INTO composite_type_partitioned_table VALUES (5, '(9, 10)'::test_composite_type); +PREPARE do_insert(int,test_composite_type) AS INSERT INTO composite_type_partitioned_table VALUES ($1,$2); +EXECUTE do_insert(5, '(9,10)'); +EXECUTE do_insert(5, '(9,10)'); +EXECUTE do_insert(5, '(9,10)'); +EXECUTE do_insert(5, '(9,10)'); +EXECUTE do_insert(5, '(9,10)'); +EXECUTE do_insert(5, '(9,10)'); + +PREPARE get_id(test_composite_type) AS SELECT min(id) FROM composite_type_partitioned_table WHERE col = $1; +EXECUTE get_id('(9,10)'); +EXECUTE get_id('(9,10)'); +EXECUTE get_id('(9,10)'); +EXECUTE get_id('(9,10)'); +EXECUTE get_id('(9,10)'); +EXECUTE get_id('(9,10)'); + + SELECT * FROM composite_type_partitioned_table WHERE col = '(7, 8)'::test_composite_type; UPDATE composite_type_partitioned_table SET id = 6 WHERE col = '(7, 8)'::test_composite_type;