mirror of https://github.com/citusdata/citus.git
Merge pull request #5296 from citusdata/partitioning-for-citus-local-tables
Add partitioning support for citus local tablespull/5360/head
commit
47e28a4faf
|
@ -527,8 +527,8 @@ ConvertTable(TableConversionState *con)
|
||||||
* Acquire ExclusiveLock as UndistributeTable does in order to
|
* Acquire ExclusiveLock as UndistributeTable does in order to
|
||||||
* make sure that no modifications happen on the relations.
|
* make sure that no modifications happen on the relations.
|
||||||
*/
|
*/
|
||||||
CascadeOperationForConnectedRelations(con->relationId, ExclusiveLock,
|
CascadeOperationForFkeyConnectedRelations(con->relationId, ExclusiveLock,
|
||||||
CASCADE_FKEY_UNDISTRIBUTE_TABLE);
|
CASCADE_FKEY_UNDISTRIBUTE_TABLE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Undistributed every foreign key connected relation in our foreign key
|
* Undistributed every foreign key connected relation in our foreign key
|
||||||
|
|
|
@ -33,9 +33,9 @@
|
||||||
|
|
||||||
|
|
||||||
static void EnsureSequentialModeForCitusTableCascadeFunction(List *relationIdList);
|
static void EnsureSequentialModeForCitusTableCascadeFunction(List *relationIdList);
|
||||||
|
static List * GetPartitionRelationIds(List *relationIdList);
|
||||||
static void LockRelationsWithLockMode(List *relationIdList, LOCKMODE lockMode);
|
static void LockRelationsWithLockMode(List *relationIdList, LOCKMODE lockMode);
|
||||||
static List * RemovePartitionRelationIds(List *relationIdList);
|
static void ErrorIfConvertingMultiLevelPartitionedTable(List *relationIdList);
|
||||||
static List * GetFKeyCreationCommandsForRelationIdList(List *relationIdList);
|
|
||||||
static void DropRelationIdListForeignKeys(List *relationIdList, int fKeyFlags);
|
static void DropRelationIdListForeignKeys(List *relationIdList, int fKeyFlags);
|
||||||
static List * GetRelationDropFkeyCommands(Oid relationId, int fKeyFlags);
|
static List * GetRelationDropFkeyCommands(Oid relationId, int fKeyFlags);
|
||||||
static char * GetDropFkeyCascadeCommand(Oid foreignKeyId);
|
static char * GetDropFkeyCascadeCommand(Oid foreignKeyId);
|
||||||
|
@ -46,17 +46,14 @@ static void ExecuteForeignKeyCreateCommand(const char *commandString,
|
||||||
bool skip_validation);
|
bool skip_validation);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CascadeOperationForConnectedRelations executes citus table function specified
|
* CascadeOperationForFkeyConnectedRelations is a wrapper function which calls
|
||||||
* by CascadeOperationType argument on each relation that relation
|
* CascadeOperationForRelationIdList for the foreign key connected relations, for
|
||||||
* with relationId is connected via it's foreign key graph, which includes
|
* the given relationId.
|
||||||
* input relation itself.
|
|
||||||
* Also see CascadeOperationType enum definition for supported
|
|
||||||
* citus table functions.
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
CascadeOperationForConnectedRelations(Oid relationId, LOCKMODE lockMode,
|
CascadeOperationForFkeyConnectedRelations(Oid relationId, LOCKMODE lockMode,
|
||||||
CascadeOperationType
|
CascadeOperationType
|
||||||
cascadeOperationType)
|
cascadeOperationType)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* As we will operate on foreign key connected relations, here we
|
* As we will operate on foreign key connected relations, here we
|
||||||
|
@ -72,7 +69,38 @@ CascadeOperationForConnectedRelations(Oid relationId, LOCKMODE lockMode,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LockRelationsWithLockMode(fKeyConnectedRelationIdList, lockMode);
|
CascadeOperationForRelationIdList(fKeyConnectedRelationIdList, lockMode,
|
||||||
|
cascadeOperationType);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CascadeOperationForRelationIdList executes citus table function specified
|
||||||
|
* by CascadeOperationType argument on each relation in the relationIdList;
|
||||||
|
* Also see CascadeOperationType enum definition for supported
|
||||||
|
* citus table functions.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
CascadeOperationForRelationIdList(List *relationIdList, LOCKMODE lockMode,
|
||||||
|
CascadeOperationType
|
||||||
|
cascadeOperationType)
|
||||||
|
{
|
||||||
|
LockRelationsWithLockMode(relationIdList, lockMode);
|
||||||
|
|
||||||
|
if (cascadeOperationType == CASCADE_ADD_LOCAL_TABLE_TO_METADATA)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* In CreateCitusLocalTable function, this check would never error out,
|
||||||
|
* since CreateCitusLocalTable gets called with partition relations, *after*
|
||||||
|
* they are detached.
|
||||||
|
* Instead, here, it would error out if the user tries to convert a multi-level
|
||||||
|
* partitioned table, since partitioned table conversions always go through here.
|
||||||
|
* Also, there can be a multi-level partitioned table, to be cascaded via foreign
|
||||||
|
* keys, and they are hard to detect in CreateCitusLocalTable.
|
||||||
|
* Therefore, we put this check here.
|
||||||
|
*/
|
||||||
|
ErrorIfConvertingMultiLevelPartitionedTable(relationIdList);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Before removing any partition relations, we should error out here if any
|
* Before removing any partition relations, we should error out here if any
|
||||||
|
@ -81,25 +109,29 @@ CascadeOperationForConnectedRelations(Oid relationId, LOCKMODE lockMode,
|
||||||
* We should handle this case here as we remove partition relations in this
|
* We should handle this case here as we remove partition relations in this
|
||||||
* function before ExecuteCascadeOperationForRelationIdList.
|
* function before ExecuteCascadeOperationForRelationIdList.
|
||||||
*/
|
*/
|
||||||
ErrorIfAnyPartitionRelationInvolvedInNonInheritedFKey(fKeyConnectedRelationIdList);
|
ErrorIfAnyPartitionRelationInvolvedInNonInheritedFKey(relationIdList);
|
||||||
|
|
||||||
|
List *partitonRelationList = GetPartitionRelationIds(relationIdList);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We shouldn't cascade through foreign keys on partition tables as citus
|
* Here we generate detach/attach commands, if there are any partition tables
|
||||||
* table functions already have their own logics to handle partition relations.
|
* in our "relations-to-cascade" list.
|
||||||
*/
|
*/
|
||||||
List *nonPartitionRelationIdList =
|
List *detachPartitionCommands =
|
||||||
RemovePartitionRelationIds(fKeyConnectedRelationIdList);
|
GenerateDetachPartitionCommandRelationIdList(partitonRelationList);
|
||||||
|
List *attachPartitionCommands =
|
||||||
|
GenerateAttachPartitionCommandRelationIdList(partitonRelationList);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Our foreign key subgraph can have distributed tables which might already
|
* Our foreign key subgraph can have distributed tables which might already
|
||||||
* be modified in current transaction. So switch to sequential execution
|
* be modified in current transaction. So switch to sequential execution
|
||||||
* before executing any ddl's to prevent erroring out later in this function.
|
* before executing any ddl's to prevent erroring out later in this function.
|
||||||
*/
|
*/
|
||||||
EnsureSequentialModeForCitusTableCascadeFunction(nonPartitionRelationIdList);
|
EnsureSequentialModeForCitusTableCascadeFunction(relationIdList);
|
||||||
|
|
||||||
/* store foreign key creation commands before dropping them */
|
/* store foreign key creation commands before dropping them */
|
||||||
List *fKeyCreationCommands =
|
List *fKeyCreationCommands =
|
||||||
GetFKeyCreationCommandsForRelationIdList(nonPartitionRelationIdList);
|
GetFKeyCreationCommandsForRelationIdList(relationIdList);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note that here we only drop referencing foreign keys for each relation.
|
* Note that here we only drop referencing foreign keys for each relation.
|
||||||
|
@ -107,16 +139,43 @@ CascadeOperationForConnectedRelations(Oid relationId, LOCKMODE lockMode,
|
||||||
* relations' referencing foreign keys.
|
* relations' referencing foreign keys.
|
||||||
*/
|
*/
|
||||||
int fKeyFlags = INCLUDE_REFERENCING_CONSTRAINTS | INCLUDE_ALL_TABLE_TYPES;
|
int fKeyFlags = INCLUDE_REFERENCING_CONSTRAINTS | INCLUDE_ALL_TABLE_TYPES;
|
||||||
DropRelationIdListForeignKeys(nonPartitionRelationIdList, fKeyFlags);
|
DropRelationIdListForeignKeys(relationIdList, fKeyFlags);
|
||||||
ExecuteCascadeOperationForRelationIdList(nonPartitionRelationIdList,
|
|
||||||
|
ExecuteAndLogUtilityCommandList(detachPartitionCommands);
|
||||||
|
|
||||||
|
ExecuteCascadeOperationForRelationIdList(relationIdList,
|
||||||
cascadeOperationType);
|
cascadeOperationType);
|
||||||
|
|
||||||
|
ExecuteAndLogUtilityCommandList(attachPartitionCommands);
|
||||||
|
|
||||||
/* now recreate foreign keys on tables */
|
/* now recreate foreign keys on tables */
|
||||||
bool skip_validation = true;
|
bool skip_validation = true;
|
||||||
ExecuteForeignKeyCreateCommandList(fKeyCreationCommands, skip_validation);
|
ExecuteForeignKeyCreateCommandList(fKeyCreationCommands, skip_validation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GetPartitionRelationIds returns a list of relation id's by picking
|
||||||
|
* partition relation id's from given relationIdList.
|
||||||
|
*/
|
||||||
|
static List *
|
||||||
|
GetPartitionRelationIds(List *relationIdList)
|
||||||
|
{
|
||||||
|
List *partitionRelationIdList = NIL;
|
||||||
|
|
||||||
|
Oid relationId = InvalidOid;
|
||||||
|
foreach_oid(relationId, relationIdList)
|
||||||
|
{
|
||||||
|
if (PartitionTable(relationId))
|
||||||
|
{
|
||||||
|
partitionRelationIdList = lappend_oid(partitionRelationIdList, relationId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return partitionRelationIdList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LockRelationsWithLockMode sorts given relationIdList and then acquires
|
* LockRelationsWithLockMode sorts given relationIdList and then acquires
|
||||||
* specified lockMode on those relations.
|
* specified lockMode on those relations.
|
||||||
|
@ -133,6 +192,36 @@ LockRelationsWithLockMode(List *relationIdList, LOCKMODE lockMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ErrorIfConvertingMultiLevelPartitionedTable iterates given relationIdList and checks
|
||||||
|
* if there's a multi-level partitioned table involved or not. As we currently don't
|
||||||
|
* support converting multi-level partitioned tables into Citus Local Tables,
|
||||||
|
* this function errors out for such a case. We detect the multi-level partitioned
|
||||||
|
* table if one of the relations is both partition and partitioned table.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ErrorIfConvertingMultiLevelPartitionedTable(List *relationIdList)
|
||||||
|
{
|
||||||
|
Oid relationId;
|
||||||
|
foreach_oid(relationId, relationIdList)
|
||||||
|
{
|
||||||
|
if (PartitionedTable(relationId) && PartitionTable(relationId))
|
||||||
|
{
|
||||||
|
Oid parentRelId = PartitionParentOid(relationId);
|
||||||
|
char *parentRelationName = get_rel_name(parentRelId);
|
||||||
|
char *relationName = get_rel_name(relationId);
|
||||||
|
|
||||||
|
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
|
errmsg("Citus does not support multi-level "
|
||||||
|
"partitioned tables"),
|
||||||
|
errdetail("Relation \"%s\" is partitioned table itself so "
|
||||||
|
"cannot be partition of relation \"%s\".",
|
||||||
|
relationName, parentRelationName)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ErrorIfAnyPartitionRelationInvolvedInNonInheritedFKey searches given
|
* ErrorIfAnyPartitionRelationInvolvedInNonInheritedFKey searches given
|
||||||
* relationIdList for a partition relation involved in a foreign key relationship
|
* relationIdList for a partition relation involved in a foreign key relationship
|
||||||
|
@ -167,30 +256,6 @@ ErrorIfAnyPartitionRelationInvolvedInNonInheritedFKey(List *relationIdList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* RemovePartitionRelationIds returns a list of relation id's by removing
|
|
||||||
* partition relation id's from given relationIdList.
|
|
||||||
*/
|
|
||||||
static List *
|
|
||||||
RemovePartitionRelationIds(List *relationIdList)
|
|
||||||
{
|
|
||||||
List *nonPartitionRelationIdList = NIL;
|
|
||||||
|
|
||||||
Oid relationId = InvalidOid;
|
|
||||||
foreach_oid(relationId, relationIdList)
|
|
||||||
{
|
|
||||||
if (PartitionTable(relationId))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
nonPartitionRelationIdList = lappend_oid(nonPartitionRelationIdList, relationId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return nonPartitionRelationIdList;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* EnsureSequentialModeForCitusTableCascadeFunction switches to sequential
|
* EnsureSequentialModeForCitusTableCascadeFunction switches to sequential
|
||||||
* execution mode if needed. If it's not possible, then errors out.
|
* execution mode if needed. If it's not possible, then errors out.
|
||||||
|
@ -247,7 +312,7 @@ RelationIdListHasReferenceTable(List *relationIdList)
|
||||||
* GetFKeyCreationCommandsForRelationIdList returns a list of DDL commands to
|
* GetFKeyCreationCommandsForRelationIdList returns a list of DDL commands to
|
||||||
* create foreign keys for each relation in relationIdList.
|
* create foreign keys for each relation in relationIdList.
|
||||||
*/
|
*/
|
||||||
static List *
|
List *
|
||||||
GetFKeyCreationCommandsForRelationIdList(List *relationIdList)
|
GetFKeyCreationCommandsForRelationIdList(List *relationIdList)
|
||||||
{
|
{
|
||||||
List *fKeyCreationCommands = NIL;
|
List *fKeyCreationCommands = NIL;
|
||||||
|
@ -409,7 +474,7 @@ ExecuteCascadeOperationForRelationIdList(List *relationIdList,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CASCADE_FKEY_ADD_LOCAL_TABLE_TO_METADATA:
|
case CASCADE_ADD_LOCAL_TABLE_TO_METADATA:
|
||||||
{
|
{
|
||||||
if (!IsCitusTable(relationId))
|
if (!IsCitusTable(relationId))
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/commands/sequence.h"
|
#include "distributed/commands/sequence.h"
|
||||||
#include "distributed/commands/utility_hook.h"
|
#include "distributed/commands/utility_hook.h"
|
||||||
|
#include "distributed/foreign_key_relationship.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
#include "distributed/local_executor.h"
|
#include "distributed/local_executor.h"
|
||||||
#include "distributed/metadata_sync.h"
|
#include "distributed/metadata_sync.h"
|
||||||
|
@ -47,6 +48,7 @@
|
||||||
|
|
||||||
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 ErrorIfAddingPartitionTableToMetadata(Oid relationId);
|
||||||
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);
|
||||||
|
@ -223,6 +225,8 @@ CreateCitusLocalTable(Oid relationId, bool cascadeViaForeignKeys)
|
||||||
|
|
||||||
ErrorIfUnsupportedCreateCitusLocalTable(relation);
|
ErrorIfUnsupportedCreateCitusLocalTable(relation);
|
||||||
|
|
||||||
|
ErrorIfAddingPartitionTableToMetadata(relationId);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We immediately close relation with NoLock right after opening it. This is
|
* We immediately close relation with NoLock right after opening it. This is
|
||||||
* because, in this function, we may execute ALTER TABLE commands modifying
|
* because, in this function, we may execute ALTER TABLE commands modifying
|
||||||
|
@ -232,15 +236,35 @@ CreateCitusLocalTable(Oid relationId, bool cascadeViaForeignKeys)
|
||||||
*/
|
*/
|
||||||
relation_close(relation, NoLock);
|
relation_close(relation, NoLock);
|
||||||
|
|
||||||
bool tableHasExternalForeignKeys = TableHasExternalForeignKeys(relationId);
|
if (TableHasExternalForeignKeys(relationId))
|
||||||
if (tableHasExternalForeignKeys && cascadeViaForeignKeys)
|
|
||||||
{
|
{
|
||||||
|
if (!cascadeViaForeignKeys)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We do not allow creating citus local table if the table is involved in a
|
||||||
|
* foreign key relationship with "any other table", unless the option
|
||||||
|
* cascadeViaForeignKeys is given true.
|
||||||
|
* Note that we allow self references.
|
||||||
|
*/
|
||||||
|
char *qualifiedRelationName = generate_qualified_relation_name(relationId);
|
||||||
|
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
|
errmsg("relation %s is involved in a foreign key "
|
||||||
|
"relationship with another table",
|
||||||
|
qualifiedRelationName),
|
||||||
|
errhint("Use cascade_via_foreign_keys option to add "
|
||||||
|
"all the relations involved in a foreign key "
|
||||||
|
"relationship with %s to citus metadata by "
|
||||||
|
"executing SELECT citus_add_local_table_to_metadata($$%s$$, "
|
||||||
|
"cascade_via_foreign_keys=>true)",
|
||||||
|
qualifiedRelationName, qualifiedRelationName)));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* By acquiring AccessExclusiveLock, make sure that no modifications happen
|
* By acquiring AccessExclusiveLock, make sure that no modifications happen
|
||||||
* on the relations.
|
* on the relations.
|
||||||
*/
|
*/
|
||||||
CascadeOperationForConnectedRelations(relationId, lockMode,
|
CascadeOperationForFkeyConnectedRelations(relationId, lockMode,
|
||||||
CASCADE_FKEY_ADD_LOCAL_TABLE_TO_METADATA);
|
CASCADE_ADD_LOCAL_TABLE_TO_METADATA);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We converted every foreign key connected table in our subgraph
|
* We converted every foreign key connected table in our subgraph
|
||||||
|
@ -248,23 +272,18 @@ CreateCitusLocalTable(Oid relationId, bool cascadeViaForeignKeys)
|
||||||
*/
|
*/
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (tableHasExternalForeignKeys)
|
|
||||||
|
if (PartitionedTable(relationId))
|
||||||
{
|
{
|
||||||
/*
|
List *relationList = PartitionList(relationId);
|
||||||
* We do not allow creating citus local table if the table is involved in a
|
if (list_length(relationList) > 0)
|
||||||
* foreign key relationship with "any other table". Note that we allow self
|
{
|
||||||
* references.
|
relationList = lappend_oid(relationList, relationId);
|
||||||
*/
|
|
||||||
char *qualifiedRelationName = generate_qualified_relation_name(relationId);
|
CascadeOperationForRelationIdList(relationList, AccessExclusiveLock,
|
||||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
CASCADE_ADD_LOCAL_TABLE_TO_METADATA);
|
||||||
errmsg("relation %s is involved in a foreign key "
|
return;
|
||||||
"relationship with another table", qualifiedRelationName),
|
}
|
||||||
errhint("Use cascade_via_foreign_keys option to add "
|
|
||||||
"all the relations involved in a foreign key "
|
|
||||||
"relationship with %s to citus metadata by "
|
|
||||||
"executing SELECT citus_add_local_table_to_metadata($$%s$$, "
|
|
||||||
"cascade_via_foreign_keys=>true)",
|
|
||||||
qualifiedRelationName, qualifiedRelationName)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectAddress tableAddress = { 0 };
|
ObjectAddress tableAddress = { 0 };
|
||||||
|
@ -333,6 +352,88 @@ CreateCitusLocalTable(Oid relationId, bool cascadeViaForeignKeys)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CreateCitusLocalTablePartitionOf generates and executes the necessary commands
|
||||||
|
* to create a table as partition of a partitioned Citus Local Table.
|
||||||
|
* The conversion is done by CreateCitusLocalTable.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
CreateCitusLocalTablePartitionOf(CreateStmt *createStatement, Oid relationId,
|
||||||
|
Oid parentRelationId)
|
||||||
|
{
|
||||||
|
if (createStatement->partspec)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Since partspec represents "PARTITION BY" clause, being different than
|
||||||
|
* NULL means that given CreateStmt attempts to create a parent table
|
||||||
|
* at the same time. That means multi-level partitioning within this
|
||||||
|
* function's context. We don't support this currently.
|
||||||
|
*/
|
||||||
|
char *parentRelationName = get_rel_name(parentRelationId);
|
||||||
|
char *relationName = get_rel_name(relationId);
|
||||||
|
|
||||||
|
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
|
errmsg("distributing multi-level partitioned tables "
|
||||||
|
"is not supported"),
|
||||||
|
errdetail("Relation \"%s\" is partitioned table itself "
|
||||||
|
"and it is also partition of relation \"%s\".",
|
||||||
|
relationName, parentRelationName)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since the shell table for the partition is not created yet on MX workers,
|
||||||
|
* we should disable DDL propagation before the DETACH command, to avoid
|
||||||
|
* getting an error on the worker.
|
||||||
|
*/
|
||||||
|
List *detachCommands = list_make3(DISABLE_DDL_PROPAGATION,
|
||||||
|
GenerateDetachPartitionCommand(relationId),
|
||||||
|
ENABLE_DDL_PROPAGATION);
|
||||||
|
char *attachCommand = GenerateAlterTableAttachPartitionCommand(relationId);
|
||||||
|
ExecuteAndLogUtilityCommandList(detachCommands);
|
||||||
|
int fKeyFlags = INCLUDE_REFERENCING_CONSTRAINTS | INCLUDE_ALL_TABLE_TYPES;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When cascadeViaForeignKeys is false, CreateCitusLocalTable doesn't expect
|
||||||
|
* any foreign keys on given relation. Note that we don't want to pass
|
||||||
|
* cascadeViaForeignKeys to be true here since we don't already allow non-inherited
|
||||||
|
* foreign keys on child relations, and for the inherited ones, we should have already
|
||||||
|
* cascaded to the other relations when creating a citus local table from parent.
|
||||||
|
*
|
||||||
|
* For this reason, we drop inherited foreign keys here, they'll anyway get created
|
||||||
|
* again with the attach command
|
||||||
|
*/
|
||||||
|
DropRelationForeignKeys(relationId, fKeyFlags);
|
||||||
|
CreateCitusLocalTable(relationId, false);
|
||||||
|
ExecuteAndLogUtilityCommand(attachCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ErrorIfAddingPartitionTableToMetadata errors out if we try to create the
|
||||||
|
* citus local table from a partition table.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
ErrorIfAddingPartitionTableToMetadata(Oid relationId)
|
||||||
|
{
|
||||||
|
if (PartitionTable(relationId))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We do not allow converting only partitions into Citus Local Tables.
|
||||||
|
* Users should call the UDF citus_add_local_table_to_metadata with the
|
||||||
|
* parent table; then the whole partitioned table will be converted.
|
||||||
|
*/
|
||||||
|
char *relationName = get_rel_name(relationId);
|
||||||
|
Oid parentRelationId = PartitionParentOid(relationId);
|
||||||
|
char *parentRelationName = get_rel_name(parentRelationId);
|
||||||
|
ereport(ERROR, (errmsg("cannot add local table %s to metadata since "
|
||||||
|
"it is a partition of %s. Instead, add the parent "
|
||||||
|
"table %s to metadata.",
|
||||||
|
relationName, parentRelationName,
|
||||||
|
parentRelationName)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ErrorIfUnsupportedCreateCitusLocalTable errors out if we cannot create the
|
* ErrorIfUnsupportedCreateCitusLocalTable errors out if we cannot create the
|
||||||
* citus local table from the relation.
|
* citus local table from the relation.
|
||||||
|
@ -387,20 +488,14 @@ ErrorIfUnsupportedCitusLocalTableKind(Oid relationId)
|
||||||
"relationships", relationName)));
|
"relationships", relationName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PartitionTable(relationId))
|
|
||||||
{
|
|
||||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
|
||||||
errmsg("cannot add local table \"%s\" to metadata, local tables "
|
|
||||||
"added to metadata cannot be partition of other tables ",
|
|
||||||
relationName)));
|
|
||||||
}
|
|
||||||
|
|
||||||
char relationKind = get_rel_relkind(relationId);
|
char relationKind = get_rel_relkind(relationId);
|
||||||
if (!(relationKind == RELKIND_RELATION || relationKind == RELKIND_FOREIGN_TABLE))
|
if (!(relationKind == RELKIND_RELATION || relationKind == RELKIND_FOREIGN_TABLE ||
|
||||||
|
relationKind == RELKIND_PARTITIONED_TABLE))
|
||||||
{
|
{
|
||||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
errmsg("cannot add local table \"%s\" to metadata, only regular "
|
errmsg("cannot add local table \"%s\" to metadata, only regular "
|
||||||
"tables and foreign tables can be added to citus metadata ",
|
"tables, partitioned tables and foreign tables"
|
||||||
|
" can be added to citus metadata ",
|
||||||
relationName)));
|
relationName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -948,7 +1043,13 @@ DropDefaultColumnDefinition(Oid relationId, char *columnName)
|
||||||
"ALTER TABLE %s ALTER COLUMN %s DROP DEFAULT",
|
"ALTER TABLE %s ALTER COLUMN %s DROP DEFAULT",
|
||||||
qualifiedRelationName, quotedColumnName);
|
qualifiedRelationName, quotedColumnName);
|
||||||
|
|
||||||
ExecuteAndLogUtilityCommand(sequenceDropCommand->data);
|
/*
|
||||||
|
* We need to disable/enable ddl propagation for this command, to prevent
|
||||||
|
* sending unnecessary ALTER COLUMN commands for partitions, to MX workers.
|
||||||
|
*/
|
||||||
|
ExecuteAndLogUtilityCommandList(list_make3(DISABLE_DDL_PROPAGATION,
|
||||||
|
sequenceDropCommand->data,
|
||||||
|
ENABLE_DDL_PROPAGATION));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -971,7 +1072,15 @@ TransferSequenceOwnership(Oid sequenceId, Oid targetRelationId, char *targetColu
|
||||||
qualifiedSequenceName, qualifiedTargetRelationName,
|
qualifiedSequenceName, qualifiedTargetRelationName,
|
||||||
quotedTargetColumnName);
|
quotedTargetColumnName);
|
||||||
|
|
||||||
ExecuteAndLogUtilityCommand(sequenceOwnershipCommand->data);
|
/*
|
||||||
|
* We need to disable/enable ddl propagation for this command, to prevent
|
||||||
|
* sending unnecessary ALTER SEQUENCE commands for partitions, to MX workers.
|
||||||
|
* Especially for partitioned tables, where the same sequence is used for
|
||||||
|
* all partitions, this might cause errors.
|
||||||
|
*/
|
||||||
|
ExecuteAndLogUtilityCommandList(list_make3(DISABLE_DDL_PROPAGATION,
|
||||||
|
sequenceOwnershipCommand->data,
|
||||||
|
ENABLE_DDL_PROPAGATION));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
@ -360,6 +356,13 @@ PostprocessCreateTableStmtPartitionOf(CreateStmt *createStatement, const
|
||||||
*/
|
*/
|
||||||
if (IsCitusTable(parentRelationId))
|
if (IsCitusTable(parentRelationId))
|
||||||
{
|
{
|
||||||
|
if (IsCitusTableType(parentRelationId, CITUS_LOCAL_TABLE))
|
||||||
|
{
|
||||||
|
CreateCitusLocalTablePartitionOf(createStatement, relationId,
|
||||||
|
parentRelationId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Var *parentDistributionColumn = DistPartitionKeyOrError(parentRelationId);
|
Var *parentDistributionColumn = DistPartitionKeyOrError(parentRelationId);
|
||||||
char parentDistributionMethod = DISTRIBUTE_BY_HASH;
|
char parentDistributionMethod = DISTRIBUTE_BY_HASH;
|
||||||
char *parentRelationName = generate_qualified_relation_name(parentRelationId);
|
char *parentRelationName = generate_qualified_relation_name(parentRelationId);
|
||||||
|
@ -442,6 +445,24 @@ PreprocessAlterTableStmtAttachPartition(AlterTableStmt *alterTableStatement,
|
||||||
if (IsCitusTable(relationId) &&
|
if (IsCitusTable(relationId) &&
|
||||||
!IsCitusTable(partitionRelationId))
|
!IsCitusTable(partitionRelationId))
|
||||||
{
|
{
|
||||||
|
if (IsCitusTableType(relationId, CITUS_LOCAL_TABLE))
|
||||||
|
{
|
||||||
|
if (PartitionedTable(partitionRelationId))
|
||||||
|
{
|
||||||
|
char *relationName = get_rel_name(partitionRelationId);
|
||||||
|
char *parentRelationName = get_rel_name(relationId);
|
||||||
|
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
|
errmsg("distributing multi-level partitioned "
|
||||||
|
"tables is not supported"),
|
||||||
|
errdetail("Relation \"%s\" is partitioned table "
|
||||||
|
"itself and it is also partition of "
|
||||||
|
"relation \"%s\".",
|
||||||
|
relationName, parentRelationName)));
|
||||||
|
}
|
||||||
|
CreateCitusLocalTable(partitionRelationId, false);
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
|
|
||||||
Var *distributionColumn = DistPartitionKeyOrError(relationId);
|
Var *distributionColumn = DistPartitionKeyOrError(relationId);
|
||||||
char *distributionColumnName = ColumnToColumnName(relationId,
|
char *distributionColumnName = ColumnToColumnName(relationId,
|
||||||
nodeToString(
|
nodeToString(
|
||||||
|
@ -1113,7 +1134,23 @@ ConvertPostgresLocalTablesToCitusLocalTables(AlterTableStmt *alterTableStatement
|
||||||
PG_TRY();
|
PG_TRY();
|
||||||
{
|
{
|
||||||
bool cascade = true;
|
bool cascade = true;
|
||||||
CreateCitusLocalTable(relationId, cascade);
|
|
||||||
|
/*
|
||||||
|
* Withoud this check, we would be erroring out in CreateCitusLocalTable
|
||||||
|
* for this case anyway. The purpose of this check&error is to provide
|
||||||
|
* a more meaningful message for the user.
|
||||||
|
*/
|
||||||
|
if (PartitionTable(relationId))
|
||||||
|
{
|
||||||
|
ereport(ERROR, (errmsg("cannot build foreign key between"
|
||||||
|
" reference table and a partition"),
|
||||||
|
errhint("Try using parent table: %s",
|
||||||
|
get_rel_name(PartitionParentOid(relationId)))));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CreateCitusLocalTable(relationId, cascade);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
PG_CATCH();
|
PG_CATCH();
|
||||||
{
|
{
|
||||||
|
@ -2477,7 +2514,17 @@ 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 either of two relations is not a Citus Local Table, then we
|
||||||
|
* don't need to check colocation since CreateCitusLocalTable would
|
||||||
|
* anyway throw an error.
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (IsCitusTable(partitionRelationId) &&
|
if (IsCitusTable(partitionRelationId) &&
|
||||||
!TablesColocated(relationId, partitionRelationId))
|
!TablesColocated(relationId, partitionRelationId))
|
||||||
|
@ -2521,7 +2568,6 @@ ErrorIfUnsupportedAlterTableStmt(AlterTableStmt *alterTableStatement)
|
||||||
"unsupported.")));
|
"unsupported.")));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
ErrorIfCitusLocalTablePartitionCommand(command, relationId);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2596,52 +2642,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
|
||||||
|
|
|
@ -44,13 +44,14 @@
|
||||||
#include "distributed/commands.h"
|
#include "distributed/commands.h"
|
||||||
#include "distributed/commands/multi_copy.h"
|
#include "distributed/commands/multi_copy.h"
|
||||||
#include "distributed/commands/utility_hook.h" /* IWYU pragma: keep */
|
#include "distributed/commands/utility_hook.h" /* IWYU pragma: keep */
|
||||||
|
#include "distributed/coordinator_protocol.h"
|
||||||
#include "distributed/deparser.h"
|
#include "distributed/deparser.h"
|
||||||
#include "distributed/deparse_shard_query.h"
|
#include "distributed/deparse_shard_query.h"
|
||||||
#include "distributed/foreign_key_relationship.h"
|
#include "distributed/foreign_key_relationship.h"
|
||||||
#include "distributed/listutils.h"
|
#include "distributed/listutils.h"
|
||||||
#include "distributed/local_executor.h"
|
#include "distributed/local_executor.h"
|
||||||
#include "distributed/maintenanced.h"
|
#include "distributed/maintenanced.h"
|
||||||
#include "distributed/coordinator_protocol.h"
|
#include "distributed/multi_partitioning_utils.h"
|
||||||
#include "distributed/metadata_cache.h"
|
#include "distributed/metadata_cache.h"
|
||||||
#include "distributed/metadata_sync.h"
|
#include "distributed/metadata_sync.h"
|
||||||
#include "distributed/multi_executor.h"
|
#include "distributed/multi_executor.h"
|
||||||
|
@ -713,6 +714,12 @@ UndistributeDisconnectedCitusLocalTables(void)
|
||||||
}
|
}
|
||||||
ReleaseSysCache(heapTuple);
|
ReleaseSysCache(heapTuple);
|
||||||
|
|
||||||
|
if (PartitionTable(citusLocalTableId))
|
||||||
|
{
|
||||||
|
/* we skip here, we'll undistribute from the parent if necessary */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (ConnectedToReferenceTableViaFKey(citusLocalTableId))
|
if (ConnectedToReferenceTableViaFKey(citusLocalTableId))
|
||||||
{
|
{
|
||||||
/* still connected to a reference table, skip it */
|
/* still connected to a reference table, skip it */
|
||||||
|
|
|
@ -1716,15 +1716,10 @@ DetachPartitionCommandList(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
List *partitionList = PartitionList(cacheEntry->relationId);
|
List *partitionList = PartitionList(cacheEntry->relationId);
|
||||||
Oid partitionRelationId = InvalidOid;
|
List *detachCommands =
|
||||||
foreach_oid(partitionRelationId, partitionList)
|
GenerateDetachPartitionCommandRelationIdList(partitionList);
|
||||||
{
|
detachPartitionCommandList = list_concat(detachPartitionCommandList,
|
||||||
char *detachPartitionCommand =
|
detachCommands);
|
||||||
GenerateDetachPartitionCommand(partitionRelationId);
|
|
||||||
|
|
||||||
detachPartitionCommandList = lappend(detachPartitionCommandList,
|
|
||||||
detachPartitionCommand);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (list_length(detachPartitionCommandList) == 0)
|
if (list_length(detachPartitionCommandList) == 0)
|
||||||
|
|
|
@ -227,11 +227,13 @@ PlacementAccessTypeToText(ShardPlacementAccessType accessType)
|
||||||
static void
|
static void
|
||||||
RecordRelationAccessBase(Oid relationId, ShardPlacementAccessType accessType)
|
RecordRelationAccessBase(Oid relationId, ShardPlacementAccessType accessType)
|
||||||
{
|
{
|
||||||
/*
|
if (IsCitusTableType(relationId, REFERENCE_TABLE))
|
||||||
* We call this only for reference tables, and we don't support partitioned
|
{
|
||||||
* reference tables.
|
/*
|
||||||
*/
|
* We don't support partitioned reference tables.
|
||||||
Assert(!PartitionedTable(relationId) && !PartitionTable(relationId));
|
*/
|
||||||
|
Assert(!PartitionedTable(relationId) && !PartitionTable(relationId));
|
||||||
|
}
|
||||||
|
|
||||||
/* make sure that this is not a conflicting access */
|
/* make sure that this is not a conflicting access */
|
||||||
CheckConflictingRelationAccesses(relationId, accessType);
|
CheckConflictingRelationAccesses(relationId, accessType);
|
||||||
|
|
|
@ -1006,6 +1006,26 @@ GenerateDetachPartitionCommand(Oid partitionTableId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GenerateDetachPartitionCommandRelationIdList returns the necessary command list to
|
||||||
|
* detach the given partitions from their parents.
|
||||||
|
*/
|
||||||
|
List *
|
||||||
|
GenerateDetachPartitionCommandRelationIdList(List *relationIds)
|
||||||
|
{
|
||||||
|
List *detachPartitionCommands = NIL;
|
||||||
|
Oid relationId = InvalidOid;
|
||||||
|
foreach_oid(relationId, relationIds)
|
||||||
|
{
|
||||||
|
Assert(PartitionTable(relationId));
|
||||||
|
char *detachCommand = GenerateDetachPartitionCommand(relationId);
|
||||||
|
detachPartitionCommands = lappend(detachPartitionCommands, detachCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
return detachPartitionCommands;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GenereatePartitioningInformation returns the partitioning type and partition column
|
* GenereatePartitioningInformation returns the partitioning type and partition column
|
||||||
* for the given parent table in the form of "PARTITION TYPE (partitioning column(s)/expression(s))".
|
* for the given parent table in the form of "PARTITION TYPE (partitioning column(s)/expression(s))".
|
||||||
|
@ -1102,6 +1122,25 @@ GenerateAlterTableAttachPartitionCommand(Oid partitionTableId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GenerateAttachPartitionCommandRelationIdList returns the necessary command list to
|
||||||
|
* attach the given partitions to their parents.
|
||||||
|
*/
|
||||||
|
List *
|
||||||
|
GenerateAttachPartitionCommandRelationIdList(List *relationIds)
|
||||||
|
{
|
||||||
|
List *attachPartitionCommands = NIL;
|
||||||
|
Oid relationId = InvalidOid;
|
||||||
|
foreach_oid(relationId, relationIds)
|
||||||
|
{
|
||||||
|
char *attachCommand = GenerateAlterTableAttachPartitionCommand(relationId);
|
||||||
|
attachPartitionCommands = lappend(attachPartitionCommands, attachCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
return attachPartitionCommands;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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.
|
||||||
|
|
|
@ -502,7 +502,8 @@ extern Oid GetTriggerFunctionId(Oid triggerId);
|
||||||
/* cascade_table_operation_for_connected_relations.c */
|
/* cascade_table_operation_for_connected_relations.c */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flags that can be passed to CascadeOperationForConnectedRelations to specify
|
* Flags that can be passed to CascadeOperationForFkeyConnectedRelations, and
|
||||||
|
* CascadeOperationForRelationIdList to specify
|
||||||
* citus table function to be executed in cascading mode.
|
* citus table function to be executed in cascading mode.
|
||||||
*/
|
*/
|
||||||
typedef enum CascadeOperationType
|
typedef enum CascadeOperationType
|
||||||
|
@ -513,14 +514,18 @@ typedef enum CascadeOperationType
|
||||||
CASCADE_FKEY_UNDISTRIBUTE_TABLE = 1 << 1,
|
CASCADE_FKEY_UNDISTRIBUTE_TABLE = 1 << 1,
|
||||||
|
|
||||||
/* execute CreateCitusLocalTable on each relation */
|
/* execute CreateCitusLocalTable on each relation */
|
||||||
CASCADE_FKEY_ADD_LOCAL_TABLE_TO_METADATA = 1 << 2,
|
CASCADE_ADD_LOCAL_TABLE_TO_METADATA = 1 << 2,
|
||||||
} CascadeOperationType;
|
} CascadeOperationType;
|
||||||
|
|
||||||
extern void CascadeOperationForConnectedRelations(Oid relationId, LOCKMODE relLockMode,
|
extern void CascadeOperationForFkeyConnectedRelations(Oid relationId,
|
||||||
CascadeOperationType
|
LOCKMODE relLockMode,
|
||||||
cascadeOperationType);
|
CascadeOperationType
|
||||||
|
cascadeOperationType);
|
||||||
|
extern void CascadeOperationForRelationIdList(List *relationIdList, LOCKMODE lockMode,
|
||||||
|
CascadeOperationType cascadeOperationType);
|
||||||
extern void ErrorIfAnyPartitionRelationInvolvedInNonInheritedFKey(List *relationIdList);
|
extern void ErrorIfAnyPartitionRelationInvolvedInNonInheritedFKey(List *relationIdList);
|
||||||
extern bool RelationIdListHasReferenceTable(List *relationIdList);
|
extern bool RelationIdListHasReferenceTable(List *relationIdList);
|
||||||
|
extern List * GetFKeyCreationCommandsForRelationIdList(List *relationIdList);
|
||||||
extern void DropRelationForeignKeys(Oid relationId, int flags);
|
extern void DropRelationForeignKeys(Oid relationId, int flags);
|
||||||
extern void SetLocalEnableLocalReferenceForeignKeys(bool state);
|
extern void SetLocalEnableLocalReferenceForeignKeys(bool state);
|
||||||
extern void ExecuteAndLogUtilityCommandList(List *ddlCommandList);
|
extern void ExecuteAndLogUtilityCommandList(List *ddlCommandList);
|
||||||
|
@ -538,5 +543,7 @@ extern void PostprocessVariableSetStmt(VariableSetStmt *setStmt, const char *set
|
||||||
/* create_citus_local_table.c */
|
/* create_citus_local_table.c */
|
||||||
|
|
||||||
extern void CreateCitusLocalTable(Oid relationId, bool cascade);
|
extern void CreateCitusLocalTable(Oid relationId, bool cascade);
|
||||||
|
extern void CreateCitusLocalTablePartitionOf(CreateStmt *createStatement,
|
||||||
|
Oid relationId, Oid parentRelationId);
|
||||||
|
|
||||||
#endif /*CITUS_COMMANDS_H */
|
#endif /*CITUS_COMMANDS_H */
|
||||||
|
|
|
@ -22,8 +22,10 @@ extern Oid PartitionParentOid(Oid partitionOid);
|
||||||
extern Oid PartitionWithLongestNameRelationId(Oid parentRelationId);
|
extern Oid PartitionWithLongestNameRelationId(Oid parentRelationId);
|
||||||
extern List * PartitionList(Oid parentRelationId);
|
extern List * PartitionList(Oid parentRelationId);
|
||||||
extern char * GenerateDetachPartitionCommand(Oid partitionTableId);
|
extern char * GenerateDetachPartitionCommand(Oid partitionTableId);
|
||||||
|
extern List * GenerateDetachPartitionCommandRelationIdList(List *relationIds);
|
||||||
extern char * GenerateAttachShardPartitionCommand(ShardInterval *shardInterval);
|
extern char * GenerateAttachShardPartitionCommand(ShardInterval *shardInterval);
|
||||||
extern char * GenerateAlterTableAttachPartitionCommand(Oid partitionTableId);
|
extern char * GenerateAlterTableAttachPartitionCommand(Oid partitionTableId);
|
||||||
|
extern List * GenerateAttachPartitionCommandRelationIdList(List *relationIds);
|
||||||
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);
|
||||||
|
|
|
@ -447,7 +447,68 @@ NOTICE: executing the command locally: SELECT value FROM citus_local_table_trig
|
||||||
100
|
100
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
|
ROLLBACK;
|
||||||
|
-- test on partitioned citus local tables
|
||||||
|
CREATE TABLE par_citus_local_table (val int) PARTITION BY RANGE(val);
|
||||||
|
CREATE TABLE par_citus_local_table_1 PARTITION OF par_citus_local_table FOR VALUES FROM (1) TO (10000);
|
||||||
|
CREATE TABLE par_another_citus_local_table (val int unique) PARTITION BY RANGE(val);
|
||||||
|
CREATE TABLE par_another_citus_local_table_1 PARTITION OF par_another_citus_local_table FOR VALUES FROM (1) TO (10000);
|
||||||
|
ALTER TABLE par_another_citus_local_table ADD CONSTRAINT fkey_self FOREIGN KEY(val) REFERENCES par_another_citus_local_table(val);
|
||||||
|
ALTER TABLE par_citus_local_table ADD CONSTRAINT fkey_c_to_c FOREIGN KEY(val) REFERENCES par_another_citus_local_table(val) ON UPDATE CASCADE;
|
||||||
|
SELECT citus_add_local_table_to_metadata('par_another_citus_local_table', cascade_via_foreign_keys=>true);
|
||||||
|
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (1507011, 'citus_local_table_triggers', 1507012, 'citus_local_table_triggers', 'ALTER TABLE citus_local_table_triggers.par_another_citus_local_table ATTACH PARTITION citus_local_table_triggers.par_another_citus_local_table_1 FOR VALUES FROM (1) TO (10000);')
|
||||||
|
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (1507013, 'citus_local_table_triggers', 1507014, 'citus_local_table_triggers', 'ALTER TABLE citus_local_table_triggers.par_citus_local_table ATTACH PARTITION citus_local_table_triggers.par_citus_local_table_1 FOR VALUES FROM (1) TO (10000);')
|
||||||
|
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (1507011, 'citus_local_table_triggers', 1507011, 'citus_local_table_triggers', 'ALTER TABLE citus_local_table_triggers.par_another_citus_local_table ADD CONSTRAINT fkey_self FOREIGN KEY (val) REFERENCES citus_local_table_triggers.par_another_citus_local_table(val)')
|
||||||
|
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (1507013, 'citus_local_table_triggers', 1507011, 'citus_local_table_triggers', 'ALTER TABLE citus_local_table_triggers.par_citus_local_table ADD CONSTRAINT fkey_c_to_c FOREIGN KEY (val) REFERENCES citus_local_table_triggers.par_another_citus_local_table(val) ON UPDATE CASCADE')
|
||||||
|
citus_add_local_table_to_metadata
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE par_reference_table(val int);
|
||||||
|
SELECT create_reference_table('par_reference_table');
|
||||||
|
create_reference_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE FUNCTION par_insert_100() RETURNS trigger AS $par_insert_100$
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO par_reference_table VALUES (100);
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$par_insert_100$ LANGUAGE plpgsql;
|
||||||
|
BEGIN;
|
||||||
|
CREATE TRIGGER par_insert_100_trigger
|
||||||
|
AFTER TRUNCATE ON par_another_citus_local_table
|
||||||
|
FOR EACH STATEMENT EXECUTE FUNCTION par_insert_100();
|
||||||
|
CREATE TRIGGER insert_100_trigger
|
||||||
|
AFTER TRUNCATE ON par_citus_local_table
|
||||||
|
FOR EACH STATEMENT EXECUTE FUNCTION par_insert_100();
|
||||||
|
TRUNCATE par_another_citus_local_table CASCADE;
|
||||||
|
NOTICE: truncate cascades to table "par_citus_local_table"
|
||||||
|
NOTICE: truncate cascades to table "par_citus_local_table_1"
|
||||||
|
NOTICE: executing the command locally: INSERT INTO citus_local_table_triggers.par_reference_table_1507015 (val) VALUES (100)
|
||||||
|
NOTICE: executing the command locally: TRUNCATE TABLE citus_local_table_triggers.par_another_citus_local_table_xxxxx CASCADE
|
||||||
|
NOTICE: truncate cascades to table "par_citus_local_table_xxxxx"
|
||||||
|
NOTICE: truncate cascades to table "par_citus_local_table_1_xxxxx"
|
||||||
|
NOTICE: executing the command locally: TRUNCATE TABLE citus_local_table_triggers.par_another_citus_local_table_1_xxxxx CASCADE
|
||||||
|
NOTICE: truncate cascades to table "par_citus_local_table_xxxxx"
|
||||||
|
NOTICE: truncate cascades to table "par_citus_local_table_1_xxxxx"
|
||||||
|
NOTICE: truncate cascades to table "par_another_citus_local_table_xxxxx"
|
||||||
|
NOTICE: executing the command locally: INSERT INTO citus_local_table_triggers.par_reference_table_1507015 (val) VALUES (100)
|
||||||
|
NOTICE: executing the command locally: TRUNCATE TABLE citus_local_table_triggers.par_citus_local_table_xxxxx CASCADE
|
||||||
|
NOTICE: executing the command locally: TRUNCATE TABLE citus_local_table_triggers.par_citus_local_table_1_xxxxx CASCADE
|
||||||
|
-- we should see two rows with "100"
|
||||||
|
SELECT * FROM par_reference_table;
|
||||||
|
NOTICE: executing the command locally: SELECT val FROM citus_local_table_triggers.par_reference_table_1507015 par_reference_table
|
||||||
|
val
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
100
|
||||||
|
100
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
-- cleanup at exit
|
-- cleanup at exit
|
||||||
DROP SCHEMA citus_local_table_triggers, "interesting!schema" CASCADE;
|
DROP SCHEMA citus_local_table_triggers, "interesting!schema" CASCADE;
|
||||||
NOTICE: drop cascades to 13 other objects
|
NOTICE: drop cascades to 20 other objects
|
||||||
|
|
|
@ -123,50 +123,6 @@ SELECT create_distributed_table('distributed_table', 'a');
|
||||||
-- cannot create citus local table from an existing citus table
|
-- cannot create citus local table from an existing citus table
|
||||||
SELECT citus_add_local_table_to_metadata('distributed_table');
|
SELECT citus_add_local_table_to_metadata('distributed_table');
|
||||||
ERROR: table "distributed_table" is already distributed
|
ERROR: table "distributed_table" is already distributed
|
||||||
-- partitioned table tests --
|
|
||||||
CREATE TABLE partitioned_table(a int, b int) PARTITION BY RANGE (a);
|
|
||||||
CREATE TABLE partitioned_table_1 PARTITION OF partitioned_table FOR VALUES FROM (0) TO (10);
|
|
||||||
CREATE TABLE partitioned_table_2 PARTITION OF partitioned_table FOR VALUES FROM (10) TO (20);
|
|
||||||
-- cannot create partitioned citus local tables
|
|
||||||
SELECT citus_add_local_table_to_metadata('partitioned_table');
|
|
||||||
ERROR: cannot add local table "partitioned_table" to metadata, only regular tables and foreign tables can be added to citus metadata
|
|
||||||
BEGIN;
|
|
||||||
CREATE TABLE citus_local_table PARTITION OF partitioned_table FOR VALUES FROM (20) TO (30);
|
|
||||||
-- cannot create citus local table as a partition of a local table
|
|
||||||
SELECT citus_add_local_table_to_metadata('citus_local_table');
|
|
||||||
ERROR: cannot add local table "citus_local_table" to metadata, local tables added to metadata cannot be partition of other tables
|
|
||||||
ROLLBACK;
|
|
||||||
BEGIN;
|
|
||||||
CREATE TABLE citus_local_table (a int, b int);
|
|
||||||
SELECT citus_add_local_table_to_metadata('citus_local_table');
|
|
||||||
citus_add_local_table_to_metadata
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- cannot create citus local table as a partition of a local table
|
|
||||||
-- via ALTER TABLE commands as well
|
|
||||||
ALTER TABLE partitioned_table ATTACH PARTITION citus_local_table FOR VALUES FROM (20) TO (30);
|
|
||||||
ERROR: non-distributed tables cannot have distributed partitions
|
|
||||||
ROLLBACK;
|
|
||||||
BEGIN;
|
|
||||||
SELECT create_distributed_table('partitioned_table', 'a');
|
|
||||||
create_distributed_table
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
CREATE TABLE citus_local_table (a int, b int);
|
|
||||||
SELECT citus_add_local_table_to_metadata('citus_local_table');
|
|
||||||
citus_add_local_table_to_metadata
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
(1 row)
|
|
||||||
|
|
||||||
-- cannot attach citus local table to a partitioned distributed table
|
|
||||||
ALTER TABLE partitioned_table ATTACH PARTITION citus_local_table FOR VALUES FROM (20) TO (30);
|
|
||||||
ERROR: cannot execute ATTACH/DETACH PARTITION command as local tables added to metadata cannot be involved in partition relationships with other tables
|
|
||||||
ROLLBACK;
|
|
||||||
-- show that we do not support inheritance relationships --
|
-- show that we do not support inheritance relationships --
|
||||||
CREATE TABLE parent_table (a int, b text);
|
CREATE TABLE parent_table (a int, b text);
|
||||||
CREATE TABLE child_table () INHERITS (parent_table);
|
CREATE TABLE child_table () INHERITS (parent_table);
|
||||||
|
@ -203,11 +159,11 @@ BEGIN;
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
INSERT INTO citus_local_table_3 VALUES (1);
|
INSERT INTO citus_local_table_3 VALUES (1);
|
||||||
NOTICE: executing the command locally: INSERT INTO citus_local_tables_test_schema.citus_local_table_3_1504024 (value) VALUES (1)
|
NOTICE: executing the command locally: INSERT INTO citus_local_tables_test_schema.citus_local_table_3_1504010 (value) VALUES (1)
|
||||||
NOTICE: executing the command locally: UPDATE citus_local_tables_test_schema.citus_local_table_3_1504024 citus_local_table_3 SET value = (value OPERATOR(pg_catalog.+) 1)
|
NOTICE: executing the command locally: UPDATE citus_local_tables_test_schema.citus_local_table_3_1504010 citus_local_table_3 SET value = (value OPERATOR(pg_catalog.+) 1)
|
||||||
-- show that trigger is executed only once, we should see "2" (not "3")
|
-- show that trigger is executed only once, we should see "2" (not "3")
|
||||||
SELECT * FROM citus_local_table_3;
|
SELECT * FROM citus_local_table_3;
|
||||||
NOTICE: executing the command locally: SELECT value FROM citus_local_tables_test_schema.citus_local_table_3_1504024 citus_local_table_3
|
NOTICE: executing the command locally: SELECT value FROM citus_local_tables_test_schema.citus_local_table_3_1504010 citus_local_table_3
|
||||||
value
|
value
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
2
|
2
|
||||||
|
@ -334,13 +290,13 @@ ERROR: relation "citus_local_table_1" is a local table
|
||||||
SELECT get_shard_id_for_distribution_column('citus_local_table_1', 'not_checking_this_arg_for_non_dist_tables');
|
SELECT get_shard_id_for_distribution_column('citus_local_table_1', 'not_checking_this_arg_for_non_dist_tables');
|
||||||
get_shard_id_for_distribution_column
|
get_shard_id_for_distribution_column
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
1504027
|
1504013
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT get_shard_id_for_distribution_column('citus_local_table_1');
|
SELECT get_shard_id_for_distribution_column('citus_local_table_1');
|
||||||
get_shard_id_for_distribution_column
|
get_shard_id_for_distribution_column
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
1504027
|
1504013
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- master_copy_shard_placement is not supported
|
-- master_copy_shard_placement is not supported
|
||||||
|
@ -352,7 +308,7 @@ BEGIN;
|
||||||
SELECT undistribute_table('citus_local_table_1');
|
SELECT undistribute_table('citus_local_table_1');
|
||||||
NOTICE: creating a new table for citus_local_tables_test_schema.citus_local_table_1
|
NOTICE: creating a new table for citus_local_tables_test_schema.citus_local_table_1
|
||||||
NOTICE: moving the data of citus_local_tables_test_schema.citus_local_table_1
|
NOTICE: moving the data of citus_local_tables_test_schema.citus_local_table_1
|
||||||
NOTICE: executing the command locally: SELECT a FROM citus_local_tables_test_schema.citus_local_table_1_1504027 citus_local_table_1
|
NOTICE: executing the command locally: SELECT a FROM citus_local_tables_test_schema.citus_local_table_1_1504013 citus_local_table_1
|
||||||
NOTICE: dropping the old citus_local_tables_test_schema.citus_local_table_1
|
NOTICE: dropping the old citus_local_tables_test_schema.citus_local_table_1
|
||||||
NOTICE: executing the command locally: DROP TABLE IF EXISTS citus_local_tables_test_schema.citus_local_table_1_xxxxx CASCADE
|
NOTICE: executing the command locally: DROP TABLE IF EXISTS citus_local_tables_test_schema.citus_local_table_1_xxxxx CASCADE
|
||||||
NOTICE: renaming the new table to citus_local_tables_test_schema.citus_local_table_1
|
NOTICE: renaming the new table to citus_local_tables_test_schema.citus_local_table_1
|
||||||
|
@ -395,7 +351,7 @@ SELECT citus_add_local_table_to_metadata('"CiTUS!LocalTables"."LocalTabLE.1!?!"'
|
||||||
-- drop the table before creating it when the search path is set
|
-- drop the table before creating it when the search path is set
|
||||||
SET search_path to "CiTUS!LocalTables" ;
|
SET search_path to "CiTUS!LocalTables" ;
|
||||||
DROP TABLE "LocalTabLE.1!?!";
|
DROP TABLE "LocalTabLE.1!?!";
|
||||||
NOTICE: executing the command locally: DROP TABLE IF EXISTS "CiTUS!LocalTables"."LocalTabLE.1!?!_1504035" CASCADE
|
NOTICE: executing the command locally: DROP TABLE IF EXISTS "CiTUS!LocalTables"."LocalTabLE.1!?!_1504021" CASCADE
|
||||||
-- have a custom type in the local table
|
-- have a custom type in the local table
|
||||||
CREATE TYPE local_type AS (key int, value jsonb);
|
CREATE TYPE local_type AS (key int, value jsonb);
|
||||||
-- create btree_gist for GiST index
|
-- create btree_gist for GiST index
|
||||||
|
@ -445,10 +401,10 @@ SELECT citus_add_local_table_to_metadata('"LocalTabLE.1!?!9012345678901234567890
|
||||||
-- create some objects after citus_add_local_table_to_metadata
|
-- create some objects after citus_add_local_table_to_metadata
|
||||||
CREATE INDEX "my!Index2" ON "LocalTabLE.1!?!9012345678901234567890123456789012345678901234567890123456789"(id) WITH ( fillfactor = 90 ) WHERE id < 20;
|
CREATE INDEX "my!Index2" ON "LocalTabLE.1!?!9012345678901234567890123456789012345678901234567890123456789"(id) WITH ( fillfactor = 90 ) WHERE id < 20;
|
||||||
NOTICE: identifier "LocalTabLE.1!?!9012345678901234567890123456789012345678901234567890123456789" will be truncated to "LocalTabLE.1!?!901234567890123456789012345678901234567890123456"
|
NOTICE: identifier "LocalTabLE.1!?!9012345678901234567890123456789012345678901234567890123456789" will be truncated to "LocalTabLE.1!?!901234567890123456789012345678901234567890123456"
|
||||||
NOTICE: executing the command locally: CREATE INDEX "my!Index2_1504036" ON "CiTUS!LocalTables"."LocalTabLE.1!?!9012345678901234567890123456789_7e923997_1504036" USING btree (id ) WITH (fillfactor = '90' )WHERE (id < 20)
|
NOTICE: executing the command locally: CREATE INDEX "my!Index2_1504022" ON "CiTUS!LocalTables"."LocalTabLE.1!?!9012345678901234567890123456789_7e923997_1504022" USING btree (id ) WITH (fillfactor = '90' )WHERE (id < 20)
|
||||||
CREATE UNIQUE INDEX uniqueIndex2 ON "LocalTabLE.1!?!9012345678901234567890123456789012345678901234567890123456789"(id);
|
CREATE UNIQUE INDEX uniqueIndex2 ON "LocalTabLE.1!?!9012345678901234567890123456789012345678901234567890123456789"(id);
|
||||||
NOTICE: identifier "LocalTabLE.1!?!9012345678901234567890123456789012345678901234567890123456789" will be truncated to "LocalTabLE.1!?!901234567890123456789012345678901234567890123456"
|
NOTICE: identifier "LocalTabLE.1!?!9012345678901234567890123456789012345678901234567890123456789" will be truncated to "LocalTabLE.1!?!901234567890123456789012345678901234567890123456"
|
||||||
NOTICE: executing the command locally: CREATE UNIQUE INDEX uniqueindex2_1504036 ON "CiTUS!LocalTables"."LocalTabLE.1!?!9012345678901234567890123456789_7e923997_1504036" USING btree (id )
|
NOTICE: executing the command locally: CREATE UNIQUE INDEX uniqueindex2_1504022 ON "CiTUS!LocalTables"."LocalTabLE.1!?!9012345678901234567890123456789_7e923997_1504022" USING btree (id )
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
---- utility command execution ----
|
---- utility command execution ----
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
|
@ -537,7 +493,7 @@ CREATE TABLE local_table_4 (
|
||||||
b int references local_table_4(a));
|
b int references local_table_4(a));
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (xxxxx, 'citus_local_tables_test_schema', xxxxx, 'citus_local_tables_test_schema', 'ALTER TABLE citus_local_tables_test_schema.local_table_4 ADD CONSTRAINT local_table_4_a_fkey FOREIGN KEY (a) REFERENCES citus_local_tables_test_schema.citus_local_table_1(a)')
|
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (xxxxx, 'citus_local_tables_test_schema', xxxxx, 'citus_local_tables_test_schema', 'ALTER TABLE citus_local_tables_test_schema.local_table_4 ADD CONSTRAINT local_table_4_a_fkey FOREIGN KEY (a) REFERENCES citus_local_tables_test_schema.citus_local_table_1(a)')
|
||||||
ALTER TABLE citus_local_table_1 ADD COLUMN b int NOT NULL;
|
ALTER TABLE citus_local_table_1 ADD COLUMN b int NOT NULL;
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1504027, 'citus_local_tables_test_schema', 'ALTER TABLE citus_local_table_1 ADD COLUMN b int NOT NULL;')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1504013, 'citus_local_tables_test_schema', 'ALTER TABLE citus_local_table_1 ADD COLUMN b int NOT NULL;')
|
||||||
-- show that we added column with NOT NULL
|
-- show that we added column with NOT NULL
|
||||||
SELECT table_name, column_name, is_nullable
|
SELECT table_name, column_name, is_nullable
|
||||||
FROM INFORMATION_SCHEMA.COLUMNS
|
FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
|
@ -546,11 +502,11 @@ ORDER BY 1;
|
||||||
table_name | column_name | is_nullable
|
table_name | column_name | is_nullable
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
citus_local_table_1 | b | NO
|
citus_local_table_1 | b | NO
|
||||||
citus_local_table_1_1504027 | b | NO
|
citus_local_table_1_1504013 | b | NO
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
ALTER TABLE citus_local_table_1 ADD CONSTRAINT unique_a_b UNIQUE (a, b);
|
ALTER TABLE citus_local_table_1 ADD CONSTRAINT unique_a_b UNIQUE (a, b);
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1504027, 'citus_local_tables_test_schema', 'ALTER TABLE citus_local_table_1 ADD CONSTRAINT unique_a_b UNIQUE (a, b);')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1504013, 'citus_local_tables_test_schema', 'ALTER TABLE citus_local_table_1 ADD CONSTRAINT unique_a_b UNIQUE (a, b);')
|
||||||
-- show that we defined unique constraints
|
-- show that we defined unique constraints
|
||||||
SELECT conrelid::regclass, conname, conkey
|
SELECT conrelid::regclass, conname, conkey
|
||||||
FROM pg_constraint
|
FROM pg_constraint
|
||||||
|
@ -558,12 +514,12 @@ WHERE conrelid::regclass::text LIKE 'citus_local_table_1%' AND contype = 'u'
|
||||||
ORDER BY 1;
|
ORDER BY 1;
|
||||||
conrelid | conname | conkey
|
conrelid | conname | conkey
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
citus_local_table_1_1504027 | unique_a_b_1504027 | {1,2}
|
citus_local_table_1_1504013 | unique_a_b_1504013 | {1,2}
|
||||||
citus_local_table_1 | unique_a_b | {1,2}
|
citus_local_table_1 | unique_a_b | {1,2}
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
CREATE UNIQUE INDEX citus_local_table_1_idx ON citus_local_table_1(b);
|
CREATE UNIQUE INDEX citus_local_table_1_idx ON citus_local_table_1(b);
|
||||||
NOTICE: executing the command locally: CREATE UNIQUE INDEX citus_local_table_1_idx_1504027 ON citus_local_tables_test_schema.citus_local_table_1_1504027 USING btree (b )
|
NOTICE: executing the command locally: CREATE UNIQUE INDEX citus_local_table_1_idx_1504013 ON citus_local_tables_test_schema.citus_local_table_1_1504013 USING btree (b )
|
||||||
-- show that we successfully defined the unique index
|
-- show that we successfully defined the unique index
|
||||||
SELECT indexrelid::regclass, indrelid::regclass, indkey
|
SELECT indexrelid::regclass, indrelid::regclass, indkey
|
||||||
FROM pg_index
|
FROM pg_index
|
||||||
|
@ -572,7 +528,7 @@ ORDER BY 1;
|
||||||
indexrelid | indrelid | indkey
|
indexrelid | indrelid | indkey
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
unique_a_b | citus_local_table_1 | 1 2
|
unique_a_b | citus_local_table_1 | 1 2
|
||||||
unique_a_b_1504027 | citus_local_table_1_1504027 | 1 2
|
unique_a_b_1504013 | citus_local_table_1_1504013 | 1 2
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
-- test creating citus local table with an index from non-default schema
|
-- test creating citus local table with an index from non-default schema
|
||||||
|
@ -580,7 +536,7 @@ CREATE SCHEMA "test_\'index_schema";
|
||||||
CREATE TABLE "test_\'index_schema".testindex (a int, b int);
|
CREATE TABLE "test_\'index_schema".testindex (a int, b int);
|
||||||
CREATE INDEX ind ON "test_\'index_schema".testindex (a);
|
CREATE INDEX ind ON "test_\'index_schema".testindex (a);
|
||||||
ALTER TABLE "test_\'index_schema".testindex ADD CONSTRAINT fkey_to_dummy_ref FOREIGN KEY (a) REFERENCES dummy_reference_table(a);
|
ALTER TABLE "test_\'index_schema".testindex ADD CONSTRAINT fkey_to_dummy_ref FOREIGN KEY (a) REFERENCES dummy_reference_table(a);
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (1504040, E'test_\\''index_schema', 1504037, 'citus_local_tables_test_schema', E'ALTER TABLE "test_\\''index_schema".testindex ADD CONSTRAINT fkey_to_dummy_ref FOREIGN KEY (a) REFERENCES dummy_reference_table(a);')
|
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (1504026, E'test_\\''index_schema', 1504023, 'citus_local_tables_test_schema', E'ALTER TABLE "test_\\''index_schema".testindex ADD CONSTRAINT fkey_to_dummy_ref FOREIGN KEY (a) REFERENCES dummy_reference_table(a);')
|
||||||
SELECT COUNT(*)=2 FROM pg_indexes WHERE tablename LIKE 'testindex%' AND indexname LIKE 'ind%';
|
SELECT COUNT(*)=2 FROM pg_indexes WHERE tablename LIKE 'testindex%' AND indexname LIKE 'ind%';
|
||||||
?column?
|
?column?
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
|
@ -605,7 +561,7 @@ DROP TABLE citus_local_table_1, citus_local_table_2, distributed_table, local_ta
|
||||||
NOTICE: executing the command locally: DROP TABLE IF EXISTS citus_local_tables_test_schema.local_table_4_xxxxx CASCADE
|
NOTICE: executing the command locally: DROP TABLE IF EXISTS citus_local_tables_test_schema.local_table_4_xxxxx CASCADE
|
||||||
NOTICE: executing the command locally: DROP TABLE IF EXISTS citus_local_tables_test_schema.reference_table_xxxxx CASCADE
|
NOTICE: executing the command locally: DROP TABLE IF EXISTS citus_local_tables_test_schema.reference_table_xxxxx CASCADE
|
||||||
NOTICE: executing the command locally: DROP TABLE IF EXISTS citus_local_tables_test_schema.local_table_xxxxx CASCADE
|
NOTICE: executing the command locally: DROP TABLE IF EXISTS citus_local_tables_test_schema.local_table_xxxxx CASCADE
|
||||||
NOTICE: drop cascades to constraint fkey_c_to_local_1504027 on table citus_local_tables_test_schema.citus_local_table_1_1504027
|
NOTICE: drop cascades to constraint fkey_c_to_local_1504013 on table citus_local_tables_test_schema.citus_local_table_1_1504013
|
||||||
NOTICE: executing the command locally: DROP TABLE IF EXISTS citus_local_tables_test_schema.citus_local_table_2_xxxxx CASCADE
|
NOTICE: executing the command locally: DROP TABLE IF EXISTS citus_local_tables_test_schema.citus_local_table_2_xxxxx CASCADE
|
||||||
NOTICE: executing the command locally: DROP TABLE IF EXISTS citus_local_tables_test_schema.citus_local_table_1_xxxxx CASCADE
|
NOTICE: executing the command locally: DROP TABLE IF EXISTS citus_local_tables_test_schema.citus_local_table_1_xxxxx CASCADE
|
||||||
-- test some other udf's with citus local tables
|
-- test some other udf's with citus local tables
|
||||||
|
@ -793,7 +749,7 @@ CREATE STATISTICS stx1 ON a, b FROM test_citus_local_table_with_stats;
|
||||||
ALTER TABLE test_citus_local_table_with_stats ADD CONSTRAINT fkey_to_dummy_ref FOREIGN KEY (a) REFERENCES dummy_reference_table(a);
|
ALTER TABLE test_citus_local_table_with_stats ADD CONSTRAINT fkey_to_dummy_ref FOREIGN KEY (a) REFERENCES dummy_reference_table(a);
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (xxxxx, 'citus_local_tables_test_schema', xxxxx, 'citus_local_tables_test_schema', 'ALTER TABLE test_citus_local_table_with_stats ADD CONSTRAINT fkey_to_dummy_ref FOREIGN KEY (a) REFERENCES dummy_reference_table(a);')
|
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (xxxxx, 'citus_local_tables_test_schema', xxxxx, 'citus_local_tables_test_schema', 'ALTER TABLE test_citus_local_table_with_stats ADD CONSTRAINT fkey_to_dummy_ref FOREIGN KEY (a) REFERENCES dummy_reference_table(a);')
|
||||||
CREATE STATISTICS "CiTUS!LocalTables"."Bad\'StatName" ON a, b FROM test_citus_local_table_with_stats;
|
CREATE STATISTICS "CiTUS!LocalTables"."Bad\'StatName" ON a, b FROM test_citus_local_table_with_stats;
|
||||||
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1504044, 'citus_local_tables_test_schema', E'CREATE STATISTICS "CiTUS!LocalTables"."Bad\\''StatName" ON a, b FROM citus_local_tables_test_schema.test_citus_local_table_with_stats')
|
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1504030, 'citus_local_tables_test_schema', E'CREATE STATISTICS "CiTUS!LocalTables"."Bad\\''StatName" ON a, b FROM citus_local_tables_test_schema.test_citus_local_table_with_stats')
|
||||||
SELECT COUNT(*)=4 FROM pg_statistic_ext WHERE stxname LIKE 'stx1%' or stxname LIKE 'Bad\\''StatName%' ;
|
SELECT COUNT(*)=4 FROM pg_statistic_ext WHERE stxname LIKE 'stx1%' or stxname LIKE 'Bad\\''StatName%' ;
|
||||||
?column?
|
?column?
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
|
@ -814,6 +770,205 @@ NOTICE: truncate cascades to table "referencing_table_xxxxxxx"
|
||||||
NOTICE: executing the command locally: TRUNCATE TABLE citus_local_tables_test_schema.referencing_table_xxxxx CASCADE
|
NOTICE: executing the command locally: TRUNCATE TABLE citus_local_tables_test_schema.referencing_table_xxxxx CASCADE
|
||||||
RESET client_min_messages;
|
RESET client_min_messages;
|
||||||
\set VERBOSITY terse
|
\set VERBOSITY terse
|
||||||
|
-- test for partitioned tables
|
||||||
|
SET client_min_messages TO ERROR;
|
||||||
|
-- verify we can convert partitioned tables into Citus Local Tables
|
||||||
|
CREATE TABLE partitioned (user_id int, time timestamp with time zone, data jsonb, PRIMARY KEY (user_id, time )) PARTITION BY RANGE ("time");
|
||||||
|
CREATE TABLE partition1 PARTITION OF partitioned FOR VALUES FROM ('2018-04-13 00:00:00+00') TO ('2018-04-14 00:00:00+00');
|
||||||
|
CREATE TABLE partition2 PARTITION OF partitioned FOR VALUES FROM ('2018-04-14 00:00:00+00') TO ('2018-04-15 00:00:00+00');
|
||||||
|
SELECT citus_add_local_table_to_metadata('partitioned');
|
||||||
|
citus_add_local_table_to_metadata
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- partitions added after the conversion get converted into CLT as well
|
||||||
|
CREATE TABLE partition3 PARTITION OF partitioned FOR VALUES FROM ('2018-04-15 00:00:00+00') TO ('2018-04-16 00:00:00+00');
|
||||||
|
--verify partitioning hierarchy is preserved after conversion
|
||||||
|
select inhrelid::regclass from pg_inherits where inhparent='partitioned'::regclass order by 1;
|
||||||
|
inhrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partition1
|
||||||
|
partition2
|
||||||
|
partition3
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT partition, from_value, to_value, access_method
|
||||||
|
FROM time_partitions
|
||||||
|
WHERE partition::text LIKE '%partition%'
|
||||||
|
ORDER BY partition::text;
|
||||||
|
partition | from_value | to_value | access_method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partition1 | Thu Apr 12 17:00:00 2018 PDT | Fri Apr 13 17:00:00 2018 PDT | heap
|
||||||
|
partition1_1504031 | Thu Apr 12 17:00:00 2018 PDT | Fri Apr 13 17:00:00 2018 PDT | heap
|
||||||
|
partition2 | Fri Apr 13 17:00:00 2018 PDT | Sat Apr 14 17:00:00 2018 PDT | heap
|
||||||
|
partition2_1504032 | Fri Apr 13 17:00:00 2018 PDT | Sat Apr 14 17:00:00 2018 PDT | heap
|
||||||
|
partition3 | Sat Apr 14 17:00:00 2018 PDT | Sun Apr 15 17:00:00 2018 PDT | heap
|
||||||
|
partition3_1504034 | Sat Apr 14 17:00:00 2018 PDT | Sun Apr 15 17:00:00 2018 PDT | heap
|
||||||
|
(6 rows)
|
||||||
|
|
||||||
|
-- undistribute succesfully
|
||||||
|
SELECT undistribute_table('partitioned');
|
||||||
|
undistribute_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- verify the partitioning hierarchy is preserved after undistributing
|
||||||
|
select inhrelid::regclass from pg_inherits where inhparent='partitioned'::regclass order by 1;
|
||||||
|
inhrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partition1
|
||||||
|
partition2
|
||||||
|
partition3
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
-- verify table is undistributed
|
||||||
|
SELECT relname FROM pg_class WHERE relname LIKE 'partition3%' AND relnamespace IN
|
||||||
|
(SELECT oid FROM pg_namespace WHERE nspname = 'citus_local_tables_test_schema')
|
||||||
|
ORDER BY relname;
|
||||||
|
relname
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partition3
|
||||||
|
partition3_pkey
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- drop successfully
|
||||||
|
DROP TABLE partitioned;
|
||||||
|
-- test creating distributed tables from partitioned citus local tables
|
||||||
|
CREATE TABLE partitioned_distributed (a INT UNIQUE) PARTITION BY RANGE(a);
|
||||||
|
CREATE TABLE partitioned_distributed_1 PARTITION OF partitioned_distributed FOR VALUES FROM (1) TO (4);
|
||||||
|
CREATE TABLE partitioned_distributed_2 PARTITION OF partitioned_distributed FOR VALUES FROM (5) TO (8);
|
||||||
|
SELECT citus_add_local_table_to_metadata('partitioned_distributed');
|
||||||
|
citus_add_local_table_to_metadata
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('partitioned_distributed','a');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname FROM pg_class
|
||||||
|
WHERE relname LIKE 'partitioned_distributed%'
|
||||||
|
AND relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = 'citus_local_tables_test_schema')
|
||||||
|
ORDER BY relname;
|
||||||
|
relname
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_distributed_1504038
|
||||||
|
partitioned_distributed_1504040
|
||||||
|
partitioned_distributed_1_1504042
|
||||||
|
partitioned_distributed_1_1504044
|
||||||
|
partitioned_distributed_1_a_key_1504042
|
||||||
|
partitioned_distributed_1_a_key_1504044
|
||||||
|
partitioned_distributed_2_1504046
|
||||||
|
partitioned_distributed_2_1504048
|
||||||
|
partitioned_distributed_2_a_key_1504046
|
||||||
|
partitioned_distributed_2_a_key_1504048
|
||||||
|
partitioned_distributed_a_key_1504038
|
||||||
|
partitioned_distributed_a_key_1504040
|
||||||
|
(12 rows)
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
SET search_path TO citus_local_tables_test_schema;
|
||||||
|
-- error out if converting multi-level partitioned table
|
||||||
|
CREATE TABLE multi_par (id text, country text) PARTITION BY RANGE (id);
|
||||||
|
ALTER TABLE multi_par ADD CONSTRAINT unique_constraint UNIQUE (id, country);
|
||||||
|
CREATE TABLE multi_par_a_to_i PARTITION OF multi_par FOR VALUES FROM ('a') TO ('j');
|
||||||
|
-- multi-level partitioning
|
||||||
|
CREATE TABLE multi_par_j_to_r PARTITION OF multi_par FOR VALUES FROM ('j') TO ('s') PARTITION BY LIST (country);
|
||||||
|
CREATE TABLE multi_par_j_to_r_japan PARTITION OF multi_par_j_to_r FOR VALUES IN ('japan');
|
||||||
|
-- these two should error out
|
||||||
|
SELECT citus_add_local_table_to_metadata('multi_par');
|
||||||
|
ERROR: Citus does not support multi-level partitioned tables
|
||||||
|
SELECT citus_add_local_table_to_metadata('multi_par',cascade_via_foreign_keys=>true);
|
||||||
|
ERROR: Citus does not support multi-level partitioned tables
|
||||||
|
-- should error out when cascading via fkeys as well
|
||||||
|
CREATE TABLE cas_1 (a text, b text);
|
||||||
|
ALTER TABLE cas_1 ADD CONSTRAINT unique_constraint_2 UNIQUE (a, b);
|
||||||
|
ALTER TABLE cas_1 ADD CONSTRAINT fkey_to_multi_parti FOREIGN KEY (a,b) REFERENCES multi_par(id, country);
|
||||||
|
SELECT citus_add_local_table_to_metadata('cas_1');
|
||||||
|
ERROR: relation citus_local_tables_test_schema.cas_1 is involved in a foreign key relationship with another table
|
||||||
|
SELECT citus_add_local_table_to_metadata('cas_1', cascade_via_foreign_keys=>true);
|
||||||
|
ERROR: Citus does not support multi-level partitioned tables
|
||||||
|
SELECT create_reference_table('cas_1');
|
||||||
|
ERROR: Citus does not support multi-level partitioned tables
|
||||||
|
ALTER TABLE cas_1 DROP CONSTRAINT fkey_to_multi_parti;
|
||||||
|
SELECT create_reference_table('cas_1');
|
||||||
|
create_reference_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
ALTER TABLE cas_1 ADD CONSTRAINT fkey_to_multi_parti FOREIGN KEY (a,b) REFERENCES multi_par(id, country);
|
||||||
|
ERROR: Citus does not support multi-level partitioned tables
|
||||||
|
-- undistribute tables to avoid unnecessary log messages later
|
||||||
|
select undistribute_table('citus_local_table_4', cascade_via_foreign_keys=>true);
|
||||||
|
NOTICE: creating a new table for citus_local_tables_test_schema.citus_local_table_4
|
||||||
|
NOTICE: moving the data of citus_local_tables_test_schema.citus_local_table_4
|
||||||
|
NOTICE: dropping the old citus_local_tables_test_schema.citus_local_table_4
|
||||||
|
NOTICE: renaming the new table to citus_local_tables_test_schema.citus_local_table_4
|
||||||
|
undistribute_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select undistribute_table('referencing_table', cascade_via_foreign_keys=>true);
|
||||||
|
NOTICE: creating a new table for citus_local_tables_test_schema.referencing_table
|
||||||
|
NOTICE: moving the data of citus_local_tables_test_schema.referencing_table
|
||||||
|
NOTICE: dropping the old citus_local_tables_test_schema.referencing_table
|
||||||
|
NOTICE: renaming the new table to citus_local_tables_test_schema.referencing_table
|
||||||
|
NOTICE: creating a new table for citus_local_tables_test_schema.referenced_table
|
||||||
|
NOTICE: moving the data of citus_local_tables_test_schema.referenced_table
|
||||||
|
NOTICE: dropping the old citus_local_tables_test_schema.referenced_table
|
||||||
|
NOTICE: renaming the new table to citus_local_tables_test_schema.referenced_table
|
||||||
|
undistribute_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- test dropping fkey
|
||||||
|
CREATE TABLE parent_2_child_1 (a int);
|
||||||
|
CREATE TABLE parent_1_child_1 (a int);
|
||||||
|
CREATE TABLE parent_2 (a INT UNIQUE) PARTITION BY RANGE(a);
|
||||||
|
CREATE TABLE parent_1 (a INT UNIQUE) PARTITION BY RANGE(a);
|
||||||
|
alter table parent_1 attach partition parent_1_child_1 default ;
|
||||||
|
alter table parent_2 attach partition parent_2_child_1 default ;
|
||||||
|
CREATE TABLE ref_table(a int unique);
|
||||||
|
alter table parent_1 add constraint fkey_test_drop foreign key(a) references ref_table(a);
|
||||||
|
alter table parent_2 add constraint fkey1 foreign key(a) references ref_table(a);
|
||||||
|
alter table parent_1 add constraint fkey2 foreign key(a) references parent_2(a);
|
||||||
|
SELECT create_reference_table('ref_table');
|
||||||
|
create_reference_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
alter table parent_1 drop constraint fkey_test_drop;
|
||||||
|
select count(*) from pg_constraint where conname = 'fkey_test_drop';
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- verify we still preserve the child-parent hierarchy after all conversions
|
||||||
|
-- check the shard partition
|
||||||
|
select inhrelid::regclass from pg_inherits where (select inhparent::regclass::text) ~ '^parent_1_\d{7}$' order by 1;
|
||||||
|
inhrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
parent_1_child_1_1190085
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- check the shell partition
|
||||||
|
select inhrelid::regclass from pg_inherits where inhparent='parent_1'::regclass order by 1;
|
||||||
|
inhrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
parent_1_child_1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
-- cleanup at exit
|
-- cleanup at exit
|
||||||
|
SET client_min_messages TO ERROR;
|
||||||
DROP SCHEMA citus_local_tables_test_schema, "CiTUS!LocalTables", "test_\'index_schema" CASCADE;
|
DROP SCHEMA citus_local_tables_test_schema, "CiTUS!LocalTables", "test_\'index_schema" CASCADE;
|
||||||
NOTICE: drop cascades to 27 other objects
|
|
||||||
|
|
|
@ -239,6 +239,412 @@ SELECT stxname FROM pg_statistic_ext ORDER BY stxname;
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
SET search_path TO citus_local_tables_mx;
|
SET search_path TO citus_local_tables_mx;
|
||||||
|
-- undistribute old tables to prevent unnecessary undistribute logs later
|
||||||
|
SELECT undistribute_table('citus_local_table', cascade_via_foreign_keys=>true);
|
||||||
|
NOTICE: creating a new table for citus_local_tables_mx.citus_local_table
|
||||||
|
NOTICE: moving the data of citus_local_tables_mx.citus_local_table
|
||||||
|
NOTICE: dropping the old citus_local_tables_mx.citus_local_table
|
||||||
|
NOTICE: renaming the new table to citus_local_tables_mx.citus_local_table
|
||||||
|
undistribute_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT undistribute_table('citus_local_table_3', cascade_via_foreign_keys=>true);
|
||||||
|
NOTICE: creating a new table for citus_local_tables_mx.citus_local_table_3
|
||||||
|
NOTICE: moving the data of citus_local_tables_mx.citus_local_table_3
|
||||||
|
NOTICE: dropping the old citus_local_tables_mx.citus_local_table_3
|
||||||
|
NOTICE: renaming the new table to citus_local_tables_mx.citus_local_table_3
|
||||||
|
NOTICE: creating a new table for citus_local_tables_mx.citus_local_table_4
|
||||||
|
NOTICE: moving the data of citus_local_tables_mx.citus_local_table_4
|
||||||
|
NOTICE: dropping the old citus_local_tables_mx.citus_local_table_4
|
||||||
|
NOTICE: renaming the new table to citus_local_tables_mx.citus_local_table_4
|
||||||
|
undistribute_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT undistribute_table('citus_local_table_stats', cascade_via_foreign_keys=>true);
|
||||||
|
NOTICE: creating a new table for citus_local_tables_mx.citus_local_table_stats
|
||||||
|
NOTICE: moving the data of citus_local_tables_mx.citus_local_table_stats
|
||||||
|
NOTICE: dropping the old citus_local_tables_mx.citus_local_table_stats
|
||||||
|
NOTICE: renaming the new table to citus_local_tables_mx.citus_local_table_stats
|
||||||
|
undistribute_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- verify that mx nodes have the shell table for partitioned citus local tables
|
||||||
|
CREATE TABLE local_table_fkey(a INT UNIQUE);
|
||||||
|
CREATE TABLE local_table_fkey2(a INT UNIQUE);
|
||||||
|
CREATE TABLE partitioned_mx (a INT UNIQUE) PARTITION BY RANGE(a);
|
||||||
|
ALTER TABLE partitioned_mx ADD CONSTRAINT fkey_to_local FOREIGN KEY (a) REFERENCES local_table_fkey(a);
|
||||||
|
CREATE TABLE IF NOT EXISTS partitioned_mx_1 PARTITION OF partitioned_mx FOR VALUES FROM (1) TO (4);
|
||||||
|
CREATE TABLE partitioned_mx_2 (a INT UNIQUE);
|
||||||
|
ALTER TABLE partitioned_mx ATTACH PARTITION partitioned_mx_2 FOR VALUES FROM (5) TO (8);
|
||||||
|
SELECT create_reference_table('local_table_fkey');
|
||||||
|
create_reference_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE partitioned_mx_3 (a INT UNIQUE);
|
||||||
|
ALTER TABLE partitioned_mx ATTACH PARTITION partitioned_mx_3 FOR VALUES FROM (9) TO (12);
|
||||||
|
-- these should error out since multi-level partitioned citus local tables are not supported
|
||||||
|
CREATE TABLE IF NOT EXISTS partitioned_mx_4 PARTITION OF partitioned_mx FOR VALUES FROM (13) TO (16) PARTITION BY RANGE (a);
|
||||||
|
ERROR: distributing multi-level partitioned tables is not supported
|
||||||
|
BEGIN;
|
||||||
|
CREATE TABLE partitioned_mx_4(a INT UNIQUE) PARTITION BY RANGE (a);
|
||||||
|
alter table partitioned_mx attach partition partitioned_mx_4 FOR VALUES FROM (13) TO (16);
|
||||||
|
ERROR: distributing multi-level partitioned tables is not supported
|
||||||
|
END;
|
||||||
|
CREATE TABLE multi_level_p (a INT UNIQUE) PARTITION BY RANGE (a);
|
||||||
|
CREATE TABLE IF NOT EXISTS multi_level_c PARTITION OF multi_level_p FOR VALUES FROM (13) TO (16) PARTITION BY RANGE (a);
|
||||||
|
select citus_add_local_table_to_metadata('multi_level_p'); --errors
|
||||||
|
ERROR: Citus does not support multi-level partitioned tables
|
||||||
|
select citus_add_local_table_to_metadata('multi_level_p', true); --errors
|
||||||
|
ERROR: Citus does not support multi-level partitioned tables
|
||||||
|
-- try attaching a partition with an external foreign key
|
||||||
|
CREATE TABLE partitioned_mx_4 (a INT UNIQUE);
|
||||||
|
ALTER TABLE partitioned_mx_4 ADD CONSTRAINT fkey_not_inherited FOREIGN KEY (a) REFERENCES local_table_fkey2(a);
|
||||||
|
-- these two should error out
|
||||||
|
ALTER TABLE partitioned_mx ATTACH PARTITION partitioned_mx_4 FOR VALUES FROM (13) TO (16);
|
||||||
|
ERROR: relation citus_local_tables_mx.partitioned_mx_4 is involved in a foreign key relationship with another table
|
||||||
|
ALTER TABLE partitioned_mx ATTACH PARTITION partitioned_mx_4 default;
|
||||||
|
ERROR: relation citus_local_tables_mx.partitioned_mx_4 is involved in a foreign key relationship with another table
|
||||||
|
SELECT
|
||||||
|
nmsp_parent.nspname AS parent_schema,
|
||||||
|
parent.relname AS parent,
|
||||||
|
nmsp_child.nspname AS child_schema,
|
||||||
|
child.relname AS child
|
||||||
|
FROM pg_inherits
|
||||||
|
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
|
||||||
|
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
|
||||||
|
JOIN pg_namespace nmsp_parent ON nmsp_parent.oid = parent.relnamespace
|
||||||
|
JOIN pg_namespace nmsp_child ON nmsp_child.oid = child.relnamespace
|
||||||
|
WHERE parent.relname='partitioned_mx'
|
||||||
|
ORDER BY child;
|
||||||
|
parent_schema | parent | child_schema | child
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
citus_local_tables_mx | partitioned_mx | citus_local_tables_mx | partitioned_mx_1
|
||||||
|
citus_local_tables_mx | partitioned_mx | citus_local_tables_mx | partitioned_mx_2
|
||||||
|
citus_local_tables_mx | partitioned_mx | citus_local_tables_mx | partitioned_mx_3
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname FROM pg_class WHERE relname LIKE 'partitioned_mx%' ORDER BY relname;
|
||||||
|
relname
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_mx
|
||||||
|
partitioned_mx_1
|
||||||
|
partitioned_mx_1_a_key
|
||||||
|
partitioned_mx_2
|
||||||
|
partitioned_mx_2_a_key
|
||||||
|
partitioned_mx_3
|
||||||
|
partitioned_mx_3_a_key
|
||||||
|
partitioned_mx_a_key
|
||||||
|
(8 rows)
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
nmsp_parent.nspname AS parent_schema,
|
||||||
|
parent.relname AS parent,
|
||||||
|
nmsp_child.nspname AS child_schema,
|
||||||
|
child.relname AS child
|
||||||
|
FROM pg_inherits
|
||||||
|
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
|
||||||
|
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
|
||||||
|
JOIN pg_namespace nmsp_parent ON nmsp_parent.oid = parent.relnamespace
|
||||||
|
JOIN pg_namespace nmsp_child ON nmsp_child.oid = child.relnamespace
|
||||||
|
WHERE parent.relname='partitioned_mx'
|
||||||
|
ORDER BY child;
|
||||||
|
parent_schema | parent | child_schema | child
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
citus_local_tables_mx | partitioned_mx | citus_local_tables_mx | partitioned_mx_1
|
||||||
|
citus_local_tables_mx | partitioned_mx | citus_local_tables_mx | partitioned_mx_2
|
||||||
|
citus_local_tables_mx | partitioned_mx | citus_local_tables_mx | partitioned_mx_3
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
SET search_path TO citus_local_tables_mx;
|
||||||
|
SET client_min_messages TO ERROR;
|
||||||
|
DROP TABLE partitioned_mx;
|
||||||
|
RESET client_min_messages;
|
||||||
|
-- test cascading via foreign keys
|
||||||
|
CREATE TABLE cas_1 (a INT UNIQUE);
|
||||||
|
CREATE TABLE cas_par (a INT UNIQUE) PARTITION BY RANGE(a);
|
||||||
|
CREATE TABLE cas_par_1 PARTITION OF cas_par FOR VALUES FROM (1) TO (4);
|
||||||
|
CREATE TABLE cas_par_2 PARTITION OF cas_par FOR VALUES FROM (5) TO (8);
|
||||||
|
ALTER TABLE cas_par_1 ADD CONSTRAINT fkey_cas_test_1 FOREIGN KEY (a) REFERENCES cas_1(a);
|
||||||
|
CREATE TABLE cas_par2 (a INT UNIQUE) PARTITION BY RANGE(a);
|
||||||
|
CREATE TABLE cas_par2_1 PARTITION OF cas_par2 FOR VALUES FROM (1) TO (4);
|
||||||
|
CREATE TABLE cas_par2_2 PARTITION OF cas_par2 FOR VALUES FROM (5) TO (8);
|
||||||
|
ALTER TABLE cas_par2_1 ADD CONSTRAINT fkey_cas_test_2 FOREIGN KEY (a) REFERENCES cas_1(a);
|
||||||
|
CREATE TABLE cas_par3 (a INT UNIQUE) PARTITION BY RANGE(a);
|
||||||
|
CREATE TABLE cas_par3_1 PARTITION OF cas_par3 FOR VALUES FROM (1) TO (4);
|
||||||
|
CREATE TABLE cas_par3_2 PARTITION OF cas_par3 FOR VALUES FROM (5) TO (8);
|
||||||
|
-- these two should error out as we should call the conversion from the parent
|
||||||
|
SELECT citus_add_local_table_to_metadata('cas_par2_2');
|
||||||
|
ERROR: cannot add local table cas_par2_2 to metadata since it is a partition of cas_par2. Instead, add the parent table cas_par2 to metadata.
|
||||||
|
SELECT citus_add_local_table_to_metadata('cas_par2_2', cascade_via_foreign_keys=>true);
|
||||||
|
ERROR: cannot add local table cas_par2_2 to metadata since it is a partition of cas_par2. Instead, add the parent table cas_par2 to metadata.
|
||||||
|
-- these two should error out as the foreign keys are not inherited from the parent
|
||||||
|
SELECT citus_add_local_table_to_metadata('cas_par2');
|
||||||
|
ERROR: cannot cascade operation via foreign keys as partition table citus_local_tables_mx.cas_par2_1 involved in a foreign key relationship that is not inherited from it's parent table
|
||||||
|
SELECT citus_add_local_table_to_metadata('cas_par2', cascade_via_foreign_keys=>true);
|
||||||
|
ERROR: cannot cascade operation via foreign keys as partition table citus_local_tables_mx.cas_par2_1 involved in a foreign key relationship that is not inherited from it's parent table
|
||||||
|
-- drop the foreign keys and establish them again using the parent table
|
||||||
|
ALTER TABLE cas_par_1 DROP CONSTRAINT fkey_cas_test_1;
|
||||||
|
ALTER TABLE cas_par2_1 DROP CONSTRAINT fkey_cas_test_2;
|
||||||
|
ALTER TABLE cas_par ADD CONSTRAINT fkey_cas_test_1 FOREIGN KEY (a) REFERENCES cas_1(a);
|
||||||
|
ALTER TABLE cas_par2 ADD CONSTRAINT fkey_cas_test_2 FOREIGN KEY (a) REFERENCES cas_1(a);
|
||||||
|
ALTER TABLE cas_par3 ADD CONSTRAINT fkey_cas_test_3 FOREIGN KEY (a) REFERENCES cas_par(a);
|
||||||
|
-- this should error out as cascade_via_foreign_keys is not set to true
|
||||||
|
SELECT citus_add_local_table_to_metadata('cas_par2');
|
||||||
|
ERROR: relation citus_local_tables_mx.cas_par2 is involved in a foreign key relationship with another table
|
||||||
|
-- this should work
|
||||||
|
SELECT citus_add_local_table_to_metadata('cas_par2', cascade_via_foreign_keys=>true);
|
||||||
|
citus_add_local_table_to_metadata
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- verify the partitioning hierarchy is preserved
|
||||||
|
select inhrelid::regclass from pg_inherits where inhparent='cas_par'::regclass order by 1;
|
||||||
|
inhrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
cas_par_1
|
||||||
|
cas_par_2
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- verify the fkeys + fkeys with shard ids are created
|
||||||
|
select conname from pg_constraint where conname like 'fkey_cas_test%' order by conname;
|
||||||
|
conname
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
fkey_cas_test_1
|
||||||
|
fkey_cas_test_1
|
||||||
|
fkey_cas_test_1
|
||||||
|
fkey_cas_test_1_1330008
|
||||||
|
fkey_cas_test_1_1330008
|
||||||
|
fkey_cas_test_1_1330008
|
||||||
|
fkey_cas_test_2
|
||||||
|
fkey_cas_test_2
|
||||||
|
fkey_cas_test_2
|
||||||
|
fkey_cas_test_2_1330006
|
||||||
|
fkey_cas_test_2_1330006
|
||||||
|
fkey_cas_test_2_1330006
|
||||||
|
fkey_cas_test_3
|
||||||
|
fkey_cas_test_3
|
||||||
|
fkey_cas_test_3
|
||||||
|
fkey_cas_test_3_1330013
|
||||||
|
fkey_cas_test_3_1330013
|
||||||
|
fkey_cas_test_3_1330013
|
||||||
|
(18 rows)
|
||||||
|
|
||||||
|
-- when all partitions are converted, there should be 40 tables and indexes
|
||||||
|
-- the individual names are not much relevant, so we only print the count
|
||||||
|
SELECT count(*) FROM pg_class WHERE relname LIKE 'cas\_%' AND relnamespace IN
|
||||||
|
(SELECT oid FROM pg_namespace WHERE nspname = 'citus_local_tables_mx');
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
40
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- verify on the mx worker
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
-- on worker, there should be 20, since the shards are created only on the coordinator
|
||||||
|
SELECT count(*) FROM pg_class WHERE relname LIKE 'cas\_%' AND relnamespace IN
|
||||||
|
(SELECT oid FROM pg_namespace WHERE nspname = 'citus_local_tables_mx');
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
20
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- verify that the shell foreign keys are created on the worker as well
|
||||||
|
select conname from pg_constraint where conname like 'fkey_cas_test%' order by conname;
|
||||||
|
conname
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
fkey_cas_test_1
|
||||||
|
fkey_cas_test_1
|
||||||
|
fkey_cas_test_1
|
||||||
|
fkey_cas_test_2
|
||||||
|
fkey_cas_test_2
|
||||||
|
fkey_cas_test_2
|
||||||
|
fkey_cas_test_3
|
||||||
|
fkey_cas_test_3
|
||||||
|
fkey_cas_test_3
|
||||||
|
(9 rows)
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
SET search_path TO citus_local_tables_mx;
|
||||||
|
-- undistribute table
|
||||||
|
-- this one should error out since we don't set the cascade option as true
|
||||||
|
SELECT undistribute_table('cas_par2');
|
||||||
|
ERROR: cannot complete operation because table cas_par2 has a foreign key
|
||||||
|
-- this one should work
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
SELECT undistribute_table('cas_par2', cascade_via_foreign_keys=>true);
|
||||||
|
undistribute_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- verify the partitioning hierarchy is preserved
|
||||||
|
select inhrelid::regclass from pg_inherits where inhparent='cas_par'::regclass order by 1;
|
||||||
|
inhrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
cas_par_1
|
||||||
|
cas_par_2
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- verify that the foreign keys with shard ids are gone, due to undistribution
|
||||||
|
select conname from pg_constraint where conname like 'fkey_cas_test%' order by conname;
|
||||||
|
conname
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
fkey_cas_test_1
|
||||||
|
fkey_cas_test_1
|
||||||
|
fkey_cas_test_1
|
||||||
|
fkey_cas_test_2
|
||||||
|
fkey_cas_test_2
|
||||||
|
fkey_cas_test_2
|
||||||
|
fkey_cas_test_3
|
||||||
|
fkey_cas_test_3
|
||||||
|
fkey_cas_test_3
|
||||||
|
(9 rows)
|
||||||
|
|
||||||
|
-- add a non-inherited fkey and verify it fails when trying to convert
|
||||||
|
ALTER TABLE cas_par2_1 ADD CONSTRAINT fkey_cas_test_3 FOREIGN KEY (a) REFERENCES cas_1(a);
|
||||||
|
SELECT citus_add_local_table_to_metadata('cas_par2', cascade_via_foreign_keys=>true);
|
||||||
|
ERROR: cannot cascade operation via foreign keys as partition table citus_local_tables_mx.cas_par2_1 involved in a foreign key relationship that is not inherited from it's parent table
|
||||||
|
-- verify undistribute_table works proper for the mx worker
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname FROM pg_class WHERE relname LIKE 'cas\_%' ORDER BY relname;
|
||||||
|
relname
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
SET search_path TO citus_local_tables_mx;
|
||||||
|
CREATE TABLE date_partitioned_citus_local_table_seq( measureid bigserial, eventdate date, measure_data jsonb, PRIMARY KEY (measureid, eventdate)) PARTITION BY RANGE(eventdate);
|
||||||
|
SELECT create_time_partitions('date_partitioned_citus_local_table_seq', INTERVAL '1 month', '2022-01-01', '2021-01-01');
|
||||||
|
create_time_partitions
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT citus_add_local_table_to_metadata('date_partitioned_citus_local_table_seq');
|
||||||
|
citus_add_local_table_to_metadata
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
DROP TABLE date_partitioned_citus_local_table_seq;
|
||||||
|
-- test sequences
|
||||||
|
CREATE TABLE par_citus_local_seq(measureid bigserial, val int) PARTITION BY RANGE(val);
|
||||||
|
CREATE TABLE par_citus_local_seq_1 PARTITION OF par_citus_local_seq FOR VALUES FROM (1) TO (4);
|
||||||
|
SELECT citus_add_local_table_to_metadata('par_citus_local_seq');
|
||||||
|
citus_add_local_table_to_metadata
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
INSERT INTO par_citus_local_seq (val) VALUES (1) RETURNING *;
|
||||||
|
measureid | val
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1 | 1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
INSERT INTO par_citus_local_seq (val) VALUES (2) RETURNING *;
|
||||||
|
measureid | val
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
2 | 2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
-- insert on the worker
|
||||||
|
INSERT INTO citus_local_tables_mx.par_citus_local_seq (val) VALUES (1) RETURNING *;
|
||||||
|
measureid | val
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
3940649673949185 | 1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
SET search_path TO citus_local_tables_mx;
|
||||||
|
INSERT INTO par_citus_local_seq (val) VALUES (2) RETURNING *;
|
||||||
|
measureid | val
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
3 | 2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT undistribute_table('par_citus_local_seq');
|
||||||
|
NOTICE: converting the partitions of citus_local_tables_mx.par_citus_local_seq
|
||||||
|
NOTICE: creating a new table for citus_local_tables_mx.par_citus_local_seq_1
|
||||||
|
NOTICE: moving the data of citus_local_tables_mx.par_citus_local_seq_1
|
||||||
|
NOTICE: dropping the old citus_local_tables_mx.par_citus_local_seq_1
|
||||||
|
NOTICE: renaming the new table to citus_local_tables_mx.par_citus_local_seq_1
|
||||||
|
NOTICE: creating a new table for citus_local_tables_mx.par_citus_local_seq
|
||||||
|
NOTICE: dropping the old citus_local_tables_mx.par_citus_local_seq
|
||||||
|
NOTICE: renaming the new table to citus_local_tables_mx.par_citus_local_seq
|
||||||
|
undistribute_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
INSERT INTO par_citus_local_seq (val) VALUES (3) RETURNING *;
|
||||||
|
measureid | val
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
4 | 3
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT measureid FROM par_citus_local_seq ORDER BY measureid;
|
||||||
|
measureid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
3940649673949185
|
||||||
|
(5 rows)
|
||||||
|
|
||||||
|
-- test adding invalid foreign key to partition table
|
||||||
|
CREATE TABLE citus_local_parent_1 (a INT UNIQUE) PARTITION BY RANGE(a);
|
||||||
|
CREATE TABLE citus_local_parent_2 (a INT UNIQUE) PARTITION BY RANGE(a);
|
||||||
|
CREATE TABLE citus_local_plain (a INT UNIQUE);
|
||||||
|
CREATE TABLE ref (a INT UNIQUE);
|
||||||
|
SELECT create_reference_table('ref');
|
||||||
|
create_reference_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
alter table citus_local_parent_1 add foreign key (a) references citus_local_parent_2(a);
|
||||||
|
alter table citus_local_plain add foreign key (a) references citus_local_parent_2(a);
|
||||||
|
CREATE TABLE citus_local_parent_1_child_1 PARTITION OF citus_local_parent_1 FOR VALUES FROM (3) TO (5);
|
||||||
|
CREATE TABLE citus_local_parent_1_child_2 PARTITION OF citus_local_parent_1 FOR VALUES FROM (30) TO (50);
|
||||||
|
CREATE TABLE citus_local_parent_2_child_1 PARTITION OF citus_local_parent_2 FOR VALUES FROM (40) TO (60);
|
||||||
|
-- this one should error out, since we cannot convert it to citus local table,
|
||||||
|
-- as citus local table partitions cannot have non-inherited foreign keys
|
||||||
|
alter table citus_local_parent_1_child_1 add foreign key(a) references ref(a);
|
||||||
|
ERROR: cannot build foreign key between reference table and a partition
|
||||||
|
-- this should work
|
||||||
|
alter table citus_local_parent_1 add constraint fkey_to_drop_test foreign key(a) references ref(a);
|
||||||
|
-- this should undistribute the table, and the entries should be gone from pg_dist_partition
|
||||||
|
select logicalrelid from pg_dist_partition where logicalrelid::text like 'citus_local_parent%';
|
||||||
|
logicalrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
citus_local_parent_1
|
||||||
|
citus_local_parent_2
|
||||||
|
citus_local_parent_2_child_1
|
||||||
|
citus_local_parent_1_child_1
|
||||||
|
citus_local_parent_1_child_2
|
||||||
|
(5 rows)
|
||||||
|
|
||||||
|
set client_min_messages to error;
|
||||||
|
alter table citus_local_parent_1 drop constraint fkey_to_drop_test;
|
||||||
|
select logicalrelid from pg_dist_partition where logicalrelid::text like 'citus_local_parent%';
|
||||||
|
logicalrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
SELECT master_remove_distributed_table_metadata_from_workers('citus_local_table_4'::regclass::oid, 'citus_local_tables_mx', 'citus_local_table_4');
|
SELECT master_remove_distributed_table_metadata_from_workers('citus_local_table_4'::regclass::oid, 'citus_local_tables_mx', 'citus_local_table_4');
|
||||||
master_remove_distributed_table_metadata_from_workers
|
master_remove_distributed_table_metadata_from_workers
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
|
@ -259,4 +665,3 @@ $$);
|
||||||
|
|
||||||
-- cleanup at exit
|
-- cleanup at exit
|
||||||
DROP SCHEMA citus_local_tables_mx CASCADE;
|
DROP SCHEMA citus_local_tables_mx CASCADE;
|
||||||
NOTICE: drop cascades to 19 other objects
|
|
||||||
|
|
|
@ -116,11 +116,12 @@ BEGIN;
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
BEGIN;
|
BEGIN;
|
||||||
CREATE TABLE partitioned_table (col_1 INT REFERENCES local_table_1 (col_1)) PARTITION BY RANGE (col_1);
|
CREATE TABLE partitioned_table (col_1 INT REFERENCES local_table_1 (col_1)) PARTITION BY RANGE (col_1);
|
||||||
-- now that we introduced a partitioned table into our foreign key subgraph,
|
|
||||||
-- citus_add_local_table_to_metadata(cascade_via_foreign_keys) would fail for
|
|
||||||
-- partitioned_table as citus_add_local_table_to_metadata doesn't support partitioned tables
|
|
||||||
SELECT citus_add_local_table_to_metadata('local_table_2', cascade_via_foreign_keys=>true);
|
SELECT citus_add_local_table_to_metadata('local_table_2', cascade_via_foreign_keys=>true);
|
||||||
ERROR: cannot add local table "partitioned_table" to metadata, only regular tables and foreign tables can be added to citus metadata
|
citus_add_local_table_to_metadata
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
BEGIN;
|
BEGIN;
|
||||||
DROP TABLE local_table_2;
|
DROP TABLE local_table_2;
|
||||||
|
|
|
@ -99,10 +99,9 @@ CREATE TABLE partitioned_table_1_100_200 PARTITION OF partitioned_table_1 FOR VA
|
||||||
CREATE TABLE partitioned_table_1_200_300 PARTITION OF partitioned_table_1 FOR VALUES FROM (200) TO (300);
|
CREATE TABLE partitioned_table_1_200_300 PARTITION OF partitioned_table_1 FOR VALUES FROM (200) TO (300);
|
||||||
INSERT INTO partitioned_table_1 SELECT i FROM generate_series(195, 205) i;
|
INSERT INTO partitioned_table_1 SELECT i FROM generate_series(195, 205) i;
|
||||||
ALTER TABLE partitioned_table_1 ADD CONSTRAINT fkey_8 FOREIGN KEY (col_1) REFERENCES local_table_4(col_1);
|
ALTER TABLE partitioned_table_1 ADD CONSTRAINT fkey_8 FOREIGN KEY (col_1) REFERENCES local_table_4(col_1);
|
||||||
-- now that we attached partitioned table to graph below errors out
|
BEGIN;
|
||||||
-- since we cannot create citus local table from partitioned tables
|
|
||||||
ALTER TABLE reference_table_1 ADD CONSTRAINT fkey_9 FOREIGN KEY (col_1) REFERENCES local_table_1(col_1);
|
ALTER TABLE reference_table_1 ADD CONSTRAINT fkey_9 FOREIGN KEY (col_1) REFERENCES local_table_1(col_1);
|
||||||
ERROR: cannot add local table "partitioned_table_1" to metadata, only regular tables and foreign tables can be added to citus metadata
|
ROLLBACK;
|
||||||
ALTER TABLE partitioned_table_1 DROP CONSTRAINT fkey_8;
|
ALTER TABLE partitioned_table_1 DROP CONSTRAINT fkey_8;
|
||||||
BEGIN;
|
BEGIN;
|
||||||
-- now that we detached partitioned table from graph, succeeds
|
-- now that we detached partitioned table from graph, succeeds
|
||||||
|
@ -329,7 +328,7 @@ BEGIN;
|
||||||
|
|
||||||
-- show that we validate foreign key constraints, errors out
|
-- show that we validate foreign key constraints, errors out
|
||||||
INSERT INTO local_table_5 VALUES (300);
|
INSERT INTO local_table_5 VALUES (300);
|
||||||
ERROR: insert or update on table "local_table_5_1518070" violates foreign key constraint "local_table_5_col_1_fkey1_1518070"
|
ERROR: insert or update on table "local_table_5_1518073" violates foreign key constraint "local_table_5_col_1_fkey1_1518073"
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
BEGIN;
|
BEGIN;
|
||||||
CREATE SCHEMA another_schema_fkeys_between_local_ref;
|
CREATE SCHEMA another_schema_fkeys_between_local_ref;
|
||||||
|
@ -620,10 +619,9 @@ ORDER BY tablename;
|
||||||
reference_table_1 | n | t
|
reference_table_1 | n | t
|
||||||
(7 rows)
|
(7 rows)
|
||||||
|
|
||||||
-- this errors out as we don't support creating citus local
|
BEGIN;
|
||||||
-- tables from partitioned tables
|
|
||||||
CREATE TABLE part_local_table (col_1 INT REFERENCES reference_table_1(col_1)) PARTITION BY RANGE (col_1);
|
CREATE TABLE part_local_table (col_1 INT REFERENCES reference_table_1(col_1)) PARTITION BY RANGE (col_1);
|
||||||
ERROR: cannot add local table "part_local_table" to metadata, only regular tables and foreign tables can be added to citus metadata
|
ROLLBACK;
|
||||||
-- they fail as col_99 does not exist
|
-- they fail as col_99 does not exist
|
||||||
CREATE TABLE local_table_5 (col_1 INT, FOREIGN KEY (col_99) REFERENCES reference_table_1(col_1));
|
CREATE TABLE local_table_5 (col_1 INT, FOREIGN KEY (col_99) REFERENCES reference_table_1(col_1));
|
||||||
ERROR: column "col_99" referenced in foreign key constraint does not exist
|
ERROR: column "col_99" referenced in foreign key constraint does not exist
|
||||||
|
|
|
@ -3763,6 +3763,306 @@ BEGIN;
|
||||||
|
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
DROP TABLE pi_table;
|
DROP TABLE pi_table;
|
||||||
|
-- 6) test with citus local table
|
||||||
|
select 1 from citus_add_node('localhost', :master_port, groupid=>0);
|
||||||
|
NOTICE: Replicating reference table "orders_reference" to the node localhost:xxxxx
|
||||||
|
NOTICE: Replicating reference table "customer" to the node localhost:xxxxx
|
||||||
|
NOTICE: Replicating reference table "nation" to the node localhost:xxxxx
|
||||||
|
NOTICE: Replicating reference table "part" to the node localhost:xxxxx
|
||||||
|
NOTICE: Replicating reference table "supplier" to the node localhost:xxxxx
|
||||||
|
NOTICE: Replicating reference table "users_ref_test_table" to the node localhost:xxxxx
|
||||||
|
NOTICE: Replicating reference table "events_reference_table" to the node localhost:xxxxx
|
||||||
|
NOTICE: Replicating reference table "users_reference_table" to the node localhost:xxxxx
|
||||||
|
?column?
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE date_partitioned_citus_local_table(
|
||||||
|
measureid integer,
|
||||||
|
eventdate date,
|
||||||
|
measure_data jsonb) PARTITION BY RANGE(eventdate);
|
||||||
|
SELECT citus_add_local_table_to_metadata('date_partitioned_citus_local_table');
|
||||||
|
citus_add_local_table_to_metadata
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- test interval must be multiple days for date partitioned table
|
||||||
|
SELECT create_time_partitions('date_partitioned_citus_local_table', INTERVAL '6 hours', '2022-01-01', '2021-01-01');
|
||||||
|
ERROR: partition interval of date partitioned table must be day or multiple days
|
||||||
|
CONTEXT: PL/pgSQL function get_missing_time_partition_ranges(regclass,interval,timestamp with time zone,timestamp with time zone) line XX at RAISE
|
||||||
|
PL/pgSQL function create_time_partitions(regclass,interval,timestamp with time zone,timestamp with time zone) line XX at FOR over SELECT rows
|
||||||
|
SELECT create_time_partitions('date_partitioned_citus_local_table', INTERVAL '1 week 1 day 1 hour', '2022-01-01', '2021-01-01');
|
||||||
|
ERROR: partition interval of date partitioned table must be day or multiple days
|
||||||
|
CONTEXT: PL/pgSQL function get_missing_time_partition_ranges(regclass,interval,timestamp with time zone,timestamp with time zone) line XX at RAISE
|
||||||
|
PL/pgSQL function create_time_partitions(regclass,interval,timestamp with time zone,timestamp with time zone) line XX at FOR over SELECT rows
|
||||||
|
-- test with various intervals
|
||||||
|
BEGIN;
|
||||||
|
SELECT create_time_partitions('date_partitioned_citus_local_table', INTERVAL '1 day', '2021-02-01', '2021-01-01');
|
||||||
|
create_time_partitions
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM time_partitions WHERE parent_table = 'date_partitioned_citus_local_table'::regclass ORDER BY 3;
|
||||||
|
parent_table | partition_column | partition | from_value | to_value | access_method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_01 | 01-01-2021 | 01-02-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_02 | 01-02-2021 | 01-03-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_03 | 01-03-2021 | 01-04-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_04 | 01-04-2021 | 01-05-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_05 | 01-05-2021 | 01-06-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_06 | 01-06-2021 | 01-07-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_07 | 01-07-2021 | 01-08-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_08 | 01-08-2021 | 01-09-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_09 | 01-09-2021 | 01-10-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_10 | 01-10-2021 | 01-11-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_11 | 01-11-2021 | 01-12-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_12 | 01-12-2021 | 01-13-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_13 | 01-13-2021 | 01-14-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_14 | 01-14-2021 | 01-15-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_15 | 01-15-2021 | 01-16-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_16 | 01-16-2021 | 01-17-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_17 | 01-17-2021 | 01-18-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_18 | 01-18-2021 | 01-19-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_19 | 01-19-2021 | 01-20-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_20 | 01-20-2021 | 01-21-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_21 | 01-21-2021 | 01-22-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_22 | 01-22-2021 | 01-23-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_23 | 01-23-2021 | 01-24-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_24 | 01-24-2021 | 01-25-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_25 | 01-25-2021 | 01-26-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_26 | 01-26-2021 | 01-27-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_27 | 01-27-2021 | 01-28-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_28 | 01-28-2021 | 01-29-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_29 | 01-29-2021 | 01-30-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_30 | 01-30-2021 | 01-31-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_31 | 01-31-2021 | 02-01-2021 | heap
|
||||||
|
(31 rows)
|
||||||
|
|
||||||
|
ROLLBACK;
|
||||||
|
BEGIN;
|
||||||
|
SELECT create_time_partitions('date_partitioned_citus_local_table', INTERVAL '1 week', '2022-01-01', '2021-01-01');
|
||||||
|
create_time_partitions
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM time_partitions WHERE parent_table = 'date_partitioned_citus_local_table'::regclass ORDER BY 3;
|
||||||
|
parent_table | partition_column | partition | from_value | to_value | access_method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2020w53 | 12-28-2020 | 01-04-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w01 | 01-04-2021 | 01-11-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w02 | 01-11-2021 | 01-18-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w03 | 01-18-2021 | 01-25-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w04 | 01-25-2021 | 02-01-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w05 | 02-01-2021 | 02-08-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w06 | 02-08-2021 | 02-15-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w07 | 02-15-2021 | 02-22-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w08 | 02-22-2021 | 03-01-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w09 | 03-01-2021 | 03-08-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w10 | 03-08-2021 | 03-15-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w11 | 03-15-2021 | 03-22-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w12 | 03-22-2021 | 03-29-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w13 | 03-29-2021 | 04-05-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w14 | 04-05-2021 | 04-12-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w15 | 04-12-2021 | 04-19-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w16 | 04-19-2021 | 04-26-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w17 | 04-26-2021 | 05-03-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w18 | 05-03-2021 | 05-10-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w19 | 05-10-2021 | 05-17-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w20 | 05-17-2021 | 05-24-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w21 | 05-24-2021 | 05-31-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w22 | 05-31-2021 | 06-07-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w23 | 06-07-2021 | 06-14-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w24 | 06-14-2021 | 06-21-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w25 | 06-21-2021 | 06-28-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w26 | 06-28-2021 | 07-05-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w27 | 07-05-2021 | 07-12-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w28 | 07-12-2021 | 07-19-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w29 | 07-19-2021 | 07-26-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w30 | 07-26-2021 | 08-02-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w31 | 08-02-2021 | 08-09-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w32 | 08-09-2021 | 08-16-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w33 | 08-16-2021 | 08-23-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w34 | 08-23-2021 | 08-30-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w35 | 08-30-2021 | 09-06-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w36 | 09-06-2021 | 09-13-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w37 | 09-13-2021 | 09-20-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w38 | 09-20-2021 | 09-27-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w39 | 09-27-2021 | 10-04-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w40 | 10-04-2021 | 10-11-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w41 | 10-11-2021 | 10-18-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w42 | 10-18-2021 | 10-25-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w43 | 10-25-2021 | 11-01-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w44 | 11-01-2021 | 11-08-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w45 | 11-08-2021 | 11-15-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w46 | 11-15-2021 | 11-22-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w47 | 11-22-2021 | 11-29-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w48 | 11-29-2021 | 12-06-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w49 | 12-06-2021 | 12-13-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w50 | 12-13-2021 | 12-20-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w51 | 12-20-2021 | 12-27-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021w52 | 12-27-2021 | 01-03-2022 | heap
|
||||||
|
(53 rows)
|
||||||
|
|
||||||
|
ROLLBACK;
|
||||||
|
set client_min_messages to error;
|
||||||
|
DROP TABLE date_partitioned_citus_local_table;
|
||||||
|
-- also test with foreign key
|
||||||
|
CREATE TABLE date_partitioned_citus_local_table(
|
||||||
|
measureid integer,
|
||||||
|
eventdate date,
|
||||||
|
measure_data jsonb, PRIMARY KEY (measureid, eventdate)) PARTITION BY RANGE(eventdate);
|
||||||
|
SELECT citus_add_local_table_to_metadata('date_partitioned_citus_local_table');
|
||||||
|
citus_add_local_table_to_metadata
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- test interval must be multiple days for date partitioned table
|
||||||
|
SELECT create_time_partitions('date_partitioned_citus_local_table', INTERVAL '1 day', '2021-02-01', '2021-01-01');
|
||||||
|
create_time_partitions
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE date_partitioned_citus_local_table_2(
|
||||||
|
measureid integer,
|
||||||
|
eventdate date,
|
||||||
|
measure_data jsonb, PRIMARY KEY (measureid, eventdate)) PARTITION BY RANGE(eventdate);
|
||||||
|
SELECT citus_add_local_table_to_metadata('date_partitioned_citus_local_table_2');
|
||||||
|
citus_add_local_table_to_metadata
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
ALTER TABLE date_partitioned_citus_local_table_2 ADD CONSTRAINT fkey_1 FOREIGN KEY (measureid, eventdate) REFERENCES date_partitioned_citus_local_table(measureid, eventdate);
|
||||||
|
SELECT create_time_partitions('date_partitioned_citus_local_table_2', INTERVAL '1 day', '2021-02-01', '2021-01-01');
|
||||||
|
create_time_partitions
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- after the above work, these should also work for creating new partitions
|
||||||
|
BEGIN;
|
||||||
|
SELECT create_time_partitions('date_partitioned_citus_local_table', INTERVAL '1 day', '2021-03-01', '2021-02-01');
|
||||||
|
create_time_partitions
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM time_partitions WHERE parent_table = 'date_partitioned_citus_local_table'::regclass ORDER BY 3;
|
||||||
|
parent_table | partition_column | partition | from_value | to_value | access_method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_01 | 01-01-2021 | 01-02-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_02 | 01-02-2021 | 01-03-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_03 | 01-03-2021 | 01-04-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_04 | 01-04-2021 | 01-05-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_05 | 01-05-2021 | 01-06-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_06 | 01-06-2021 | 01-07-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_07 | 01-07-2021 | 01-08-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_08 | 01-08-2021 | 01-09-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_09 | 01-09-2021 | 01-10-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_10 | 01-10-2021 | 01-11-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_11 | 01-11-2021 | 01-12-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_12 | 01-12-2021 | 01-13-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_13 | 01-13-2021 | 01-14-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_14 | 01-14-2021 | 01-15-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_15 | 01-15-2021 | 01-16-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_16 | 01-16-2021 | 01-17-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_17 | 01-17-2021 | 01-18-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_18 | 01-18-2021 | 01-19-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_19 | 01-19-2021 | 01-20-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_20 | 01-20-2021 | 01-21-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_21 | 01-21-2021 | 01-22-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_22 | 01-22-2021 | 01-23-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_23 | 01-23-2021 | 01-24-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_24 | 01-24-2021 | 01-25-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_25 | 01-25-2021 | 01-26-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_26 | 01-26-2021 | 01-27-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_27 | 01-27-2021 | 01-28-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_28 | 01-28-2021 | 01-29-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_29 | 01-29-2021 | 01-30-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_30 | 01-30-2021 | 01-31-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_31 | 01-31-2021 | 02-01-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_01 | 02-01-2021 | 02-02-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_02 | 02-02-2021 | 02-03-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_03 | 02-03-2021 | 02-04-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_04 | 02-04-2021 | 02-05-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_05 | 02-05-2021 | 02-06-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_06 | 02-06-2021 | 02-07-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_07 | 02-07-2021 | 02-08-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_08 | 02-08-2021 | 02-09-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_09 | 02-09-2021 | 02-10-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_10 | 02-10-2021 | 02-11-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_11 | 02-11-2021 | 02-12-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_12 | 02-12-2021 | 02-13-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_13 | 02-13-2021 | 02-14-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_14 | 02-14-2021 | 02-15-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_15 | 02-15-2021 | 02-16-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_16 | 02-16-2021 | 02-17-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_17 | 02-17-2021 | 02-18-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_18 | 02-18-2021 | 02-19-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_19 | 02-19-2021 | 02-20-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_20 | 02-20-2021 | 02-21-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_21 | 02-21-2021 | 02-22-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_22 | 02-22-2021 | 02-23-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_23 | 02-23-2021 | 02-24-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_24 | 02-24-2021 | 02-25-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_25 | 02-25-2021 | 02-26-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_26 | 02-26-2021 | 02-27-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_27 | 02-27-2021 | 02-28-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_02_28 | 02-28-2021 | 03-01-2021 | heap
|
||||||
|
(59 rows)
|
||||||
|
|
||||||
|
ROLLBACK;
|
||||||
|
BEGIN;
|
||||||
|
SELECT create_time_partitions('date_partitioned_citus_local_table_2', INTERVAL '1 day', '2021-03-01', '2021-02-01');
|
||||||
|
create_time_partitions
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM time_partitions WHERE parent_table = 'date_partitioned_citus_local_table'::regclass ORDER BY 3;
|
||||||
|
parent_table | partition_column | partition | from_value | to_value | access_method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_01 | 01-01-2021 | 01-02-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_02 | 01-02-2021 | 01-03-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_03 | 01-03-2021 | 01-04-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_04 | 01-04-2021 | 01-05-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_05 | 01-05-2021 | 01-06-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_06 | 01-06-2021 | 01-07-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_07 | 01-07-2021 | 01-08-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_08 | 01-08-2021 | 01-09-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_09 | 01-09-2021 | 01-10-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_10 | 01-10-2021 | 01-11-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_11 | 01-11-2021 | 01-12-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_12 | 01-12-2021 | 01-13-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_13 | 01-13-2021 | 01-14-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_14 | 01-14-2021 | 01-15-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_15 | 01-15-2021 | 01-16-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_16 | 01-16-2021 | 01-17-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_17 | 01-17-2021 | 01-18-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_18 | 01-18-2021 | 01-19-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_19 | 01-19-2021 | 01-20-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_20 | 01-20-2021 | 01-21-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_21 | 01-21-2021 | 01-22-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_22 | 01-22-2021 | 01-23-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_23 | 01-23-2021 | 01-24-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_24 | 01-24-2021 | 01-25-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_25 | 01-25-2021 | 01-26-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_26 | 01-26-2021 | 01-27-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_27 | 01-27-2021 | 01-28-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_28 | 01-28-2021 | 01-29-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_29 | 01-29-2021 | 01-30-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_30 | 01-30-2021 | 01-31-2021 | heap
|
||||||
|
date_partitioned_citus_local_table | eventdate | date_partitioned_citus_local_table_p2021_01_31 | 01-31-2021 | 02-01-2021 | heap
|
||||||
|
(31 rows)
|
||||||
|
|
||||||
|
ROLLBACK;
|
||||||
|
set client_min_messages to notice;
|
||||||
-- c) test drop_old_time_partitions
|
-- c) test drop_old_time_partitions
|
||||||
-- 1) test with date partitioned table
|
-- 1) test with date partitioned table
|
||||||
CREATE TABLE date_partitioned_table_to_exp (event_date date, event int) partition by range (event_date);
|
CREATE TABLE date_partitioned_table_to_exp (event_date date, event int) partition by range (event_date);
|
||||||
|
@ -3875,6 +4175,46 @@ SELECT partition FROM time_partitions WHERE parent_table = '"test !/ \n _dist_12
|
||||||
|
|
||||||
\set VERBOSITY default
|
\set VERBOSITY default
|
||||||
DROP TABLE "test !/ \n _dist_123_table_exp";
|
DROP TABLE "test !/ \n _dist_123_table_exp";
|
||||||
|
-- 4) test with citus local tables
|
||||||
|
CREATE TABLE date_partitioned_table_to_exp (event_date date, event int) partition by range (event_date);
|
||||||
|
SELECT citus_add_local_table_to_metadata('date_partitioned_table_to_exp');
|
||||||
|
citus_add_local_table_to_metadata
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE date_partitioned_table_to_exp_d00 PARTITION OF date_partitioned_table_to_exp FOR VALUES FROM ('2000-01-01') TO ('2009-12-31');
|
||||||
|
CREATE TABLE date_partitioned_table_to_exp_d10 PARTITION OF date_partitioned_table_to_exp FOR VALUES FROM ('2010-01-01') TO ('2019-12-31');
|
||||||
|
CREATE TABLE date_partitioned_table_to_exp_d20 PARTITION OF date_partitioned_table_to_exp FOR VALUES FROM ('2020-01-01') TO ('2029-12-31');
|
||||||
|
\set VERBOSITY terse
|
||||||
|
-- expire no partitions
|
||||||
|
CALL drop_old_time_partitions('date_partitioned_table_to_exp', '1999-01-01');
|
||||||
|
SELECT partition FROM time_partitions WHERE parent_table = 'date_partitioned_table_to_exp'::regclass ORDER BY partition::text;
|
||||||
|
partition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
date_partitioned_table_to_exp_d00
|
||||||
|
date_partitioned_table_to_exp_d10
|
||||||
|
date_partitioned_table_to_exp_d20
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
-- expire 2 old partitions
|
||||||
|
CALL drop_old_time_partitions('date_partitioned_table_to_exp', '2021-01-01');
|
||||||
|
NOTICE: dropping date_partitioned_table_to_exp_d00 with start time 01-01-2000 and end time 12-31-2009
|
||||||
|
NOTICE: dropping date_partitioned_table_to_exp_d10 with start time 01-01-2010 and end time 12-31-2019
|
||||||
|
SELECT partition FROM time_partitions WHERE parent_table = 'date_partitioned_table_to_exp'::regclass ORDER BY partition::text;
|
||||||
|
partition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
date_partitioned_table_to_exp_d20
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\set VERBOSITY default
|
||||||
|
DROP TABLE date_partitioned_table_to_exp;
|
||||||
|
SELECT citus_remove_node('localhost', :master_port);
|
||||||
|
citus_remove_node
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
-- d) invalid tables for helper UDFs
|
-- d) invalid tables for helper UDFs
|
||||||
CREATE TABLE multiple_partition_column_table(
|
CREATE TABLE multiple_partition_column_table(
|
||||||
event_id bigserial,
|
event_id bigserial,
|
||||||
|
@ -3986,10 +4326,12 @@ NOTICE: dropping metadata on the node (localhost,57637)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
DROP SCHEMA partitioning_schema CASCADE;
|
DROP SCHEMA partitioning_schema CASCADE;
|
||||||
NOTICE: drop cascades to 4 other objects
|
NOTICE: drop cascades to 6 other objects
|
||||||
DETAIL: drop cascades to table partitioning_schema."schema-test"
|
DETAIL: drop cascades to table partitioning_schema."schema-test"
|
||||||
drop cascades to table partitioning_schema.another_distributed_table
|
drop cascades to table partitioning_schema.another_distributed_table
|
||||||
drop cascades to table partitioning_schema.distributed_parent_table
|
drop cascades to table partitioning_schema.distributed_parent_table
|
||||||
|
drop cascades to table partitioning_schema.date_partitioned_citus_local_table
|
||||||
|
drop cascades to table partitioning_schema.date_partitioned_citus_local_table_2
|
||||||
drop cascades to table partitioning_schema.part_table_with_very_long_name
|
drop cascades to table partitioning_schema.part_table_with_very_long_name
|
||||||
RESET search_path;
|
RESET search_path;
|
||||||
DROP TABLE IF EXISTS
|
DROP TABLE IF EXISTS
|
||||||
|
|
|
@ -1289,14 +1289,6 @@ ALTER TABLE citus_local_table_1 ADD CONSTRAINT fkey_4 FOREIGN KEY (col_1) REFERE
|
||||||
ALTER TABLE partitioned_table_1 ADD CONSTRAINT fkey_5 FOREIGN KEY (col_1) REFERENCES reference_table_1(col_2);
|
ALTER TABLE partitioned_table_1 ADD CONSTRAINT fkey_5 FOREIGN KEY (col_1) REFERENCES reference_table_1(col_2);
|
||||||
SELECT undistribute_table('partitioned_table_1', cascade_via_foreign_keys=>true);
|
SELECT undistribute_table('partitioned_table_1', cascade_via_foreign_keys=>true);
|
||||||
NOTICE: converting the partitions of single_node.partitioned_table_1
|
NOTICE: converting the partitions of single_node.partitioned_table_1
|
||||||
NOTICE: creating a new table for single_node.partitioned_table_1_100_200
|
|
||||||
NOTICE: moving the data of single_node.partitioned_table_1_100_200
|
|
||||||
NOTICE: dropping the old single_node.partitioned_table_1_100_200
|
|
||||||
NOTICE: renaming the new table to single_node.partitioned_table_1_100_200
|
|
||||||
NOTICE: creating a new table for single_node.partitioned_table_1_200_300
|
|
||||||
NOTICE: moving the data of single_node.partitioned_table_1_200_300
|
|
||||||
NOTICE: dropping the old single_node.partitioned_table_1_200_300
|
|
||||||
NOTICE: renaming the new table to single_node.partitioned_table_1_200_300
|
|
||||||
NOTICE: creating a new table for single_node.partitioned_table_1
|
NOTICE: creating a new table for single_node.partitioned_table_1
|
||||||
NOTICE: dropping the old single_node.partitioned_table_1
|
NOTICE: dropping the old single_node.partitioned_table_1
|
||||||
NOTICE: renaming the new table to single_node.partitioned_table_1
|
NOTICE: renaming the new table to single_node.partitioned_table_1
|
||||||
|
@ -1312,6 +1304,14 @@ NOTICE: creating a new table for single_node.citus_local_table_1
|
||||||
NOTICE: moving the data of single_node.citus_local_table_1
|
NOTICE: moving the data of single_node.citus_local_table_1
|
||||||
NOTICE: dropping the old single_node.citus_local_table_1
|
NOTICE: dropping the old single_node.citus_local_table_1
|
||||||
NOTICE: renaming the new table to single_node.citus_local_table_1
|
NOTICE: renaming the new table to single_node.citus_local_table_1
|
||||||
|
NOTICE: creating a new table for single_node.partitioned_table_1_100_200
|
||||||
|
NOTICE: moving the data of single_node.partitioned_table_1_100_200
|
||||||
|
NOTICE: dropping the old single_node.partitioned_table_1_100_200
|
||||||
|
NOTICE: renaming the new table to single_node.partitioned_table_1_100_200
|
||||||
|
NOTICE: creating a new table for single_node.partitioned_table_1_200_300
|
||||||
|
NOTICE: moving the data of single_node.partitioned_table_1_200_300
|
||||||
|
NOTICE: dropping the old single_node.partitioned_table_1_200_300
|
||||||
|
NOTICE: renaming the new table to single_node.partitioned_table_1_200_300
|
||||||
undistribute_table
|
undistribute_table
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -382,12 +382,12 @@ BEGIN;
|
||||||
ORDER BY 1,2,3;
|
ORDER BY 1,2,3;
|
||||||
conname | conrelid | confrelid
|
conname | conrelid | confrelid
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
|
fkey_10 | partitioned_table_2 | reference_table_3
|
||||||
fkey_10 | partitioned_table_2_100_200 | reference_table_3
|
fkey_10 | partitioned_table_2_100_200 | reference_table_3
|
||||||
fkey_10 | partitioned_table_2_200_300 | reference_table_3
|
fkey_10 | partitioned_table_2_200_300 | reference_table_3
|
||||||
fkey_10 | partitioned_table_2 | reference_table_3
|
fkey_9 | partitioned_table_1 | reference_table_3
|
||||||
fkey_9 | partitioned_table_1_100_200 | reference_table_3
|
fkey_9 | partitioned_table_1_100_200 | reference_table_3
|
||||||
fkey_9 | partitioned_table_1_200_300 | reference_table_3
|
fkey_9 | partitioned_table_1_200_300 | reference_table_3
|
||||||
fkey_9 | partitioned_table_1 | reference_table_3
|
|
||||||
(6 rows)
|
(6 rows)
|
||||||
|
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
|
|
|
@ -301,5 +301,40 @@ BEGIN;
|
||||||
SELECT * FROM reference_table;
|
SELECT * FROM reference_table;
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
|
|
||||||
|
-- test on partitioned citus local tables
|
||||||
|
CREATE TABLE par_citus_local_table (val int) PARTITION BY RANGE(val);
|
||||||
|
CREATE TABLE par_citus_local_table_1 PARTITION OF par_citus_local_table FOR VALUES FROM (1) TO (10000);
|
||||||
|
CREATE TABLE par_another_citus_local_table (val int unique) PARTITION BY RANGE(val);
|
||||||
|
CREATE TABLE par_another_citus_local_table_1 PARTITION OF par_another_citus_local_table FOR VALUES FROM (1) TO (10000);
|
||||||
|
|
||||||
|
ALTER TABLE par_another_citus_local_table ADD CONSTRAINT fkey_self FOREIGN KEY(val) REFERENCES par_another_citus_local_table(val);
|
||||||
|
ALTER TABLE par_citus_local_table ADD CONSTRAINT fkey_c_to_c FOREIGN KEY(val) REFERENCES par_another_citus_local_table(val) ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
SELECT citus_add_local_table_to_metadata('par_another_citus_local_table', cascade_via_foreign_keys=>true);
|
||||||
|
|
||||||
|
CREATE TABLE par_reference_table(val int);
|
||||||
|
SELECT create_reference_table('par_reference_table');
|
||||||
|
|
||||||
|
CREATE FUNCTION par_insert_100() RETURNS trigger AS $par_insert_100$
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO par_reference_table VALUES (100);
|
||||||
|
RETURN NEW;
|
||||||
|
END;
|
||||||
|
$par_insert_100$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
CREATE TRIGGER par_insert_100_trigger
|
||||||
|
AFTER TRUNCATE ON par_another_citus_local_table
|
||||||
|
FOR EACH STATEMENT EXECUTE FUNCTION par_insert_100();
|
||||||
|
|
||||||
|
CREATE TRIGGER insert_100_trigger
|
||||||
|
AFTER TRUNCATE ON par_citus_local_table
|
||||||
|
FOR EACH STATEMENT EXECUTE FUNCTION par_insert_100();
|
||||||
|
|
||||||
|
TRUNCATE par_another_citus_local_table CASCADE;
|
||||||
|
-- we should see two rows with "100"
|
||||||
|
SELECT * FROM par_reference_table;
|
||||||
|
ROLLBACK;
|
||||||
|
|
||||||
-- cleanup at exit
|
-- cleanup at exit
|
||||||
DROP SCHEMA citus_local_table_triggers, "interesting!schema" CASCADE;
|
DROP SCHEMA citus_local_table_triggers, "interesting!schema" CASCADE;
|
||||||
|
|
|
@ -93,42 +93,6 @@ SELECT create_distributed_table('distributed_table', 'a');
|
||||||
-- cannot create citus local table from an existing citus table
|
-- cannot create citus local table from an existing citus table
|
||||||
SELECT citus_add_local_table_to_metadata('distributed_table');
|
SELECT citus_add_local_table_to_metadata('distributed_table');
|
||||||
|
|
||||||
-- partitioned table tests --
|
|
||||||
|
|
||||||
CREATE TABLE partitioned_table(a int, b int) PARTITION BY RANGE (a);
|
|
||||||
CREATE TABLE partitioned_table_1 PARTITION OF partitioned_table FOR VALUES FROM (0) TO (10);
|
|
||||||
CREATE TABLE partitioned_table_2 PARTITION OF partitioned_table FOR VALUES FROM (10) TO (20);
|
|
||||||
|
|
||||||
-- cannot create partitioned citus local tables
|
|
||||||
SELECT citus_add_local_table_to_metadata('partitioned_table');
|
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
CREATE TABLE citus_local_table PARTITION OF partitioned_table FOR VALUES FROM (20) TO (30);
|
|
||||||
|
|
||||||
-- cannot create citus local table as a partition of a local table
|
|
||||||
SELECT citus_add_local_table_to_metadata('citus_local_table');
|
|
||||||
ROLLBACK;
|
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
CREATE TABLE citus_local_table (a int, b int);
|
|
||||||
|
|
||||||
SELECT citus_add_local_table_to_metadata('citus_local_table');
|
|
||||||
|
|
||||||
-- cannot create citus local table as a partition of a local table
|
|
||||||
-- via ALTER TABLE commands as well
|
|
||||||
ALTER TABLE partitioned_table ATTACH PARTITION citus_local_table FOR VALUES FROM (20) TO (30);
|
|
||||||
ROLLBACK;
|
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
SELECT create_distributed_table('partitioned_table', 'a');
|
|
||||||
|
|
||||||
CREATE TABLE citus_local_table (a int, b int);
|
|
||||||
SELECT citus_add_local_table_to_metadata('citus_local_table');
|
|
||||||
|
|
||||||
-- cannot attach citus local table to a partitioned distributed table
|
|
||||||
ALTER TABLE partitioned_table ATTACH PARTITION citus_local_table FOR VALUES FROM (20) TO (30);
|
|
||||||
ROLLBACK;
|
|
||||||
|
|
||||||
-- show that we do not support inheritance relationships --
|
-- show that we do not support inheritance relationships --
|
||||||
|
|
||||||
CREATE TABLE parent_table (a int, b text);
|
CREATE TABLE parent_table (a int, b text);
|
||||||
|
@ -539,5 +503,95 @@ TRUNCATE referenced_table CASCADE;
|
||||||
RESET client_min_messages;
|
RESET client_min_messages;
|
||||||
\set VERBOSITY terse
|
\set VERBOSITY terse
|
||||||
|
|
||||||
|
-- test for partitioned tables
|
||||||
|
SET client_min_messages TO ERROR;
|
||||||
|
-- verify we can convert partitioned tables into Citus Local Tables
|
||||||
|
CREATE TABLE partitioned (user_id int, time timestamp with time zone, data jsonb, PRIMARY KEY (user_id, time )) PARTITION BY RANGE ("time");
|
||||||
|
CREATE TABLE partition1 PARTITION OF partitioned FOR VALUES FROM ('2018-04-13 00:00:00+00') TO ('2018-04-14 00:00:00+00');
|
||||||
|
CREATE TABLE partition2 PARTITION OF partitioned FOR VALUES FROM ('2018-04-14 00:00:00+00') TO ('2018-04-15 00:00:00+00');
|
||||||
|
SELECT citus_add_local_table_to_metadata('partitioned');
|
||||||
|
-- partitions added after the conversion get converted into CLT as well
|
||||||
|
CREATE TABLE partition3 PARTITION OF partitioned FOR VALUES FROM ('2018-04-15 00:00:00+00') TO ('2018-04-16 00:00:00+00');
|
||||||
|
--verify partitioning hierarchy is preserved after conversion
|
||||||
|
select inhrelid::regclass from pg_inherits where inhparent='partitioned'::regclass order by 1;
|
||||||
|
SELECT partition, from_value, to_value, access_method
|
||||||
|
FROM time_partitions
|
||||||
|
WHERE partition::text LIKE '%partition%'
|
||||||
|
ORDER BY partition::text;
|
||||||
|
-- undistribute succesfully
|
||||||
|
SELECT undistribute_table('partitioned');
|
||||||
|
-- verify the partitioning hierarchy is preserved after undistributing
|
||||||
|
select inhrelid::regclass from pg_inherits where inhparent='partitioned'::regclass order by 1;
|
||||||
|
|
||||||
|
-- verify table is undistributed
|
||||||
|
SELECT relname FROM pg_class WHERE relname LIKE 'partition3%' AND relnamespace IN
|
||||||
|
(SELECT oid FROM pg_namespace WHERE nspname = 'citus_local_tables_test_schema')
|
||||||
|
ORDER BY relname;
|
||||||
|
|
||||||
|
-- drop successfully
|
||||||
|
DROP TABLE partitioned;
|
||||||
|
|
||||||
|
-- test creating distributed tables from partitioned citus local tables
|
||||||
|
CREATE TABLE partitioned_distributed (a INT UNIQUE) PARTITION BY RANGE(a);
|
||||||
|
CREATE TABLE partitioned_distributed_1 PARTITION OF partitioned_distributed FOR VALUES FROM (1) TO (4);
|
||||||
|
CREATE TABLE partitioned_distributed_2 PARTITION OF partitioned_distributed FOR VALUES FROM (5) TO (8);
|
||||||
|
SELECT citus_add_local_table_to_metadata('partitioned_distributed');
|
||||||
|
SELECT create_distributed_table('partitioned_distributed','a');
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname FROM pg_class
|
||||||
|
WHERE relname LIKE 'partitioned_distributed%'
|
||||||
|
AND relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = 'citus_local_tables_test_schema')
|
||||||
|
ORDER BY relname;
|
||||||
|
\c - - - :master_port
|
||||||
|
SET search_path TO citus_local_tables_test_schema;
|
||||||
|
|
||||||
|
-- error out if converting multi-level partitioned table
|
||||||
|
CREATE TABLE multi_par (id text, country text) PARTITION BY RANGE (id);
|
||||||
|
ALTER TABLE multi_par ADD CONSTRAINT unique_constraint UNIQUE (id, country);
|
||||||
|
CREATE TABLE multi_par_a_to_i PARTITION OF multi_par FOR VALUES FROM ('a') TO ('j');
|
||||||
|
-- multi-level partitioning
|
||||||
|
CREATE TABLE multi_par_j_to_r PARTITION OF multi_par FOR VALUES FROM ('j') TO ('s') PARTITION BY LIST (country);
|
||||||
|
CREATE TABLE multi_par_j_to_r_japan PARTITION OF multi_par_j_to_r FOR VALUES IN ('japan');
|
||||||
|
-- these two should error out
|
||||||
|
SELECT citus_add_local_table_to_metadata('multi_par');
|
||||||
|
SELECT citus_add_local_table_to_metadata('multi_par',cascade_via_foreign_keys=>true);
|
||||||
|
|
||||||
|
-- should error out when cascading via fkeys as well
|
||||||
|
CREATE TABLE cas_1 (a text, b text);
|
||||||
|
ALTER TABLE cas_1 ADD CONSTRAINT unique_constraint_2 UNIQUE (a, b);
|
||||||
|
ALTER TABLE cas_1 ADD CONSTRAINT fkey_to_multi_parti FOREIGN KEY (a,b) REFERENCES multi_par(id, country);
|
||||||
|
SELECT citus_add_local_table_to_metadata('cas_1');
|
||||||
|
SELECT citus_add_local_table_to_metadata('cas_1', cascade_via_foreign_keys=>true);
|
||||||
|
SELECT create_reference_table('cas_1');
|
||||||
|
ALTER TABLE cas_1 DROP CONSTRAINT fkey_to_multi_parti;
|
||||||
|
SELECT create_reference_table('cas_1');
|
||||||
|
ALTER TABLE cas_1 ADD CONSTRAINT fkey_to_multi_parti FOREIGN KEY (a,b) REFERENCES multi_par(id, country);
|
||||||
|
|
||||||
|
-- undistribute tables to avoid unnecessary log messages later
|
||||||
|
select undistribute_table('citus_local_table_4', cascade_via_foreign_keys=>true);
|
||||||
|
select undistribute_table('referencing_table', cascade_via_foreign_keys=>true);
|
||||||
|
|
||||||
|
-- test dropping fkey
|
||||||
|
CREATE TABLE parent_2_child_1 (a int);
|
||||||
|
CREATE TABLE parent_1_child_1 (a int);
|
||||||
|
CREATE TABLE parent_2 (a INT UNIQUE) PARTITION BY RANGE(a);
|
||||||
|
CREATE TABLE parent_1 (a INT UNIQUE) PARTITION BY RANGE(a);
|
||||||
|
alter table parent_1 attach partition parent_1_child_1 default ;
|
||||||
|
alter table parent_2 attach partition parent_2_child_1 default ;
|
||||||
|
CREATE TABLE ref_table(a int unique);
|
||||||
|
alter table parent_1 add constraint fkey_test_drop foreign key(a) references ref_table(a);
|
||||||
|
alter table parent_2 add constraint fkey1 foreign key(a) references ref_table(a);
|
||||||
|
alter table parent_1 add constraint fkey2 foreign key(a) references parent_2(a);
|
||||||
|
SELECT create_reference_table('ref_table');
|
||||||
|
alter table parent_1 drop constraint fkey_test_drop;
|
||||||
|
select count(*) from pg_constraint where conname = 'fkey_test_drop';
|
||||||
|
-- verify we still preserve the child-parent hierarchy after all conversions
|
||||||
|
-- check the shard partition
|
||||||
|
select inhrelid::regclass from pg_inherits where (select inhparent::regclass::text) ~ '^parent_1_\d{7}$' order by 1;
|
||||||
|
-- check the shell partition
|
||||||
|
select inhrelid::regclass from pg_inherits where inhparent='parent_1'::regclass order by 1;
|
||||||
|
|
||||||
-- cleanup at exit
|
-- cleanup at exit
|
||||||
|
SET client_min_messages TO ERROR;
|
||||||
DROP SCHEMA citus_local_tables_test_schema, "CiTUS!LocalTables", "test_\'index_schema" CASCADE;
|
DROP SCHEMA citus_local_tables_test_schema, "CiTUS!LocalTables", "test_\'index_schema" CASCADE;
|
||||||
|
|
|
@ -168,6 +168,180 @@ SELECT stxname FROM pg_statistic_ext ORDER BY stxname;
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
SET search_path TO citus_local_tables_mx;
|
SET search_path TO citus_local_tables_mx;
|
||||||
|
|
||||||
|
-- undistribute old tables to prevent unnecessary undistribute logs later
|
||||||
|
SELECT undistribute_table('citus_local_table', cascade_via_foreign_keys=>true);
|
||||||
|
SELECT undistribute_table('citus_local_table_3', cascade_via_foreign_keys=>true);
|
||||||
|
SELECT undistribute_table('citus_local_table_stats', cascade_via_foreign_keys=>true);
|
||||||
|
|
||||||
|
-- verify that mx nodes have the shell table for partitioned citus local tables
|
||||||
|
CREATE TABLE local_table_fkey(a INT UNIQUE);
|
||||||
|
CREATE TABLE local_table_fkey2(a INT UNIQUE);
|
||||||
|
CREATE TABLE partitioned_mx (a INT UNIQUE) PARTITION BY RANGE(a);
|
||||||
|
ALTER TABLE partitioned_mx ADD CONSTRAINT fkey_to_local FOREIGN KEY (a) REFERENCES local_table_fkey(a);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS partitioned_mx_1 PARTITION OF partitioned_mx FOR VALUES FROM (1) TO (4);
|
||||||
|
CREATE TABLE partitioned_mx_2 (a INT UNIQUE);
|
||||||
|
ALTER TABLE partitioned_mx ATTACH PARTITION partitioned_mx_2 FOR VALUES FROM (5) TO (8);
|
||||||
|
SELECT create_reference_table('local_table_fkey');
|
||||||
|
CREATE TABLE partitioned_mx_3 (a INT UNIQUE);
|
||||||
|
ALTER TABLE partitioned_mx ATTACH PARTITION partitioned_mx_3 FOR VALUES FROM (9) TO (12);
|
||||||
|
-- these should error out since multi-level partitioned citus local tables are not supported
|
||||||
|
CREATE TABLE IF NOT EXISTS partitioned_mx_4 PARTITION OF partitioned_mx FOR VALUES FROM (13) TO (16) PARTITION BY RANGE (a);
|
||||||
|
BEGIN;
|
||||||
|
CREATE TABLE partitioned_mx_4(a INT UNIQUE) PARTITION BY RANGE (a);
|
||||||
|
alter table partitioned_mx attach partition partitioned_mx_4 FOR VALUES FROM (13) TO (16);
|
||||||
|
END;
|
||||||
|
CREATE TABLE multi_level_p (a INT UNIQUE) PARTITION BY RANGE (a);
|
||||||
|
CREATE TABLE IF NOT EXISTS multi_level_c PARTITION OF multi_level_p FOR VALUES FROM (13) TO (16) PARTITION BY RANGE (a);
|
||||||
|
select citus_add_local_table_to_metadata('multi_level_p'); --errors
|
||||||
|
select citus_add_local_table_to_metadata('multi_level_p', true); --errors
|
||||||
|
-- try attaching a partition with an external foreign key
|
||||||
|
CREATE TABLE partitioned_mx_4 (a INT UNIQUE);
|
||||||
|
ALTER TABLE partitioned_mx_4 ADD CONSTRAINT fkey_not_inherited FOREIGN KEY (a) REFERENCES local_table_fkey2(a);
|
||||||
|
-- these two should error out
|
||||||
|
ALTER TABLE partitioned_mx ATTACH PARTITION partitioned_mx_4 FOR VALUES FROM (13) TO (16);
|
||||||
|
ALTER TABLE partitioned_mx ATTACH PARTITION partitioned_mx_4 default;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
nmsp_parent.nspname AS parent_schema,
|
||||||
|
parent.relname AS parent,
|
||||||
|
nmsp_child.nspname AS child_schema,
|
||||||
|
child.relname AS child
|
||||||
|
FROM pg_inherits
|
||||||
|
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
|
||||||
|
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
|
||||||
|
JOIN pg_namespace nmsp_parent ON nmsp_parent.oid = parent.relnamespace
|
||||||
|
JOIN pg_namespace nmsp_child ON nmsp_child.oid = child.relnamespace
|
||||||
|
WHERE parent.relname='partitioned_mx'
|
||||||
|
ORDER BY child;
|
||||||
|
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname FROM pg_class WHERE relname LIKE 'partitioned_mx%' ORDER BY relname;
|
||||||
|
SELECT
|
||||||
|
nmsp_parent.nspname AS parent_schema,
|
||||||
|
parent.relname AS parent,
|
||||||
|
nmsp_child.nspname AS child_schema,
|
||||||
|
child.relname AS child
|
||||||
|
FROM pg_inherits
|
||||||
|
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
|
||||||
|
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
|
||||||
|
JOIN pg_namespace nmsp_parent ON nmsp_parent.oid = parent.relnamespace
|
||||||
|
JOIN pg_namespace nmsp_child ON nmsp_child.oid = child.relnamespace
|
||||||
|
WHERE parent.relname='partitioned_mx'
|
||||||
|
ORDER BY child;
|
||||||
|
|
||||||
|
\c - - - :master_port
|
||||||
|
SET search_path TO citus_local_tables_mx;
|
||||||
|
SET client_min_messages TO ERROR;
|
||||||
|
DROP TABLE partitioned_mx;
|
||||||
|
RESET client_min_messages;
|
||||||
|
-- test cascading via foreign keys
|
||||||
|
CREATE TABLE cas_1 (a INT UNIQUE);
|
||||||
|
CREATE TABLE cas_par (a INT UNIQUE) PARTITION BY RANGE(a);
|
||||||
|
CREATE TABLE cas_par_1 PARTITION OF cas_par FOR VALUES FROM (1) TO (4);
|
||||||
|
CREATE TABLE cas_par_2 PARTITION OF cas_par FOR VALUES FROM (5) TO (8);
|
||||||
|
ALTER TABLE cas_par_1 ADD CONSTRAINT fkey_cas_test_1 FOREIGN KEY (a) REFERENCES cas_1(a);
|
||||||
|
CREATE TABLE cas_par2 (a INT UNIQUE) PARTITION BY RANGE(a);
|
||||||
|
CREATE TABLE cas_par2_1 PARTITION OF cas_par2 FOR VALUES FROM (1) TO (4);
|
||||||
|
CREATE TABLE cas_par2_2 PARTITION OF cas_par2 FOR VALUES FROM (5) TO (8);
|
||||||
|
ALTER TABLE cas_par2_1 ADD CONSTRAINT fkey_cas_test_2 FOREIGN KEY (a) REFERENCES cas_1(a);
|
||||||
|
CREATE TABLE cas_par3 (a INT UNIQUE) PARTITION BY RANGE(a);
|
||||||
|
CREATE TABLE cas_par3_1 PARTITION OF cas_par3 FOR VALUES FROM (1) TO (4);
|
||||||
|
CREATE TABLE cas_par3_2 PARTITION OF cas_par3 FOR VALUES FROM (5) TO (8);
|
||||||
|
-- these two should error out as we should call the conversion from the parent
|
||||||
|
SELECT citus_add_local_table_to_metadata('cas_par2_2');
|
||||||
|
SELECT citus_add_local_table_to_metadata('cas_par2_2', cascade_via_foreign_keys=>true);
|
||||||
|
-- these two should error out as the foreign keys are not inherited from the parent
|
||||||
|
SELECT citus_add_local_table_to_metadata('cas_par2');
|
||||||
|
SELECT citus_add_local_table_to_metadata('cas_par2', cascade_via_foreign_keys=>true);
|
||||||
|
-- drop the foreign keys and establish them again using the parent table
|
||||||
|
ALTER TABLE cas_par_1 DROP CONSTRAINT fkey_cas_test_1;
|
||||||
|
ALTER TABLE cas_par2_1 DROP CONSTRAINT fkey_cas_test_2;
|
||||||
|
ALTER TABLE cas_par ADD CONSTRAINT fkey_cas_test_1 FOREIGN KEY (a) REFERENCES cas_1(a);
|
||||||
|
ALTER TABLE cas_par2 ADD CONSTRAINT fkey_cas_test_2 FOREIGN KEY (a) REFERENCES cas_1(a);
|
||||||
|
ALTER TABLE cas_par3 ADD CONSTRAINT fkey_cas_test_3 FOREIGN KEY (a) REFERENCES cas_par(a);
|
||||||
|
-- this should error out as cascade_via_foreign_keys is not set to true
|
||||||
|
SELECT citus_add_local_table_to_metadata('cas_par2');
|
||||||
|
-- this should work
|
||||||
|
SELECT citus_add_local_table_to_metadata('cas_par2', cascade_via_foreign_keys=>true);
|
||||||
|
-- verify the partitioning hierarchy is preserved
|
||||||
|
select inhrelid::regclass from pg_inherits where inhparent='cas_par'::regclass order by 1;
|
||||||
|
-- verify the fkeys + fkeys with shard ids are created
|
||||||
|
select conname from pg_constraint where conname like 'fkey_cas_test%' order by conname;
|
||||||
|
-- when all partitions are converted, there should be 40 tables and indexes
|
||||||
|
-- the individual names are not much relevant, so we only print the count
|
||||||
|
SELECT count(*) FROM pg_class WHERE relname LIKE 'cas\_%' AND relnamespace IN
|
||||||
|
(SELECT oid FROM pg_namespace WHERE nspname = 'citus_local_tables_mx');
|
||||||
|
-- verify on the mx worker
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
-- on worker, there should be 20, since the shards are created only on the coordinator
|
||||||
|
SELECT count(*) FROM pg_class WHERE relname LIKE 'cas\_%' AND relnamespace IN
|
||||||
|
(SELECT oid FROM pg_namespace WHERE nspname = 'citus_local_tables_mx');
|
||||||
|
-- verify that the shell foreign keys are created on the worker as well
|
||||||
|
select conname from pg_constraint where conname like 'fkey_cas_test%' order by conname;
|
||||||
|
\c - - - :master_port
|
||||||
|
SET search_path TO citus_local_tables_mx;
|
||||||
|
-- undistribute table
|
||||||
|
-- this one should error out since we don't set the cascade option as true
|
||||||
|
SELECT undistribute_table('cas_par2');
|
||||||
|
-- this one should work
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
SELECT undistribute_table('cas_par2', cascade_via_foreign_keys=>true);
|
||||||
|
-- verify the partitioning hierarchy is preserved
|
||||||
|
select inhrelid::regclass from pg_inherits where inhparent='cas_par'::regclass order by 1;
|
||||||
|
-- verify that the foreign keys with shard ids are gone, due to undistribution
|
||||||
|
select conname from pg_constraint where conname like 'fkey_cas_test%' order by conname;
|
||||||
|
-- add a non-inherited fkey and verify it fails when trying to convert
|
||||||
|
ALTER TABLE cas_par2_1 ADD CONSTRAINT fkey_cas_test_3 FOREIGN KEY (a) REFERENCES cas_1(a);
|
||||||
|
SELECT citus_add_local_table_to_metadata('cas_par2', cascade_via_foreign_keys=>true);
|
||||||
|
-- verify undistribute_table works proper for the mx worker
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
SELECT relname FROM pg_class WHERE relname LIKE 'cas\_%' ORDER BY relname;
|
||||||
|
\c - - - :master_port
|
||||||
|
SET search_path TO citus_local_tables_mx;
|
||||||
|
|
||||||
|
CREATE TABLE date_partitioned_citus_local_table_seq( measureid bigserial, eventdate date, measure_data jsonb, PRIMARY KEY (measureid, eventdate)) PARTITION BY RANGE(eventdate);
|
||||||
|
SELECT create_time_partitions('date_partitioned_citus_local_table_seq', INTERVAL '1 month', '2022-01-01', '2021-01-01');
|
||||||
|
SELECT citus_add_local_table_to_metadata('date_partitioned_citus_local_table_seq');
|
||||||
|
DROP TABLE date_partitioned_citus_local_table_seq;
|
||||||
|
-- test sequences
|
||||||
|
CREATE TABLE par_citus_local_seq(measureid bigserial, val int) PARTITION BY RANGE(val);
|
||||||
|
CREATE TABLE par_citus_local_seq_1 PARTITION OF par_citus_local_seq FOR VALUES FROM (1) TO (4);
|
||||||
|
SELECT citus_add_local_table_to_metadata('par_citus_local_seq');
|
||||||
|
INSERT INTO par_citus_local_seq (val) VALUES (1) RETURNING *;
|
||||||
|
INSERT INTO par_citus_local_seq (val) VALUES (2) RETURNING *;
|
||||||
|
\c - - - :worker_1_port
|
||||||
|
-- insert on the worker
|
||||||
|
INSERT INTO citus_local_tables_mx.par_citus_local_seq (val) VALUES (1) RETURNING *;
|
||||||
|
\c - - - :master_port
|
||||||
|
SET search_path TO citus_local_tables_mx;
|
||||||
|
INSERT INTO par_citus_local_seq (val) VALUES (2) RETURNING *;
|
||||||
|
SELECT undistribute_table('par_citus_local_seq');
|
||||||
|
INSERT INTO par_citus_local_seq (val) VALUES (3) RETURNING *;
|
||||||
|
SELECT measureid FROM par_citus_local_seq ORDER BY measureid;
|
||||||
|
|
||||||
|
-- test adding invalid foreign key to partition table
|
||||||
|
CREATE TABLE citus_local_parent_1 (a INT UNIQUE) PARTITION BY RANGE(a);
|
||||||
|
CREATE TABLE citus_local_parent_2 (a INT UNIQUE) PARTITION BY RANGE(a);
|
||||||
|
CREATE TABLE citus_local_plain (a INT UNIQUE);
|
||||||
|
CREATE TABLE ref (a INT UNIQUE);
|
||||||
|
SELECT create_reference_table('ref');
|
||||||
|
alter table citus_local_parent_1 add foreign key (a) references citus_local_parent_2(a);
|
||||||
|
alter table citus_local_plain add foreign key (a) references citus_local_parent_2(a);
|
||||||
|
CREATE TABLE citus_local_parent_1_child_1 PARTITION OF citus_local_parent_1 FOR VALUES FROM (3) TO (5);
|
||||||
|
CREATE TABLE citus_local_parent_1_child_2 PARTITION OF citus_local_parent_1 FOR VALUES FROM (30) TO (50);
|
||||||
|
CREATE TABLE citus_local_parent_2_child_1 PARTITION OF citus_local_parent_2 FOR VALUES FROM (40) TO (60);
|
||||||
|
-- this one should error out, since we cannot convert it to citus local table,
|
||||||
|
-- as citus local table partitions cannot have non-inherited foreign keys
|
||||||
|
alter table citus_local_parent_1_child_1 add foreign key(a) references ref(a);
|
||||||
|
-- this should work
|
||||||
|
alter table citus_local_parent_1 add constraint fkey_to_drop_test foreign key(a) references ref(a);
|
||||||
|
-- this should undistribute the table, and the entries should be gone from pg_dist_partition
|
||||||
|
select logicalrelid from pg_dist_partition where logicalrelid::text like 'citus_local_parent%';
|
||||||
|
set client_min_messages to error;
|
||||||
|
alter table citus_local_parent_1 drop constraint fkey_to_drop_test;
|
||||||
|
select logicalrelid from pg_dist_partition where logicalrelid::text like 'citus_local_parent%';
|
||||||
|
|
||||||
SELECT master_remove_distributed_table_metadata_from_workers('citus_local_table_4'::regclass::oid, 'citus_local_tables_mx', 'citus_local_table_4');
|
SELECT master_remove_distributed_table_metadata_from_workers('citus_local_table_4'::regclass::oid, 'citus_local_tables_mx', 'citus_local_table_4');
|
||||||
|
|
||||||
-- both workers should print 0 as master_remove_distributed_table_metadata_from_workers
|
-- both workers should print 0 as master_remove_distributed_table_metadata_from_workers
|
||||||
|
@ -176,6 +350,5 @@ SELECT run_command_on_workers(
|
||||||
$$
|
$$
|
||||||
SELECT count(*) FROM pg_catalog.pg_tables WHERE tablename='citus_local_table_4'
|
SELECT count(*) FROM pg_catalog.pg_tables WHERE tablename='citus_local_table_4'
|
||||||
$$);
|
$$);
|
||||||
|
|
||||||
-- cleanup at exit
|
-- cleanup at exit
|
||||||
DROP SCHEMA citus_local_tables_mx CASCADE;
|
DROP SCHEMA citus_local_tables_mx CASCADE;
|
||||||
|
|
|
@ -76,9 +76,6 @@ ROLLBACK;
|
||||||
|
|
||||||
BEGIN;
|
BEGIN;
|
||||||
CREATE TABLE partitioned_table (col_1 INT REFERENCES local_table_1 (col_1)) PARTITION BY RANGE (col_1);
|
CREATE TABLE partitioned_table (col_1 INT REFERENCES local_table_1 (col_1)) PARTITION BY RANGE (col_1);
|
||||||
-- now that we introduced a partitioned table into our foreign key subgraph,
|
|
||||||
-- citus_add_local_table_to_metadata(cascade_via_foreign_keys) would fail for
|
|
||||||
-- partitioned_table as citus_add_local_table_to_metadata doesn't support partitioned tables
|
|
||||||
SELECT citus_add_local_table_to_metadata('local_table_2', cascade_via_foreign_keys=>true);
|
SELECT citus_add_local_table_to_metadata('local_table_2', cascade_via_foreign_keys=>true);
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
|
|
||||||
|
|
|
@ -82,11 +82,9 @@ CREATE TABLE partitioned_table_1_200_300 PARTITION OF partitioned_table_1 FOR VA
|
||||||
INSERT INTO partitioned_table_1 SELECT i FROM generate_series(195, 205) i;
|
INSERT INTO partitioned_table_1 SELECT i FROM generate_series(195, 205) i;
|
||||||
|
|
||||||
ALTER TABLE partitioned_table_1 ADD CONSTRAINT fkey_8 FOREIGN KEY (col_1) REFERENCES local_table_4(col_1);
|
ALTER TABLE partitioned_table_1 ADD CONSTRAINT fkey_8 FOREIGN KEY (col_1) REFERENCES local_table_4(col_1);
|
||||||
|
BEGIN;
|
||||||
-- now that we attached partitioned table to graph below errors out
|
|
||||||
-- since we cannot create citus local table from partitioned tables
|
|
||||||
ALTER TABLE reference_table_1 ADD CONSTRAINT fkey_9 FOREIGN KEY (col_1) REFERENCES local_table_1(col_1);
|
ALTER TABLE reference_table_1 ADD CONSTRAINT fkey_9 FOREIGN KEY (col_1) REFERENCES local_table_1(col_1);
|
||||||
|
ROLLBACK;
|
||||||
ALTER TABLE partitioned_table_1 DROP CONSTRAINT fkey_8;
|
ALTER TABLE partitioned_table_1 DROP CONSTRAINT fkey_8;
|
||||||
|
|
||||||
BEGIN;
|
BEGIN;
|
||||||
|
@ -405,9 +403,9 @@ SELECT logicalrelid::text AS tablename, partmethod, repmodel FROM pg_dist_partit
|
||||||
WHERE logicalrelid::text IN (SELECT tablename FROM pg_tables WHERE schemaname='fkeys_between_local_ref')
|
WHERE logicalrelid::text IN (SELECT tablename FROM pg_tables WHERE schemaname='fkeys_between_local_ref')
|
||||||
ORDER BY tablename;
|
ORDER BY tablename;
|
||||||
|
|
||||||
-- this errors out as we don't support creating citus local
|
BEGIN;
|
||||||
-- tables from partitioned tables
|
|
||||||
CREATE TABLE part_local_table (col_1 INT REFERENCES reference_table_1(col_1)) PARTITION BY RANGE (col_1);
|
CREATE TABLE part_local_table (col_1 INT REFERENCES reference_table_1(col_1)) PARTITION BY RANGE (col_1);
|
||||||
|
ROLLBACK;
|
||||||
|
|
||||||
-- they fail as col_99 does not exist
|
-- they fail as col_99 does not exist
|
||||||
CREATE TABLE local_table_5 (col_1 INT, FOREIGN KEY (col_99) REFERENCES reference_table_1(col_1));
|
CREATE TABLE local_table_5 (col_1 INT, FOREIGN KEY (col_99) REFERENCES reference_table_1(col_1));
|
||||||
|
|
|
@ -1785,6 +1785,61 @@ ROLLBACK;
|
||||||
|
|
||||||
DROP TABLE pi_table;
|
DROP TABLE pi_table;
|
||||||
|
|
||||||
|
-- 6) test with citus local table
|
||||||
|
select 1 from citus_add_node('localhost', :master_port, groupid=>0);
|
||||||
|
CREATE TABLE date_partitioned_citus_local_table(
|
||||||
|
measureid integer,
|
||||||
|
eventdate date,
|
||||||
|
measure_data jsonb) PARTITION BY RANGE(eventdate);
|
||||||
|
|
||||||
|
SELECT citus_add_local_table_to_metadata('date_partitioned_citus_local_table');
|
||||||
|
|
||||||
|
-- test interval must be multiple days for date partitioned table
|
||||||
|
SELECT create_time_partitions('date_partitioned_citus_local_table', INTERVAL '6 hours', '2022-01-01', '2021-01-01');
|
||||||
|
SELECT create_time_partitions('date_partitioned_citus_local_table', INTERVAL '1 week 1 day 1 hour', '2022-01-01', '2021-01-01');
|
||||||
|
|
||||||
|
-- test with various intervals
|
||||||
|
BEGIN;
|
||||||
|
SELECT create_time_partitions('date_partitioned_citus_local_table', INTERVAL '1 day', '2021-02-01', '2021-01-01');
|
||||||
|
SELECT * FROM time_partitions WHERE parent_table = 'date_partitioned_citus_local_table'::regclass ORDER BY 3;
|
||||||
|
ROLLBACK;
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
SELECT create_time_partitions('date_partitioned_citus_local_table', INTERVAL '1 week', '2022-01-01', '2021-01-01');
|
||||||
|
SELECT * FROM time_partitions WHERE parent_table = 'date_partitioned_citus_local_table'::regclass ORDER BY 3;
|
||||||
|
ROLLBACK;
|
||||||
|
|
||||||
|
set client_min_messages to error;
|
||||||
|
DROP TABLE date_partitioned_citus_local_table;
|
||||||
|
-- also test with foreign key
|
||||||
|
CREATE TABLE date_partitioned_citus_local_table(
|
||||||
|
measureid integer,
|
||||||
|
eventdate date,
|
||||||
|
measure_data jsonb, PRIMARY KEY (measureid, eventdate)) PARTITION BY RANGE(eventdate);
|
||||||
|
|
||||||
|
SELECT citus_add_local_table_to_metadata('date_partitioned_citus_local_table');
|
||||||
|
|
||||||
|
-- test interval must be multiple days for date partitioned table
|
||||||
|
SELECT create_time_partitions('date_partitioned_citus_local_table', INTERVAL '1 day', '2021-02-01', '2021-01-01');
|
||||||
|
|
||||||
|
CREATE TABLE date_partitioned_citus_local_table_2(
|
||||||
|
measureid integer,
|
||||||
|
eventdate date,
|
||||||
|
measure_data jsonb, PRIMARY KEY (measureid, eventdate)) PARTITION BY RANGE(eventdate);
|
||||||
|
|
||||||
|
SELECT citus_add_local_table_to_metadata('date_partitioned_citus_local_table_2');
|
||||||
|
ALTER TABLE date_partitioned_citus_local_table_2 ADD CONSTRAINT fkey_1 FOREIGN KEY (measureid, eventdate) REFERENCES date_partitioned_citus_local_table(measureid, eventdate);
|
||||||
|
SELECT create_time_partitions('date_partitioned_citus_local_table_2', INTERVAL '1 day', '2021-02-01', '2021-01-01');
|
||||||
|
-- after the above work, these should also work for creating new partitions
|
||||||
|
BEGIN;
|
||||||
|
SELECT create_time_partitions('date_partitioned_citus_local_table', INTERVAL '1 day', '2021-03-01', '2021-02-01');
|
||||||
|
SELECT * FROM time_partitions WHERE parent_table = 'date_partitioned_citus_local_table'::regclass ORDER BY 3;
|
||||||
|
ROLLBACK;
|
||||||
|
BEGIN;
|
||||||
|
SELECT create_time_partitions('date_partitioned_citus_local_table_2', INTERVAL '1 day', '2021-03-01', '2021-02-01');
|
||||||
|
SELECT * FROM time_partitions WHERE parent_table = 'date_partitioned_citus_local_table'::regclass ORDER BY 3;
|
||||||
|
ROLLBACK;
|
||||||
|
set client_min_messages to notice;
|
||||||
-- c) test drop_old_time_partitions
|
-- c) test drop_old_time_partitions
|
||||||
-- 1) test with date partitioned table
|
-- 1) test with date partitioned table
|
||||||
CREATE TABLE date_partitioned_table_to_exp (event_date date, event int) partition by range (event_date);
|
CREATE TABLE date_partitioned_table_to_exp (event_date date, event int) partition by range (event_date);
|
||||||
|
@ -1858,6 +1913,29 @@ SELECT partition FROM time_partitions WHERE parent_table = '"test !/ \n _dist_12
|
||||||
\set VERBOSITY default
|
\set VERBOSITY default
|
||||||
DROP TABLE "test !/ \n _dist_123_table_exp";
|
DROP TABLE "test !/ \n _dist_123_table_exp";
|
||||||
|
|
||||||
|
-- 4) test with citus local tables
|
||||||
|
CREATE TABLE date_partitioned_table_to_exp (event_date date, event int) partition by range (event_date);
|
||||||
|
SELECT citus_add_local_table_to_metadata('date_partitioned_table_to_exp');
|
||||||
|
|
||||||
|
CREATE TABLE date_partitioned_table_to_exp_d00 PARTITION OF date_partitioned_table_to_exp FOR VALUES FROM ('2000-01-01') TO ('2009-12-31');
|
||||||
|
CREATE TABLE date_partitioned_table_to_exp_d10 PARTITION OF date_partitioned_table_to_exp FOR VALUES FROM ('2010-01-01') TO ('2019-12-31');
|
||||||
|
CREATE TABLE date_partitioned_table_to_exp_d20 PARTITION OF date_partitioned_table_to_exp FOR VALUES FROM ('2020-01-01') TO ('2029-12-31');
|
||||||
|
|
||||||
|
\set VERBOSITY terse
|
||||||
|
|
||||||
|
-- expire no partitions
|
||||||
|
CALL drop_old_time_partitions('date_partitioned_table_to_exp', '1999-01-01');
|
||||||
|
SELECT partition FROM time_partitions WHERE parent_table = 'date_partitioned_table_to_exp'::regclass ORDER BY partition::text;
|
||||||
|
|
||||||
|
-- expire 2 old partitions
|
||||||
|
CALL drop_old_time_partitions('date_partitioned_table_to_exp', '2021-01-01');
|
||||||
|
SELECT partition FROM time_partitions WHERE parent_table = 'date_partitioned_table_to_exp'::regclass ORDER BY partition::text;
|
||||||
|
|
||||||
|
\set VERBOSITY default
|
||||||
|
DROP TABLE date_partitioned_table_to_exp;
|
||||||
|
|
||||||
|
SELECT citus_remove_node('localhost', :master_port);
|
||||||
|
|
||||||
-- d) invalid tables for helper UDFs
|
-- d) invalid tables for helper UDFs
|
||||||
CREATE TABLE multiple_partition_column_table(
|
CREATE TABLE multiple_partition_column_table(
|
||||||
event_id bigserial,
|
event_id bigserial,
|
||||||
|
|
Loading…
Reference in New Issue