From b8eedcd261fd62a07b9ee36fb0f742c1f0f7d13e Mon Sep 17 00:00:00 2001 From: Ahmet Gedemenli Date: Fri, 4 Mar 2022 17:26:39 +0300 Subject: [PATCH] Notice when create_distributed_function called without params (#5752) * Notice when create_distributed_function called without params * Move variable comments to top * Add valid check for cache entry * add objtype to notice msg * update test outputs * Add more tests * Address feedback --- src/backend/distributed/commands/function.c | 75 ++- .../regress/expected/aggregate_support.out | 18 + .../expected/coordinator_evaluation.out | 4 + .../coordinator_evaluation_modify.out | 2 + .../coordinator_evaluation_select.out | 2 + .../expected/distributed_functions.out | 20 + .../distributed_functions_conflict.out | 4 + .../expected/forcedelegation_functions.out | 4 +- .../regress/expected/function_propagation.out | 514 +++++++++++------- .../expected/insert_select_repartition.out | 1 + .../expected/local_shard_execution.out | 2 + .../local_shard_execution_replicated.out | 4 + .../expected/multi_deparse_function.out | 4 + .../expected/multi_function_evaluation.out | 2 + .../expected/multi_index_statements.out | 4 + src/test/regress/expected/multi_multiuser.out | 2 + src/test/regress/expected/multi_mx_call.out | 12 +- src/test/regress/expected/multi_mx_call_0.out | 12 +- .../multi_mx_function_call_delegation.out | 10 + .../multi_mx_function_call_delegation_0.out | 10 + .../multi_mx_insert_select_repartition.out | 2 + .../expected/multi_row_router_insert.out | 1 + src/test/regress/expected/pg14.out | 2 + src/test/regress/expected/row_types.out | 6 + src/test/regress/sql/function_propagation.sql | 46 ++ 25 files changed, 558 insertions(+), 205 deletions(-) diff --git a/src/backend/distributed/commands/function.c b/src/backend/distributed/commands/function.c index f990a225a..11729a21f 100644 --- a/src/backend/distributed/commands/function.c +++ b/src/backend/distributed/commands/function.c @@ -69,6 +69,10 @@ (strncmp(arg, prefix, strlen(prefix)) == 0) /* forward declaration for helper functions*/ +static bool RecreateSameNonColocatedFunction(ObjectAddress functionAddress, + char *distributionArgumentName, + bool colocateWithTableNameDefault, + bool *forceDelegationAddress); static void ErrorIfAnyNodeDoesNotHaveMetadata(void); static char * GetAggregateDDLCommand(const RegProcedure funcOid, bool useCreateOrReplace); static char * GetFunctionAlterOwnerCommand(const RegProcedure funcOid); @@ -128,6 +132,7 @@ create_distributed_function(PG_FUNCTION_ARGS) char *distributionArgumentName = NULL; char *colocateWithTableName = NULL; + bool colocateWithTableNameDefault = false; bool *forceDelegationAddress = NULL; bool forceDelegation = false; ObjectAddress extensionAddress = { 0 }; @@ -167,8 +172,13 @@ create_distributed_function(PG_FUNCTION_ARGS) colocateWithText = PG_GETARG_TEXT_P(2); colocateWithTableName = text_to_cstring(colocateWithText); + if (pg_strncasecmp(colocateWithTableName, "default", NAMEDATALEN) == 0) + { + colocateWithTableNameDefault = true; + } + /* check if the colocation belongs to a reference table */ - if (pg_strncasecmp(colocateWithTableName, "default", NAMEDATALEN) != 0) + if (!colocateWithTableNameDefault) { Oid colocationRelationId = ResolveRelationId(colocateWithText, false); colocatedWithReferenceTable = IsCitusTableType(colocationRelationId, @@ -192,6 +202,20 @@ create_distributed_function(PG_FUNCTION_ARGS) ObjectAddressSet(functionAddress, ProcedureRelationId, funcOid); + if (RecreateSameNonColocatedFunction(functionAddress, + distributionArgumentName, + colocateWithTableNameDefault, + forceDelegationAddress)) + { + char *schemaName = get_namespace_name(get_func_namespace(funcOid)); + char *functionName = get_func_name(funcOid); + char *qualifiedName = quote_qualified_identifier(schemaName, functionName); + ereport(NOTICE, (errmsg("procedure %s is already distributed", qualifiedName), + errdetail("Citus distributes procedures with CREATE " + "[PROCEDURE|FUNCTION|AGGREGATE] commands"))); + PG_RETURN_VOID(); + } + /* * If the function is owned by an extension, only update the * pg_dist_object, and not propagate the CREATE FUNCTION. Function @@ -259,6 +283,55 @@ create_distributed_function(PG_FUNCTION_ARGS) } +/* + * RecreateSameNonColocatedFunction returns true if the given parameters of + * create_distributed_function will not change anything on the given function. + * Returns false otherwise. + */ +static bool +RecreateSameNonColocatedFunction(ObjectAddress functionAddress, + char *distributionArgumentName, + bool colocateWithTableNameDefault, + bool *forceDelegationAddress) +{ + DistObjectCacheEntry *cacheEntry = + LookupDistObjectCacheEntry(ProcedureRelationId, + functionAddress.objectId, + InvalidOid); + + if (cacheEntry == NULL || !cacheEntry->isValid || !cacheEntry->isDistributed) + { + return false; + } + + /* + * If the colocationId, forceDelegation and distributionArgIndex fields of a + * pg_dist_object entry of a distributed function are all set to zero, it means + * that function is either automatically distributed by ddl propagation, without + * calling create_distributed_function. Or, it could be distributed via + * create_distributed_function, but with no parameters. + * + * For these cases, calling create_distributed_function for that function, + * without parameters would be idempotent. Hence we can simply early return here, + * by providing a notice message to the user. + */ + + /* are pg_dist_object fields set to zero? */ + bool functionDistributedWithoutParams = + cacheEntry->colocationId == 0 && + cacheEntry->forceDelegation == 0 && + cacheEntry->distributionArgIndex == 0; + + /* called create_distributed_function without parameters? */ + bool distributingAgainWithNoParams = + distributionArgumentName == NULL && + colocateWithTableNameDefault && + forceDelegationAddress == NULL; + + return functionDistributedWithoutParams && distributingAgainWithNoParams; +} + + /* * ErrorIfAnyNodeDoesNotHaveMetadata throws error if any * of the worker nodes does not have the metadata. diff --git a/src/test/regress/expected/aggregate_support.out b/src/test/regress/expected/aggregate_support.out index 57bb03060..e17948d56 100644 --- a/src/test/regress/expected/aggregate_support.out +++ b/src/test/regress/expected/aggregate_support.out @@ -40,12 +40,16 @@ create aggregate sum2_strict (int) ( combinefunc = sum2_sfunc_strict ); select create_distributed_function('sum2(int)'); +NOTICE: procedure aggregate_support.sum2 is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- (1 row) select create_distributed_function('sum2_strict(int)'); +NOTICE: procedure aggregate_support.sum2_strict is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -96,12 +100,16 @@ create aggregate psum_strict(int, int)( initcond=0 ); select create_distributed_function('psum(int,int)'); +NOTICE: procedure aggregate_support.psum is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- (1 row) select create_distributed_function('psum_strict(int,int)'); +NOTICE: procedure aggregate_support.psum_strict is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -298,6 +306,8 @@ SELECT run_command_on_workers($$select count(*) from pg_aggregate where aggfnoid (2 rows) select create_distributed_function('binstragg(text,text)'); +NOTICE: procedure aggregate_support.binstragg is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -527,12 +537,16 @@ CREATE AGGREGATE last ( combinefunc = last_agg ); SELECT create_distributed_function('first(anyelement)'); +NOTICE: procedure aggregate_support.first is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- (1 row) SELECT create_distributed_function('last(anyelement)'); +NOTICE: procedure aggregate_support.last is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -590,6 +604,8 @@ SELECT run_command_on_workers($$select aggfnoid from pg_aggregate where aggfnoid (2 rows) select create_distributed_function('sumstring(text)'); +NOTICE: procedure aggregate_support.sumstring is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -614,6 +630,8 @@ create aggregate array_collect_sort(el int) ( initcond = '{}' ); select create_distributed_function('array_collect_sort(int)'); +NOTICE: procedure aggregate_support.array_collect_sort is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/coordinator_evaluation.out b/src/test/regress/expected/coordinator_evaluation.out index 47696a462..a0ed7ea51 100644 --- a/src/test/regress/expected/coordinator_evaluation.out +++ b/src/test/regress/expected/coordinator_evaluation.out @@ -11,6 +11,8 @@ BEGIN RETURN localGroupId; END; $$ language plpgsql VOLATILE; SELECT create_distributed_function('get_local_node_id_volatile()'); +NOTICE: procedure coordinator_evaluation.get_local_node_id_volatile is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -24,6 +26,8 @@ BEGIN RETURN localGroupId; END; $$ language plpgsql VOLATILE; SELECT create_distributed_function('get_local_node_id_volatile_sum_with_param(int)'); +NOTICE: procedure coordinator_evaluation.get_local_node_id_volatile_sum_with_param is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/coordinator_evaluation_modify.out b/src/test/regress/expected/coordinator_evaluation_modify.out index e75ac60b1..0b14c109d 100644 --- a/src/test/regress/expected/coordinator_evaluation_modify.out +++ b/src/test/regress/expected/coordinator_evaluation_modify.out @@ -21,6 +21,8 @@ BEGIN RETURN localGroupId; END; $$ language plpgsql STABLE; SELECT create_distributed_function('get_local_node_id_stable()'); +NOTICE: procedure coordinator_evaluation_combinations_modify.get_local_node_id_stable is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/coordinator_evaluation_select.out b/src/test/regress/expected/coordinator_evaluation_select.out index 0fa70f066..e387de2be 100644 --- a/src/test/regress/expected/coordinator_evaluation_select.out +++ b/src/test/regress/expected/coordinator_evaluation_select.out @@ -21,6 +21,8 @@ BEGIN RETURN localGroupId; END; $$ language plpgsql VOLATILE; SELECT create_distributed_function('get_local_node_id_volatile()'); +NOTICE: procedure coordinator_evaluation_combinations.get_local_node_id_volatile is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/distributed_functions.out b/src/test/regress/expected/distributed_functions.out index 614f19288..5547feaf0 100644 --- a/src/test/regress/expected/distributed_functions.out +++ b/src/test/regress/expected/distributed_functions.out @@ -33,6 +33,8 @@ BEGIN END; $$; SELECT create_distributed_function('notice(text)'); +NOTICE: procedure function_tests.notice is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -486,6 +488,8 @@ AS 'select $1 = $2;' IMMUTABLE RETURNS NULL ON NULL INPUT; select create_distributed_function('eq(macaddr,macaddr)'); +NOTICE: procedure function_tests.eq is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -797,6 +801,8 @@ BEGIN END; $$; SELECT create_distributed_function('func_with_return_table(int)'); +NOTICE: procedure function_tests.func_with_return_table is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -824,6 +830,8 @@ CREATE OR REPLACE FUNCTION func_with_out_param(a int, out b int) RETURNS int LANGUAGE sql AS $$ select 1; $$; SELECT create_distributed_function('func_with_out_param(int)'); +NOTICE: procedure function_tests.func_with_out_param is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -869,6 +877,8 @@ SELECT create_distributed_function('func_with_inout_param(int)'); ERROR: function "func_with_inout_param(int)" does not exist -- this should work SELECT create_distributed_function('func_with_inout_param(int,int)'); +NOTICE: procedure function_tests.func_with_inout_param is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -893,6 +903,8 @@ CREATE OR REPLACE FUNCTION func_with_variadic_param(a int, variadic b int[]) LANGUAGE sql AS $$ select 1; $$; -- this should work SELECT create_distributed_function('func_with_variadic_param(int,int[])'); +NOTICE: procedure function_tests.func_with_variadic_param is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -923,6 +935,8 @@ $BODY$ LANGUAGE plpgsql VOLATILE COST 100; SELECT create_distributed_function('func_returning_setof_int(date,interval)'); +NOTICE: procedure function_tests.func_returning_setof_int is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -961,6 +975,8 @@ $BODY$ LANGUAGE plpgsql VOLATILE COST 100; SELECT create_distributed_function('func_returning_setof_int_with_variadic_param(date,int[])'); +NOTICE: procedure function_tests.func_returning_setof_int_with_variadic_param is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -997,6 +1013,8 @@ SELECT create_distributed_function('proc_with_variadic_param(date)'); ERROR: function "proc_with_variadic_param(date)" does not exist -- this should work SELECT create_distributed_function('proc_with_variadic_param(date,int[])'); +NOTICE: procedure function_tests.proc_with_variadic_param is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -1028,6 +1046,8 @@ SELECT create_distributed_function('proc_with_inout_param(date)'); ERROR: function "proc_with_inout_param(date)" does not exist -- this should work SELECT create_distributed_function('proc_with_inout_param(date,int)'); +NOTICE: procedure function_tests.proc_with_inout_param is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/distributed_functions_conflict.out b/src/test/regress/expected/distributed_functions_conflict.out index 354aea9c0..8101cf0f1 100644 --- a/src/test/regress/expected/distributed_functions_conflict.out +++ b/src/test/regress/expected/distributed_functions_conflict.out @@ -26,6 +26,8 @@ CREATE AGGREGATE existing_agg(int) ( STYPE = int ); SELECT create_distributed_function('existing_agg(int)'); +NOTICE: procedure proc_conflict.existing_agg is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -87,6 +89,8 @@ CREATE AGGREGATE existing_agg(int) ( STYPE = int ); SELECT create_distributed_function('existing_agg(int)'); +NOTICE: procedure proc_conflict.existing_agg is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/forcedelegation_functions.out b/src/test/regress/expected/forcedelegation_functions.out index c26f7b75b..1bb6b8ba7 100644 --- a/src/test/regress/expected/forcedelegation_functions.out +++ b/src/test/regress/expected/forcedelegation_functions.out @@ -307,8 +307,8 @@ $$ LANGUAGE plpgsql; DEBUG: switching to sequential query execution mode DETAIL: A command for a distributed function is run. To make sure subsequent commands see the function correctly we need to make sure to use only one connection for all future commands SELECT create_distributed_function('func_calls_forcepush_func()'); -DEBUG: switching to sequential query execution mode -DETAIL: A command for a distributed function is run. To make sure subsequent commands see the function correctly we need to make sure to use only one connection for all future commands +NOTICE: procedure forcepushdown_schema.func_calls_forcepush_func is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/function_propagation.out b/src/test/regress/expected/function_propagation.out index 7aefbb697..d41de5a18 100644 --- a/src/test/regress/expected/function_propagation.out +++ b/src/test/regress/expected/function_propagation.out @@ -134,7 +134,7 @@ BEGIN return 1; END; $$; -WARNING: Citus can't distribute function "func_4" having dependency on non-distributed relation "function_prop_table" +WARNING: Citus can't distribute function "func_4" having dependency on non-distributed relation "function_prop_table" DETAIL: Function will be created only locally HINT: To distribute function, distribute dependent relations first. Then, re-create the function CREATE OR REPLACE FUNCTION func_5(param_1 int) @@ -319,29 +319,29 @@ $$; -- Show that functions are propagated (or not) as a dependency -- Function as a default column BEGIN; -CREATE OR REPLACE FUNCTION func_in_transaction_def() -RETURNS int -LANGUAGE plpgsql AS -$$ -BEGIN - return 1; -END; -$$; --- Function shouldn't be propagated within transaction -SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_def'::regproc::oid; + CREATE OR REPLACE FUNCTION func_in_transaction_def() + RETURNS int + LANGUAGE plpgsql AS + $$ + BEGIN + return 1; + END; + $$; + -- Function shouldn't be propagated within transaction + SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_def'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (0 rows) -CREATE TABLE table_to_prop_func(id int, col_1 int default func_in_transaction_def()); -SELECT create_distributed_table('table_to_prop_func','id'); + CREATE TABLE table_to_prop_func(id int, col_1 int default func_in_transaction_def()); + SELECT create_distributed_table('table_to_prop_func','id'); create_distributed_table --------------------------------------------------------------------- (1 row) --- Function should be marked as distributed after distributing the table that depends on it -SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_def'::regproc::oid; + -- Function should be marked as distributed after distributing the table that depends on it + SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_def'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (function,"{function_propagation_schema,func_in_transaction_def}",{}) @@ -350,7 +350,7 @@ SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dis COMMIT; -- Function should be marked as distributed on the worker after committing changes SELECT * FROM run_command_on_workers($$SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_def'::regproc::oid;$$) ORDER BY 1,2; - nodename | nodeport | success | result + nodename | nodeport | success | result --------------------------------------------------------------------- localhost | 57637 | t | (function,"{function_propagation_schema,func_in_transaction_def}",{}) localhost | 57638 | t | (function,"{function_propagation_schema,func_in_transaction_def}",{}) @@ -358,48 +358,48 @@ SELECT * FROM run_command_on_workers($$SELECT pg_identify_object_as_address(clas -- Multiple functions as a default column BEGIN; -CREATE OR REPLACE FUNCTION func_in_transaction_1() -RETURNS int -LANGUAGE plpgsql AS -$$ -BEGIN - return 1; -END; -$$; -CREATE OR REPLACE FUNCTION func_in_transaction_2() -RETURNS int -LANGUAGE plpgsql AS -$$ -BEGIN - return 1; -END; -$$; --- Functions shouldn't be propagated within transaction -SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_1'::regproc::oid; + CREATE OR REPLACE FUNCTION func_in_transaction_1() + RETURNS int + LANGUAGE plpgsql AS + $$ + BEGIN + return 1; + END; + $$; + CREATE OR REPLACE FUNCTION func_in_transaction_2() + RETURNS int + LANGUAGE plpgsql AS + $$ + BEGIN + return 1; + END; + $$; + -- Functions shouldn't be propagated within transaction + SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_1'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (0 rows) -SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_2'::regproc::oid; + SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_2'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (0 rows) -CREATE TABLE table_to_prop_func_2(id int, col_1 int default func_in_transaction_1() + func_in_transaction_2()); -SELECT create_distributed_table('table_to_prop_func_2','id'); + CREATE TABLE table_to_prop_func_2(id int, col_1 int default func_in_transaction_1() + func_in_transaction_2()); + SELECT create_distributed_table('table_to_prop_func_2','id'); create_distributed_table --------------------------------------------------------------------- (1 row) --- Functions should be marked as distribued after distributing the table that depends on it -SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_1'::regproc::oid; + -- Functions should be marked as distribued after distributing the table that depends on it + SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_1'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (function,"{function_propagation_schema,func_in_transaction_1}",{}) (1 row) -SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_2'::regproc::oid; + SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_2'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (function,"{function_propagation_schema,func_in_transaction_2}",{}) @@ -408,14 +408,14 @@ SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dis COMMIT; -- Functions should be marked as distributed on the worker after committing changes SELECT * FROM run_command_on_workers($$SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_1'::regproc::oid;$$) ORDER BY 1,2; - nodename | nodeport | success | result + nodename | nodeport | success | result --------------------------------------------------------------------- localhost | 57637 | t | (function,"{function_propagation_schema,func_in_transaction_1}",{}) localhost | 57638 | t | (function,"{function_propagation_schema,func_in_transaction_1}",{}) (2 rows) SELECT * FROM run_command_on_workers($$SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_2'::regproc::oid;$$) ORDER BY 1,2; - nodename | nodeport | success | result + nodename | nodeport | success | result --------------------------------------------------------------------- localhost | 57637 | t | (function,"{function_propagation_schema,func_in_transaction_2}",{}) localhost | 57638 | t | (function,"{function_propagation_schema,func_in_transaction_2}",{}) @@ -423,47 +423,47 @@ SELECT * FROM run_command_on_workers($$SELECT pg_identify_object_as_address(clas -- If function has dependency on non-distributed table it should error out BEGIN; -CREATE TABLE non_dist_table(id int); -CREATE OR REPLACE FUNCTION func_in_transaction_3(param_1 non_dist_table) -RETURNS int -LANGUAGE plpgsql AS -$$ -BEGIN - return 1; -END; -$$; -CREATE TABLE table_to_prop_func_3(id int, col_1 int default func_in_transaction_3(NULL::non_dist_table)); --- It should error out as there is a non-distributed table dependency -SELECT create_distributed_table('table_to_prop_func_3','id'); + CREATE TABLE non_dist_table(id int); + CREATE OR REPLACE FUNCTION func_in_transaction_3(param_1 non_dist_table) + RETURNS int + LANGUAGE plpgsql AS + $$ + BEGIN + return 1; + END; + $$; + CREATE TABLE table_to_prop_func_3(id int, col_1 int default func_in_transaction_3(NULL::non_dist_table)); + -- It should error out as there is a non-distributed table dependency + SELECT create_distributed_table('table_to_prop_func_3','id'); ERROR: Relation "table_to_prop_func_3" has dependency to a table "non_dist_table" that is not in Citus' metadata HINT: Distribute dependent relation first. COMMIT; -- Adding a column with default value should propagate the function BEGIN; -CREATE TABLE table_to_prop_func_4(id int); -SELECT create_distributed_table('table_to_prop_func_4', 'id'); + CREATE TABLE table_to_prop_func_4(id int); + SELECT create_distributed_table('table_to_prop_func_4', 'id'); create_distributed_table --------------------------------------------------------------------- (1 row) -CREATE OR REPLACE FUNCTION func_in_transaction_4() -RETURNS int -LANGUAGE plpgsql AS -$$ -BEGIN - return 1; -END; -$$; --- Function shouldn't be propagated within transaction -SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_4'::regproc::oid; + CREATE OR REPLACE FUNCTION func_in_transaction_4() + RETURNS int + LANGUAGE plpgsql AS + $$ + BEGIN + return 1; + END; + $$; + -- Function shouldn't be propagated within transaction + SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_4'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (0 rows) -ALTER TABLE table_to_prop_func_4 ADD COLUMN col_1 int default function_propagation_schema.func_in_transaction_4(); --- Function should be marked as distributed after adding the column -SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_4'::regproc::oid; + ALTER TABLE table_to_prop_func_4 ADD COLUMN col_1 int default function_propagation_schema.func_in_transaction_4(); + -- Function should be marked as distributed after adding the column + SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_4'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (function,"{function_propagation_schema,func_in_transaction_4}",{}) @@ -472,7 +472,7 @@ SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dis COMMIT; -- Functions should be marked as distributed on the worker after committing changes SELECT * FROM run_command_on_workers($$SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_4'::regproc::oid;$$) ORDER BY 1,2; - nodename | nodeport | success | result + nodename | nodeport | success | result --------------------------------------------------------------------- localhost | 57637 | t | (function,"{function_propagation_schema,func_in_transaction_4}",{}) localhost | 57638 | t | (function,"{function_propagation_schema,func_in_transaction_4}",{}) @@ -502,48 +502,48 @@ HINT: Distribute dependent relation first. ROLLBACK; -- Adding multiple columns with default values should propagate the function BEGIN; -CREATE OR REPLACE FUNCTION func_in_transaction_5() -RETURNS int -LANGUAGE plpgsql AS -$$ -BEGIN - return 1; -END; -$$; -CREATE OR REPLACE FUNCTION func_in_transaction_6() -RETURNS int -LANGUAGE plpgsql AS -$$ -BEGIN - return 1; -END; -$$; --- Functions shouldn't be propagated within transaction -SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_5'::regproc::oid; + CREATE OR REPLACE FUNCTION func_in_transaction_5() + RETURNS int + LANGUAGE plpgsql AS + $$ + BEGIN + return 1; + END; + $$; + CREATE OR REPLACE FUNCTION func_in_transaction_6() + RETURNS int + LANGUAGE plpgsql AS + $$ + BEGIN + return 1; + END; + $$; + -- Functions shouldn't be propagated within transaction + SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_5'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (0 rows) -SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_6'::regproc::oid; + SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_6'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (0 rows) -CREATE TABLE table_to_prop_func_5(id int, col_1 int default func_in_transaction_5(), col_2 int default func_in_transaction_6()); -SELECT create_distributed_table('table_to_prop_func_5', 'id'); + CREATE TABLE table_to_prop_func_5(id int, col_1 int default func_in_transaction_5(), col_2 int default func_in_transaction_6()); + SELECT create_distributed_table('table_to_prop_func_5', 'id'); create_distributed_table --------------------------------------------------------------------- (1 row) --- Functions should be marked as distributed after adding the column -SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_5'::regproc::oid; + -- Functions should be marked as distributed after adding the column + SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_5'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (function,"{function_propagation_schema,func_in_transaction_5}",{}) (1 row) -SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_6'::regproc::oid; + SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_6'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (function,"{function_propagation_schema,func_in_transaction_6}",{}) @@ -552,14 +552,14 @@ SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dis COMMIT; -- Functions should be marked as distributed on the worker after committing changes SELECT * FROM run_command_on_workers($$SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_5'::regproc::oid;$$) ORDER BY 1,2; - nodename | nodeport | success | result + nodename | nodeport | success | result --------------------------------------------------------------------- localhost | 57637 | t | (function,"{function_propagation_schema,func_in_transaction_5}",{}) localhost | 57638 | t | (function,"{function_propagation_schema,func_in_transaction_5}",{}) (2 rows) SELECT * FROM run_command_on_workers($$SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_6'::regproc::oid;$$) ORDER BY 1,2; - nodename | nodeport | success | result + nodename | nodeport | success | result --------------------------------------------------------------------- localhost | 57637 | t | (function,"{function_propagation_schema,func_in_transaction_6}",{}) localhost | 57638 | t | (function,"{function_propagation_schema,func_in_transaction_6}",{}) @@ -567,29 +567,29 @@ SELECT * FROM run_command_on_workers($$SELECT pg_identify_object_as_address(clas -- Adding a constraint with function check should propagate the function BEGIN; -CREATE OR REPLACE FUNCTION func_in_transaction_7(param_1 int) -RETURNS boolean -LANGUAGE plpgsql AS -$$ -BEGIN - return param_1 > 5; -END; -$$; --- Functions shouldn't be propagated within transaction -SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_7'::regproc::oid; + CREATE OR REPLACE FUNCTION func_in_transaction_7(param_1 int) + RETURNS boolean + LANGUAGE plpgsql AS + $$ + BEGIN + return param_1 > 5; + END; + $$; + -- Functions shouldn't be propagated within transaction + SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_7'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (0 rows) -CREATE TABLE table_to_prop_func_6(id int, col_1 int check (function_propagation_schema.func_in_transaction_7(col_1))); -SELECT create_distributed_table('table_to_prop_func_6', 'id'); + CREATE TABLE table_to_prop_func_6(id int, col_1 int check (function_propagation_schema.func_in_transaction_7(col_1))); + SELECT create_distributed_table('table_to_prop_func_6', 'id'); create_distributed_table --------------------------------------------------------------------- (1 row) --- Function should be marked as distributed after adding the column -SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_7'::regproc::oid; + -- Function should be marked as distributed after adding the column + SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_7'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (function,"{function_propagation_schema,func_in_transaction_7}",{integer}) @@ -598,7 +598,7 @@ SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dis COMMIT; -- Function should be marked as distributed on the worker after committing changes SELECT * FROM run_command_on_workers($$SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_7'::regproc::oid;$$) ORDER BY 1,2; - nodename | nodeport | success | result + nodename | nodeport | success | result --------------------------------------------------------------------- localhost | 57637 | t | (function,"{function_propagation_schema,func_in_transaction_7}",{integer}) localhost | 57638 | t | (function,"{function_propagation_schema,func_in_transaction_7}",{integer}) @@ -606,48 +606,48 @@ SELECT * FROM run_command_on_workers($$SELECT pg_identify_object_as_address(clas -- Adding a constraint with multiple functions check should propagate the function BEGIN; -CREATE OR REPLACE FUNCTION func_in_transaction_8(param_1 int) -RETURNS boolean -LANGUAGE plpgsql AS -$$ -BEGIN - return param_1 > 5; -END; -$$; -CREATE OR REPLACE FUNCTION func_in_transaction_9(param_1 int) -RETURNS boolean -LANGUAGE plpgsql AS -$$ -BEGIN - return param_1 > 5; -END; -$$; --- Functions shouldn't be propagated within transaction -SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_8'::regproc::oid; + CREATE OR REPLACE FUNCTION func_in_transaction_8(param_1 int) + RETURNS boolean + LANGUAGE plpgsql AS + $$ + BEGIN + return param_1 > 5; + END; + $$; + CREATE OR REPLACE FUNCTION func_in_transaction_9(param_1 int) + RETURNS boolean + LANGUAGE plpgsql AS + $$ + BEGIN + return param_1 > 5; + END; + $$; + -- Functions shouldn't be propagated within transaction + SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_8'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (0 rows) -SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_9'::regproc::oid; + SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_9'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (0 rows) -CREATE TABLE table_to_prop_func_7(id int, col_1 int check (function_propagation_schema.func_in_transaction_8(col_1) and function_propagation_schema.func_in_transaction_9(col_1))); -SELECT create_distributed_table('table_to_prop_func_7', 'id'); + CREATE TABLE table_to_prop_func_7(id int, col_1 int check (function_propagation_schema.func_in_transaction_8(col_1) and function_propagation_schema.func_in_transaction_9(col_1))); + SELECT create_distributed_table('table_to_prop_func_7', 'id'); create_distributed_table --------------------------------------------------------------------- (1 row) --- Function should be marked as distributed after adding the column -SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_8'::regproc::oid; + -- Function should be marked as distributed after adding the column + SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_8'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (function,"{function_propagation_schema,func_in_transaction_8}",{integer}) (1 row) -SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_9'::regproc::oid; + SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_9'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (function,"{function_propagation_schema,func_in_transaction_9}",{integer}) @@ -656,14 +656,14 @@ SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dis COMMIT; -- Functions should be marked as distributed on the worker after committing changes SELECT * FROM run_command_on_workers($$SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_8'::regproc::oid;$$) ORDER BY 1,2; - nodename | nodeport | success | result + nodename | nodeport | success | result --------------------------------------------------------------------- localhost | 57637 | t | (function,"{function_propagation_schema,func_in_transaction_8}",{integer}) localhost | 57638 | t | (function,"{function_propagation_schema,func_in_transaction_8}",{integer}) (2 rows) SELECT * FROM run_command_on_workers($$SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_9'::regproc::oid;$$) ORDER BY 1,2; - nodename | nodeport | success | result + nodename | nodeport | success | result --------------------------------------------------------------------- localhost | 57637 | t | (function,"{function_propagation_schema,func_in_transaction_9}",{integer}) localhost | 57638 | t | (function,"{function_propagation_schema,func_in_transaction_9}",{integer}) @@ -671,30 +671,30 @@ SELECT * FROM run_command_on_workers($$SELECT pg_identify_object_as_address(clas -- Adding a column with constraint should propagate the function BEGIN; -CREATE TABLE table_to_prop_func_8(id int, col_1 int); -SELECT create_distributed_table('table_to_prop_func_8', 'id'); + CREATE TABLE table_to_prop_func_8(id int, col_1 int); + SELECT create_distributed_table('table_to_prop_func_8', 'id'); create_distributed_table --------------------------------------------------------------------- (1 row) -CREATE OR REPLACE FUNCTION func_in_transaction_10(param_1 int) -RETURNS boolean -LANGUAGE plpgsql AS -$$ -BEGIN - return param_1 > 5; -END; -$$; --- Functions shouldn't be propagated within transaction -SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_10'::regproc::oid; + CREATE OR REPLACE FUNCTION func_in_transaction_10(param_1 int) + RETURNS boolean + LANGUAGE plpgsql AS + $$ + BEGIN + return param_1 > 5; + END; + $$; + -- Functions shouldn't be propagated within transaction + SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_10'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (0 rows) -ALTER TABLE table_to_prop_func_8 ADD CONSTRAINT col1_check CHECK (function_propagation_schema.func_in_transaction_10(col_1)); --- Function should be marked as distributed after adding the constraint -SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_10'::regproc::oid; + ALTER TABLE table_to_prop_func_8 ADD CONSTRAINT col1_check CHECK (function_propagation_schema.func_in_transaction_10(col_1)); + -- Function should be marked as distributed after adding the constraint + SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_10'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (function,"{function_propagation_schema,func_in_transaction_10}",{integer}) @@ -703,7 +703,7 @@ SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dis COMMIT; -- Function should be marked as distributed on the worker after committing changes SELECT * FROM run_command_on_workers($$SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_in_transaction_10'::regproc::oid;$$) ORDER BY 1,2; - nodename | nodeport | success | result + nodename | nodeport | success | result --------------------------------------------------------------------- localhost | 57637 | t | (function,"{function_propagation_schema,func_in_transaction_10}",{integer}) localhost | 57638 | t | (function,"{function_propagation_schema,func_in_transaction_10}",{integer}) @@ -711,39 +711,39 @@ SELECT * FROM run_command_on_workers($$SELECT pg_identify_object_as_address(clas -- If constraint depends on a non-distributed table it should error out BEGIN; -CREATE TABLE local_table_for_const(id int); -CREATE OR REPLACE FUNCTION func_in_transaction_11(param_1 int, param_2 local_table_for_const) -RETURNS boolean -LANGUAGE plpgsql AS -$$ -BEGIN - return param_1 > 5; -END; -$$; -CREATE TABLE table_to_prop_func_9(id int, col_1 int check (func_in_transaction_11(col_1, NULL::local_table_for_const))); --- It should error out since there is non-distributed table dependency exists -SELECT create_distributed_table('table_to_prop_func_9', 'id'); + CREATE TABLE local_table_for_const(id int); + CREATE OR REPLACE FUNCTION func_in_transaction_11(param_1 int, param_2 local_table_for_const) + RETURNS boolean + LANGUAGE plpgsql AS + $$ + BEGIN + return param_1 > 5; + END; + $$; + CREATE TABLE table_to_prop_func_9(id int, col_1 int check (func_in_transaction_11(col_1, NULL::local_table_for_const))); + -- It should error out since there is non-distributed table dependency exists + SELECT create_distributed_table('table_to_prop_func_9', 'id'); ERROR: Relation "table_to_prop_func_9" has dependency to a table "local_table_for_const" that is not in Citus' metadata HINT: Distribute dependent relation first. COMMIT; -- Show that function as a part of generated always is supporte BEGIN; - CREATE OR REPLACE FUNCTION non_sense_func_for_generated_always() - RETURNS int - LANGUAGE plpgsql IMMUTABLE AS - $$ - BEGIN - return 1; - END; - $$; + CREATE OR REPLACE FUNCTION non_sense_func_for_generated_always() + RETURNS int + LANGUAGE plpgsql IMMUTABLE AS + $$ + BEGIN + return 1; + END; + $$; -- Functions shouldn't be propagated within transaction SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.non_sense_func_for_generated_always'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (0 rows) - CREATE TABLE people ( - id int, + CREATE TABLE people ( + id int, height_cm numeric, height_in numeric GENERATED ALWAYS AS (height_cm / non_sense_func_for_generated_always()) STORED); SELECT create_distributed_table('people', 'id'); @@ -762,24 +762,24 @@ BEGIN; COMMIT; -- Show that functions depending table via rule are also distributed BEGIN; -CREATE OR REPLACE FUNCTION func_for_rule() -RETURNS int -LANGUAGE plpgsql STABLE AS -$$ -BEGIN - return 4; -END; -$$; + CREATE OR REPLACE FUNCTION func_for_rule() + RETURNS int + LANGUAGE plpgsql STABLE AS + $$ + BEGIN + return 4; + END; + $$; -- Functions shouldn't be propagated within transaction SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_for_rule'::regproc::oid; pg_identify_object_as_address --------------------------------------------------------------------- (0 rows) -CREATE TABLE table_1_for_rule(id int, col_1 int); -CREATE TABLE table_2_for_rule(id int, col_1 int); -CREATE RULE rule_1 AS ON UPDATE TO table_1_for_rule DO ALSO UPDATE table_2_for_rule SET col_1 = col_1 * func_for_rule(); -SELECT create_distributed_table('table_1_for_rule','id'); + CREATE TABLE table_1_for_rule(id int, col_1 int); + CREATE TABLE table_2_for_rule(id int, col_1 int); + CREATE RULE rule_1 AS ON UPDATE TO table_1_for_rule DO ALSO UPDATE table_2_for_rule SET col_1 = col_1 * func_for_rule(); + SELECT create_distributed_table('table_1_for_rule','id'); create_distributed_table --------------------------------------------------------------------- @@ -803,14 +803,14 @@ SELECT * FROM run_command_on_workers($$SELECT pg_identify_object_as_address(clas -- Show that functions as partitioning functions are supported BEGIN; - CREATE OR REPLACE FUNCTION non_sense_func_for_partitioning(int) - RETURNS int - LANGUAGE plpgsql IMMUTABLE AS - $$ - BEGIN - return 1; - END; - $$; + CREATE OR REPLACE FUNCTION non_sense_func_for_partitioning(int) + RETURNS int + LANGUAGE plpgsql IMMUTABLE AS + $$ + BEGIN + return 1; + END; + $$; -- Functions shouldn't be propagated within transaction SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.non_sense_func_for_partitioning'::regproc::oid; pg_identify_object_as_address @@ -861,7 +861,7 @@ BEGIN; NOTICE: localhost:xxxxx is the coordinator and already contains metadata, skipping syncing the metadata ?column? --------------------------------------------------------------------- - 1 + 1 (1 row) SELECT citus_add_local_table_to_metadata('citus_local_table_to_test_func'); @@ -984,7 +984,7 @@ BEGIN; -- Function should be marked as distributed after distributing the table that depends on it SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_for_func_dep_1'::regproc::oid; - pg_identify_object_as_address + pg_identify_object_as_address --------------------------------------------------------------------- (function,"{function_propagation_schema,func_for_func_dep_1}",{}) (1 row) @@ -992,7 +992,7 @@ BEGIN; COMMIT; -- Function should be marked as distributed on the worker after committing changes SELECT * FROM run_command_on_workers($$SELECT pg_identify_object_as_address(classid, objid, objsubid) from citus.pg_dist_object where objid = 'function_propagation_schema.func_for_func_dep_1'::regproc::oid;$$) ORDER BY 1,2; - nodename | nodeport | success | result + nodename | nodeport | success | result --------------------------------------------------------------------- localhost | 57637 | t | (function,"{function_propagation_schema,func_for_func_dep_1}",{}) localhost | 57638 | t | (function,"{function_propagation_schema,func_for_func_dep_1}",{}) @@ -1070,6 +1070,124 @@ SELECT create_distributed_table('table_non_for_func_dist', 'a'); (1 row) +SET citus.shard_replication_factor = 1; +-- test creating a colocated function +CREATE TABLE tbl_to_colocate (a int); +SELECT create_distributed_table('tbl_to_colocate', 'a'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +-- first test colocating function with a ref table +CREATE TABLE tbl_to_colocate_ref (a int); +SELECT create_reference_table('tbl_to_colocate_ref'); + create_reference_table +--------------------------------------------------------------------- + +(1 row) + +CREATE FUNCTION func_to_colocate (a int) returns int as $$select 1;$$ language sql; +-- see the empty pg_dist_object entries +SELECT distribution_argument_index, colocationid, force_delegation FROM citus.pg_dist_object WHERE objid = 'func_to_colocate'::regproc; + distribution_argument_index | colocationid | force_delegation +--------------------------------------------------------------------- + | | +(1 row) + +-- colocate the function with ref table +SELECT create_distributed_function('func_to_colocate(int)', colocate_with:='tbl_to_colocate_ref'); + create_distributed_function +--------------------------------------------------------------------- + +(1 row) + +-- see the pg_dist_object entry +SELECT distribution_argument_index, colocationid, force_delegation FROM citus.pg_dist_object WHERE objid = 'func_to_colocate'::regproc; + distribution_argument_index | colocationid | force_delegation +--------------------------------------------------------------------- + | 10003 | +(1 row) + +-- convert to non-delegated +SELECT create_distributed_function('func_to_colocate(int)'); + create_distributed_function +--------------------------------------------------------------------- + +(1 row) + +-- show that the pg_dist_object fields are gone +SELECT distribution_argument_index, colocationid, force_delegation FROM citus.pg_dist_object WHERE objid = 'func_to_colocate'::regproc; + distribution_argument_index | colocationid | force_delegation +--------------------------------------------------------------------- + | | +(1 row) + +-- colocate the function with distributed table +SELECT create_distributed_function('func_to_colocate(int)','$1','tbl_to_colocate'); + create_distributed_function +--------------------------------------------------------------------- + +(1 row) + +-- see the pg_dist_object entry +SELECT distribution_argument_index, colocationid, force_delegation FROM citus.pg_dist_object WHERE objid = 'func_to_colocate'::regproc; + distribution_argument_index | colocationid | force_delegation +--------------------------------------------------------------------- + 0 | 10005 | +(1 row) + +-- try create or replace the same func +CREATE OR REPLACE FUNCTION func_to_colocate (a int) returns int as $$select 1;$$ language sql; +-- verify the pg_dist_object entry is the same +SELECT distribution_argument_index, colocationid, force_delegation FROM citus.pg_dist_object WHERE objid = 'func_to_colocate'::regproc; + distribution_argument_index | colocationid | force_delegation +--------------------------------------------------------------------- + 0 | 10005 | +(1 row) + +-- convert to non-delegated +SELECT create_distributed_function('func_to_colocate(int)'); + create_distributed_function +--------------------------------------------------------------------- + +(1 row) + +-- show that the pg_dist_object fields are gone +SELECT distribution_argument_index, colocationid, force_delegation FROM citus.pg_dist_object WHERE objid = 'func_to_colocate'::regproc; + distribution_argument_index | colocationid | force_delegation +--------------------------------------------------------------------- + | | +(1 row) + +-- force delegate +SELECT create_distributed_function('func_to_colocate(int)','$1','tbl_to_colocate', true); + create_distributed_function +--------------------------------------------------------------------- + +(1 row) + +-- show pg_dist_object fields +SELECT distribution_argument_index, colocationid, force_delegation FROM citus.pg_dist_object WHERE objid = 'func_to_colocate'::regproc; + distribution_argument_index | colocationid | force_delegation +--------------------------------------------------------------------- + 0 | 10005 | t +(1 row) + +-- convert to non-delegated +SELECT create_distributed_function('func_to_colocate(int)'); + create_distributed_function +--------------------------------------------------------------------- + +(1 row) + +-- show that the pg_dist_object fields are gone +SELECT distribution_argument_index, colocationid, force_delegation FROM citus.pg_dist_object WHERE objid = 'func_to_colocate'::regproc; + distribution_argument_index | colocationid | force_delegation +--------------------------------------------------------------------- + | | +(1 row) + RESET search_path; SET client_min_messages TO WARNING; DROP SCHEMA function_propagation_schema CASCADE; diff --git a/src/test/regress/expected/insert_select_repartition.out b/src/test/regress/expected/insert_select_repartition.out index afa54b7e8..856690159 100644 --- a/src/test/regress/expected/insert_select_repartition.out +++ b/src/test/regress/expected/insert_select_repartition.out @@ -1182,6 +1182,7 @@ END; $$ LANGUAGE plpgsql STABLE; SELECT create_distributed_function('dist_func(int, int)'); +NOTICE: procedure insert_select_repartition.dist_func is already distributed create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/local_shard_execution.out b/src/test/regress/expected/local_shard_execution.out index 5cb61b2d5..5d29a4e71 100644 --- a/src/test/regress/expected/local_shard_execution.out +++ b/src/test/regress/expected/local_shard_execution.out @@ -55,6 +55,8 @@ BEGIN RETURN localGroupId; END; $$ language plpgsql VOLATILE; SELECT create_distributed_function('get_local_node_id_volatile()'); +NOTICE: procedure local_shard_execution.get_local_node_id_volatile is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/local_shard_execution_replicated.out b/src/test/regress/expected/local_shard_execution_replicated.out index 285327095..c297f0a99 100644 --- a/src/test/regress/expected/local_shard_execution_replicated.out +++ b/src/test/regress/expected/local_shard_execution_replicated.out @@ -60,6 +60,8 @@ BEGIN RETURN localGroupId; END; $$ language plpgsql VOLATILE; SELECT create_distributed_function('get_local_node_id_volatile()'); +NOTICE: procedure local_shard_execution_replicated.get_local_node_id_volatile is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -2284,6 +2286,8 @@ BEGIN END; $fn$; SELECT create_distributed_function('register_for_event(int,int,invite_resp)'); +NOTICE: procedure local_shard_execution_replicated.register_for_event is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/multi_deparse_function.out b/src/test/regress/expected/multi_deparse_function.out index 656c89c40..6ac5dcd17 100644 --- a/src/test/regress/expected/multi_deparse_function.out +++ b/src/test/regress/expected/multi_deparse_function.out @@ -683,6 +683,8 @@ CREATE FUNCTION func_custom_param(IN param intpair, OUT total INT) LANGUAGE SQL; SET citus.enable_metadata_sync TO OFF; SELECT create_distributed_function('func_custom_param(intpair)'); +NOTICE: procedure function_tests.func_custom_param is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -697,6 +699,8 @@ CREATE FUNCTION func_returns_table(IN count INT) LANGUAGE SQL; SET citus.enable_metadata_sync TO OFF; SELECT create_distributed_function('func_returns_table(INT)'); +NOTICE: procedure function_tests.func_returns_table is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/multi_function_evaluation.out b/src/test/regress/expected/multi_function_evaluation.out index 1b2531060..93fdfbffa 100644 --- a/src/test/regress/expected/multi_function_evaluation.out +++ b/src/test/regress/expected/multi_function_evaluation.out @@ -169,6 +169,8 @@ BEGIN END; $function$; SELECT create_distributed_function('stable_squared(int)'); +NOTICE: procedure multi_function_evaluation.stable_squared is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/multi_index_statements.out b/src/test/regress/expected/multi_index_statements.out index aab013acf..59a2626af 100644 --- a/src/test/regress/expected/multi_index_statements.out +++ b/src/test/regress/expected/multi_index_statements.out @@ -84,6 +84,8 @@ BEGIN END; $$ LANGUAGE plpgsql; SELECT create_distributed_function('value_plus_one(int)'); +NOTICE: procedure multi_index_statements.value_plus_one is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -96,6 +98,8 @@ BEGIN END; $$ LANGUAGE plpgsql; SELECT create_distributed_function('multi_index_statements_2.value_plus_one(int)'); +NOTICE: procedure multi_index_statements_2.value_plus_one is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/multi_multiuser.out b/src/test/regress/expected/multi_multiuser.out index 0e25a38d2..f2ccf29e7 100644 --- a/src/test/regress/expected/multi_multiuser.out +++ b/src/test/regress/expected/multi_multiuser.out @@ -471,6 +471,8 @@ SELECT create_distributed_function('usage_access_func(usage_access_type,int[])') ERROR: must be owner of function usage_access_func SET ROLE usage_access; SELECT create_distributed_function('usage_access_func(usage_access_type,int[])'); +NOTICE: procedure public.usage_access_func is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/multi_mx_call.out b/src/test/regress/expected/multi_mx_call.out index 5d440e67b..a8fb95b5f 100644 --- a/src/test/regress/expected/multi_mx_call.out +++ b/src/test/regress/expected/multi_mx_call.out @@ -166,24 +166,32 @@ call mx_call_proc_custom_types('S', 'A'); -- Mark both procedures as distributed ... select create_distributed_function('mx_call_proc(int,int)'); +NOTICE: procedure multi_mx_call.mx_call_proc is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- (1 row) select create_distributed_function('mx_call_proc_bigint(bigint,bigint)'); +NOTICE: procedure multi_mx_call.mx_call_proc_bigint is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- (1 row) select create_distributed_function('mx_call_proc_custom_types(mx_call_enum,mx_call_enum)'); +NOTICE: procedure multi_mx_call.mx_call_proc_custom_types is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- (1 row) select create_distributed_function('mx_call_proc_copy(int)'); +NOTICE: procedure multi_mx_call.mx_call_proc_copy is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -559,8 +567,8 @@ CREATE FUNCTION mx_call_add(int, int) RETURNS int DEBUG: switching to sequential query execution mode DETAIL: A command for a distributed function is run. To make sure subsequent commands see the function correctly we need to make sure to use only one connection for all future commands SELECT create_distributed_function('mx_call_add(int,int)'); -DEBUG: switching to sequential query execution mode -DETAIL: A command for a distributed function is run. To make sure subsequent commands see the function correctly we need to make sure to use only one connection for all future commands +NOTICE: procedure multi_mx_call.mx_call_add is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/multi_mx_call_0.out b/src/test/regress/expected/multi_mx_call_0.out index 474d3a637..37d538bf2 100644 --- a/src/test/regress/expected/multi_mx_call_0.out +++ b/src/test/regress/expected/multi_mx_call_0.out @@ -166,24 +166,32 @@ call mx_call_proc_custom_types('S', 'A'); -- Mark both procedures as distributed ... select create_distributed_function('mx_call_proc(int,int)'); +NOTICE: procedure multi_mx_call.mx_call_proc is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- (1 row) select create_distributed_function('mx_call_proc_bigint(bigint,bigint)'); +NOTICE: procedure multi_mx_call.mx_call_proc_bigint is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- (1 row) select create_distributed_function('mx_call_proc_custom_types(mx_call_enum,mx_call_enum)'); +NOTICE: procedure multi_mx_call.mx_call_proc_custom_types is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- (1 row) select create_distributed_function('mx_call_proc_copy(int)'); +NOTICE: procedure multi_mx_call.mx_call_proc_copy is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -559,8 +567,8 @@ CREATE FUNCTION mx_call_add(int, int) RETURNS int DEBUG: switching to sequential query execution mode DETAIL: A command for a distributed function is run. To make sure subsequent commands see the function correctly we need to make sure to use only one connection for all future commands SELECT create_distributed_function('mx_call_add(int,int)'); -DEBUG: switching to sequential query execution mode -DETAIL: A command for a distributed function is run. To make sure subsequent commands see the function correctly we need to make sure to use only one connection for all future commands +NOTICE: procedure multi_mx_call.mx_call_add is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/multi_mx_function_call_delegation.out b/src/test/regress/expected/multi_mx_function_call_delegation.out index 552af7bf5..5ba1566dc 100644 --- a/src/test/regress/expected/multi_mx_function_call_delegation.out +++ b/src/test/regress/expected/multi_mx_function_call_delegation.out @@ -132,30 +132,40 @@ select mx_call_func(2, 0); -- Mark both functions as distributed ... select create_distributed_function('mx_call_func(int,int)'); +NOTICE: procedure multi_mx_function_call_delegation.mx_call_func is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- (1 row) select create_distributed_function('mx_call_func_bigint(bigint,bigint)'); +NOTICE: procedure multi_mx_function_call_delegation.mx_call_func_bigint is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- (1 row) select create_distributed_function('mx_call_func_custom_types(mx_call_enum,mx_call_enum)'); +NOTICE: procedure multi_mx_function_call_delegation.mx_call_func_custom_types is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- (1 row) select create_distributed_function('mx_call_func_copy(int)'); +NOTICE: procedure multi_mx_function_call_delegation.mx_call_func_copy is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- (1 row) select create_distributed_function('squares(int)'); +NOTICE: procedure multi_mx_function_call_delegation.squares is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/multi_mx_function_call_delegation_0.out b/src/test/regress/expected/multi_mx_function_call_delegation_0.out index cab2f6394..2d317b34e 100644 --- a/src/test/regress/expected/multi_mx_function_call_delegation_0.out +++ b/src/test/regress/expected/multi_mx_function_call_delegation_0.out @@ -132,30 +132,40 @@ select mx_call_func(2, 0); -- Mark both functions as distributed ... select create_distributed_function('mx_call_func(int,int)'); +NOTICE: procedure multi_mx_function_call_delegation.mx_call_func is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- (1 row) select create_distributed_function('mx_call_func_bigint(bigint,bigint)'); +NOTICE: procedure multi_mx_function_call_delegation.mx_call_func_bigint is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- (1 row) select create_distributed_function('mx_call_func_custom_types(mx_call_enum,mx_call_enum)'); +NOTICE: procedure multi_mx_function_call_delegation.mx_call_func_custom_types is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- (1 row) select create_distributed_function('mx_call_func_copy(int)'); +NOTICE: procedure multi_mx_function_call_delegation.mx_call_func_copy is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- (1 row) select create_distributed_function('squares(int)'); +NOTICE: procedure multi_mx_function_call_delegation.squares is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/multi_mx_insert_select_repartition.out b/src/test/regress/expected/multi_mx_insert_select_repartition.out index 59dca03e3..47fd8d18f 100644 --- a/src/test/regress/expected/multi_mx_insert_select_repartition.out +++ b/src/test/regress/expected/multi_mx_insert_select_repartition.out @@ -24,6 +24,8 @@ CREATE FUNCTION square(int) RETURNS INT AS $$ SELECT $1 * $1 $$ LANGUAGE SQL; select create_distributed_function('square(int)'); +NOTICE: procedure multi_mx_insert_select_repartition.square is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/multi_row_router_insert.out b/src/test/regress/expected/multi_row_router_insert.out index 8f1b3366c..d5af7e467 100644 --- a/src/test/regress/expected/multi_row_router_insert.out +++ b/src/test/regress/expected/multi_row_router_insert.out @@ -71,6 +71,7 @@ BEGIN RETURN a*a; END; $$ LANGUAGE PLPGSQL STABLE; SELECT create_distributed_function('square(int)'); +NOTICE: procedure multi_row_router_insert.square is already distributed create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/pg14.out b/src/test/regress/expected/pg14.out index 134190dda..e264533a1 100644 --- a/src/test/regress/expected/pg14.out +++ b/src/test/regress/expected/pg14.out @@ -1232,6 +1232,8 @@ SELECT create_distributed_function('proc_with_out_param(date,int)'); ERROR: function "proc_with_out_param(date,int)" does not exist -- this should work SELECT create_distributed_function('proc_with_out_param(date)'); +NOTICE: procedure pg14.proc_with_out_param is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/expected/row_types.out b/src/test/regress/expected/row_types.out index c82b33b48..43a5ddf2d 100644 --- a/src/test/regress/expected/row_types.out +++ b/src/test/regress/expected/row_types.out @@ -15,6 +15,8 @@ BEGIN END; $$ language plpgsql; SELECT create_distributed_function('table_returner(int)'); +NOTICE: procedure row_types.table_returner is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -29,6 +31,8 @@ BEGIN END; $$ language plpgsql; SELECT create_distributed_function('record_returner(int)'); +NOTICE: procedure row_types.record_returner is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- @@ -42,6 +46,8 @@ BEGIN END; $$ language plpgsql; SELECT create_distributed_function('identity_returner(anyelement)'); +NOTICE: procedure row_types.identity_returner is already distributed +DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- diff --git a/src/test/regress/sql/function_propagation.sql b/src/test/regress/sql/function_propagation.sql index cd915045f..287b7f25a 100644 --- a/src/test/regress/sql/function_propagation.sql +++ b/src/test/regress/sql/function_propagation.sql @@ -709,6 +709,52 @@ CREATE TABLE table_non_for_func_dist ( b int DEFAULT non_sense_func_for_default_val(NULL::loc_for_func_dist)); SELECT create_distributed_table('table_non_for_func_dist', 'a'); +SET citus.shard_replication_factor = 1; +-- test creating a colocated function +CREATE TABLE tbl_to_colocate (a int); +SELECT create_distributed_table('tbl_to_colocate', 'a'); +-- first test colocating function with a ref table +CREATE TABLE tbl_to_colocate_ref (a int); +SELECT create_reference_table('tbl_to_colocate_ref'); + +CREATE FUNCTION func_to_colocate (a int) returns int as $$select 1;$$ language sql; +-- see the empty pg_dist_object entries +SELECT distribution_argument_index, colocationid, force_delegation FROM citus.pg_dist_object WHERE objid = 'func_to_colocate'::regproc; + +-- colocate the function with ref table +SELECT create_distributed_function('func_to_colocate(int)', colocate_with:='tbl_to_colocate_ref'); +-- see the pg_dist_object entry +SELECT distribution_argument_index, colocationid, force_delegation FROM citus.pg_dist_object WHERE objid = 'func_to_colocate'::regproc; + +-- convert to non-delegated +SELECT create_distributed_function('func_to_colocate(int)'); +-- show that the pg_dist_object fields are gone +SELECT distribution_argument_index, colocationid, force_delegation FROM citus.pg_dist_object WHERE objid = 'func_to_colocate'::regproc; + +-- colocate the function with distributed table +SELECT create_distributed_function('func_to_colocate(int)','$1','tbl_to_colocate'); +-- see the pg_dist_object entry +SELECT distribution_argument_index, colocationid, force_delegation FROM citus.pg_dist_object WHERE objid = 'func_to_colocate'::regproc; + +-- try create or replace the same func +CREATE OR REPLACE FUNCTION func_to_colocate (a int) returns int as $$select 1;$$ language sql; +-- verify the pg_dist_object entry is the same +SELECT distribution_argument_index, colocationid, force_delegation FROM citus.pg_dist_object WHERE objid = 'func_to_colocate'::regproc; + +-- convert to non-delegated +SELECT create_distributed_function('func_to_colocate(int)'); +-- show that the pg_dist_object fields are gone +SELECT distribution_argument_index, colocationid, force_delegation FROM citus.pg_dist_object WHERE objid = 'func_to_colocate'::regproc; + +-- force delegate +SELECT create_distributed_function('func_to_colocate(int)','$1','tbl_to_colocate', true); +-- show pg_dist_object fields +SELECT distribution_argument_index, colocationid, force_delegation FROM citus.pg_dist_object WHERE objid = 'func_to_colocate'::regproc; + +-- convert to non-delegated +SELECT create_distributed_function('func_to_colocate(int)'); +-- show that the pg_dist_object fields are gone +SELECT distribution_argument_index, colocationid, force_delegation FROM citus.pg_dist_object WHERE objid = 'func_to_colocate'::regproc; RESET search_path; SET client_min_messages TO WARNING;