Add unsupported objects check

velioglu/tmpfuncprop
Burak Velioglu 2022-02-18 00:10:48 +03:00
parent 236d1cd1ef
commit b8e530862e
No known key found for this signature in database
GPG Key ID: F6827E620F6549C6
6 changed files with 58 additions and 39 deletions

View File

@ -82,8 +82,7 @@ static void EnsureFunctionCanBeColocatedWithTable(Oid functionOid, Oid
static bool ShouldPropagateCreateFunction(CreateFunctionStmt *stmt);
static bool ShouldPropagateAlterFunction(const ObjectAddress *address);
static bool ShouldAddFunctionSignature(FunctionParameterMode mode);
static ObjectAddress * GetUndistributableRelationDependency(
ObjectAddress *functionAddress);
static ObjectAddress * GetUndistributableDependency(ObjectAddress *functionAddress);
static ObjectAddress FunctionToObjectAddress(ObjectType objectType,
ObjectWithArgs *objectWithArgs,
bool missing_ok);
@ -1295,19 +1294,20 @@ PostprocessCreateFunctionStmt(Node *node, const char *queryString)
}
/*
* This check should have been
* (a) valid for all objects not only for functions
* (b) should check for all types of objects no only for relations.
*
* We do this limited check for now as functions are more likely to be used with
* (a) and (b), and we want to scope it for now
* This check should have been valid for all objects not only for functions. Though,
* we do this limited check for now as functions are more likely to be used with
* such dependencies, and we want to scope it for now
*/
ObjectAddress *undistributableDependency = GetUndistributableRelationDependency(
ObjectAddress *undistributableDependency = GetUndistributableDependency(
&functionAddress);
if (undistributableDependency != NULL)
{
if (SupportedDependencyByCitus(undistributableDependency))
{
/*
* Citus can't distribute some relations as dependency, although those
* types as supported by Citus. So we can use get_rel_name directly
*/
RangeVar *functionRangeVar = makeRangeVarFromNameList(stmt->funcname);
char *functionName = functionRangeVar->relname;
char *dependentRelationName =
@ -1322,10 +1322,15 @@ PostprocessCreateFunctionStmt(Node *node, const char *queryString)
}
else
{
char *objectType = NULL;
#if PG_VERSION_NUM >= PG_VERSION_14
objectType = getObjectTypeDescription(undistributableDependency, false);
#else
objectType = getObjectTypeDescription(undistributableDependency);
#endif
ereport(WARNING, (errmsg("Citus can't distribute functions having "
"dependency on unsupported relation with relkind %c",
get_rel_relkind(
undistributableDependency->objectId)),
"dependency on unsupported object of type \"%s\"",
objectType),
errdetail("Function will be created only locally")));
}
@ -1344,11 +1349,11 @@ PostprocessCreateFunctionStmt(Node *node, const char *queryString)
/*
* GetUndistributableRelationDependency checks whether object has any non-distributable
* relation dependency. If any one found, it will be returned.
* GetUndistributableDependency checks whether object has any non-distributable
* dependency. If any one found, it will be returned.
*/
static ObjectAddress *
GetUndistributableRelationDependency(ObjectAddress *objectAddress)
GetUndistributableDependency(ObjectAddress *objectAddress)
{
List *dependencies = GetAllDependenciesForObject(objectAddress);
ObjectAddress *dependency = NULL;
@ -1359,22 +1364,32 @@ GetUndistributableRelationDependency(ObjectAddress *objectAddress)
continue;
}
if (getObjectClass(dependency) != OCLASS_CLASS)
if (!SupportedDependencyByCitus(dependency))
{
continue;
/*
* Although languages are not supported by Citus, all must be created
* with the postgres itself, so skip them. Since roles should also be
* handled manually with Citus community, skip them as well.
*/
if (getObjectClass(dependency) != OCLASS_LANGUAGE &&
getObjectClass(dependency) != OCLASS_ROLE)
{
return dependency;
}
}
/*
* Citus can only distribute dependent non-distributed sequence and composite
* types.
*/
char relKind = get_rel_relkind(dependency->objectId);
if (relKind == RELKIND_SEQUENCE || relKind == RELKIND_COMPOSITE_TYPE)
if (getObjectClass(dependency) == OCLASS_CLASS)
{
continue;
/*
* Citus can only distribute dependent non-distributed sequence
* and composite types.
*/
char relKind = get_rel_relkind(dependency->objectId);
if (relKind != RELKIND_SEQUENCE && relKind != RELKIND_COMPOSITE_TYPE)
{
return dependency;
}
}
return dependency;
}
return NULL;

View File

