-- Test passing off CALL to mx workers create schema multi_mx_call; set search_path to multi_mx_call, public; -- Create worker-local tables to test procedure calls were routed set citus.shard_replication_factor to 2; -- This table requires specific settings, create before getting into things create table mx_call_dist_table_replica(id int, val int); select create_distributed_table('mx_call_dist_table_replica', 'id'); create_distributed_table --------------------------------------------------------------------- (1 row) insert into mx_call_dist_table_replica values (9,1),(8,2),(7,3),(6,4),(5,5); set citus.shard_replication_factor to 1; -- -- Create tables and procedures we want to use in tests -- create table mx_call_dist_table_1(id int, val int); select create_distributed_table('mx_call_dist_table_1', 'id'); create_distributed_table --------------------------------------------------------------------- (1 row) insert into mx_call_dist_table_1 values (3,1),(4,5),(9,2),(6,5),(3,5); create table mx_call_dist_table_2(id int, val int); select create_distributed_table('mx_call_dist_table_2', 'id'); create_distributed_table --------------------------------------------------------------------- (1 row) insert into mx_call_dist_table_2 values (1,1),(1,2),(2,2),(3,3),(3,4); create table mx_call_dist_table_bigint(id bigint, val bigint); select create_distributed_table('mx_call_dist_table_bigint', 'id'); create_distributed_table --------------------------------------------------------------------- (1 row) insert into mx_call_dist_table_bigint values (1,1),(1,2),(2,2),(3,3),(3,4); create table mx_call_dist_table_ref(id int, val int); select create_reference_table('mx_call_dist_table_ref'); create_reference_table --------------------------------------------------------------------- (1 row) insert into mx_call_dist_table_ref values (2,7),(1,8),(2,8),(1,8),(2,8); create type mx_call_enum as enum ('A', 'S', 'D', 'F'); create table mx_call_dist_table_enum(id int, key mx_call_enum); select create_distributed_table('mx_call_dist_table_enum', 'key'); create_distributed_table --------------------------------------------------------------------- (1 row) insert into mx_call_dist_table_enum values (1,'S'),(2,'A'),(3,'D'),(4,'F'); -- test that a distributed function can be colocated with a reference table CREATE TABLE ref(groupid int); SELECT create_reference_table('ref'); create_reference_table --------------------------------------------------------------------- (1 row) CREATE OR REPLACE PROCEDURE my_group_id_proc() LANGUAGE plpgsql SET search_path FROM CURRENT AS $$ DECLARE gid int; BEGIN SELECT groupid INTO gid FROM pg_dist_local_group; INSERT INTO ref(groupid) VALUES (gid); END; $$; SELECT create_distributed_function('my_group_id_proc()', colocate_with := 'ref'); create_distributed_function --------------------------------------------------------------------- (1 row) CALL my_group_id_proc(); CALL my_group_id_proc(); SELECT DISTINCT(groupid) FROM ref ORDER BY 1; groupid --------------------------------------------------------------------- 14 (1 row) TRUNCATE TABLE ref; -- test round robin task assignment policy uses different workers on consecutive procedure calls. SET citus.task_assignment_policy TO 'round-robin'; CALL my_group_id_proc(); CALL my_group_id_proc(); CALL my_group_id_proc(); SELECT DISTINCT(groupid) FROM ref ORDER BY 1; groupid --------------------------------------------------------------------- 14 18 (2 rows) TRUNCATE TABLE ref; RESET citus.task_assignment_policy; CREATE PROCEDURE mx_call_proc(x int, INOUT y int) LANGUAGE plpgsql AS $$ BEGIN -- groupid is 0 in coordinator and non-zero in workers, so by using it here -- we make sure the procedure is being executed in the worker. y := x + (select case groupid when 0 then 1 else 0 end from pg_dist_local_group); -- we also make sure that we can run distributed queries in the procedures -- that are routed to the workers. y := y + (select sum(t1.val + t2.val) from multi_mx_call.mx_call_dist_table_1 t1 join multi_mx_call.mx_call_dist_table_2 t2 on t1.id = t2.id); END;$$; CREATE PROCEDURE mx_call_proc_bigint(x bigint, INOUT y bigint) LANGUAGE plpgsql AS $$ BEGIN y := x + y * 2; END;$$; -- create another procedure which verifies: -- 1. we work fine with multiple return columns -- 2. we work fine in combination with custom types CREATE PROCEDURE mx_call_proc_custom_types(INOUT x mx_call_enum, INOUT y mx_call_enum) LANGUAGE plpgsql AS $$ BEGIN y := x; x := (select case groupid when 0 then 'F' else 'S' end from pg_dist_local_group); END;$$; CREATE PROCEDURE mx_call_proc_copy(x int) LANGUAGE plpgsql AS $$ BEGIN INSERT INTO multi_mx_call.mx_call_dist_table_1 SELECT s,s FROM generate_series(100, 110) s; END;$$; -- Test that undistributed procedures have no issue executing call multi_mx_call.mx_call_proc(2, 0); y --------------------------------------------------------------------- 29 (1 row) call multi_mx_call.mx_call_proc_custom_types('S', 'A'); x | y --------------------------------------------------------------------- F | S (1 row) call multi_mx_call.mx_call_proc_copy(2); -- Same for unqualified names call mx_call_proc(2, 0); y --------------------------------------------------------------------- 29 (1 row) call mx_call_proc_custom_types('S', 'A'); x | y --------------------------------------------------------------------- F | S (1 row) -- 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 --------------------------------------------------------------------- (1 row) -- We still don't route them to the workers, because they aren't -- colocated with any distributed tables. SET client_min_messages TO DEBUG1; call multi_mx_call.mx_call_proc(2, 0); DEBUG: stored procedure does not have co-located tables DEBUG: generating subplan XXX_1 for subquery SELECT sum((t1.val OPERATOR(pg_catalog.+) t2.val)) AS sum FROM (multi_mx_call.mx_call_dist_table_1 t1 JOIN multi_mx_call.mx_call_dist_table_2 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.id))) CONTEXT: PL/pgSQL assignment "y := y + (select sum(t1.val + t2.val) from multi_mx_call.mx_call_dist_table_1 t1 join multi_mx_call.mx_call_dist_table_2 t2 on t1.id = t2.id)" PL/pgSQL function mx_call_proc(integer,integer) line XX at assignment DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT ((3 OPERATOR(pg_catalog.+) (SELECT intermediate_result.sum FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(sum bigint))))::integer CONTEXT: PL/pgSQL assignment "y := y + (select sum(t1.val + t2.val) from multi_mx_call.mx_call_dist_table_1 t1 join multi_mx_call.mx_call_dist_table_2 t2 on t1.id = t2.id)" PL/pgSQL function mx_call_proc(integer,integer) line XX at assignment y --------------------------------------------------------------------- 29 (1 row) call mx_call_proc_bigint(4, 2); DEBUG: stored procedure does not have co-located tables y --------------------------------------------------------------------- 8 (1 row) call multi_mx_call.mx_call_proc_custom_types('S', 'A'); DEBUG: stored procedure does not have co-located tables x | y --------------------------------------------------------------------- F | S (1 row) call multi_mx_call.mx_call_proc_copy(2); DEBUG: stored procedure does not have co-located tables DEBUG: Collecting INSERT ... SELECT results on coordinator CONTEXT: SQL statement "INSERT INTO multi_mx_call.mx_call_dist_table_1 SELECT s,s FROM generate_series(100, 110) s" PL/pgSQL function mx_call_proc_copy(integer) line XX at SQL statement -- Mark them as colocated with a table. Now we should route them to workers. select colocate_proc_with_table('mx_call_proc', 'mx_call_dist_table_1'::regclass, 1); colocate_proc_with_table --------------------------------------------------------------------- (1 row) select colocate_proc_with_table('mx_call_proc_bigint', 'mx_call_dist_table_bigint'::regclass, 1); colocate_proc_with_table --------------------------------------------------------------------- (1 row) select colocate_proc_with_table('mx_call_proc_custom_types', 'mx_call_dist_table_enum'::regclass, 1); colocate_proc_with_table --------------------------------------------------------------------- (1 row) select colocate_proc_with_table('mx_call_proc_copy', 'mx_call_dist_table_1'::regclass, 0); colocate_proc_with_table --------------------------------------------------------------------- (1 row) call multi_mx_call.mx_call_proc(2, 0); DEBUG: pushing down the procedure y --------------------------------------------------------------------- 28 (1 row) call multi_mx_call.mx_call_proc_custom_types('S', 'A'); DEBUG: pushing down the procedure x | y --------------------------------------------------------------------- S | S (1 row) call mx_call_proc(2, 0); DEBUG: pushing down the procedure y --------------------------------------------------------------------- 28 (1 row) call mx_call_proc_custom_types('S', 'A'); DEBUG: pushing down the procedure x | y --------------------------------------------------------------------- S | S (1 row) call mx_call_proc_copy(2); DEBUG: pushing down the procedure -- Test implicit cast of int to bigint call mx_call_proc_bigint(4, 2); DEBUG: pushing down the procedure y --------------------------------------------------------------------- 8 (1 row) -- We don't allow distributing calls inside transactions begin; call multi_mx_call.mx_call_proc(2, 0); DEBUG: cannot push down CALL in multi-statement transaction DEBUG: generating subplan XXX_1 for subquery SELECT sum((t1.val OPERATOR(pg_catalog.+) t2.val)) AS sum FROM (multi_mx_call.mx_call_dist_table_1 t1 JOIN multi_mx_call.mx_call_dist_table_2 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.id))) CONTEXT: PL/pgSQL assignment "y := y + (select sum(t1.val + t2.val) from multi_mx_call.mx_call_dist_table_1 t1 join multi_mx_call.mx_call_dist_table_2 t2 on t1.id = t2.id)" PL/pgSQL function mx_call_proc(integer,integer) line XX at assignment DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT ((3 OPERATOR(pg_catalog.+) (SELECT intermediate_result.sum FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(sum bigint))))::integer CONTEXT: PL/pgSQL assignment "y := y + (select sum(t1.val + t2.val) from multi_mx_call.mx_call_dist_table_1 t1 join multi_mx_call.mx_call_dist_table_2 t2 on t1.id = t2.id)" PL/pgSQL function mx_call_proc(integer,integer) line XX at assignment y --------------------------------------------------------------------- 29 (1 row) commit; -- Drop the table colocated with mx_call_proc_custom_types. Now it shouldn't -- be routed to workers anymore. SET client_min_messages TO NOTICE; drop table mx_call_dist_table_enum; SET client_min_messages TO DEBUG1; call multi_mx_call.mx_call_proc_custom_types('S', 'A'); DEBUG: stored procedure does not have co-located tables x | y --------------------------------------------------------------------- F | S (1 row) -- Make sure we do bounds checking on distributed argument index -- This also tests that we have cache invalidation for pg_dist_object updates select colocate_proc_with_table('mx_call_proc', 'mx_call_dist_table_1'::regclass, -1); colocate_proc_with_table --------------------------------------------------------------------- (1 row) call multi_mx_call.mx_call_proc(2, 0); DEBUG: cannot push down invalid distribution_argument_index DEBUG: generating subplan XXX_1 for subquery SELECT sum((t1.val OPERATOR(pg_catalog.+) t2.val)) AS sum FROM (multi_mx_call.mx_call_dist_table_1 t1 JOIN multi_mx_call.mx_call_dist_table_2 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.id))) CONTEXT: PL/pgSQL assignment "y := y + (select sum(t1.val + t2.val) from multi_mx_call.mx_call_dist_table_1 t1 join multi_mx_call.mx_call_dist_table_2 t2 on t1.id = t2.id)" PL/pgSQL function mx_call_proc(integer,integer) line XX at assignment DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT ((3 OPERATOR(pg_catalog.+) (SELECT intermediate_result.sum FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(sum bigint))))::integer CONTEXT: PL/pgSQL assignment "y := y + (select sum(t1.val + t2.val) from multi_mx_call.mx_call_dist_table_1 t1 join multi_mx_call.mx_call_dist_table_2 t2 on t1.id = t2.id)" PL/pgSQL function mx_call_proc(integer,integer) line XX at assignment y --------------------------------------------------------------------- 29 (1 row) select colocate_proc_with_table('mx_call_proc', 'mx_call_dist_table_1'::regclass, 2); colocate_proc_with_table --------------------------------------------------------------------- (1 row) call multi_mx_call.mx_call_proc(2, 0); DEBUG: cannot push down invalid distribution_argument_index DEBUG: generating subplan XXX_1 for subquery SELECT sum((t1.val OPERATOR(pg_catalog.+) t2.val)) AS sum FROM (multi_mx_call.mx_call_dist_table_1 t1 JOIN multi_mx_call.mx_call_dist_table_2 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.id))) CONTEXT: PL/pgSQL assignment "y := y + (select sum(t1.val + t2.val) from multi_mx_call.mx_call_dist_table_1 t1 join multi_mx_call.mx_call_dist_table_2 t2 on t1.id = t2.id)" PL/pgSQL function mx_call_proc(integer,integer) line XX at assignment DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT ((3 OPERATOR(pg_catalog.+) (SELECT intermediate_result.sum FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(sum bigint))))::integer CONTEXT: PL/pgSQL assignment "y := y + (select sum(t1.val + t2.val) from multi_mx_call.mx_call_dist_table_1 t1 join multi_mx_call.mx_call_dist_table_2 t2 on t1.id = t2.id)" PL/pgSQL function mx_call_proc(integer,integer) line XX at assignment y --------------------------------------------------------------------- 29 (1 row) -- We support colocating with reference tables select colocate_proc_with_table('mx_call_proc', 'mx_call_dist_table_ref'::regclass, NULL); colocate_proc_with_table --------------------------------------------------------------------- (1 row) call multi_mx_call.mx_call_proc(2, 0); DEBUG: will push down CALL for reference tables DEBUG: pushing down the procedure y --------------------------------------------------------------------- 28 (1 row) -- We don't currently support colocating with replicated tables select colocate_proc_with_table('mx_call_proc', 'mx_call_dist_table_replica'::regclass, 1); colocate_proc_with_table --------------------------------------------------------------------- (1 row) call multi_mx_call.mx_call_proc(2, 0); DEBUG: cannot push down function call for replicated distributed tables DEBUG: generating subplan XXX_1 for subquery SELECT sum((t1.val OPERATOR(pg_catalog.+) t2.val)) AS sum FROM (multi_mx_call.mx_call_dist_table_1 t1 JOIN multi_mx_call.mx_call_dist_table_2 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.id))) CONTEXT: PL/pgSQL assignment "y := y + (select sum(t1.val + t2.val) from multi_mx_call.mx_call_dist_table_1 t1 join multi_mx_call.mx_call_dist_table_2 t2 on t1.id = t2.id)" PL/pgSQL function mx_call_proc(integer,integer) line XX at assignment DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT ((3 OPERATOR(pg_catalog.+) (SELECT intermediate_result.sum FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(sum bigint))))::integer CONTEXT: PL/pgSQL assignment "y := y + (select sum(t1.val + t2.val) from multi_mx_call.mx_call_dist_table_1 t1 join multi_mx_call.mx_call_dist_table_2 t2 on t1.id = t2.id)" PL/pgSQL function mx_call_proc(integer,integer) line XX at assignment y --------------------------------------------------------------------- 29 (1 row) SET client_min_messages TO NOTICE; drop table mx_call_dist_table_replica; SET client_min_messages TO DEBUG1; select colocate_proc_with_table('mx_call_proc', 'mx_call_dist_table_1'::regclass, 1); colocate_proc_with_table --------------------------------------------------------------------- (1 row) -- Test that we handle transactional constructs correctly inside a procedure -- that is routed to the workers. SET citus.enable_metadata_sync TO OFF; CREATE PROCEDURE mx_call_proc_tx(x int) LANGUAGE plpgsql AS $$ BEGIN INSERT INTO multi_mx_call.mx_call_dist_table_1 VALUES (x, -1), (x+1, 4); COMMIT; UPDATE multi_mx_call.mx_call_dist_table_1 SET val = val+1 WHERE id >= x; ROLLBACK; -- Now do the final update! UPDATE multi_mx_call.mx_call_dist_table_1 SET val = val-1 WHERE id >= x; END;$$; RESET citus.enable_metadata_sync; -- before distribution ... CALL multi_mx_call.mx_call_proc_tx(10); -- after distribution ... select create_distributed_function('mx_call_proc_tx(int)', '$1', 'mx_call_dist_table_1'); 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 create_distributed_function --------------------------------------------------------------------- (1 row) CALL multi_mx_call.mx_call_proc_tx(20); DEBUG: pushing down the procedure SELECT id, val FROM mx_call_dist_table_1 ORDER BY id, val; id | val --------------------------------------------------------------------- 3 | 1 3 | 5 4 | 5 6 | 5 9 | 2 10 | -2 11 | 3 20 | -2 21 | 3 100 | 98 100 | 98 100 | 98 101 | 99 101 | 99 101 | 99 102 | 100 102 | 100 102 | 100 103 | 101 103 | 101 103 | 101 104 | 102 104 | 102 104 | 102 105 | 103 105 | 103 105 | 103 106 | 104 106 | 104 106 | 104 107 | 105 107 | 105 107 | 105 108 | 106 108 | 106 108 | 106 109 | 107 109 | 107 109 | 107 110 | 108 110 | 108 110 | 108 (42 rows) -- Show that function delegation works from worker nodes as well \c - - - :worker_1_port SET search_path to multi_mx_call, public; SET client_min_messages TO DEBUG1; CALL multi_mx_call.mx_call_proc_tx(9); DEBUG: pushing down the procedure \c - - - :master_port SET search_path to multi_mx_call, public; SET client_min_messages TO DEBUG1; -- Test that we properly propagate errors raised from procedures. CREATE PROCEDURE mx_call_proc_raise(x int) LANGUAGE plpgsql AS $$ BEGIN RAISE WARNING 'warning'; RAISE EXCEPTION 'error'; END;$$; 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_proc_raise(int)', '$1', 'mx_call_dist_table_1'); 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 create_distributed_function --------------------------------------------------------------------- (1 row) \set VERBOSITY terse call multi_mx_call.mx_call_proc_raise(2); DEBUG: pushing down the procedure WARNING: warning ERROR: error \set VERBOSITY default -- Test that we don't propagate to non-metadata worker nodes SET client_min_messages TO WARNING; select stop_metadata_sync_to_node('localhost', :worker_1_port); stop_metadata_sync_to_node --------------------------------------------------------------------- (1 row) select stop_metadata_sync_to_node('localhost', :worker_2_port); stop_metadata_sync_to_node --------------------------------------------------------------------- (1 row) SET client_min_messages TO DEBUG1; call multi_mx_call.mx_call_proc(2, 0); DEBUG: there is no worker node with metadata DEBUG: generating subplan XXX_1 for subquery SELECT sum((t1.val OPERATOR(pg_catalog.+) t2.val)) AS sum FROM (multi_mx_call.mx_call_dist_table_1 t1 JOIN multi_mx_call.mx_call_dist_table_2 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.id))) CONTEXT: PL/pgSQL assignment "y := y + (select sum(t1.val + t2.val) from multi_mx_call.mx_call_dist_table_1 t1 join multi_mx_call.mx_call_dist_table_2 t2 on t1.id = t2.id)" PL/pgSQL function mx_call_proc(integer,integer) line XX at assignment DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT ((3 OPERATOR(pg_catalog.+) (SELECT intermediate_result.sum FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(sum bigint))))::integer CONTEXT: PL/pgSQL assignment "y := y + (select sum(t1.val + t2.val) from multi_mx_call.mx_call_dist_table_1 t1 join multi_mx_call.mx_call_dist_table_2 t2 on t1.id = t2.id)" PL/pgSQL function mx_call_proc(integer,integer) line XX at assignment y --------------------------------------------------------------------- 29 (1 row) SET client_min_messages TO NOTICE; select start_metadata_sync_to_node('localhost', :worker_1_port); start_metadata_sync_to_node --------------------------------------------------------------------- (1 row) select start_metadata_sync_to_node('localhost', :worker_2_port); start_metadata_sync_to_node --------------------------------------------------------------------- (1 row) -- stop_metadata_sync_to_node()/start_metadata_sync_to_node() might make -- worker backend caches inconsistent. Reconnect to coordinator to use -- new worker connections, hence new backends. \c - - - :master_port SET search_path to multi_mx_call, public; SET client_min_messages TO DEBUG1; -- -- Test non-const parameter values -- CREATE FUNCTION mx_call_add(int, int) RETURNS int AS 'select $1 + $2;' LANGUAGE SQL IMMUTABLE; 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)'); NOTICE: procedure multi_mx_call.mx_call_add is already distributed DETAIL: Citus distributes procedures with CREATE [PROCEDURE|FUNCTION|AGGREGATE] commands create_distributed_function --------------------------------------------------------------------- (1 row) -- non-const distribution parameters cannot be pushed down call multi_mx_call.mx_call_proc(2, mx_call_add(3, 4)); DEBUG: distribution argument value must be a constant DEBUG: generating subplan XXX_1 for subquery SELECT sum((t1.val OPERATOR(pg_catalog.+) t2.val)) AS sum FROM (multi_mx_call.mx_call_dist_table_1 t1 JOIN multi_mx_call.mx_call_dist_table_2 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.id))) CONTEXT: PL/pgSQL assignment "y := y + (select sum(t1.val + t2.val) from multi_mx_call.mx_call_dist_table_1 t1 join multi_mx_call.mx_call_dist_table_2 t2 on t1.id = t2.id)" PL/pgSQL function mx_call_proc(integer,integer) line XX at assignment DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT ((3 OPERATOR(pg_catalog.+) (SELECT intermediate_result.sum FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(sum bigint))))::integer CONTEXT: PL/pgSQL assignment "y := y + (select sum(t1.val + t2.val) from multi_mx_call.mx_call_dist_table_1 t1 join multi_mx_call.mx_call_dist_table_2 t2 on t1.id = t2.id)" PL/pgSQL function mx_call_proc(integer,integer) line XX at assignment y --------------------------------------------------------------------- 29 (1 row) -- non-const parameter can be pushed down call multi_mx_call.mx_call_proc(multi_mx_call.mx_call_add(3, 4), 2); DEBUG: pushing down the procedure y --------------------------------------------------------------------- 33 (1 row) -- volatile parameter cannot be pushed down call multi_mx_call.mx_call_proc(floor(random())::int, 2); DEBUG: arguments in a distributed stored procedure must be constant expressions DEBUG: generating subplan XXX_1 for subquery SELECT sum((t1.val OPERATOR(pg_catalog.+) t2.val)) AS sum FROM (multi_mx_call.mx_call_dist_table_1 t1 JOIN multi_mx_call.mx_call_dist_table_2 t2 ON ((t1.id OPERATOR(pg_catalog.=) t2.id))) CONTEXT: PL/pgSQL assignment "y := y + (select sum(t1.val + t2.val) from multi_mx_call.mx_call_dist_table_1 t1 join multi_mx_call.mx_call_dist_table_2 t2 on t1.id = t2.id)" PL/pgSQL function mx_call_proc(integer,integer) line XX at assignment DEBUG: Plan XXX query after replacing subqueries and CTEs: SELECT ((1 OPERATOR(pg_catalog.+) (SELECT intermediate_result.sum FROM read_intermediate_result('XXX_1'::text, 'binary'::citus_copy_format) intermediate_result(sum bigint))))::integer CONTEXT: PL/pgSQL assignment "y := y + (select sum(t1.val + t2.val) from multi_mx_call.mx_call_dist_table_1 t1 join multi_mx_call.mx_call_dist_table_2 t2 on t1.id = t2.id)" PL/pgSQL function mx_call_proc(integer,integer) line XX at assignment y --------------------------------------------------------------------- 27 (1 row) reset client_min_messages; \set VERBOSITY terse drop schema multi_mx_call cascade; NOTICE: drop cascades to 14 other objects