mirror of https://github.com/citusdata/citus.git
Succesfully create CitusLocalTables from partitioned tables
parent
360c11f7fd
commit
e95022b737
|
@ -47,6 +47,8 @@
|
||||||
|
|
||||||
static void citus_add_local_table_to_metadata_internal(Oid relationId,
|
static void citus_add_local_table_to_metadata_internal(Oid relationId,
|
||||||
bool cascadeViaForeignKeys);
|
bool cascadeViaForeignKeys);
|
||||||
|
static void CreateChildLocalTablesIfRelationIsPartitioned(Oid shellRelationId,
|
||||||
|
Oid shardRelationId);
|
||||||
static void ErrorIfUnsupportedCreateCitusLocalTable(Relation relation);
|
static void ErrorIfUnsupportedCreateCitusLocalTable(Relation relation);
|
||||||
static void ErrorIfUnsupportedCitusLocalTableKind(Oid relationId);
|
static void ErrorIfUnsupportedCitusLocalTableKind(Oid relationId);
|
||||||
static void ErrorIfUnsupportedCitusLocalColumnDefinition(Relation relation);
|
static void ErrorIfUnsupportedCitusLocalColumnDefinition(Relation relation);
|
||||||
|
@ -331,14 +333,40 @@ CreateCitusLocalTable(Oid relationId, bool cascadeViaForeignKeys)
|
||||||
|
|
||||||
FinalizeCitusLocalTableCreation(shellRelationId, dependentSequenceList);
|
FinalizeCitusLocalTableCreation(shellRelationId, dependentSequenceList);
|
||||||
|
|
||||||
|
CreateChildLocalTablesIfRelationIsPartitioned(shellRelationId, shardRelationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CreateChildLocalTablesIfRelationIsPartitioned takes a relation id and creates
|
||||||
|
* Citus Local Tables for its partitions, if it's a partitioned table.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
CreateChildLocalTablesIfRelationIsPartitioned(Oid shellRelationId, Oid shardRelationId)
|
||||||
|
{
|
||||||
/* if this table is partitioned table, add its partitions to metadata too */
|
/* if this table is partitioned table, add its partitions to metadata too */
|
||||||
if (PartitionedTable(relationId))
|
if (PartitionedTable(shardRelationId))
|
||||||
{
|
{
|
||||||
List *partitionList = PartitionList(relationId);
|
List *partitionList = PartitionList(shardRelationId);
|
||||||
Oid partitionRelationId = InvalidOid;
|
Oid partitionRelationId = InvalidOid;
|
||||||
foreach_oid(partitionRelationId, partitionList)
|
foreach_oid(partitionRelationId, partitionList)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* We get the parent shell relation name before creating Citus Local Table,
|
||||||
|
* since it will be renamed later. Then we generate the command in form of
|
||||||
|
* ALTER TABLE .. ATTACH PARTITION .., for attaching the shell child to the
|
||||||
|
* shell parent later.
|
||||||
|
*/
|
||||||
|
char *qualifiedShellRelationName = generate_qualified_relation_name(
|
||||||
|
shellRelationId);
|
||||||
|
char *attachToParentCommand =
|
||||||
|
GenerateAlterTableAttachPartitionToParentCommand(partitionRelationId,
|
||||||
|
qualifiedShellRelationName);
|
||||||
CreateCitusLocalTable(partitionRelationId, false);
|
CreateCitusLocalTable(partitionRelationId, false);
|
||||||
|
char *detachPartitionCommand = GenerateDetachPartitionCommand(
|
||||||
|
partitionRelationId);
|
||||||
|
ExecuteAndLogUtilityCommandList(list_make2(detachPartitionCommand,
|
||||||
|
attachToParentCommand));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,10 +78,6 @@ static List * GetRelationIdListFromRangeVarList(List *rangeVarList, LOCKMODE loc
|
||||||
static bool AlterTableCommandTypeIsTrigger(AlterTableType alterTableType);
|
static bool AlterTableCommandTypeIsTrigger(AlterTableType alterTableType);
|
||||||
static bool AlterTableDropsForeignKey(AlterTableStmt *alterTableStatement);
|
static bool AlterTableDropsForeignKey(AlterTableStmt *alterTableStatement);
|
||||||
static void ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement);
|
static void ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement);
|
||||||
static void ErrorIfCitusLocalTablePartitionCommand(AlterTableCmd *alterTableCmd,
|
|
||||||
Oid parentRelationId);
|
|
||||||
static Oid GetPartitionCommandChildRelationId(AlterTableCmd *alterTableCmd,
|
|
||||||
bool missingOk);
|
|
||||||
static List * InterShardDDLTaskList(Oid leftRelationId, Oid rightRelationId,
|
static List * InterShardDDLTaskList(Oid leftRelationId, Oid rightRelationId,
|
||||||
const char *commandString);
|
const char *commandString);
|
||||||
static bool AlterInvolvesPartitionColumn(AlterTableStmt *alterTableStatement,
|
static bool AlterInvolvesPartitionColumn(AlterTableStmt *alterTableStatement,
|
||||||
|
@ -362,7 +358,10 @@ PostprocessCreateTableStmtPartitionOf(CreateStmt *createStatement, const
|
||||||
{
|
{
|
||||||
if (IsCitusTableType(parentRelationId, CITUS_LOCAL_TABLE))
|
if (IsCitusTableType(parentRelationId, CITUS_LOCAL_TABLE))
|
||||||
{
|
{
|
||||||
/* if it's a citus local table, we don't need distribution column */
|
/*
|
||||||
|
* If the parent is a citus local table, we don't need distribution column.
|
||||||
|
* We can do create a Citus Local Table with current table and early return.
|
||||||
|
*/
|
||||||
CreateCitusLocalTable(relationId, false);
|
CreateCitusLocalTable(relationId, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2484,8 +2483,16 @@ ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement)
|
||||||
"separately.")));
|
"separately.")));
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorIfCitusLocalTablePartitionCommand(command, relationId);
|
if (IsCitusTableType(partitionRelationId, CITUS_LOCAL_TABLE) &&
|
||||||
|
IsCitusTableType(relationId, CITUS_LOCAL_TABLE))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Citus Local Tables cannot be colocated with other tables.
|
||||||
|
* If both the parent and child tables are Citus Local Tables,
|
||||||
|
* we don't need to check colocation.
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (IsCitusTable(partitionRelationId) &&
|
if (IsCitusTable(partitionRelationId) &&
|
||||||
!TablesColocated(relationId, partitionRelationId))
|
!TablesColocated(relationId, partitionRelationId))
|
||||||
{
|
{
|
||||||
|
@ -2603,52 +2610,6 @@ ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ErrorIfCitusLocalTablePartitionCommand errors out if given alter table subcommand is
|
|
||||||
* an ALTER TABLE ATTACH / DETACH PARTITION command run for a citus local table.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
ErrorIfCitusLocalTablePartitionCommand(AlterTableCmd *alterTableCmd, Oid parentRelationId)
|
|
||||||
{
|
|
||||||
AlterTableType alterTableType = alterTableCmd->subtype;
|
|
||||||
if (alterTableType != AT_AttachPartition && alterTableType != AT_DetachPartition)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool missingOK = false;
|
|
||||||
Oid childRelationId = GetPartitionCommandChildRelationId(alterTableCmd, missingOK);
|
|
||||||
if (!IsCitusTableType(parentRelationId, CITUS_LOCAL_TABLE) &&
|
|
||||||
!IsCitusTableType(childRelationId, CITUS_LOCAL_TABLE))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
|
||||||
errmsg("cannot execute ATTACH/DETACH PARTITION command as "
|
|
||||||
"local tables added to metadata cannot be involved in "
|
|
||||||
"partition relationships with other tables")));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GetPartitionCommandChildRelationId returns child relationId for given
|
|
||||||
* ALTER TABLE ATTACH / DETACH PARTITION subcommand.
|
|
||||||
*/
|
|
||||||
static Oid
|
|
||||||
GetPartitionCommandChildRelationId(AlterTableCmd *alterTableCmd, bool missingOk)
|
|
||||||
{
|
|
||||||
AlterTableType alterTableType PG_USED_FOR_ASSERTS_ONLY = alterTableCmd->subtype;
|
|
||||||
Assert(alterTableType == AT_AttachPartition || alterTableType == AT_DetachPartition);
|
|
||||||
|
|
||||||
PartitionCmd *partitionCommand = (PartitionCmd *) alterTableCmd->def;
|
|
||||||
RangeVar *childRelationRangeVar = partitionCommand->name;
|
|
||||||
Oid childRelationId = RangeVarGetRelid(childRelationRangeVar, AccessExclusiveLock,
|
|
||||||
missingOk);
|
|
||||||
return childRelationId;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SetupExecutionModeForAlterTable is the function that is responsible
|
* SetupExecutionModeForAlterTable is the function that is responsible
|
||||||
* for two things for practical purpose for not doing the same checks
|
* for two things for practical purpose for not doing the same checks
|
||||||
|
|
|
@ -731,6 +731,36 @@ GenerateAlterTableAttachPartitionCommand(Oid partitionTableId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GenerateAlterTableAttachPartitionCommand returns the necessary command to
|
||||||
|
* attach the given partition to its parent.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
GenerateAlterTableAttachPartitionToParentCommand(Oid partitionTableId,
|
||||||
|
char *parentTableQualifiedName)
|
||||||
|
{
|
||||||
|
StringInfo createPartitionCommand = makeStringInfo();
|
||||||
|
|
||||||
|
|
||||||
|
if (!PartitionTable(partitionTableId))
|
||||||
|
{
|
||||||
|
char *relationName = get_rel_name(partitionTableId);
|
||||||
|
|
||||||
|
ereport(ERROR, (errmsg("\"%s\" is not a partition", relationName)));
|
||||||
|
}
|
||||||
|
|
||||||
|
char *tableQualifiedName = generate_qualified_relation_name(partitionTableId);
|
||||||
|
|
||||||
|
char *partitionBoundCString = PartitionBound(partitionTableId);
|
||||||
|
|
||||||
|
appendStringInfo(createPartitionCommand, "ALTER TABLE %s ATTACH PARTITION %s %s;",
|
||||||
|
parentTableQualifiedName, tableQualifiedName,
|
||||||
|
partitionBoundCString);
|
||||||
|
|
||||||
|
return createPartitionCommand->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function heaviliy inspired from RelationBuildPartitionDesc()
|
* This function heaviliy inspired from RelationBuildPartitionDesc()
|
||||||
* which is avaliable in src/backend/catalog/partition.c.
|
* which is avaliable in src/backend/catalog/partition.c.
|
||||||
|
|
|
@ -24,6 +24,9 @@ extern List * PartitionList(Oid parentRelationId);
|
||||||
extern char * GenerateDetachPartitionCommand(Oid partitionTableId);
|
extern char * GenerateDetachPartitionCommand(Oid partitionTableId);
|
||||||
extern char * GenerateAttachShardPartitionCommand(ShardInterval *shardInterval);
|
extern char * GenerateAttachShardPartitionCommand(ShardInterval *shardInterval);
|
||||||
extern char * GenerateAlterTableAttachPartitionCommand(Oid partitionTableId);
|
extern char * GenerateAlterTableAttachPartitionCommand(Oid partitionTableId);
|
||||||
|
extern char * GenerateAlterTableAttachPartitionToParentCommand(Oid partitionTableId,
|
||||||
|
char *
|
||||||
|
parentTableQualifiedName);
|
||||||
extern char * GeneratePartitioningInformation(Oid tableId);
|
extern char * GeneratePartitioningInformation(Oid tableId);
|
||||||
extern void FixPartitionConstraintsOnWorkers(Oid relationId);
|
extern void FixPartitionConstraintsOnWorkers(Oid relationId);
|
||||||
extern void FixLocalPartitionConstraints(Oid relationId, int64 shardId);
|
extern void FixLocalPartitionConstraints(Oid relationId, int64 shardId);
|
||||||
|
|
Loading…
Reference in New Issue