mirror of https://github.com/citusdata/citus.git
Create type locally if it has undistributable dependency
parent
0944c631f1
commit
2c2064bf36
|
@ -57,6 +57,7 @@
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "distributed/commands/utility_hook.h"
|
||||||
#include "distributed/deparser.h"
|
#include "distributed/deparser.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
|
#include "distributed/metadata/dependency.h"
|
||||||
#include "distributed/metadata/distobject.h"
|
#include "distributed/metadata/distobject.h"
|
||||||
#include "distributed/metadata_sync.h"
|
#include "distributed/metadata_sync.h"
|
||||||
#include "distributed/multi_executor.h"
|
#include "distributed/multi_executor.h"
|
||||||
|
@ -132,28 +133,7 @@ PreprocessCompositeTypeStmt(Node *node, const char *queryString,
|
||||||
/* fully qualify before lookup and later deparsing */
|
/* fully qualify before lookup and later deparsing */
|
||||||
QualifyTreeNode(node);
|
QualifyTreeNode(node);
|
||||||
|
|
||||||
/*
|
return NIL;
|
||||||
* reconstruct creation statement in a portable fashion. The create_or_replace helper
|
|
||||||
* function will be used to create the type in an idempotent manner on the workers.
|
|
||||||
*
|
|
||||||
* Types could exist on the worker prior to being created on the coordinator when the
|
|
||||||
* type previously has been attempted to be created in a transaction which did not
|
|
||||||
* commit on the coordinator.
|
|
||||||
*/
|
|
||||||
const char *compositeTypeStmtSql = DeparseCompositeTypeStmt(node);
|
|
||||||
compositeTypeStmtSql = WrapCreateOrReplace(compositeTypeStmtSql);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* when we allow propagation within a transaction block we should make sure to only
|
|
||||||
* allow this in sequential mode
|
|
||||||
*/
|
|
||||||
EnsureSequentialMode(OBJECT_TYPE);
|
|
||||||
|
|
||||||
List *commands = list_make3(DISABLE_DDL_PROPAGATION,
|
|
||||||
(void *) compositeTypeStmtSql,
|
|
||||||
ENABLE_DDL_PROPAGATION);
|
|
||||||
|
|
||||||
return NodeDDLTaskList(NON_COORDINATOR_NODES, commands);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -176,9 +156,39 @@ PostprocessCompositeTypeStmt(Node *node, const char *queryString)
|
||||||
* locally it can't be missing
|
* locally it can't be missing
|
||||||
*/
|
*/
|
||||||
ObjectAddress typeAddress = GetObjectAddressFromParseTree(node, false);
|
ObjectAddress typeAddress = GetObjectAddressFromParseTree(node, false);
|
||||||
|
|
||||||
|
/* If the type has any unsupported dependency, create it locally */
|
||||||
|
DeferredErrorMessage *errMsg = DeferErrorIfHasUnsupportedDependency(&typeAddress);
|
||||||
|
if (errMsg != NULL)
|
||||||
|
{
|
||||||
|
RaiseDeferredError(errMsg, WARNING);
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* when we allow propagation within a transaction block we should make sure to only
|
||||||
|
* allow this in sequential mode
|
||||||
|
*/
|
||||||
|
EnsureSequentialMode(OBJECT_TYPE);
|
||||||
|
|
||||||
EnsureDependenciesExistOnAllNodes(&typeAddress);
|
EnsureDependenciesExistOnAllNodes(&typeAddress);
|
||||||
|
|
||||||
return NIL;
|
/*
|
||||||
|
* reconstruct creation statement in a portable fashion. The create_or_replace helper
|
||||||
|
* function will be used to create the type in an idempotent manner on the workers.
|
||||||
|
*
|
||||||
|
* Types could exist on the worker prior to being created on the coordinator when the
|
||||||
|
* type previously has been attempted to be created in a transaction which did not
|
||||||
|
* commit on the coordinator.
|
||||||
|
*/
|
||||||
|
const char *compositeTypeStmtSql = DeparseCompositeTypeStmt(node);
|
||||||
|
compositeTypeStmtSql = WrapCreateOrReplace(compositeTypeStmtSql);
|
||||||
|
|
||||||
|
List *commands = list_make3(DISABLE_DDL_PROPAGATION,
|
||||||
|
(void *) compositeTypeStmtSql,
|
||||||
|
ENABLE_DDL_PROPAGATION);
|
||||||
|
|
||||||
|
return NodeDDLTaskList(NON_COORDINATOR_NODES, commands);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -776,10 +776,11 @@ DeferErrorIfHasUnsupportedDependency(const ObjectAddress *objectAddress)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the given object is a procedure, we want to create it locally,
|
* If the given object is a procedure or type, we want to create it locally,
|
||||||
* so provide that information in the error detail.
|
* so provide that information in the error detail.
|
||||||
*/
|
*/
|
||||||
if (getObjectClass(objectAddress) == OCLASS_PROC)
|
if (getObjectClass(objectAddress) == OCLASS_PROC ||
|
||||||
|
getObjectClass(objectAddress) == OCLASS_TYPE)
|
||||||
{
|
{
|
||||||
appendStringInfo(detailInfo, "\"%s\" will be created only locally",
|
appendStringInfo(detailInfo, "\"%s\" will be created only locally",
|
||||||
objectDescription);
|
objectDescription);
|
||||||
|
|
|
@ -566,6 +566,37 @@ CREATE TYPE circ_type1 AS (a int);
|
||||||
CREATE TYPE circ_type2 AS (a int, b circ_type1);
|
CREATE TYPE circ_type2 AS (a int, b circ_type1);
|
||||||
ALTER TYPE circ_type1 ADD ATTRIBUTE b circ_type2;
|
ALTER TYPE circ_type1 ADD ATTRIBUTE b circ_type2;
|
||||||
ERROR: composite type circ_type1 cannot be made a member of itself
|
ERROR: composite type circ_type1 cannot be made a member of itself
|
||||||
|
-- Show that types can be created locally if has unsupported dependency
|
||||||
|
CREATE TYPE text_local_def;
|
||||||
|
CREATE FUNCTION text_local_def_in(cstring)
|
||||||
|
RETURNS text_local_def
|
||||||
|
AS 'textin'
|
||||||
|
LANGUAGE internal STRICT IMMUTABLE;
|
||||||
|
NOTICE: return type text_local_def is only a shell
|
||||||
|
WARNING: "function text_local_def_in(cstring)" has dependency on unsupported object "type text_local_def"
|
||||||
|
DETAIL: "function text_local_def_in(cstring)" will be created only locally
|
||||||
|
CREATE FUNCTION text_local_def_out(text_local_def)
|
||||||
|
RETURNS cstring
|
||||||
|
AS 'textout'
|
||||||
|
LANGUAGE internal STRICT IMMUTABLE;
|
||||||
|
NOTICE: argument type text_local_def is only a shell
|
||||||
|
WARNING: "function text_local_def_out(text_local_def)" has dependency on unsupported object "type text_local_def"
|
||||||
|
DETAIL: "function text_local_def_out(text_local_def)" will be created only locally
|
||||||
|
CREATE TYPE text_local_def (
|
||||||
|
internallength = variable,
|
||||||
|
input = text_local_def_in,
|
||||||
|
output = text_local_def_out,
|
||||||
|
alignment = int4,
|
||||||
|
default = 'zippo'
|
||||||
|
);
|
||||||
|
-- It should be created locally as it has unsupported dependency
|
||||||
|
CREATE TYPE default_test_row AS (f1 text_local_def, f2 int4);
|
||||||
|
WARNING: "type default_test_row" has dependency on unsupported object "type text_local_def"
|
||||||
|
DETAIL: "type default_test_row" will be created only locally
|
||||||
|
-- Distributing table depending on that type should error out
|
||||||
|
CREATE TABLE table_text_local_def(id int, col_1 default_test_row);
|
||||||
|
SELECT create_distributed_table('table_text_local_def','id');
|
||||||
|
ERROR: "table table_text_local_def" has dependency on unsupported object "type text_local_def"
|
||||||
-- clear objects
|
-- clear objects
|
||||||
SET client_min_messages TO error; -- suppress cascading objects dropping
|
SET client_min_messages TO error; -- suppress cascading objects dropping
|
||||||
DROP SCHEMA type_tests CASCADE;
|
DROP SCHEMA type_tests CASCADE;
|
||||||
|
|
|
@ -334,6 +334,31 @@ CREATE TYPE circ_type1 AS (a int);
|
||||||
CREATE TYPE circ_type2 AS (a int, b circ_type1);
|
CREATE TYPE circ_type2 AS (a int, b circ_type1);
|
||||||
ALTER TYPE circ_type1 ADD ATTRIBUTE b circ_type2;
|
ALTER TYPE circ_type1 ADD ATTRIBUTE b circ_type2;
|
||||||
|
|
||||||
|
-- Show that types can be created locally if has unsupported dependency
|
||||||
|
CREATE TYPE text_local_def;
|
||||||
|
CREATE FUNCTION text_local_def_in(cstring)
|
||||||
|
RETURNS text_local_def
|
||||||
|
AS 'textin'
|
||||||
|
LANGUAGE internal STRICT IMMUTABLE;
|
||||||
|
CREATE FUNCTION text_local_def_out(text_local_def)
|
||||||
|
RETURNS cstring
|
||||||
|
AS 'textout'
|
||||||
|
LANGUAGE internal STRICT IMMUTABLE;
|
||||||
|
CREATE TYPE text_local_def (
|
||||||
|
internallength = variable,
|
||||||
|
input = text_local_def_in,
|
||||||
|
output = text_local_def_out,
|
||||||
|
alignment = int4,
|
||||||
|
default = 'zippo'
|
||||||
|
);
|
||||||
|
|
||||||
|
-- It should be created locally as it has unsupported dependency
|
||||||
|
CREATE TYPE default_test_row AS (f1 text_local_def, f2 int4);
|
||||||
|
|
||||||
|
-- Distributing table depending on that type should error out
|
||||||
|
CREATE TABLE table_text_local_def(id int, col_1 default_test_row);
|
||||||
|
SELECT create_distributed_table('table_text_local_def','id');
|
||||||
|
|
||||||
-- clear objects
|
-- clear objects
|
||||||
SET client_min_messages TO error; -- suppress cascading objects dropping
|
SET client_min_messages TO error; -- suppress cascading objects dropping
|
||||||
DROP SCHEMA type_tests CASCADE;
|
DROP SCHEMA type_tests CASCADE;
|
||||||
|
|
Loading…
Reference in New Issue