mirror of https://github.com/citusdata/citus.git
Merge pull request #5540 from citusdata/fix-function-signature-generation
Fix function signature generationpull/5550/head
commit
d5a969b055
|
@ -80,6 +80,7 @@ static void EnsureSequentialModeForFunctionDDL(void);
|
||||||
static void TriggerSyncMetadataToPrimaryNodes(void);
|
static void TriggerSyncMetadataToPrimaryNodes(void);
|
||||||
static bool ShouldPropagateCreateFunction(CreateFunctionStmt *stmt);
|
static bool ShouldPropagateCreateFunction(CreateFunctionStmt *stmt);
|
||||||
static bool ShouldPropagateAlterFunction(const ObjectAddress *address);
|
static bool ShouldPropagateAlterFunction(const ObjectAddress *address);
|
||||||
|
static bool ShouldAddFunctionSignature(FunctionParameterMode mode);
|
||||||
static ObjectAddress FunctionToObjectAddress(ObjectType objectType,
|
static ObjectAddress FunctionToObjectAddress(ObjectType objectType,
|
||||||
ObjectWithArgs *objectWithArgs,
|
ObjectWithArgs *objectWithArgs,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
|
@ -1328,7 +1329,11 @@ CreateFunctionStmtObjectAddress(Node *node, bool missing_ok)
|
||||||
FunctionParameter *funcParam = NULL;
|
FunctionParameter *funcParam = NULL;
|
||||||
foreach_ptr(funcParam, stmt->parameters)
|
foreach_ptr(funcParam, stmt->parameters)
|
||||||
{
|
{
|
||||||
objectWithArgs->objargs = lappend(objectWithArgs->objargs, funcParam->argType);
|
if (ShouldAddFunctionSignature(funcParam->mode))
|
||||||
|
{
|
||||||
|
objectWithArgs->objargs = lappend(objectWithArgs->objargs,
|
||||||
|
funcParam->argType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return FunctionToObjectAddress(objectType, objectWithArgs, missing_ok);
|
return FunctionToObjectAddress(objectType, objectWithArgs, missing_ok);
|
||||||
|
@ -1885,8 +1890,7 @@ ObjectWithArgsFromOid(Oid funcOid)
|
||||||
|
|
||||||
for (int i = 0; i < numargs; i++)
|
for (int i = 0; i < numargs; i++)
|
||||||
{
|
{
|
||||||
if (argModes == NULL ||
|
if (argModes == NULL || ShouldAddFunctionSignature(argModes[i]))
|
||||||
argModes[i] != PROARGMODE_OUT || argModes[i] != PROARGMODE_TABLE)
|
|
||||||
{
|
{
|
||||||
objargs = lappend(objargs, makeTypeNameFromOid(argTypes[i], -1));
|
objargs = lappend(objargs, makeTypeNameFromOid(argTypes[i], -1));
|
||||||
}
|
}
|
||||||
|
@ -1899,6 +1903,35 @@ ObjectWithArgsFromOid(Oid funcOid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ShouldAddFunctionSignature takes a FunctionParameterMode and returns true if it should
|
||||||
|
* be included in the function signature. Returns false otherwise.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
ShouldAddFunctionSignature(FunctionParameterMode mode)
|
||||||
|
{
|
||||||
|
/* only input parameters should be added to the generated signature */
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case FUNC_PARAM_IN:
|
||||||
|
case FUNC_PARAM_INOUT:
|
||||||
|
case FUNC_PARAM_VARIADIC:
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case FUNC_PARAM_OUT:
|
||||||
|
case FUNC_PARAM_TABLE:
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FunctionToObjectAddress returns the ObjectAddress of a Function or Procedure based on
|
* FunctionToObjectAddress returns the ObjectAddress of a Function or Procedure based on
|
||||||
* its type and ObjectWithArgs describing the Function/Procedure. If missing_ok is set to
|
* its type and ObjectWithArgs describing the Function/Procedure. If missing_ok is set to
|
||||||
|
|
|
@ -61,7 +61,7 @@ WrapCreateOrReplace(const char *sql)
|
||||||
* have this functionality or where their implementation is not sufficient.
|
* have this functionality or where their implementation is not sufficient.
|
||||||
*
|
*
|
||||||
* Besides checking if an object of said name exists it tries to compare the object to be
|
* Besides checking if an object of said name exists it tries to compare the object to be
|
||||||
* created with the one in the local catalog. If there is a difference the on in the local
|
* created with the one in the local catalog. If there is a difference the one in the local
|
||||||
* catalog will be renamed after which the statement can be executed on this worker to
|
* catalog will be renamed after which the statement can be executed on this worker to
|
||||||
* create the object.
|
* create the object.
|
||||||
*
|
*
|
||||||
|
|
|
@ -829,6 +829,266 @@ SELECT * FROM test ORDER BY id;
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
DROP TABLE test;
|
DROP TABLE test;
|
||||||
|
-- verify that recreating distributed functions with TABLE params gets propagated to workers
|
||||||
|
CREATE OR REPLACE FUNCTION func_with_return_table(int)
|
||||||
|
RETURNS TABLE (date date)
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
BEGIN
|
||||||
|
RETURN query SELECT '2011-01-01'::date;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
SELECT create_distributed_function('func_with_return_table(int)');
|
||||||
|
create_distributed_function
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION func_with_return_table(int)
|
||||||
|
RETURNS TABLE (date date)
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
BEGIN
|
||||||
|
RETURN query SELECT '2011-01-02'::date;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
SELECT count(*) FROM
|
||||||
|
(SELECT result FROM
|
||||||
|
run_command_on_workers($$select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc) from pg_proc where proname = 'func_with_return_table';$$)
|
||||||
|
UNION select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc)::text from pg_proc where proname = 'func_with_return_table')
|
||||||
|
as test;
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- verify that recreating distributed functions with OUT params gets propagated to workers
|
||||||
|
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)');
|
||||||
|
create_distributed_function
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SET client_min_messages TO ERROR;
|
||||||
|
CREATE ROLE r1;
|
||||||
|
SELECT 1 FROM run_command_on_workers($$CREATE ROLE r1;$$);
|
||||||
|
?column?
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
1
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
GRANT EXECUTE ON FUNCTION func_with_out_param TO r1;
|
||||||
|
SELECT 1 FROM run_command_on_workers($$GRANT EXECUTE ON FUNCTION func_with_out_param TO r1;$$);
|
||||||
|
?column?
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
1
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
RESET client_min_messages;
|
||||||
|
CREATE OR REPLACE FUNCTION func_with_out_param(a int, out b int)
|
||||||
|
RETURNS int
|
||||||
|
LANGUAGE sql AS $$ select 2; $$;
|
||||||
|
SELECT count(*) FROM
|
||||||
|
(SELECT result FROM
|
||||||
|
run_command_on_workers($$select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc, pg_proc.proowner) from pg_proc where proname = 'func_with_out_param';$$)
|
||||||
|
UNION select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc, pg_proc.proowner)::text from pg_proc where proname = 'func_with_out_param')
|
||||||
|
as test;
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- verify that recreating distributed functions with INOUT params gets propagated to workers
|
||||||
|
CREATE OR REPLACE FUNCTION func_with_inout_param(a int, inout b int)
|
||||||
|
RETURNS int
|
||||||
|
LANGUAGE sql AS $$ select 1; $$;
|
||||||
|
-- this should error out
|
||||||
|
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)');
|
||||||
|
create_distributed_function
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION func_with_inout_param(a int, inout b int)
|
||||||
|
RETURNS int
|
||||||
|
LANGUAGE sql AS $$ select 2; $$;
|
||||||
|
SELECT count(*) FROM
|
||||||
|
(SELECT result FROM
|
||||||
|
run_command_on_workers($$select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc) from pg_proc where proname = 'func_with_inout_param';$$)
|
||||||
|
UNION select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc)::text from pg_proc where proname = 'func_with_inout_param')
|
||||||
|
as test;
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- verify that recreating distributed functions with VARIADIC params gets propagated to workers
|
||||||
|
CREATE OR REPLACE FUNCTION func_with_variadic_param(a int, variadic b int[])
|
||||||
|
RETURNS int
|
||||||
|
LANGUAGE sql AS $$ select 1; $$;
|
||||||
|
-- this should work
|
||||||
|
SELECT create_distributed_function('func_with_variadic_param(int,int[])');
|
||||||
|
create_distributed_function
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION func_with_variadic_param(a int, variadic b int[])
|
||||||
|
RETURNS int
|
||||||
|
LANGUAGE sql AS $$ select 2; $$;
|
||||||
|
SELECT count(*) FROM
|
||||||
|
(SELECT result FROM
|
||||||
|
run_command_on_workers($$select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc) from pg_proc where proname = 'func_with_variadic_param';$$)
|
||||||
|
UNION select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc)::text from pg_proc where proname = 'func_with_variadic_param')
|
||||||
|
as test;
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- verify that recreating distributed functions returning setof records gets propagated to workers
|
||||||
|
CREATE OR REPLACE FUNCTION func_returning_setof_int(IN parm1 date, IN parm2 interval)
|
||||||
|
RETURNS SETOF integer AS
|
||||||
|
$BODY$
|
||||||
|
BEGIN
|
||||||
|
RETURN QUERY
|
||||||
|
SELECT 1;
|
||||||
|
END;
|
||||||
|
$BODY$
|
||||||
|
LANGUAGE plpgsql VOLATILE
|
||||||
|
COST 100;
|
||||||
|
SELECT create_distributed_function('func_returning_setof_int(date,interval)');
|
||||||
|
create_distributed_function
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION func_returning_setof_int(IN parm1 date, IN parm2 interval)
|
||||||
|
RETURNS SETOF integer AS
|
||||||
|
$BODY$
|
||||||
|
BEGIN
|
||||||
|
RETURN QUERY
|
||||||
|
SELECT 2;
|
||||||
|
|
||||||
|
END;
|
||||||
|
$BODY$
|
||||||
|
LANGUAGE plpgsql VOLATILE
|
||||||
|
COST 100;
|
||||||
|
SELECT count(*) FROM
|
||||||
|
(SELECT result FROM
|
||||||
|
run_command_on_workers($$select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc) from pg_proc where proname = 'func_returning_setof_int';$$)
|
||||||
|
UNION select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc)::text from pg_proc where proname = 'func_returning_setof_int')
|
||||||
|
as test;
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- verify that recreating distributed functions with variadic param returning setof records gets propagated to workers
|
||||||
|
CREATE OR REPLACE FUNCTION func_returning_setof_int_with_variadic_param(IN parm1 date, VARIADIC parm2 int[])
|
||||||
|
RETURNS SETOF integer AS
|
||||||
|
$BODY$
|
||||||
|
BEGIN
|
||||||
|
RETURN QUERY
|
||||||
|
SELECT 1;
|
||||||
|
END;
|
||||||
|
$BODY$
|
||||||
|
LANGUAGE plpgsql VOLATILE
|
||||||
|
COST 100;
|
||||||
|
SELECT create_distributed_function('func_returning_setof_int_with_variadic_param(date,int[])');
|
||||||
|
create_distributed_function
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION func_returning_setof_int_with_variadic_param(IN parm1 date, VARIADIC parm2 int[])
|
||||||
|
RETURNS SETOF integer AS
|
||||||
|
$BODY$
|
||||||
|
BEGIN
|
||||||
|
RETURN QUERY
|
||||||
|
SELECT 2;
|
||||||
|
END;
|
||||||
|
$BODY$
|
||||||
|
LANGUAGE plpgsql VOLATILE
|
||||||
|
COST 100;
|
||||||
|
SELECT count(*) FROM
|
||||||
|
(SELECT result FROM
|
||||||
|
run_command_on_workers($$select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc) from pg_proc where proname = 'func_returning_setof_int_with_variadic_param';$$)
|
||||||
|
UNION select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc)::text from pg_proc where proname = 'func_returning_setof_int_with_variadic_param')
|
||||||
|
as test;
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- verify that recreating distributed procedures with out params gets propagated to workers
|
||||||
|
CREATE OR REPLACE PROCEDURE proc_with_variadic_param(IN parm1 date, VARIADIC parm2 int[])
|
||||||
|
LANGUAGE SQL
|
||||||
|
AS $$
|
||||||
|
SELECT 1;
|
||||||
|
$$;
|
||||||
|
-- this should error out
|
||||||
|
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[])');
|
||||||
|
create_distributed_function
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE OR REPLACE PROCEDURE proc_with_variadic_param(IN parm1 date, VARIADIC parm2 int[])
|
||||||
|
LANGUAGE SQL
|
||||||
|
AS $$
|
||||||
|
SELECT 2;
|
||||||
|
$$;
|
||||||
|
SELECT count(*) FROM
|
||||||
|
(SELECT result FROM
|
||||||
|
run_command_on_workers($$select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc) from pg_proc where proname = 'proc_with_variadic_param';$$)
|
||||||
|
UNION select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc)::text from pg_proc where proname = 'proc_with_variadic_param')
|
||||||
|
as test;
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- verify that recreating distributed procedures with INOUT param gets propagated to workers
|
||||||
|
CREATE OR REPLACE PROCEDURE proc_with_inout_param(IN parm1 date, INOUT parm2 int)
|
||||||
|
LANGUAGE SQL
|
||||||
|
AS $$
|
||||||
|
SELECT 1;
|
||||||
|
$$;
|
||||||
|
-- this should error out
|
||||||
|
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)');
|
||||||
|
create_distributed_function
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE OR REPLACE PROCEDURE proc_with_inout_param(IN parm1 date, INOUT parm2 int)
|
||||||
|
LANGUAGE SQL
|
||||||
|
AS $$
|
||||||
|
SELECT 2;
|
||||||
|
$$;
|
||||||
|
SELECT count(*) FROM
|
||||||
|
(SELECT result FROM
|
||||||
|
run_command_on_workers($$select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc) from pg_proc where proname = 'proc_with_inout_param';$$)
|
||||||
|
UNION select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc)::text from pg_proc where proname = 'proc_with_inout_param')
|
||||||
|
as test;
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
SET client_min_messages TO error; -- suppress cascading objects dropping
|
SET client_min_messages TO error; -- suppress cascading objects dropping
|
||||||
DROP SCHEMA function_tests CASCADE;
|
DROP SCHEMA function_tests CASCADE;
|
||||||
DROP SCHEMA function_tests2 CASCADE;
|
DROP SCHEMA function_tests2 CASCADE;
|
||||||
|
|
|
@ -139,6 +139,27 @@ SELECT worker_create_or_replace_object('CREATE AGGREGATE proc_conflict.existing_
|
||||||
f
|
f
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- test worker_create_or_replace_object with a function that returns table
|
||||||
|
CREATE OR REPLACE FUNCTION func_with_return_table(int)
|
||||||
|
RETURNS TABLE (date date)
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
BEGIN
|
||||||
|
RETURN query SELECT '2011-01-01'::date;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
SELECT worker_create_or_replace_object('CREATE OR REPLACE FUNCTION func_with_return_table(int) RETURNS TABLE (date date) LANGUAGE plpgsql AS $$ BEGIN RETURN query SELECT ''2011-01-01''::date; END; $$;');
|
||||||
|
worker_create_or_replace_object
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- verify that a backup function is created
|
||||||
|
SELECT COUNT(*)=2 FROM pg_proc WHERE proname LIKE 'func_with_return_table%';
|
||||||
|
?column?
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
-- hide cascades
|
-- hide cascades
|
||||||
SET client_min_messages TO error;
|
SET client_min_messages TO error;
|
||||||
DROP SCHEMA proc_conflict CASCADE;
|
DROP SCHEMA proc_conflict CASCADE;
|
||||||
|
|
|
@ -1221,5 +1221,54 @@ select * from nummultirange_test natural join nummultirange_test2 order by nmr;
|
||||||
{[1.1,2.2)}
|
{[1.1,2.2)}
|
||||||
(7 rows)
|
(7 rows)
|
||||||
|
|
||||||
|
-- verify that recreating distributed procedures with OUT param gets propagated to workers
|
||||||
|
CREATE OR REPLACE PROCEDURE proc_with_out_param(IN parm1 date, OUT parm2 int)
|
||||||
|
LANGUAGE SQL
|
||||||
|
AS $$
|
||||||
|
SELECT 1;
|
||||||
|
$$;
|
||||||
|
-- this should error out
|
||||||
|
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)');
|
||||||
|
create_distributed_function
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SET client_min_messages TO ERROR;
|
||||||
|
CREATE ROLE r1;
|
||||||
|
SELECT 1 FROM run_command_on_workers($$CREATE ROLE r1;$$);
|
||||||
|
?column?
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
1
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
GRANT EXECUTE ON PROCEDURE proc_with_out_param TO r1;
|
||||||
|
SELECT 1 FROM run_command_on_workers($$GRANT EXECUTE ON PROCEDURE proc_with_out_param TO r1;$$);
|
||||||
|
?column?
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
1
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
RESET client_min_messages;
|
||||||
|
CREATE OR REPLACE PROCEDURE proc_with_out_param(IN parm1 date, OUT parm2 int)
|
||||||
|
LANGUAGE SQL
|
||||||
|
AS $$
|
||||||
|
SELECT 2;
|
||||||
|
$$;
|
||||||
|
SELECT count(*) FROM
|
||||||
|
(SELECT result FROM
|
||||||
|
run_command_on_workers($$select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc, pg_proc.proowner) from pg_proc where proname = 'proc_with_out_param';$$)
|
||||||
|
UNION select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc, pg_proc.proowner)::text from pg_proc where proname = 'proc_with_out_param')
|
||||||
|
as test;
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
set client_min_messages to error;
|
set client_min_messages to error;
|
||||||
drop schema pg14 cascade;
|
drop schema pg14 cascade;
|
||||||
|
|
|
@ -482,6 +482,204 @@ SELECT * FROM test ORDER BY id;
|
||||||
|
|
||||||
DROP TABLE test;
|
DROP TABLE test;
|
||||||
|
|
||||||
|
-- verify that recreating distributed functions with TABLE params gets propagated to workers
|
||||||
|
CREATE OR REPLACE FUNCTION func_with_return_table(int)
|
||||||
|
RETURNS TABLE (date date)
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
BEGIN
|
||||||
|
RETURN query SELECT '2011-01-01'::date;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
SELECT create_distributed_function('func_with_return_table(int)');
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION func_with_return_table(int)
|
||||||
|
RETURNS TABLE (date date)
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
BEGIN
|
||||||
|
RETURN query SELECT '2011-01-02'::date;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
SELECT count(*) FROM
|
||||||
|
(SELECT result FROM
|
||||||
|
run_command_on_workers($$select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc) from pg_proc where proname = 'func_with_return_table';$$)
|
||||||
|
UNION select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc)::text from pg_proc where proname = 'func_with_return_table')
|
||||||
|
as test;
|
||||||
|
|
||||||
|
-- verify that recreating distributed functions with OUT params gets propagated to workers
|
||||||
|
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)');
|
||||||
|
|
||||||
|
SET client_min_messages TO ERROR;
|
||||||
|
CREATE ROLE r1;
|
||||||
|
SELECT 1 FROM run_command_on_workers($$CREATE ROLE r1;$$);
|
||||||
|
GRANT EXECUTE ON FUNCTION func_with_out_param TO r1;
|
||||||
|
SELECT 1 FROM run_command_on_workers($$GRANT EXECUTE ON FUNCTION func_with_out_param TO r1;$$);
|
||||||
|
RESET client_min_messages;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION func_with_out_param(a int, out b int)
|
||||||
|
RETURNS int
|
||||||
|
LANGUAGE sql AS $$ select 2; $$;
|
||||||
|
|
||||||
|
SELECT count(*) FROM
|
||||||
|
(SELECT result FROM
|
||||||
|
run_command_on_workers($$select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc, pg_proc.proowner) from pg_proc where proname = 'func_with_out_param';$$)
|
||||||
|
UNION select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc, pg_proc.proowner)::text from pg_proc where proname = 'func_with_out_param')
|
||||||
|
as test;
|
||||||
|
|
||||||
|
-- verify that recreating distributed functions with INOUT params gets propagated to workers
|
||||||
|
CREATE OR REPLACE FUNCTION func_with_inout_param(a int, inout b int)
|
||||||
|
RETURNS int
|
||||||
|
LANGUAGE sql AS $$ select 1; $$;
|
||||||
|
|
||||||
|
-- this should error out
|
||||||
|
SELECT create_distributed_function('func_with_inout_param(int)');
|
||||||
|
-- this should work
|
||||||
|
SELECT create_distributed_function('func_with_inout_param(int,int)');
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION func_with_inout_param(a int, inout b int)
|
||||||
|
RETURNS int
|
||||||
|
LANGUAGE sql AS $$ select 2; $$;
|
||||||
|
|
||||||
|
SELECT count(*) FROM
|
||||||
|
(SELECT result FROM
|
||||||
|
run_command_on_workers($$select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc) from pg_proc where proname = 'func_with_inout_param';$$)
|
||||||
|
UNION select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc)::text from pg_proc where proname = 'func_with_inout_param')
|
||||||
|
as test;
|
||||||
|
|
||||||
|
-- verify that recreating distributed functions with VARIADIC params gets propagated to workers
|
||||||
|
CREATE OR REPLACE FUNCTION func_with_variadic_param(a int, variadic b int[])
|
||||||
|
RETURNS int
|
||||||
|
LANGUAGE sql AS $$ select 1; $$;
|
||||||
|
|
||||||
|
-- this should work
|
||||||
|
SELECT create_distributed_function('func_with_variadic_param(int,int[])');
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION func_with_variadic_param(a int, variadic b int[])
|
||||||
|
RETURNS int
|
||||||
|
LANGUAGE sql AS $$ select 2; $$;
|
||||||
|
|
||||||
|
SELECT count(*) FROM
|
||||||
|
(SELECT result FROM
|
||||||
|
run_command_on_workers($$select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc) from pg_proc where proname = 'func_with_variadic_param';$$)
|
||||||
|
UNION select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc)::text from pg_proc where proname = 'func_with_variadic_param')
|
||||||
|
as test;
|
||||||
|
|
||||||
|
-- verify that recreating distributed functions returning setof records gets propagated to workers
|
||||||
|
CREATE OR REPLACE FUNCTION func_returning_setof_int(IN parm1 date, IN parm2 interval)
|
||||||
|
RETURNS SETOF integer AS
|
||||||
|
$BODY$
|
||||||
|
BEGIN
|
||||||
|
RETURN QUERY
|
||||||
|
SELECT 1;
|
||||||
|
END;
|
||||||
|
$BODY$
|
||||||
|
LANGUAGE plpgsql VOLATILE
|
||||||
|
COST 100;
|
||||||
|
|
||||||
|
SELECT create_distributed_function('func_returning_setof_int(date,interval)');
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION func_returning_setof_int(IN parm1 date, IN parm2 interval)
|
||||||
|
RETURNS SETOF integer AS
|
||||||
|
$BODY$
|
||||||
|
BEGIN
|
||||||
|
RETURN QUERY
|
||||||
|
SELECT 2;
|
||||||
|
|
||||||
|
END;
|
||||||
|
$BODY$
|
||||||
|
LANGUAGE plpgsql VOLATILE
|
||||||
|
COST 100;
|
||||||
|
|
||||||
|
SELECT count(*) FROM
|
||||||
|
(SELECT result FROM
|
||||||
|
run_command_on_workers($$select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc) from pg_proc where proname = 'func_returning_setof_int';$$)
|
||||||
|
UNION select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc)::text from pg_proc where proname = 'func_returning_setof_int')
|
||||||
|
as test;
|
||||||
|
|
||||||
|
-- verify that recreating distributed functions with variadic param returning setof records gets propagated to workers
|
||||||
|
CREATE OR REPLACE FUNCTION func_returning_setof_int_with_variadic_param(IN parm1 date, VARIADIC parm2 int[])
|
||||||
|
RETURNS SETOF integer AS
|
||||||
|
$BODY$
|
||||||
|
BEGIN
|
||||||
|
RETURN QUERY
|
||||||
|
SELECT 1;
|
||||||
|
END;
|
||||||
|
$BODY$
|
||||||
|
LANGUAGE plpgsql VOLATILE
|
||||||
|
COST 100;
|
||||||
|
|
||||||
|
SELECT create_distributed_function('func_returning_setof_int_with_variadic_param(date,int[])');
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION func_returning_setof_int_with_variadic_param(IN parm1 date, VARIADIC parm2 int[])
|
||||||
|
RETURNS SETOF integer AS
|
||||||
|
$BODY$
|
||||||
|
BEGIN
|
||||||
|
RETURN QUERY
|
||||||
|
SELECT 2;
|
||||||
|
END;
|
||||||
|
$BODY$
|
||||||
|
LANGUAGE plpgsql VOLATILE
|
||||||
|
COST 100;
|
||||||
|
|
||||||
|
SELECT count(*) FROM
|
||||||
|
(SELECT result FROM
|
||||||
|
run_command_on_workers($$select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc) from pg_proc where proname = 'func_returning_setof_int_with_variadic_param';$$)
|
||||||
|
UNION select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc)::text from pg_proc where proname = 'func_returning_setof_int_with_variadic_param')
|
||||||
|
as test;
|
||||||
|
|
||||||
|
-- verify that recreating distributed procedures with out params gets propagated to workers
|
||||||
|
CREATE OR REPLACE PROCEDURE proc_with_variadic_param(IN parm1 date, VARIADIC parm2 int[])
|
||||||
|
LANGUAGE SQL
|
||||||
|
AS $$
|
||||||
|
SELECT 1;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- this should error out
|
||||||
|
SELECT create_distributed_function('proc_with_variadic_param(date)');
|
||||||
|
-- this should work
|
||||||
|
SELECT create_distributed_function('proc_with_variadic_param(date,int[])');
|
||||||
|
|
||||||
|
CREATE OR REPLACE PROCEDURE proc_with_variadic_param(IN parm1 date, VARIADIC parm2 int[])
|
||||||
|
LANGUAGE SQL
|
||||||
|
AS $$
|
||||||
|
SELECT 2;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
SELECT count(*) FROM
|
||||||
|
(SELECT result FROM
|
||||||
|
run_command_on_workers($$select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc) from pg_proc where proname = 'proc_with_variadic_param';$$)
|
||||||
|
UNION select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc)::text from pg_proc where proname = 'proc_with_variadic_param')
|
||||||
|
as test;
|
||||||
|
|
||||||
|
-- verify that recreating distributed procedures with INOUT param gets propagated to workers
|
||||||
|
CREATE OR REPLACE PROCEDURE proc_with_inout_param(IN parm1 date, INOUT parm2 int)
|
||||||
|
LANGUAGE SQL
|
||||||
|
AS $$
|
||||||
|
SELECT 1;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- this should error out
|
||||||
|
SELECT create_distributed_function('proc_with_inout_param(date)');
|
||||||
|
-- this should work
|
||||||
|
SELECT create_distributed_function('proc_with_inout_param(date,int)');
|
||||||
|
|
||||||
|
CREATE OR REPLACE PROCEDURE proc_with_inout_param(IN parm1 date, INOUT parm2 int)
|
||||||
|
LANGUAGE SQL
|
||||||
|
AS $$
|
||||||
|
SELECT 2;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
SELECT count(*) FROM
|
||||||
|
(SELECT result FROM
|
||||||
|
run_command_on_workers($$select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc) from pg_proc where proname = 'proc_with_inout_param';$$)
|
||||||
|
UNION select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc)::text from pg_proc where proname = 'proc_with_inout_param')
|
||||||
|
as test;
|
||||||
|
|
||||||
SET client_min_messages TO error; -- suppress cascading objects dropping
|
SET client_min_messages TO error; -- suppress cascading objects dropping
|
||||||
DROP SCHEMA function_tests CASCADE;
|
DROP SCHEMA function_tests CASCADE;
|
||||||
DROP SCHEMA function_tests2 CASCADE;
|
DROP SCHEMA function_tests2 CASCADE;
|
||||||
|
|
|
@ -115,6 +115,20 @@ $$ LANGUAGE plpgsql STRICT IMMUTABLE;
|
||||||
SELECT worker_create_or_replace_object('CREATE AGGREGATE proc_conflict.existing_agg(integer) (STYPE = integer,SFUNC = proc_conflict.existing_func2)');
|
SELECT worker_create_or_replace_object('CREATE AGGREGATE proc_conflict.existing_agg(integer) (STYPE = integer,SFUNC = proc_conflict.existing_func2)');
|
||||||
SELECT worker_create_or_replace_object('CREATE AGGREGATE proc_conflict.existing_agg(integer) (STYPE = integer,SFUNC = proc_conflict.existing_func2)');
|
SELECT worker_create_or_replace_object('CREATE AGGREGATE proc_conflict.existing_agg(integer) (STYPE = integer,SFUNC = proc_conflict.existing_func2)');
|
||||||
|
|
||||||
|
-- test worker_create_or_replace_object with a function that returns table
|
||||||
|
CREATE OR REPLACE FUNCTION func_with_return_table(int)
|
||||||
|
RETURNS TABLE (date date)
|
||||||
|
LANGUAGE plpgsql AS $$
|
||||||
|
BEGIN
|
||||||
|
RETURN query SELECT '2011-01-01'::date;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
SELECT worker_create_or_replace_object('CREATE OR REPLACE FUNCTION func_with_return_table(int) RETURNS TABLE (date date) LANGUAGE plpgsql AS $$ BEGIN RETURN query SELECT ''2011-01-01''::date; END; $$;');
|
||||||
|
|
||||||
|
-- verify that a backup function is created
|
||||||
|
SELECT COUNT(*)=2 FROM pg_proc WHERE proname LIKE 'func_with_return_table%';
|
||||||
|
|
||||||
-- hide cascades
|
-- hide cascades
|
||||||
SET client_min_messages TO error;
|
SET client_min_messages TO error;
|
||||||
DROP SCHEMA proc_conflict CASCADE;
|
DROP SCHEMA proc_conflict CASCADE;
|
||||||
|
|
|
@ -609,5 +609,36 @@ set enable_hashjoin=f;
|
||||||
set enable_mergejoin=f;
|
set enable_mergejoin=f;
|
||||||
select * from nummultirange_test natural join nummultirange_test2 order by nmr;
|
select * from nummultirange_test natural join nummultirange_test2 order by nmr;
|
||||||
|
|
||||||
|
-- verify that recreating distributed procedures with OUT param gets propagated to workers
|
||||||
|
CREATE OR REPLACE PROCEDURE proc_with_out_param(IN parm1 date, OUT parm2 int)
|
||||||
|
LANGUAGE SQL
|
||||||
|
AS $$
|
||||||
|
SELECT 1;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
-- this should error out
|
||||||
|
SELECT create_distributed_function('proc_with_out_param(date,int)');
|
||||||
|
-- this should work
|
||||||
|
SELECT create_distributed_function('proc_with_out_param(date)');
|
||||||
|
|
||||||
|
SET client_min_messages TO ERROR;
|
||||||
|
CREATE ROLE r1;
|
||||||
|
SELECT 1 FROM run_command_on_workers($$CREATE ROLE r1;$$);
|
||||||
|
GRANT EXECUTE ON PROCEDURE proc_with_out_param TO r1;
|
||||||
|
SELECT 1 FROM run_command_on_workers($$GRANT EXECUTE ON PROCEDURE proc_with_out_param TO r1;$$);
|
||||||
|
RESET client_min_messages;
|
||||||
|
|
||||||
|
CREATE OR REPLACE PROCEDURE proc_with_out_param(IN parm1 date, OUT parm2 int)
|
||||||
|
LANGUAGE SQL
|
||||||
|
AS $$
|
||||||
|
SELECT 2;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
SELECT count(*) FROM
|
||||||
|
(SELECT result FROM
|
||||||
|
run_command_on_workers($$select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc, pg_proc.proowner) from pg_proc where proname = 'proc_with_out_param';$$)
|
||||||
|
UNION select row(pg_proc.pronargs, pg_proc.proargtypes, pg_proc.prosrc, pg_proc.proowner)::text from pg_proc where proname = 'proc_with_out_param')
|
||||||
|
as test;
|
||||||
|
|
||||||
set client_min_messages to error;
|
set client_min_messages to error;
|
||||||
drop schema pg14 cascade;
|
drop schema pg14 cascade;
|
||||||
|
|
Loading…
Reference in New Issue