support 2 level of objecttypes

refactor/dist-ops-linker
Nils Dijk 2020-02-07 16:03:26 +01:00
parent a52ef4ea35
commit b5f3ed6523
No known key found for this signature in database
GPG Key ID: CA1177EF9434F241
6 changed files with 78 additions and 102 deletions

View File

@ -15,6 +15,10 @@
#include "distributed/commands.h" #include "distributed/commands.h"
#include "distributed/deparser.h" #include "distributed/deparser.h"
static bool MatchOnAllNestedObjectTypes(Node *node,
DistributedObjectOpsContainerNestedInfo *
nestedInfo);
static DistributeObjectOps NoDistributeOps = { static DistributeObjectOps NoDistributeOps = {
.deparse = NULL, .deparse = NULL,
.qualify = NULL, .qualify = NULL,
@ -23,17 +27,6 @@ static DistributeObjectOps NoDistributeOps = {
.address = NULL, .address = NULL,
}; };
/* TODO this is a 2 level nested statement which we do not currently support */
static DistributeObjectOps Attribute_Rename = {
.deparse = DeparseRenameAttributeStmt,
.qualify = QualifyRenameAttributeStmt,
.preprocess = PreprocessRenameAttributeStmt,
.postprocess = NULL,
.address = RenameAttributeStmtObjectAddress,
};
REGISTER_DISTRIBUTED_OPERATION_NESTED(RenameStmt, renameType, OBJECT_ATTRIBUTE,
Attribute_Rename);
/* linker provided pointers */ /* linker provided pointers */
SECTION_ARRAY(DistributedObjectOpsContainer *, opscontainer); SECTION_ARRAY(DistributedObjectOpsContainer *, opscontainer);
@ -50,20 +43,9 @@ GetDistributeObjectOps(Node *node)
for (i = 0; i < sz; i++) for (i = 0; i < sz; i++)
{ {
DistributedObjectOpsContainer *container = opscontainer_array[i]; DistributedObjectOpsContainer *container = opscontainer_array[i];
if (node->type == container->type) if (node->type == container->type &&
MatchOnAllNestedObjectTypes(node, container->nestedInfo))
{ {
if (container->nested)
{
/* nested types are not perse a match */
ObjectType nestedType = *((ObjectType *) (((char *) node) +
container->nestedOffset));
if (container->nestedType != nestedType)
{
/* nested types do not match, skip this entry */
continue;
}
}
/* this DistributedObjectOps is a match for the current statement */ /* this DistributedObjectOps is a match for the current statement */
return container->ops; return container->ops;
} }
@ -72,3 +54,31 @@ GetDistributeObjectOps(Node *node)
/* no DistributedObjectOps linked for this statement type */ /* no DistributedObjectOps linked for this statement type */
return &NoDistributeOps; return &NoDistributeOps;
} }
static bool
MatchOnAllNestedObjectTypes(Node *node,
DistributedObjectOpsContainerNestedInfo *nestedInfo)
{
if (nestedInfo == NULL)
{
/* No nested information, matching by convention */
return true;
}
/*
* Iterate till you find the last entry { 0 }. For convenience it is the only one with
* offset 0
*/
for (; nestedInfo->offset != 0; ++nestedInfo)
{
ObjectType nestedType = *((ObjectType *) (((char *) node) + nestedInfo->offset));
if (nestedInfo->type != nestedType)
{
/* nested object type is not matching*/
return false;
}
}
return true;
}

View File

@ -154,30 +154,3 @@ ErrorIfUnsupportedRenameStmt(RenameStmt *renameStmt)
"currently unsupported"))); "currently unsupported")));
} }
} }
/*
* PreprocessRenameAttributeStmt called for RenameStmt's that are targetting an attribute eg.
* type attributes. Based on the relation type the attribute gets renamed it dispatches to
* a specialized implementation if present, otherwise return an empty list for its DDLJobs
*/
List *
PreprocessRenameAttributeStmt(Node *node, const char *queryString)
{
RenameStmt *stmt = castNode(RenameStmt, node);
Assert(stmt->renameType == OBJECT_ATTRIBUTE);
switch (stmt->relationType)
{
case OBJECT_TYPE:
{
return PreprocessRenameTypeAttributeStmt(node, queryString);
}
default:
{
/* unsupported relation for attribute rename, do nothing */
return NIL;
}
}
}

View File