@ -358,14 +358,16 @@ PL/pgSQL function func_calls_forcepush_func() line XX at SQL statement
101
(1 row)
-- Block distributing that function as distributing it causes
-- different test output on PG 14.
SET citus.enable_metadata_sync TO OFF;
CREATE OR REPLACE FUNCTION get_val()
RETURNS INT AS $$
BEGIN
RETURN 100::INT;
END;
$$ 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
RESET citus.enable_metadata_sync;
--
-- UDF calling another UDF in a FROM clause
-- fn()
@ -387,9 +389,6 @@ 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 func_calls_forcepush_func_infrom();
DEBUG: function does not have co-located tables
DEBUG: not pushing down function calls in a multi-statement transaction
CONTEXT: SQL statement "SELECT get_val()"
PL/pgSQL function func_calls_forcepush_func_infrom() line XX at assignment
DEBUG: pushing down function call in a multi-statement transaction
CONTEXT: SQL statement "SELECT inner_force_delegation_function FROM inner_force_delegation_function(add_val + 100)"
PL/pgSQL function func_calls_forcepush_func_infrom() line XX at SQL statement
@ -445,9 +444,6 @@ 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 func_calls_forcepush_func_intarget();
DEBUG: function does not have co-located tables
DEBUG: not pushing down function calls in a multi-statement transaction
CONTEXT: SQL statement "SELECT get_val()"
PL/pgSQL function func_calls_forcepush_func_intarget() line XX at assignment
DEBUG: pushing down function call in a multi-statement transaction
CONTEXT: SQL statement "SELECT inner_force_delegation_function(100 + 100) OFFSET 0"
PL/pgSQL function func_calls_forcepush_func_intarget() line XX at SQL statement

View File

@ -186,7 +186,7 @@ BEGIN
return 1;
END;
$$;
WARNING: Citus can't distribute functions having dependency on unsupported relation with relkind v
WARNING: Citus can't distribute functions having dependency on unsupported object of type "view"
DETAIL: Function will be created only locally
CREATE OR REPLACE FUNCTION func_8(param_1 int)
RETURNS function_prop_view
@ -196,7 +196,7 @@ BEGIN
return 1;
END;
$$;
WARNING: Citus can't distribute functions having dependency on unsupported relation with relkind v
WARNING: Citus can't distribute functions having dependency on unsupported object of type "view"
DETAIL: Function will be created only locally
-- Check within transaction
BEGIN;

View File

@ -77,7 +77,7 @@ END
$func$ LANGUAGE plpgsql;
CREATE SCHEMA test;
:create_function_test_maintenance_worker
WARNING: Citus can't distribute functions having dependency on unsupported relation with relkind v
WARNING: Citus can't distribute functions having dependency on unsupported object of type "view"
DETAIL: Function will be created only locally
-- check maintenance daemon is started
SELECT datname, current_database(),
@ -1200,7 +1200,7 @@ HINT: You can manually create a database and its extensions on workers.
CREATE EXTENSION citus;
CREATE SCHEMA test;
:create_function_test_maintenance_worker
WARNING: Citus can't distribute functions having dependency on unsupported relation with relkind v
WARNING: Citus can't distribute functions having dependency on unsupported object of type "view"
DETAIL: Function will be created only locally
-- see that the daemon started
SELECT datname, current_database(),

View File

@ -145,9 +145,13 @@ CREATE TYPE myvarchar;
CREATE FUNCTION myvarcharin(cstring, oid, integer) RETURNS myvarchar
LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'varcharin';
NOTICE: return type myvarchar is only a shell
WARNING: Citus can't distribute functions having dependency on unsupported object of type "type"
DETAIL: Function will be created only locally
CREATE FUNCTION myvarcharout(myvarchar) RETURNS cstring
LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'varcharout';
NOTICE: argument type myvarchar is only a shell
WARNING: Citus can't distribute functions having dependency on unsupported object of type "type"
DETAIL: Function will be created only locally
CREATE TYPE myvarchar (
input = myvarcharin,
output = myvarcharout,
@ -160,7 +164,7 @@ CREATE TABLE my_table (a int, b myvarchar);
-- """Add ALTER TYPE options useful for extensions,
-- like TOAST and I/O functions control (Tomas Vondra, Tom Lane)"""
SELECT create_distributed_table('my_table', 'a');
ERROR: type "test_pg13.myvarchar" is only a shell
ERROR: type "test_pg13.myvarchar" does not exist
CONTEXT: while executing command on localhost:xxxxx
CREATE TABLE test_table(a int, b tsvector);
SELECT create_distributed_table('test_table', 'a');

View File

@ -189,12 +189,16 @@ COMMIT;
SELECT func_calls_forcepush_func();
-- Block distributing that function as distributing it causes
-- different test output on PG 14.
SET citus.enable_metadata_sync TO OFF;
CREATE OR REPLACE FUNCTION get_val()
RETURNS INT AS $$
BEGIN
RETURN 100::INT;
END;
$$ LANGUAGE plpgsql;
RESET citus.enable_metadata_sync;
--
-- UDF calling another UDF in a FROM clause