mirror of https://github.com/citusdata/citus.git
support 2 level of objecttypes
parent
a52ef4ea35
commit
b5f3ed6523
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue