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/deparser.h"
static bool MatchOnAllNestedObjectTypes(Node *node,
DistributedObjectOpsContainerNestedInfo *
nestedInfo);
static DistributeObjectOps NoDistributeOps = {
.deparse = NULL,
.qualify = NULL,
@ -23,17 +27,6 @@ static DistributeObjectOps NoDistributeOps = {
.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 */
SECTION_ARRAY(DistributedObjectOpsContainer *, opscontainer);
@ -50,20 +43,9 @@ GetDistributeObjectOps(Node *node)
for (i = 0; i < sz; 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 */
return container->ops;
}
@ -72,3 +54,31 @@ GetDistributeObjectOps(Node *node)
/* no DistributedObjectOps linked for this statement type */
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")));
}
}
/*
* 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);
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 * PostprocessCompositeTypeStmt(Node *node, const char *queryString);
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
* keep the type in sync across the cluster.
*/
List *
static List *
PreprocessRenameTypeAttributeStmt(Node *node, const char *queryString)
{
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
* whole type distribution.
*/
ObjectAddress
static ObjectAddress
RenameTypeAttributeStmtObjectAddress(Node *node, bool missing_ok)
{
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
* 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);
} DistributeObjectOps;
typedef struct DistributedObjectOpsContainerNestedInfo
{
size_t offset;
ObjectType type;
} DistributedObjectOpsContainerNestedInfo;
typedef struct DistributedObjectOpsContainer
{
NodeTag type;
/*
* 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;
DistributedObjectOpsContainerNestedInfo *nestedInfo;
DistributeObjectOps *ops;
} DistributedObjectOpsContainer;
@ -97,18 +87,36 @@ typedef struct DistributedObjectOpsContainer
((size_t) ((__stop_ ## sect - __start_ ## sect)))
#define REGISTER_DISTRIBUTED_OPERATION(stmt, opsvar) \
static DistributedObjectOpsContainer PP_CAT(opscontainer, opsvar) = { \
static DistributedObjectOpsContainer PP_CAT(opscontainer_, stmt) = { \
.type = T_ ## stmt, \
.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) \
static DistributedObjectOpsContainerNestedInfo \
PP_CAT3(opscontainer_info, stmt, objtype)[] = { \
{ offsetof(stmt, objectVarName), objtype }, \
{ 0 } \
}; \
static DistributedObjectOpsContainer PP_CAT3(opscontainer_, stmt, objtype) = { \
.type = T_ ## stmt, \
.nested = true, \
.nestedOffset = offsetof(stmt, objectVarName), \
.nestedType = objtype, \
.nestedInfo = &PP_CAT3(opscontainer_info, stmt, objtype)[0], \
.ops = &opsvar, \
}; \
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, \
}; \
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*/
extern void ErrorIfUnsupportedRenameStmt(RenameStmt *renameStmt);
extern List * PreprocessRenameAttributeStmt(Node *stmt, const char *queryString);
/* role.c - forward declarations*/
@ -214,11 +221,8 @@ extern void ErrorIfUnsupportedConstraint(Relation relation, char distributionMet
extern void PostprocessTruncateStatement(TruncateStmt *truncateStatement);
/* type.c - forward declarations */
extern List * PreprocessRenameTypeAttributeStmt(Node *stmt, const char *queryString);
extern Node * CreateTypeStmtByObjectAddress(const ObjectAddress *address);
extern ObjectAddress RenameTypeAttributeStmtObjectAddress(Node *stmt,
bool missing_ok);
extern List * CreateTypeDDLCommandsIdempotent(const ObjectAddress *typeAddress);
extern char * GenerateBackupNameForTypeCollision(const ObjectAddress *address);

View File

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