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/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;
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue