-- 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;
set citus.replication_model to 'statement';
-- 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;
set citus.replication_model to 'streaming';
--
-- 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');
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;$$;
-- 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)

-- 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)');
 create_distributed_function
---------------------------------------------------------------------

(1 row)

select create_distributed_function('mx_call_proc_bigint(bigint,bigint)');
 create_distributed_function
---------------------------------------------------------------------

(1 row)

select create_distributed_function('mx_call_proc_custom_types(mx_call_enum,mx_call_enum)');
 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:  SQL statement "SELECT 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 8 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)))
CONTEXT:  SQL statement "SELECT 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 8 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)

-- 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)

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)

-- 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:  SQL statement "SELECT 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 8 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)))
CONTEXT:  SQL statement "SELECT 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 8 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:  SQL statement "SELECT 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 8 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)))
CONTEXT:  SQL statement "SELECT 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 8 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:  SQL statement "SELECT 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 8 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)))
CONTEXT:  SQL statement "SELECT 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 8 at assignment
 y
---------------------------------------------------------------------
 29
(1 row)

-- We don't currently support colocating with reference tables
select colocate_proc_with_table('mx_call_proc', 'mx_call_dist_table_ref'::regclass, 1);
 colocate_proc_with_table
---------------------------------------------------------------------

(1 row)

call multi_mx_call.mx_call_proc(2, 0);
DEBUG:  cannot push down CALL for reference 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:  SQL statement "SELECT 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 8 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)))
CONTEXT:  SQL statement "SELECT 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 8 at assignment
 y
---------------------------------------------------------------------
 29
(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 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:  SQL statement "SELECT 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 8 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)))
CONTEXT:  SQL statement "SELECT 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 8 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.
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;$$;
-- 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 distributed function is created. To make sure subsequent commands see the type 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
(9 rows)

-- 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;$$;
select create_distributed_function('mx_call_proc_raise(int)', '$1', 'mx_call_dist_table_1');
DEBUG:  switching to sequential query execution mode
DETAIL:  A distributed function is created. To make sure subsequent commands see the type 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
DEBUG:  warning
ERROR:  error
\set VERBOSITY default
-- Test that we don't propagate to non-metadata worker nodes
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)

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:  SQL statement "SELECT 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 8 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)))
CONTEXT:  SQL statement "SELECT 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 8 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;
SELECT create_distributed_function('mx_call_add(int,int)');
DEBUG:  switching to sequential query execution mode
DETAIL:  A distributed function is created. To make sure subsequent commands see the type correctly we need to make sure to use only one connection for all future 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:  SQL statement "SELECT 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 8 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)))
CONTEXT:  SQL statement "SELECT 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 8 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:  SQL statement "SELECT 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 8 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)))
CONTEXT:  SQL statement "SELECT 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 8 at assignment
 y
---------------------------------------------------------------------
 27
(1 row)

reset client_min_messages;
\set VERBOSITY terse
drop schema multi_mx_call cascade;
NOTICE:  drop cascades to 11 other objects
