Merge pull request #5827 from citusdata/velioglu/local_object_creation

Create type locally if it has undistributable dependency
pull/5810/head
Burak Velioglu 2022-03-18 18:36:51 +03:00 committed by GitHub
commit 2994b10024
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 92 additions and 25 deletions

View File

@ -57,6 +57,7 @@
#include "distributed/commands/utility_hook.h"
#include "distributed/deparser.h"
#include "distributed/listutils.h"
#include "distributed/metadata/dependency.h"
#include "distributed/metadata/distobject.h"
#include "distributed/metadata_sync.h"
#include "distributed/multi_executor.h"
@ -132,28 +133,7 @@ PreprocessCompositeTypeStmt(Node *node, const char *queryString,
/* fully qualify before lookup and later deparsing */
QualifyTreeNode(node);
/*
* 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);
return NIL;
}
@ -176,9 +156,39 @@ PostprocessCompositeTypeStmt(Node *node, const char *queryString)
* locally it can't be missing
*/
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);
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);
}

View File

@ -776,10 +776,11 @@ DeferErrorIfHasUnsupportedDependency(const ObjectAddress *objectAddress)
#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.
*/
if (getObjectClass(objectAddress) == OCLASS_PROC)
if (getObjectClass(objectAddress) == OCLASS_PROC ||
getObjectClass(objectAddress) == OCLASS_TYPE)
{
appendStringInfo(detailInfo, "\"%s\" will be created only locally",
objectDescription);

View File

@ -566,6 +566,37 @@ CREATE TYPE circ_type1 AS (a int);
CREATE TYPE circ_type2 AS (a int, b circ_type1);
ALTER TYPE circ_type1 ADD ATTRIBUTE b circ_type2;
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
SET client_min_messages TO error; -- suppress cascading objects dropping
DROP SCHEMA type_tests CASCADE;

View File

@ -334,6 +334,31 @@ CREATE TYPE circ_type1 AS (a int);
CREATE TYPE circ_type2 AS (a int, b circ_type1);
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
SET client_min_messages TO error; -- suppress cascading objects dropping
DROP SCHEMA type_tests CASCADE;