@ -158,6 +158,18 @@ static DistributeObjectOps Type_Rename = {
}; };
REGISTER_DISTRIBUTED_OPERATION_NESTED(RenameStmt, renameType, OBJECT_TYPE, Type_Rename); REGISTER_DISTRIBUTED_OPERATION_NESTED(RenameStmt, renameType, OBJECT_TYPE, Type_Rename);
static List * PreprocessRenameTypeAttributeStmt(Node *node, const char *queryString);
static ObjectAddress RenameTypeAttributeStmtObjectAddress(Node *node, bool missing_ok);
static DistributeObjectOps Type_Rename_Attribute = {
.deparse = DeparseRenameAttributeStmt,
.qualify = QualifyRenameAttributeStmt,
.preprocess = PreprocessRenameTypeAttributeStmt,
.postprocess = NULL,
.address = RenameTypeAttributeStmtObjectAddress,
};
REGISTER_DISTRIBUTED_OPERATION_NESTED2(RenameStmt, renameType, OBJECT_ATTRIBUTE,
relationType, OBJECT_TYPE, Type_Rename_Attribute);
static List * PreprocessCompositeTypeStmt(Node *node, const char *queryString); static List * PreprocessCompositeTypeStmt(Node *node, const char *queryString);
static List * PostprocessCompositeTypeStmt(Node *node, const char *queryString); static List * PostprocessCompositeTypeStmt(Node *node, const char *queryString);
static ObjectAddress CompositeTypeStmtObjectAddress(Node *node, bool missing_ok); static ObjectAddress CompositeTypeStmtObjectAddress(Node *node, bool missing_ok);
@ -638,7 +650,7 @@ PreprocessRenameTypeStmt(Node *node, const char *queryString)
* For distributed types we apply the attribute renames directly on all the workers to * For distributed types we apply the attribute renames directly on all the workers to
* keep the type in sync across the cluster. * keep the type in sync across the cluster.
*/ */
List * static List *
PreprocessRenameTypeAttributeStmt(Node *node, const char *queryString) PreprocessRenameTypeAttributeStmt(Node *node, const char *queryString)
{ {
RenameStmt *stmt = castNode(RenameStmt, node); RenameStmt *stmt = castNode(RenameStmt, node);
@ -1075,7 +1087,7 @@ AlterTypeSchemaStmtObjectAddress(Node *node, bool missing_ok)
* changed as Attributes are not distributed on their own but as a side effect of the * changed as Attributes are not distributed on their own but as a side effect of the
* whole type distribution. * whole type distribution.
*/ */
ObjectAddress static ObjectAddress
RenameTypeAttributeStmtObjectAddress(Node *node, bool missing_ok) RenameTypeAttributeStmtObjectAddress(Node *node, bool missing_ok)
{ {
RenameStmt *stmt = castNode(RenameStmt, node); RenameStmt *stmt = castNode(RenameStmt, node);

View File

@ -37,28 +37,6 @@ GetObjectAddressFromParseTree(Node *parseTree, bool missing_ok)
} }
ObjectAddress
RenameAttributeStmtObjectAddress(Node *node, bool missing_ok)
{
RenameStmt *stmt = castNode(RenameStmt, node);
Assert(stmt->renameType == OBJECT_ATTRIBUTE);
switch (stmt->relationType)
{
case OBJECT_TYPE:
{
return RenameTypeAttributeStmtObjectAddress(node, missing_ok);
}
default:
{
ereport(ERROR, (errmsg("unsupported alter rename attribute statement to get "
"object address for")));
}
}
}
/* /*
* AlterExtensionStmtObjectAddress finds the ObjectAddress for the extension described * AlterExtensionStmtObjectAddress finds the ObjectAddress for the extension described
* by the AlterExtensionStmt. If missing_ok is false, then this function throws an * by the AlterExtensionStmt. If missing_ok is false, then this function throws an

View File

@ -44,26 +44,16 @@ typedef struct DistributeObjectOps
ObjectAddress (*address)(Node *, bool); ObjectAddress (*address)(Node *, bool);
} DistributeObjectOps; } DistributeObjectOps;
typedef struct DistributedObjectOpsContainerNestedInfo
{
size_t offset;
ObjectType type;
} DistributedObjectOpsContainerNestedInfo;
typedef struct DistributedObjectOpsContainer typedef struct DistributedObjectOpsContainer
{ {
NodeTag type; NodeTag type;
DistributedObjectOpsContainerNestedInfo *nestedInfo;
/*
* Nested information is only set for statements that can operate on multiple
* different objects like ALTER ... SET SCHEMA. The object type is encoded in a field
* in the statement.
*
* bool nested
* signals this container describes a nested tyoe
* size_t nestedOffset
* the offest of the ObjectType field within the statement
* ObjectType nestedType
* the object type the DistributedObjectOps of this container operates on
*/
bool nested;
size_t nestedOffset;
ObjectType nestedType;
DistributeObjectOps *ops; DistributeObjectOps *ops;
} DistributedObjectOpsContainer; } DistributedObjectOpsContainer;
@ -97,18 +87,36 @@ typedef struct DistributedObjectOpsContainer
((size_t) ((__stop_ ## sect - __start_ ## sect))) ((size_t) ((__stop_ ## sect - __start_ ## sect)))
#define REGISTER_DISTRIBUTED_OPERATION(stmt, opsvar) \ #define REGISTER_DISTRIBUTED_OPERATION(stmt, opsvar) \
static DistributedObjectOpsContainer PP_CAT(opscontainer, opsvar) = { \ static DistributedObjectOpsContainer PP_CAT(opscontainer_, stmt) = { \
.type = T_ ## stmt, \ .type = T_ ## stmt, \
.ops = &opsvar, \ .ops = &opsvar, \
}; \ }; \
REGISTER_SECTION_POINTER(opscontainer, PP_CAT(opscontainer, opsvar)) REGISTER_SECTION_POINTER(opscontainer, PP_CAT(opscontainer_, stmt))
#define REGISTER_DISTRIBUTED_OPERATION_NESTED(stmt, objectVarName, objtype, opsvar) \ #define REGISTER_DISTRIBUTED_OPERATION_NESTED(stmt, objectVarName, objtype, opsvar) \
static DistributedObjectOpsContainerNestedInfo \
PP_CAT3(opscontainer_info, stmt, objtype)[] = { \
{ offsetof(stmt, objectVarName), objtype }, \
{ 0 } \
}; \
static DistributedObjectOpsContainer PP_CAT3(opscontainer_, stmt, objtype) = { \ static DistributedObjectOpsContainer PP_CAT3(opscontainer_, stmt, objtype) = { \
.type = T_ ## stmt, \ .type = T_ ## stmt, \
.nested = true, \ .nestedInfo = &PP_CAT3(opscontainer_info, stmt, objtype)[0], \
.nestedOffset = offsetof(stmt, objectVarName), \ .ops = &opsvar, \
.nestedType = objtype, \ }; \
REGISTER_SECTION_POINTER(opscontainer, PP_CAT3(opscontainer_, stmt, objtype))
#define REGISTER_DISTRIBUTED_OPERATION_NESTED2(stmt, objectVarName1, objtype1, \
objectVarName2, objtype2, opsvar) \
static DistributedObjectOpsContainerNestedInfo \
PP_CAT3(opscontainer_info, stmt, objtype)[] = { \
{ offsetof(stmt, objectVarName1), objtype1 }, \
{ offsetof(stmt, objectVarName2), objtype2 }, \
{ 0 } \
}; \
static DistributedObjectOpsContainer PP_CAT3(opscontainer_, stmt, objtype) = { \
.type = T_ ## stmt, \
.nestedInfo = &PP_CAT3(opscontainer_info, stmt, objtype)[0], \
.ops = &opsvar, \ .ops = &opsvar, \
}; \ }; \
REGISTER_SECTION_POINTER(opscontainer, PP_CAT3(opscontainer_, stmt, objtype)) REGISTER_SECTION_POINTER(opscontainer, PP_CAT3(opscontainer_, stmt, objtype))
@ -178,7 +186,6 @@ extern void DropPolicyEventExtendNames(DropStmt *stmt, const char *schemaName, u
/* rename.c - forward declarations*/ /* rename.c - forward declarations*/
extern void ErrorIfUnsupportedRenameStmt(RenameStmt *renameStmt); extern void ErrorIfUnsupportedRenameStmt(RenameStmt *renameStmt);
extern List * PreprocessRenameAttributeStmt(Node *stmt, const char *queryString);
/* role.c - forward declarations*/ /* role.c - forward declarations*/
@ -214,11 +221,8 @@ extern void ErrorIfUnsupportedConstraint(Relation relation, char distributionMet
extern void PostprocessTruncateStatement(TruncateStmt *truncateStatement); extern void PostprocessTruncateStatement(TruncateStmt *truncateStatement);
/* type.c - forward declarations */ /* type.c - forward declarations */
extern List * PreprocessRenameTypeAttributeStmt(Node *stmt, const char *queryString);
extern Node * CreateTypeStmtByObjectAddress(const ObjectAddress *address); extern Node * CreateTypeStmtByObjectAddress(const ObjectAddress *address);
extern ObjectAddress RenameTypeAttributeStmtObjectAddress(Node *stmt,
bool missing_ok);
extern List * CreateTypeDDLCommandsIdempotent(const ObjectAddress *typeAddress); extern List * CreateTypeDDLCommandsIdempotent(const ObjectAddress *typeAddress);
extern char * GenerateBackupNameForTypeCollision(const ObjectAddress *address); extern char * GenerateBackupNameForTypeCollision(const ObjectAddress *address);

View File

@ -76,7 +76,6 @@ extern void QualifyAlterTypeSchemaStmt(Node *stmt);
extern void QualifyAlterTypeOwnerStmt(Node *stmt); extern void QualifyAlterTypeOwnerStmt(Node *stmt);
extern ObjectAddress GetObjectAddressFromParseTree(Node *parseTree, bool missing_ok); extern ObjectAddress GetObjectAddressFromParseTree(Node *parseTree, bool missing_ok);
extern ObjectAddress RenameAttributeStmtObjectAddress(Node *stmt, bool missing_ok);
/* forward declarations for deparse_function_stmts.c */ /* forward declarations for deparse_function_stmts.c */
extern char * DeparseDropFunctionStmt(Node *stmt); extern char * DeparseDropFunctionStmt(Node *stmt);