mirror of https://github.com/citusdata/citus.git
Add unsupported objects check
parent
236d1cd1ef
commit
b8e530862e
|
@ -82,8 +82,7 @@ static void EnsureFunctionCanBeColocatedWithTable(Oid functionOid, Oid
|
||||||
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 bool ShouldAddFunctionSignature(FunctionParameterMode mode);
|
||||||
static ObjectAddress * GetUndistributableRelationDependency(
|
static ObjectAddress * GetUndistributableDependency(ObjectAddress *functionAddress);
|
||||||
ObjectAddress *functionAddress);
|
|
||||||
static ObjectAddress FunctionToObjectAddress(ObjectType objectType,
|
static ObjectAddress FunctionToObjectAddress(ObjectType objectType,
|
||||||
ObjectWithArgs *objectWithArgs,
|
ObjectWithArgs *objectWithArgs,
|
||||||
bool missing_ok);
|
bool missing_ok);
|
||||||
|
@ -1295,19 +1294,20 @@ PostprocessCreateFunctionStmt(Node *node, const char *queryString)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This check should have been
|
* This check should have been valid for all objects not only for functions. Though,
|
||||||
* (a) valid for all objects not only for functions
|
* we do this limited check for now as functions are more likely to be used with
|
||||||
* (b) should check for all types of objects no only for relations.
|
* such dependencies, and we want to scope it for now
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*/
|
*/
|
||||||
ObjectAddress *undistributableDependency = GetUndistributableRelationDependency(
|
ObjectAddress *undistributableDependency = GetUndistributableDependency(
|
||||||
&functionAddress);
|
&functionAddress);
|
||||||
if (undistributableDependency != NULL)
|
if (undistributableDependency != NULL)
|
||||||
{
|
{
|
||||||
if (SupportedDependencyByCitus(undistributableDependency))
|
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);
|
RangeVar *functionRangeVar = makeRangeVarFromNameList(stmt->funcname);
|
||||||
char *functionName = functionRangeVar->relname;
|
char *functionName = functionRangeVar->relname;
|
||||||
char *dependentRelationName =
|
char *dependentRelationName =
|
||||||
|
@ -1322,10 +1322,15 @@ PostprocessCreateFunctionStmt(Node *node, const char *queryString)
|
||||||
}
|
}
|
||||||
else
|
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 "
|
ereport(WARNING, (errmsg("Citus can't distribute functions having "
|
||||||
"dependency on unsupported relation with relkind %c",
|
"dependency on unsupported object of type \"%s\"",
|
||||||
get_rel_relkind(
|
objectType),
|
||||||
undistributableDependency->objectId)),
|
|
||||||
errdetail("Function will be created only locally")));
|
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
|
* GetUndistributableDependency checks whether object has any non-distributable
|
||||||
* relation dependency. If any one found, it will be returned.
|
* dependency. If any one found, it will be returned.
|
||||||
*/
|
*/
|
||||||
static ObjectAddress *
|
static ObjectAddress *
|
||||||
GetUndistributableRelationDependency(ObjectAddress *objectAddress)
|
GetUndistributableDependency(ObjectAddress *objectAddress)
|
||||||
{
|
{
|
||||||
List *dependencies = GetAllDependenciesForObject(objectAddress);
|
List *dependencies = GetAllDependenciesForObject(objectAddress);
|
||||||
ObjectAddress *dependency = NULL;
|
ObjectAddress *dependency = NULL;
|
||||||
|
@ -1359,22 +1364,32 @@ GetUndistributableRelationDependency(ObjectAddress *objectAddress)
|
||||||
continue;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
if (getObjectClass(dependency) == OCLASS_CLASS)
|
||||||
* 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)
|
|
||||||
{
|
{
|
||||||
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;
|
return NULL;
|
||||||
|
|
|
@ -358,14 +358,16 @@ PL/pgSQL function func_calls_forcepush_func() line XX at SQL statement
|
||||||
101
|
101
|
||||||
(1 row)
|
(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()
|
CREATE OR REPLACE FUNCTION get_val()
|
||||||
RETURNS INT AS $$
|
RETURNS INT AS $$
|
||||||
BEGIN
|
BEGIN
|
||||||
RETURN 100::INT;
|
RETURN 100::INT;
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
DEBUG: switching to sequential query execution mode
|
RESET citus.enable_metadata_sync;
|
||||||
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
|
|
||||||
--
|
--
|
||||||
-- UDF calling another UDF in a FROM clause
|
-- UDF calling another UDF in a FROM clause
|
||||||
-- fn()
|
-- 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
|
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();
|
SELECT func_calls_forcepush_func_infrom();
|
||||||
DEBUG: function does not have co-located tables
|
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
|
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)"
|
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
|
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
|
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();
|
SELECT func_calls_forcepush_func_intarget();
|
||||||
DEBUG: function does not have co-located tables
|
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
|
DEBUG: pushing down function call in a multi-statement transaction
|
||||||
CONTEXT: SQL statement "SELECT inner_force_delegation_function(100 + 100) OFFSET 0"
|
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
|
PL/pgSQL function func_calls_forcepush_func_intarget() line XX at SQL statement
|
||||||
|
|
|
@ -186,7 +186,7 @@ BEGIN
|
||||||
return 1;
|
return 1;
|
||||||
END;
|
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
|
DETAIL: Function will be created only locally
|
||||||
CREATE OR REPLACE FUNCTION func_8(param_1 int)
|
CREATE OR REPLACE FUNCTION func_8(param_1 int)
|
||||||
RETURNS function_prop_view
|
RETURNS function_prop_view
|
||||||
|
@ -196,7 +196,7 @@ BEGIN
|
||||||
return 1;
|
return 1;
|
||||||
END;
|
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
|
DETAIL: Function will be created only locally
|
||||||
-- Check within transaction
|
-- Check within transaction
|
||||||
BEGIN;
|
BEGIN;
|
||||||
|
|
|
@ -77,7 +77,7 @@ END
|
||||||
$func$ LANGUAGE plpgsql;
|
$func$ LANGUAGE plpgsql;
|
||||||
CREATE SCHEMA test;
|
CREATE SCHEMA test;
|
||||||
:create_function_test_maintenance_worker
|
: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
|
DETAIL: Function will be created only locally
|
||||||
-- check maintenance daemon is started
|
-- check maintenance daemon is started
|
||||||
SELECT datname, current_database(),
|
SELECT datname, current_database(),
|
||||||
|
@ -1200,7 +1200,7 @@ HINT: You can manually create a database and its extensions on workers.
|
||||||
CREATE EXTENSION citus;
|
CREATE EXTENSION citus;
|
||||||
CREATE SCHEMA test;
|
CREATE SCHEMA test;
|
||||||
:create_function_test_maintenance_worker
|
: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
|
DETAIL: Function will be created only locally
|
||||||
-- see that the daemon started
|
-- see that the daemon started
|
||||||
SELECT datname, current_database(),
|
SELECT datname, current_database(),
|
||||||
|
|
|
@ -145,9 +145,13 @@ CREATE TYPE myvarchar;
|
||||||
CREATE FUNCTION myvarcharin(cstring, oid, integer) RETURNS myvarchar
|
CREATE FUNCTION myvarcharin(cstring, oid, integer) RETURNS myvarchar
|
||||||
LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'varcharin';
|
LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'varcharin';
|
||||||
NOTICE: return type myvarchar is only a shell
|
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
|
CREATE FUNCTION myvarcharout(myvarchar) RETURNS cstring
|
||||||
LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'varcharout';
|
LANGUAGE internal IMMUTABLE PARALLEL SAFE STRICT AS 'varcharout';
|
||||||
NOTICE: argument type myvarchar is only a shell
|
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 (
|
CREATE TYPE myvarchar (
|
||||||
input = myvarcharin,
|
input = myvarcharin,
|
||||||
output = myvarcharout,
|
output = myvarcharout,
|
||||||
|
@ -160,7 +164,7 @@ CREATE TABLE my_table (a int, b myvarchar);
|
||||||
-- """Add ALTER TYPE options useful for extensions,
|
-- """Add ALTER TYPE options useful for extensions,
|
||||||
-- like TOAST and I/O functions control (Tomas Vondra, Tom Lane)"""
|
-- like TOAST and I/O functions control (Tomas Vondra, Tom Lane)"""
|
||||||
SELECT create_distributed_table('my_table', 'a');
|
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
|
CONTEXT: while executing command on localhost:xxxxx
|
||||||
CREATE TABLE test_table(a int, b tsvector);
|
CREATE TABLE test_table(a int, b tsvector);
|
||||||
SELECT create_distributed_table('test_table', 'a');
|
SELECT create_distributed_table('test_table', 'a');
|
||||||
|
|
|
@ -189,12 +189,16 @@ COMMIT;
|
||||||
|
|
||||||
SELECT func_calls_forcepush_func();
|
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()
|
CREATE OR REPLACE FUNCTION get_val()
|
||||||
RETURNS INT AS $$
|
RETURNS INT AS $$
|
||||||
BEGIN
|
BEGIN
|
||||||
RETURN 100::INT;
|
RETURN 100::INT;
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
RESET citus.enable_metadata_sync;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- UDF calling another UDF in a FROM clause
|
-- UDF calling another UDF in a FROM clause
|
||||||
|
|
Loading…
Reference in New Issue