mirror of https://github.com/citusdata/citus.git
commit
a4f377282e
|
@ -1440,18 +1440,6 @@ CitusCreateAlterColumnarTableSet(char *qualifiedRelationName,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ColumnarTableDDLContext holds the instance variable for the TableDDLCommandFunction
|
|
||||||
* instance described below.
|
|
||||||
*/
|
|
||||||
typedef struct ColumnarTableDDLContext
|
|
||||||
{
|
|
||||||
char *schemaName;
|
|
||||||
char *relationName;
|
|
||||||
ColumnarOptions options;
|
|
||||||
} ColumnarTableDDLContext;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GetTableDDLCommandColumnar is an internal function used to turn a
|
* GetTableDDLCommandColumnar is an internal function used to turn a
|
||||||
* ColumnarTableDDLContext stored on the context of a TableDDLCommandFunction into a sql
|
* ColumnarTableDDLContext stored on the context of a TableDDLCommandFunction into a sql
|
||||||
|
@ -1477,7 +1465,7 @@ GetTableDDLCommandColumnar(void *context)
|
||||||
* command that will be executed against a shard. The resulting command will set the
|
* command that will be executed against a shard. The resulting command will set the
|
||||||
* options of the shard to the same options as the relation the shard is based on.
|
* options of the shard to the same options as the relation the shard is based on.
|
||||||
*/
|
*/
|
||||||
static char *
|
char *
|
||||||
GetShardedTableDDLCommandColumnar(uint64 shardId, void *context)
|
GetShardedTableDDLCommandColumnar(uint64 shardId, void *context)
|
||||||
{
|
{
|
||||||
ColumnarTableDDLContext *tableDDLContext = (ColumnarTableDDLContext *) context;
|
ColumnarTableDDLContext *tableDDLContext = (ColumnarTableDDLContext *) context;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -27,9 +27,6 @@
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
|
|
||||||
|
|
||||||
typedef void (*CascadeOperationFunction)(Oid, bool);
|
|
||||||
|
|
||||||
|
|
||||||
static void EnsureSequentialModeForCitusTableCascadeFunction(List *relationIdList);
|
static void EnsureSequentialModeForCitusTableCascadeFunction(List *relationIdList);
|
||||||
static bool RelationIdListHasReferenceTable(List *relationIdList);
|
static bool RelationIdListHasReferenceTable(List *relationIdList);
|
||||||
static void LockRelationsWithLockMode(List *relationIdList, LOCKMODE lockMode);
|
static void LockRelationsWithLockMode(List *relationIdList, LOCKMODE lockMode);
|
||||||
|
@ -42,8 +39,6 @@ static char * GetDropFkeyCascadeCommand(Oid relationId, Oid foreignKeyId);
|
||||||
static void ExecuteCascadeOperationForRelationIdList(List *relationIdList,
|
static void ExecuteCascadeOperationForRelationIdList(List *relationIdList,
|
||||||
CascadeOperationType
|
CascadeOperationType
|
||||||
cascadeOperationType);
|
cascadeOperationType);
|
||||||
static CascadeOperationFunction GetCascadeOperationFunction(CascadeOperationType
|
|
||||||
cascadeOperationType);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -342,45 +337,37 @@ ExecuteCascadeOperationForRelationIdList(List *relationIdList,
|
||||||
Oid relationId = InvalidOid;
|
Oid relationId = InvalidOid;
|
||||||
foreach_oid(relationId, relationIdList)
|
foreach_oid(relationId, relationIdList)
|
||||||
{
|
{
|
||||||
CascadeOperationFunction cascadeOperationFunction =
|
|
||||||
GetCascadeOperationFunction(cascadeOperationType);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Caller already passed the relations that we should operate on,
|
* Caller already passed the relations that we should operate on,
|
||||||
* so we should not cascade here.
|
* so we should not cascade here.
|
||||||
*/
|
*/
|
||||||
bool cascadeViaForeignKeys = false;
|
bool cascadeViaForeignKeys = false;
|
||||||
cascadeOperationFunction(relationId, cascadeViaForeignKeys);
|
switch (cascadeOperationType)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GetCascadeOperationFunction returns c api for citus table operation according
|
|
||||||
* to given CascadeOperationType.
|
|
||||||
*/
|
|
||||||
static CascadeOperationFunction
|
|
||||||
GetCascadeOperationFunction(CascadeOperationType cascadeOperationType)
|
|
||||||
{
|
|
||||||
switch (cascadeOperationType)
|
|
||||||
{
|
|
||||||
case UNDISTRIBUTE_TABLE:
|
|
||||||
{
|
{
|
||||||
return UndistributeTable;
|
case CASCADE_FKEY_UNDISTRIBUTE_TABLE:
|
||||||
}
|
{
|
||||||
|
TableConversionParameters params = {
|
||||||
|
.relationId = relationId,
|
||||||
|
.cascadeViaForeignKeys = cascadeViaForeignKeys
|
||||||
|
};
|
||||||
|
UndistributeTable(¶ms);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case CREATE_CITUS_LOCAL_TABLE:
|
case CASCADE_FKEY_CREATE_CITUS_LOCAL_TABLE:
|
||||||
{
|
{
|
||||||
return CreateCitusLocalTable;
|
CreateCitusLocalTable(relationId, cascadeViaForeignKeys);
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* This is not expected as other create table functions don't have
|
* This is not expected as other create table functions don't have
|
||||||
* cascade option yet. To be on the safe side, error out here.
|
* cascade option yet. To be on the safe side, error out here.
|
||||||
*/
|
*/
|
||||||
ereport(ERROR, (errmsg("citus table function could not be found")));
|
ereport(ERROR, (errmsg("citus table function could not be found")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,7 +139,7 @@ CreateCitusLocalTable(Oid relationId, bool cascadeViaForeignKeys)
|
||||||
if (tableHasExternalForeignKeys && cascadeViaForeignKeys)
|
if (tableHasExternalForeignKeys && cascadeViaForeignKeys)
|
||||||
{
|
{
|
||||||
CascadeOperationForConnectedRelations(relationId, lockMode,
|
CascadeOperationForConnectedRelations(relationId, lockMode,
|
||||||
CREATE_CITUS_LOCAL_TABLE);
|
CASCADE_FKEY_CREATE_CITUS_LOCAL_TABLE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We converted every foreign key connected table in our subgraph
|
* We converted every foreign key connected table in our subgraph
|
||||||
|
|
|
@ -86,10 +86,6 @@
|
||||||
*/
|
*/
|
||||||
#define LOG_PER_TUPLE_AMOUNT 1000000
|
#define LOG_PER_TUPLE_AMOUNT 1000000
|
||||||
|
|
||||||
#define UNDISTRIBUTE_TABLE_CASCADE_HINT \
|
|
||||||
"Use cascade option to undistribute all the relations involved in " \
|
|
||||||
"a foreign key relationship with %s by executing SELECT " \
|
|
||||||
"undistribute_table($$%s$$, cascade_via_foreign_keys=>true)"
|
|
||||||
|
|
||||||
/* Replication model to use when creating distributed tables */
|
/* Replication model to use when creating distributed tables */
|
||||||
int ReplicationModel = REPLICATION_MODEL_COORDINATOR;
|
int ReplicationModel = REPLICATION_MODEL_COORDINATOR;
|
||||||
|
@ -97,11 +93,12 @@ int ReplicationModel = REPLICATION_MODEL_COORDINATOR;
|
||||||
|
|
||||||
/* local function forward declarations */
|
/* local function forward declarations */
|
||||||
static char DecideReplicationModel(char distributionMethod, bool viaDeprecatedAPI);
|
static char DecideReplicationModel(char distributionMethod, bool viaDeprecatedAPI);
|
||||||
static void CreateHashDistributedTableShards(Oid relationId, Oid colocatedTableId,
|
static void CreateHashDistributedTableShards(Oid relationId, int shardCount,
|
||||||
bool localTableEmpty);
|
Oid colocatedTableId, bool localTableEmpty);
|
||||||
static uint32 ColocationIdForNewTable(Oid relationId, Var *distributionColumn,
|
static uint32 ColocationIdForNewTable(Oid relationId, Var *distributionColumn,
|
||||||
char distributionMethod, char replicationModel,
|
char distributionMethod, char replicationModel,
|
||||||
char *colocateWithTableName, bool viaDeprecatedAPI);
|
int shardCount, char *colocateWithTableName,
|
||||||
|
bool viaDeprecatedAPI);
|
||||||
static void EnsureRelationCanBeDistributed(Oid relationId, Var *distributionColumn,
|
static void EnsureRelationCanBeDistributed(Oid relationId, Var *distributionColumn,
|
||||||
char distributionMethod, uint32 colocationId,
|
char distributionMethod, uint32 colocationId,
|
||||||
char replicationModel, bool viaDeprecatedAPI);
|
char replicationModel, bool viaDeprecatedAPI);
|
||||||
|
@ -117,7 +114,6 @@ static void EnsureLocalTableEmptyIfNecessary(Oid relationId, char distributionMe
|
||||||
static bool ShouldLocalTableBeEmpty(Oid relationId, char distributionMethod, bool
|
static bool ShouldLocalTableBeEmpty(Oid relationId, char distributionMethod, bool
|
||||||
viaDeprecatedAPI);
|
viaDeprecatedAPI);
|
||||||
static void EnsureCitusTableCanBeCreated(Oid relationOid);
|
static void EnsureCitusTableCanBeCreated(Oid relationOid);
|
||||||
static void EnsureRelationExists(Oid relationId);
|
|
||||||
static bool LocalTableEmpty(Oid tableId);
|
static bool LocalTableEmpty(Oid tableId);
|
||||||
static void CopyLocalDataIntoShards(Oid relationId);
|
static void CopyLocalDataIntoShards(Oid relationId);
|
||||||
static List * TupleDescColumnNameList(TupleDesc tupleDescriptor);
|
static List * TupleDescColumnNameList(TupleDesc tupleDescriptor);
|
||||||
|
@ -129,14 +125,11 @@ static void DoCopyFromLocalTableIntoShards(Relation distributedRelation,
|
||||||
DestReceiver *copyDest,
|
DestReceiver *copyDest,
|
||||||
TupleTableSlot *slot,
|
TupleTableSlot *slot,
|
||||||
EState *estate);
|
EState *estate);
|
||||||
static List * GetViewCreationCommandsOfTable(Oid relationId);
|
|
||||||
static void ReplaceTable(Oid sourceId, Oid targetId);
|
|
||||||
|
|
||||||
/* exports for SQL callable functions */
|
/* exports for SQL callable functions */
|
||||||
PG_FUNCTION_INFO_V1(master_create_distributed_table);
|
PG_FUNCTION_INFO_V1(master_create_distributed_table);
|
||||||
PG_FUNCTION_INFO_V1(create_distributed_table);
|
PG_FUNCTION_INFO_V1(create_distributed_table);
|
||||||
PG_FUNCTION_INFO_V1(create_reference_table);
|
PG_FUNCTION_INFO_V1(create_reference_table);
|
||||||
PG_FUNCTION_INFO_V1(undistribute_table);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -180,7 +173,7 @@ master_create_distributed_table(PG_FUNCTION_ARGS)
|
||||||
char distributionMethod = LookupDistributionMethod(distributionMethodOid);
|
char distributionMethod = LookupDistributionMethod(distributionMethodOid);
|
||||||
|
|
||||||
CreateDistributedTable(relationId, distributionColumn, distributionMethod,
|
CreateDistributedTable(relationId, distributionColumn, distributionMethod,
|
||||||
colocateWithTableName, viaDeprecatedAPI);
|
ShardCount, colocateWithTableName, viaDeprecatedAPI);
|
||||||
|
|
||||||
relation_close(relation, NoLock);
|
relation_close(relation, NoLock);
|
||||||
|
|
||||||
|
@ -232,7 +225,7 @@ create_distributed_table(PG_FUNCTION_ARGS)
|
||||||
char *colocateWithTableName = text_to_cstring(colocateWithTableNameText);
|
char *colocateWithTableName = text_to_cstring(colocateWithTableNameText);
|
||||||
|
|
||||||
CreateDistributedTable(relationId, distributionColumn, distributionMethod,
|
CreateDistributedTable(relationId, distributionColumn, distributionMethod,
|
||||||
colocateWithTableName, viaDeprecatedAPI);
|
ShardCount, colocateWithTableName, viaDeprecatedAPI);
|
||||||
|
|
||||||
relation_close(relation, NoLock);
|
relation_close(relation, NoLock);
|
||||||
|
|
||||||
|
@ -283,7 +276,7 @@ create_reference_table(PG_FUNCTION_ARGS)
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateDistributedTable(relationId, distributionColumn, DISTRIBUTE_BY_NONE,
|
CreateDistributedTable(relationId, distributionColumn, DISTRIBUTE_BY_NONE,
|
||||||
colocateWithTableName, viaDeprecatedAPI);
|
ShardCount, colocateWithTableName, viaDeprecatedAPI);
|
||||||
|
|
||||||
relation_close(relation, NoLock);
|
relation_close(relation, NoLock);
|
||||||
|
|
||||||
|
@ -291,24 +284,6 @@ create_reference_table(PG_FUNCTION_ARGS)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* undistribute_table gets a distributed table name and
|
|
||||||
* udistributes it.
|
|
||||||
*/
|
|
||||||
Datum
|
|
||||||
undistribute_table(PG_FUNCTION_ARGS)
|
|
||||||
{
|
|
||||||
Oid relationId = PG_GETARG_OID(0);
|
|
||||||
bool cascadeViaForeignKeys = PG_GETARG_BOOL(1);
|
|
||||||
|
|
||||||
CheckCitusVersion(ERROR);
|
|
||||||
|
|
||||||
UndistributeTable(relationId, cascadeViaForeignKeys);
|
|
||||||
|
|
||||||
PG_RETURN_VOID();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* EnsureCitusTableCanBeCreated checks if
|
* EnsureCitusTableCanBeCreated checks if
|
||||||
* - we are on the coordinator
|
* - we are on the coordinator
|
||||||
|
@ -335,7 +310,7 @@ EnsureCitusTableCanBeCreated(Oid relationOid)
|
||||||
* EnsureRelationExists does a basic check on whether the OID belongs to
|
* EnsureRelationExists does a basic check on whether the OID belongs to
|
||||||
* an existing relation.
|
* an existing relation.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
EnsureRelationExists(Oid relationId)
|
EnsureRelationExists(Oid relationId)
|
||||||
{
|
{
|
||||||
if (!RelationExists(relationId))
|
if (!RelationExists(relationId))
|
||||||
|
@ -361,7 +336,7 @@ EnsureRelationExists(Oid relationId)
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
CreateDistributedTable(Oid relationId, Var *distributionColumn, char distributionMethod,
|
CreateDistributedTable(Oid relationId, Var *distributionColumn, char distributionMethod,
|
||||||
char *colocateWithTableName, bool viaDeprecatedAPI)
|
int shardCount, char *colocateWithTableName, bool viaDeprecatedAPI)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* distributed tables might have dependencies on different objects, since we create
|
* distributed tables might have dependencies on different objects, since we create
|
||||||
|
@ -382,7 +357,7 @@ CreateDistributedTable(Oid relationId, Var *distributionColumn, char distributio
|
||||||
*/
|
*/
|
||||||
uint32 colocationId = ColocationIdForNewTable(relationId, distributionColumn,
|
uint32 colocationId = ColocationIdForNewTable(relationId, distributionColumn,
|
||||||
distributionMethod, replicationModel,
|
distributionMethod, replicationModel,
|
||||||
colocateWithTableName,
|
shardCount, colocateWithTableName,
|
||||||
viaDeprecatedAPI);
|
viaDeprecatedAPI);
|
||||||
|
|
||||||
EnsureRelationCanBeDistributed(relationId, distributionColumn, distributionMethod,
|
EnsureRelationCanBeDistributed(relationId, distributionColumn, distributionMethod,
|
||||||
|
@ -421,7 +396,8 @@ CreateDistributedTable(Oid relationId, Var *distributionColumn, char distributio
|
||||||
/* create shards for hash distributed and reference tables */
|
/* create shards for hash distributed and reference tables */
|
||||||
if (distributionMethod == DISTRIBUTE_BY_HASH)
|
if (distributionMethod == DISTRIBUTE_BY_HASH)
|
||||||
{
|
{
|
||||||
CreateHashDistributedTableShards(relationId, colocatedTableId, localTableEmpty);
|
CreateHashDistributedTableShards(relationId, shardCount, colocatedTableId,
|
||||||
|
localTableEmpty);
|
||||||
}
|
}
|
||||||
else if (distributionMethod == DISTRIBUTE_BY_NONE)
|
else if (distributionMethod == DISTRIBUTE_BY_NONE)
|
||||||
{
|
{
|
||||||
|
@ -450,8 +426,8 @@ CreateDistributedTable(Oid relationId, Var *distributionColumn, char distributio
|
||||||
foreach_oid(partitionRelationId, partitionList)
|
foreach_oid(partitionRelationId, partitionList)
|
||||||
{
|
{
|
||||||
CreateDistributedTable(partitionRelationId, distributionColumn,
|
CreateDistributedTable(partitionRelationId, distributionColumn,
|
||||||
distributionMethod, colocateWithTableName,
|
distributionMethod, shardCount,
|
||||||
viaDeprecatedAPI);
|
colocateWithTableName, viaDeprecatedAPI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,8 +495,8 @@ DecideReplicationModel(char distributionMethod, bool viaDeprecatedAPI)
|
||||||
* CreateHashDistributedTableShards creates shards of given hash distributed table.
|
* CreateHashDistributedTableShards creates shards of given hash distributed table.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
CreateHashDistributedTableShards(Oid relationId, Oid colocatedTableId,
|
CreateHashDistributedTableShards(Oid relationId, int shardCount,
|
||||||
bool localTableEmpty)
|
Oid colocatedTableId, bool localTableEmpty)
|
||||||
{
|
{
|
||||||
bool useExclusiveConnection = false;
|
bool useExclusiveConnection = false;
|
||||||
|
|
||||||
|
@ -545,10 +521,9 @@ CreateHashDistributedTableShards(Oid relationId, Oid colocatedTableId,
|
||||||
/*
|
/*
|
||||||
* This path is only reached by create_distributed_table for the distributed
|
* This path is only reached by create_distributed_table for the distributed
|
||||||
* tables which will not be part of an existing colocation group. Therefore,
|
* tables which will not be part of an existing colocation group. Therefore,
|
||||||
* we can directly use ShardCount and ShardReplicationFactor global variables
|
* we can directly use ShardReplicationFactor global variable here.
|
||||||
* here.
|
|
||||||
*/
|
*/
|
||||||
CreateShardsWithRoundRobinPolicy(relationId, ShardCount, ShardReplicationFactor,
|
CreateShardsWithRoundRobinPolicy(relationId, shardCount, ShardReplicationFactor,
|
||||||
useExclusiveConnection);
|
useExclusiveConnection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -568,7 +543,8 @@ CreateHashDistributedTableShards(Oid relationId, Oid colocatedTableId,
|
||||||
static uint32
|
static uint32
|
||||||
ColocationIdForNewTable(Oid relationId, Var *distributionColumn,
|
ColocationIdForNewTable(Oid relationId, Var *distributionColumn,
|
||||||
char distributionMethod, char replicationModel,
|
char distributionMethod, char replicationModel,
|
||||||
char *colocateWithTableName, bool viaDeprecatedAPI)
|
int shardCount, char *colocateWithTableName,
|
||||||
|
bool viaDeprecatedAPI)
|
||||||
{
|
{
|
||||||
uint32 colocationId = INVALID_COLOCATION_ID;
|
uint32 colocationId = INVALID_COLOCATION_ID;
|
||||||
|
|
||||||
|
@ -611,13 +587,13 @@ ColocationIdForNewTable(Oid relationId, Var *distributionColumn,
|
||||||
if (pg_strncasecmp(colocateWithTableName, "default", NAMEDATALEN) == 0)
|
if (pg_strncasecmp(colocateWithTableName, "default", NAMEDATALEN) == 0)
|
||||||
{
|
{
|
||||||
/* check for default colocation group */
|
/* check for default colocation group */
|
||||||
colocationId = ColocationId(ShardCount, ShardReplicationFactor,
|
colocationId = ColocationId(shardCount, ShardReplicationFactor,
|
||||||
distributionColumnType,
|
distributionColumnType,
|
||||||
distributionColumnCollation);
|
distributionColumnCollation);
|
||||||
|
|
||||||
if (colocationId == INVALID_COLOCATION_ID)
|
if (colocationId == INVALID_COLOCATION_ID)
|
||||||
{
|
{
|
||||||
colocationId = CreateColocationGroup(ShardCount, ShardReplicationFactor,
|
colocationId = CreateColocationGroup(shardCount, ShardReplicationFactor,
|
||||||
distributionColumnType,
|
distributionColumnType,
|
||||||
distributionColumnCollation);
|
distributionColumnCollation);
|
||||||
createdColocationGroup = true;
|
createdColocationGroup = true;
|
||||||
|
@ -1543,295 +1519,3 @@ DistributionColumnUsesGeneratedStoredColumn(TupleDesc relationDesc,
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* UndistributeTable undistributes the given table. The undistribution is done by
|
|
||||||
* creating a new table, moving everything to the new table and dropping the old one.
|
|
||||||
* So the oid of the table is not preserved.
|
|
||||||
*
|
|
||||||
* The undistributed table will have the same name, columns and rows. It will also have
|
|
||||||
* partitions, views, sequences of the old table. Finally it will have everything created
|
|
||||||
* by GetPostLoadTableCreationCommands function, which include indexes. These will be
|
|
||||||
* re-created during undistribution, so their oids are not preserved either (except for
|
|
||||||
* sequences). However, their names are preserved.
|
|
||||||
*
|
|
||||||
* The tables with references are not supported. The function gives an error if there are
|
|
||||||
* any references to or from the table.
|
|
||||||
*
|
|
||||||
* The dropping of old table is done with CASCADE. Anything not mentioned here will
|
|
||||||
* be dropped.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
UndistributeTable(Oid relationId, bool cascadeViaForeignKeys)
|
|
||||||
{
|
|
||||||
EnsureCoordinator();
|
|
||||||
EnsureRelationExists(relationId);
|
|
||||||
EnsureTableOwner(relationId);
|
|
||||||
|
|
||||||
LOCKMODE lockMode = ExclusiveLock;
|
|
||||||
Relation relation = try_relation_open(relationId, lockMode);
|
|
||||||
if (relation == NULL)
|
|
||||||
{
|
|
||||||
ereport(ERROR, (errmsg("cannot undistribute table"),
|
|
||||||
errdetail("because no such distributed table exists")));
|
|
||||||
}
|
|
||||||
|
|
||||||
relation_close(relation, NoLock);
|
|
||||||
|
|
||||||
if (!IsCitusTable(relationId))
|
|
||||||
{
|
|
||||||
ereport(ERROR, (errmsg("cannot undistribute table "),
|
|
||||||
errdetail("because the table is not distributed")));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool tableReferencing = TableReferencing(relationId);
|
|
||||||
bool tableReferenced = TableReferenced(relationId);
|
|
||||||
if (cascadeViaForeignKeys && (tableReferencing || tableReferenced))
|
|
||||||
{
|
|
||||||
CascadeOperationForConnectedRelations(relationId, lockMode, UNDISTRIBUTE_TABLE);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Undistributed every foreign key connected relation in our foreign key
|
|
||||||
* subgraph including itself, so return here.
|
|
||||||
*/
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tableReferencing)
|
|
||||||
{
|
|
||||||
char *qualifiedRelationName = generate_qualified_relation_name(relationId);
|
|
||||||
ereport(ERROR, (errmsg("cannot undistribute table "
|
|
||||||
"because it has a foreign key"),
|
|
||||||
errhint(UNDISTRIBUTE_TABLE_CASCADE_HINT,
|
|
||||||
qualifiedRelationName,
|
|
||||||
qualifiedRelationName)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tableReferenced)
|
|
||||||
{
|
|
||||||
char *qualifiedRelationName = generate_qualified_relation_name(relationId);
|
|
||||||
ereport(ERROR, (errmsg("cannot undistribute table "
|
|
||||||
"because a foreign key references to it"),
|
|
||||||
errhint(UNDISTRIBUTE_TABLE_CASCADE_HINT,
|
|
||||||
qualifiedRelationName,
|
|
||||||
qualifiedRelationName)));
|
|
||||||
}
|
|
||||||
|
|
||||||
char relationKind = get_rel_relkind(relationId);
|
|
||||||
if (relationKind == RELKIND_FOREIGN_TABLE)
|
|
||||||
{
|
|
||||||
ereport(ERROR, (errmsg("cannot undistribute table "
|
|
||||||
"because it is a foreign table")));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PartitionTable(relationId))
|
|
||||||
{
|
|
||||||
Oid parentRelationId = PartitionParentOid(relationId);
|
|
||||||
char *parentRelationName = get_rel_name(parentRelationId);
|
|
||||||
ereport(ERROR, (errmsg("cannot undistribute table "
|
|
||||||
"because it is a partition"),
|
|
||||||
errhint("undistribute the partitioned table \"%s\" instead",
|
|
||||||
parentRelationName)));
|
|
||||||
}
|
|
||||||
|
|
||||||
List *preLoadCommands = GetPreLoadTableCreationCommands(relationId, true);
|
|
||||||
List *postLoadCommands = GetPostLoadTableCreationCommands(relationId);
|
|
||||||
|
|
||||||
postLoadCommands = list_concat(postLoadCommands,
|
|
||||||
GetViewCreationCommandsOfTable(relationId));
|
|
||||||
|
|
||||||
int spiResult = SPI_connect();
|
|
||||||
if (spiResult != SPI_OK_CONNECT)
|
|
||||||
{
|
|
||||||
ereport(ERROR, (errmsg("could not connect to SPI manager")));
|
|
||||||
}
|
|
||||||
|
|
||||||
char *relationName = get_rel_name(relationId);
|
|
||||||
Oid schemaId = get_rel_namespace(relationId);
|
|
||||||
char *schemaName = get_namespace_name(schemaId);
|
|
||||||
|
|
||||||
if (PartitionedTable(relationId))
|
|
||||||
{
|
|
||||||
ereport(NOTICE, (errmsg("undistributing the partitions of %s",
|
|
||||||
quote_qualified_identifier(schemaName, relationName))));
|
|
||||||
List *partitionList = PartitionList(relationId);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is a less common pattern where foreing key is directly from/to
|
|
||||||
* the partition relation as we already handled inherited foreign keys
|
|
||||||
* on partitions either by erroring out or cascading via foreign keys.
|
|
||||||
* It seems an acceptable limitation for now to ask users to drop such
|
|
||||||
* foreign keys manually.
|
|
||||||
*/
|
|
||||||
ErrorIfAnyPartitionRelationInvolvedInNonInheritedFKey(partitionList);
|
|
||||||
|
|
||||||
Oid partitionRelationId = InvalidOid;
|
|
||||||
foreach_oid(partitionRelationId, partitionList)
|
|
||||||
{
|
|
||||||
char *detachPartitionCommand = GenerateDetachPartitionCommand(
|
|
||||||
partitionRelationId);
|
|
||||||
char *attachPartitionCommand = GenerateAlterTableAttachPartitionCommand(
|
|
||||||
partitionRelationId);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We first detach the partitions to be able to undistribute them separately.
|
|
||||||
*/
|
|
||||||
spiResult = SPI_execute(detachPartitionCommand, false, 0);
|
|
||||||
if (spiResult != SPI_OK_UTILITY)
|
|
||||||
{
|
|
||||||
ereport(ERROR, (errmsg("could not run SPI query")));
|
|
||||||
}
|
|
||||||
preLoadCommands = lappend(preLoadCommands,
|
|
||||||
makeTableDDLCommandString(attachPartitionCommand));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Even if we called UndistributeTable with cascade option, we
|
|
||||||
* shouldn't cascade via foreign keys on partitions. Otherwise,
|
|
||||||
* we might try to undistribute partitions of other tables in
|
|
||||||
* our foreign key subgraph more than once.
|
|
||||||
*/
|
|
||||||
bool cascadeOnPartitionsViaForeignKeys = false;
|
|
||||||
UndistributeTable(partitionRelationId, cascadeOnPartitionsViaForeignKeys);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char *tempName = pstrdup(relationName);
|
|
||||||
uint32 hashOfName = hash_any((unsigned char *) tempName, strlen(tempName));
|
|
||||||
AppendShardIdToName(&tempName, hashOfName);
|
|
||||||
|
|
||||||
|
|
||||||
ereport(NOTICE, (errmsg("creating a new local table for %s",
|
|
||||||
quote_qualified_identifier(schemaName, relationName))));
|
|
||||||
|
|
||||||
TableDDLCommand *tableCreationCommand = NULL;
|
|
||||||
foreach_ptr(tableCreationCommand, preLoadCommands)
|
|
||||||
{
|
|
||||||
Assert(CitusIsA(tableCreationCommand, TableDDLCommand));
|
|
||||||
|
|
||||||
char *tableCreationSql = GetTableDDLCommand(tableCreationCommand);
|
|
||||||
Node *parseTree = ParseTreeNode(tableCreationSql);
|
|
||||||
|
|
||||||
RelayEventExtendNames(parseTree, schemaName, hashOfName);
|
|
||||||
CitusProcessUtility(parseTree, tableCreationSql, PROCESS_UTILITY_TOPLEVEL,
|
|
||||||
NULL, None_Receiver, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReplaceTable(relationId, get_relname_relid(tempName, schemaId));
|
|
||||||
|
|
||||||
TableDDLCommand *tableConstructionCommand = NULL;
|
|
||||||
foreach_ptr(tableConstructionCommand, postLoadCommands)
|
|
||||||
{
|
|
||||||
Assert(CitusIsA(tableConstructionCommand, TableDDLCommand));
|
|
||||||
char *tableConstructionSQL = GetTableDDLCommand(tableConstructionCommand);
|
|
||||||
spiResult = SPI_execute(tableConstructionSQL, false, 0);
|
|
||||||
if (spiResult != SPI_OK_UTILITY)
|
|
||||||
{
|
|
||||||
ereport(ERROR, (errmsg("could not run SPI query")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spiResult = SPI_finish();
|
|
||||||
if (spiResult != SPI_OK_FINISH)
|
|
||||||
{
|
|
||||||
ereport(ERROR, (errmsg("could not finish SPI connection")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GetViewCreationCommandsOfTable takes a table oid generates the CREATE VIEW
|
|
||||||
* commands for views that depend to the given table. This includes the views
|
|
||||||
* that recursively depend on the table too.
|
|
||||||
*/
|
|
||||||
List *
|
|
||||||
GetViewCreationCommandsOfTable(Oid relationId)
|
|
||||||
{
|
|
||||||
List *views = GetDependingViews(relationId);
|
|
||||||
List *commands = NIL;
|
|
||||||
|
|
||||||
Oid viewOid = InvalidOid;
|
|
||||||
foreach_oid(viewOid, views)
|
|
||||||
{
|
|
||||||
Datum viewDefinitionDatum = DirectFunctionCall1(pg_get_viewdef,
|
|
||||||
ObjectIdGetDatum(viewOid));
|
|
||||||
char *viewDefinition = TextDatumGetCString(viewDefinitionDatum);
|
|
||||||
StringInfo query = makeStringInfo();
|
|
||||||
char *viewName = get_rel_name(viewOid);
|
|
||||||
char *schemaName = get_namespace_name(get_rel_namespace(viewOid));
|
|
||||||
char *qualifiedViewName = quote_qualified_identifier(schemaName, viewName);
|
|
||||||
appendStringInfo(query,
|
|
||||||
"CREATE VIEW %s AS %s",
|
|
||||||
qualifiedViewName,
|
|
||||||
viewDefinition);
|
|
||||||
commands = lappend(commands, makeTableDDLCommandString(query->data));
|
|
||||||
}
|
|
||||||
return commands;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ReplaceTable replaces the source table with the target table.
|
|
||||||
* It moves all the rows of the source table to target table with INSERT SELECT.
|
|
||||||
* Changes the dependencies of the sequences owned by source table to target table.
|
|
||||||
* Then drops the source table and renames the target table to source tables name.
|
|
||||||
*
|
|
||||||
* Source and target tables need to be in the same schema and have the same columns.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ReplaceTable(Oid sourceId, Oid targetId)
|
|
||||||
{
|
|
||||||
char *sourceName = get_rel_name(sourceId);
|
|
||||||
char *targetName = get_rel_name(targetId);
|
|
||||||
Oid schemaId = get_rel_namespace(sourceId);
|
|
||||||
char *schemaName = get_namespace_name(schemaId);
|
|
||||||
|
|
||||||
StringInfo query = makeStringInfo();
|
|
||||||
|
|
||||||
ereport(NOTICE, (errmsg("Moving the data of %s",
|
|
||||||
quote_qualified_identifier(schemaName, sourceName))));
|
|
||||||
|
|
||||||
appendStringInfo(query, "INSERT INTO %s SELECT * FROM %s",
|
|
||||||
quote_qualified_identifier(schemaName, targetName),
|
|
||||||
quote_qualified_identifier(schemaName, sourceName));
|
|
||||||
int spiResult = SPI_execute(query->data, false, 0);
|
|
||||||
if (spiResult != SPI_OK_INSERT)
|
|
||||||
{
|
|
||||||
ereport(ERROR, (errmsg("could not run SPI query")));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_13
|
|
||||||
List *ownedSequences = getOwnedSequences(sourceId);
|
|
||||||
#else
|
|
||||||
List *ownedSequences = getOwnedSequences(sourceId, InvalidAttrNumber);
|
|
||||||
#endif
|
|
||||||
Oid sequenceOid = InvalidOid;
|
|
||||||
foreach_oid(sequenceOid, ownedSequences)
|
|
||||||
{
|
|
||||||
changeDependencyFor(RelationRelationId, sequenceOid,
|
|
||||||
RelationRelationId, sourceId, targetId);
|
|
||||||
}
|
|
||||||
|
|
||||||
ereport(NOTICE, (errmsg("Dropping the old %s",
|
|
||||||
quote_qualified_identifier(schemaName, sourceName))));
|
|
||||||
|
|
||||||
resetStringInfo(query);
|
|
||||||
appendStringInfo(query, "DROP TABLE %s CASCADE",
|
|
||||||
quote_qualified_identifier(schemaName, sourceName));
|
|
||||||
spiResult = SPI_execute(query->data, false, 0);
|
|
||||||
if (spiResult != SPI_OK_UTILITY)
|
|
||||||
{
|
|
||||||
ereport(ERROR, (errmsg("could not run SPI query")));
|
|
||||||
}
|
|
||||||
|
|
||||||
ereport(NOTICE, (errmsg("Renaming the new table to %s",
|
|
||||||
quote_qualified_identifier(schemaName, sourceName))));
|
|
||||||
|
|
||||||
#if PG_VERSION_NUM >= PG_VERSION_12
|
|
||||||
RenameRelationInternal(targetId,
|
|
||||||
sourceName, false, false);
|
|
||||||
#else
|
|
||||||
RenameRelationInternal(targetId,
|
|
||||||
sourceName, false);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
|
@ -616,6 +616,48 @@ GetReferencingForeignConstaintCommands(Oid relationId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GetForeignConstraintToReferenceTablesCommands takes in a relationId, and
|
||||||
|
* returns the list of foreign constraint commands needed to reconstruct
|
||||||
|
* foreign key constraints that the table is involved in as the "referencing"
|
||||||
|
* one and the "referenced" table is a reference table.
|
||||||
|
*/
|
||||||
|
List *
|
||||||
|
GetForeignConstraintToReferenceTablesCommands(Oid relationId)
|
||||||
|
{
|
||||||
|
int flags = INCLUDE_REFERENCING_CONSTRAINTS | INCLUDE_REFERENCE_TABLES;
|
||||||
|
return GetForeignConstraintCommandsInternal(relationId, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GetForeignConstraintToDistributedTablesCommands takes in a relationId, and
|
||||||
|
* returns the list of foreign constraint commands needed to reconstruct
|
||||||
|
* foreign key constraints that the table is involved in as the "referencing"
|
||||||
|
* one and the "referenced" table is a distributed table.
|
||||||
|
*/
|
||||||
|
List *
|
||||||
|
GetForeignConstraintToDistributedTablesCommands(Oid relationId)
|
||||||
|
{
|
||||||
|
int flags = INCLUDE_REFERENCING_CONSTRAINTS | INCLUDE_DISTRIBUTED_TABLES;
|
||||||
|
return GetForeignConstraintCommandsInternal(relationId, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GetForeignConstraintFromDistributedTablesCommands takes in a relationId, and
|
||||||
|
* returns the list of foreign constraint commands needed to reconstruct
|
||||||
|
* foreign key constraints that the table is involved in as the "referenced"
|
||||||
|
* one and the "referencing" table is a distributed table.
|
||||||
|
*/
|
||||||
|
List *
|
||||||
|
GetForeignConstraintFromDistributedTablesCommands(Oid relationId)
|
||||||
|
{
|
||||||
|
int flags = INCLUDE_REFERENCED_CONSTRAINTS | INCLUDE_DISTRIBUTED_TABLES;
|
||||||
|
return GetForeignConstraintCommandsInternal(relationId, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GetForeignConstraintCommandsInternal is a wrapper function to get the
|
* GetForeignConstraintCommandsInternal is a wrapper function to get the
|
||||||
* DDL commands to recreate the foreign key constraints returned by
|
* DDL commands to recreate the foreign key constraints returned by
|
||||||
|
|
|
@ -225,8 +225,8 @@ PostprocessCreateTableStmtPartitionOf(CreateStmt *createStatement, const
|
||||||
bool viaDeprecatedAPI = false;
|
bool viaDeprecatedAPI = false;
|
||||||
|
|
||||||
CreateDistributedTable(relationId, parentDistributionColumn,
|
CreateDistributedTable(relationId, parentDistributionColumn,
|
||||||
parentDistributionMethod, parentRelationName,
|
parentDistributionMethod, ShardCount,
|
||||||
viaDeprecatedAPI);
|
parentRelationName, viaDeprecatedAPI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,8 +299,8 @@ PostprocessAlterTableStmtAttachPartition(AlterTableStmt *alterTableStatement,
|
||||||
bool viaDeprecatedAPI = false;
|
bool viaDeprecatedAPI = false;
|
||||||
|
|
||||||
CreateDistributedTable(partitionRelationId, distributionColumn,
|
CreateDistributedTable(partitionRelationId, distributionColumn,
|
||||||
distributionMethod, parentRelationName,
|
distributionMethod, ShardCount,
|
||||||
viaDeprecatedAPI);
|
parentRelationName, viaDeprecatedAPI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -248,7 +248,8 @@ pg_get_sequencedef(Oid sequenceRelationId)
|
||||||
* DEFAULT clauses for columns getting their default values from a sequence.
|
* DEFAULT clauses for columns getting their default values from a sequence.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
pg_get_tableschemadef_string(Oid tableRelationId, bool includeSequenceDefaults)
|
pg_get_tableschemadef_string(Oid tableRelationId, bool includeSequenceDefaults,
|
||||||
|
char *accessMethod)
|
||||||
{
|
{
|
||||||
char relationKind = 0;
|
char relationKind = 0;
|
||||||
bool firstAttributePrinted = false;
|
bool firstAttributePrinted = false;
|
||||||
|
@ -457,7 +458,11 @@ pg_get_tableschemadef_string(Oid tableRelationId, bool includeSequenceDefaults)
|
||||||
* Add table access methods for pg12 and higher when the table is configured with an
|
* Add table access methods for pg12 and higher when the table is configured with an
|
||||||
* access method
|
* access method
|
||||||
*/
|
*/
|
||||||
if (OidIsValid(relation->rd_rel->relam))
|
if (accessMethod)
|
||||||
|
{
|
||||||
|
appendStringInfo(&buffer, " USING %s", quote_identifier(accessMethod));
|
||||||
|
}
|
||||||
|
else if (OidIsValid(relation->rd_rel->relam))
|
||||||
{
|
{
|
||||||
HeapTuple amTup = SearchSysCache1(AMOID, ObjectIdGetDatum(
|
HeapTuple amTup = SearchSysCache1(AMOID, ObjectIdGetDatum(
|
||||||
relation->rd_rel->relam));
|
relation->rd_rel->relam));
|
||||||
|
|
|
@ -540,12 +540,12 @@ GetFullTableCreationCommands(Oid relationId, bool includeSequenceDefaults)
|
||||||
List *tableDDLEventList = NIL;
|
List *tableDDLEventList = NIL;
|
||||||
|
|
||||||
List *preLoadCreationCommandList =
|
List *preLoadCreationCommandList =
|
||||||
GetPreLoadTableCreationCommands(relationId, includeSequenceDefaults);
|
GetPreLoadTableCreationCommands(relationId, includeSequenceDefaults, NULL);
|
||||||
|
|
||||||
tableDDLEventList = list_concat(tableDDLEventList, preLoadCreationCommandList);
|
tableDDLEventList = list_concat(tableDDLEventList, preLoadCreationCommandList);
|
||||||
|
|
||||||
List *postLoadCreationCommandList =
|
List *postLoadCreationCommandList =
|
||||||
GetPostLoadTableCreationCommands(relationId);
|
GetPostLoadTableCreationCommands(relationId, true);
|
||||||
|
|
||||||
tableDDLEventList = list_concat(tableDDLEventList, postLoadCreationCommandList);
|
tableDDLEventList = list_concat(tableDDLEventList, postLoadCreationCommandList);
|
||||||
|
|
||||||
|
@ -558,12 +558,16 @@ GetFullTableCreationCommands(Oid relationId, bool includeSequenceDefaults)
|
||||||
* of DDL commands that should be applied after loading the data.
|
* of DDL commands that should be applied after loading the data.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
GetPostLoadTableCreationCommands(Oid relationId)
|
GetPostLoadTableCreationCommands(Oid relationId, bool includeIndexes)
|
||||||
{
|
{
|
||||||
List *tableDDLEventList = NIL;
|
List *tableDDLEventList = NIL;
|
||||||
|
|
||||||
List *indexAndConstraintCommandList = GetTableIndexAndConstraintCommands(relationId);
|
if (includeIndexes)
|
||||||
tableDDLEventList = list_concat(tableDDLEventList, indexAndConstraintCommandList);
|
{
|
||||||
|
List *indexAndConstraintCommandList =
|
||||||
|
GetTableIndexAndConstraintCommands(relationId);
|
||||||
|
tableDDLEventList = list_concat(tableDDLEventList, indexAndConstraintCommandList);
|
||||||
|
}
|
||||||
|
|
||||||
List *replicaIdentityEvents = GetTableReplicaIdentityCommand(relationId);
|
List *replicaIdentityEvents = GetTableReplicaIdentityCommand(relationId);
|
||||||
tableDDLEventList = list_concat(tableDDLEventList, replicaIdentityEvents);
|
tableDDLEventList = list_concat(tableDDLEventList, replicaIdentityEvents);
|
||||||
|
@ -616,7 +620,8 @@ GetTableReplicaIdentityCommand(Oid relationId)
|
||||||
* to facilitate faster data load.
|
* to facilitate faster data load.
|
||||||
*/
|
*/
|
||||||
List *
|
List *
|
||||||
GetPreLoadTableCreationCommands(Oid relationId, bool includeSequenceDefaults)
|
GetPreLoadTableCreationCommands(Oid relationId, bool includeSequenceDefaults,
|
||||||
|
char *accessMethod)
|
||||||
{
|
{
|
||||||
List *tableDDLEventList = NIL;
|
List *tableDDLEventList = NIL;
|
||||||
|
|
||||||
|
@ -640,7 +645,8 @@ GetPreLoadTableCreationCommands(Oid relationId, bool includeSequenceDefaults)
|
||||||
|
|
||||||
/* fetch table schema and column option definitions */
|
/* fetch table schema and column option definitions */
|
||||||
char *tableSchemaDef = pg_get_tableschemadef_string(relationId,
|
char *tableSchemaDef = pg_get_tableschemadef_string(relationId,
|
||||||
includeSequenceDefaults);
|
includeSequenceDefaults,
|
||||||
|
accessMethod);
|
||||||
char *tableColumnOptionsDef = pg_get_tablecolumnoptionsdef_string(relationId);
|
char *tableColumnOptionsDef = pg_get_tablecolumnoptionsdef_string(relationId);
|
||||||
|
|
||||||
tableDDLEventList = lappend(tableDDLEventList, makeTableDDLCommandString(
|
tableDDLEventList = lappend(tableDDLEventList, makeTableDDLCommandString(
|
||||||
|
@ -654,7 +660,7 @@ GetPreLoadTableCreationCommands(Oid relationId, bool includeSequenceDefaults)
|
||||||
#if PG_VERSION_NUM >= 120000
|
#if PG_VERSION_NUM >= 120000
|
||||||
|
|
||||||
/* add columnar options for cstore tables */
|
/* add columnar options for cstore tables */
|
||||||
if (IsCStoreTableAmTable(relationId))
|
if (accessMethod == NULL && IsCStoreTableAmTable(relationId))
|
||||||
{
|
{
|
||||||
TableDDLCommand *cstoreOptionsDDL = ColumnarGetTableOptionsDDL(relationId);
|
TableDDLCommand *cstoreOptionsDDL = ColumnarGetTableOptionsDDL(relationId);
|
||||||
if (cstoreOptionsDDL != NULL)
|
if (cstoreOptionsDDL != NULL)
|
||||||
|
|
|
@ -937,7 +937,7 @@ CopyShardCommandList(ShardInterval *shardInterval, const char *sourceNodeName,
|
||||||
copyShardDataCommand->data);
|
copyShardDataCommand->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
List *indexCommandList = GetPostLoadTableCreationCommands(relationId);
|
List *indexCommandList = GetPostLoadTableCreationCommands(relationId, true);
|
||||||
indexCommandList = WorkerApplyShardDDLCommandList(indexCommandList, shardId);
|
indexCommandList = WorkerApplyShardDDLCommandList(indexCommandList, shardId);
|
||||||
|
|
||||||
copyShardToNodeCommandsList = list_concat(copyShardToNodeCommandsList,
|
copyShardToNodeCommandsList = list_concat(copyShardToNodeCommandsList,
|
||||||
|
@ -1143,7 +1143,8 @@ RecreateTableDDLCommandList(Oid relationId)
|
||||||
|
|
||||||
List *dropCommandList = list_make1(makeTableDDLCommandString(dropCommand->data));
|
List *dropCommandList = list_make1(makeTableDDLCommandString(dropCommand->data));
|
||||||
List *createCommandList = GetPreLoadTableCreationCommands(relationId,
|
List *createCommandList = GetPreLoadTableCreationCommands(relationId,
|
||||||
includeSequenceDefaults);
|
includeSequenceDefaults,
|
||||||
|
NULL);
|
||||||
List *recreateCommandList = list_concat(dropCommandList, createCommandList);
|
List *recreateCommandList = list_concat(dropCommandList, createCommandList);
|
||||||
|
|
||||||
return recreateCommandList;
|
return recreateCommandList;
|
||||||
|
|
|
@ -6,6 +6,8 @@ DROP FUNCTION IF EXISTS pg_catalog.citus_total_relation_size(regclass);
|
||||||
#include "udfs/citus_total_relation_size/10.0-1.sql"
|
#include "udfs/citus_total_relation_size/10.0-1.sql"
|
||||||
#include "udfs/citus_tables/10.0-1.sql"
|
#include "udfs/citus_tables/10.0-1.sql"
|
||||||
#include "udfs/citus_finish_pg_upgrade/10.0-1.sql"
|
#include "udfs/citus_finish_pg_upgrade/10.0-1.sql"
|
||||||
|
#include "udfs/alter_distributed_table/10.0-1.sql"
|
||||||
|
#include "udfs/alter_table_set_access_method/10.0-1.sql"
|
||||||
#include "udfs/undistribute_table/10.0-1.sql"
|
#include "udfs/undistribute_table/10.0-1.sql"
|
||||||
#include "udfs/create_citus_local_table/10.0-1.sql"
|
#include "udfs/create_citus_local_table/10.0-1.sql"
|
||||||
#include "udfs/citus_set_coordinator_host/10.0-1.sql"
|
#include "udfs/citus_set_coordinator_host/10.0-1.sql"
|
||||||
|
@ -24,6 +26,7 @@ DROP FUNCTION IF EXISTS pg_catalog.citus_total_relation_size(regclass);
|
||||||
#include "udfs/citus_copy_shard_placement/10.0-1.sql"
|
#include "udfs/citus_copy_shard_placement/10.0-1.sql"
|
||||||
#include "udfs/citus_move_shard_placement/10.0-1.sql"
|
#include "udfs/citus_move_shard_placement/10.0-1.sql"
|
||||||
#include "udfs/citus_drop_trigger/10.0-1.sql"
|
#include "udfs/citus_drop_trigger/10.0-1.sql"
|
||||||
|
#include "udfs/worker_change_sequence_dependency/10.0-1.sql"
|
||||||
|
|
||||||
#include "../../columnar/sql/columnar--9.5-1--10.0-1.sql"
|
#include "../../columnar/sql/columnar--9.5-1--10.0-1.sql"
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#include "../../../columnar/sql/downgrades/columnar--10.0-1--9.5-1.sql"
|
#include "../../../columnar/sql/downgrades/columnar--10.0-1--9.5-1.sql"
|
||||||
|
|
||||||
DROP VIEW public.citus_tables;
|
DROP VIEW public.citus_tables;
|
||||||
|
DROP FUNCTION pg_catalog.alter_distributed_table(regclass, text, int, text, boolean);
|
||||||
|
DROP FUNCTION pg_catalog.alter_table_set_access_method(regclass, text);
|
||||||
DROP FUNCTION pg_catalog.citus_total_relation_size(regclass,boolean);
|
DROP FUNCTION pg_catalog.citus_total_relation_size(regclass,boolean);
|
||||||
DROP FUNCTION pg_catalog.undistribute_table(regclass,boolean);
|
DROP FUNCTION pg_catalog.undistribute_table(regclass,boolean);
|
||||||
DROP FUNCTION pg_catalog.create_citus_local_table(regclass,boolean);
|
DROP FUNCTION pg_catalog.create_citus_local_table(regclass,boolean);
|
||||||
|
@ -45,6 +47,7 @@ DROP VIEW pg_catalog.time_partitions;
|
||||||
DROP FUNCTION pg_catalog.time_partition_range(regclass);
|
DROP FUNCTION pg_catalog.time_partition_range(regclass);
|
||||||
|
|
||||||
DROP FUNCTION pg_catalog.citus_set_coordinator_host(text,int,noderole,name);
|
DROP FUNCTION pg_catalog.citus_set_coordinator_host(text,int,noderole,name);
|
||||||
|
DROP FUNCTION pg_catalog.worker_change_sequence_dependency(regclass, regclass, regclass);
|
||||||
|
|
||||||
CREATE FUNCTION pg_catalog.master_modify_multiple_shards(text)
|
CREATE FUNCTION pg_catalog.master_modify_multiple_shards(text)
|
||||||
RETURNS integer
|
RETURNS integer
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
CREATE OR REPLACE FUNCTION pg_catalog.alter_distributed_table(
|
||||||
|
table_name regclass, distribution_column text DEFAULT NULL, shard_count int DEFAULT NULL, colocate_with text DEFAULT NULL, cascade_to_colocated boolean DEFAULT NULL)
|
||||||
|
RETURNS VOID
|
||||||
|
LANGUAGE C
|
||||||
|
AS 'MODULE_PATHNAME', $$alter_distributed_table$$;
|
||||||
|
|
||||||
|
COMMENT ON FUNCTION pg_catalog.alter_distributed_table(
|
||||||
|
table_name regclass, distribution_column text, shard_count int, colocate_with text, cascade_to_colocated boolean)
|
||||||
|
IS 'alters a distributed table';
|
|
@ -0,0 +1,9 @@
|
||||||
|
CREATE OR REPLACE FUNCTION pg_catalog.alter_distributed_table(
|
||||||
|
table_name regclass, distribution_column text DEFAULT NULL, shard_count int DEFAULT NULL, colocate_with text DEFAULT NULL, cascade_to_colocated boolean DEFAULT NULL)
|
||||||
|
RETURNS VOID
|
||||||
|
LANGUAGE C
|
||||||
|
AS 'MODULE_PATHNAME', $$alter_distributed_table$$;
|
||||||
|
|
||||||
|
COMMENT ON FUNCTION pg_catalog.alter_distributed_table(
|
||||||
|
table_name regclass, distribution_column text, shard_count int, colocate_with text, cascade_to_colocated boolean)
|
||||||
|
IS 'alters a distributed table';
|
|
@ -0,0 +1,9 @@
|
||||||
|
CREATE OR REPLACE FUNCTION pg_catalog.alter_table_set_access_method(
|
||||||
|
table_name regclass, access_method text)
|
||||||
|
RETURNS VOID
|
||||||
|
LANGUAGE C STRICT
|
||||||
|
AS 'MODULE_PATHNAME', $$alter_table_set_access_method$$;
|
||||||
|
|
||||||
|
COMMENT ON FUNCTION pg_catalog.alter_table_set_access_method(
|
||||||
|
table_name regclass, access_method text)
|
||||||
|
IS 'alters a table''s access method';
|
|
@ -0,0 +1,9 @@
|
||||||
|
CREATE OR REPLACE FUNCTION pg_catalog.alter_table_set_access_method(
|
||||||
|
table_name regclass, access_method text)
|
||||||
|
RETURNS VOID
|
||||||
|
LANGUAGE C STRICT
|
||||||
|
AS 'MODULE_PATHNAME', $$alter_table_set_access_method$$;
|
||||||
|
|
||||||
|
COMMENT ON FUNCTION pg_catalog.alter_table_set_access_method(
|
||||||
|
table_name regclass, access_method text)
|
||||||
|
IS 'alters a table''s access method';
|
13
src/backend/distributed/sql/udfs/worker_change_sequence_dependency/10.0-1.sql
generated
Normal file
13
src/backend/distributed/sql/udfs/worker_change_sequence_dependency/10.0-1.sql
generated
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
CREATE OR REPLACE FUNCTION pg_catalog.worker_change_sequence_dependency(
|
||||||
|
sequence regclass,
|
||||||
|
source_table regclass,
|
||||||
|
target_table regclass)
|
||||||
|
RETURNS VOID
|
||||||
|
LANGUAGE C STRICT
|
||||||
|
AS 'MODULE_PATHNAME', $$worker_change_sequence_dependency$$;
|
||||||
|
|
||||||
|
COMMENT ON FUNCTION pg_catalog.worker_change_sequence_dependency(
|
||||||
|
sequence regclass,
|
||||||
|
source_table regclass,
|
||||||
|
target_table regclass)
|
||||||
|
IS 'changes sequence''s dependency from source table to target table';
|
|
@ -0,0 +1,13 @@
|
||||||
|
CREATE OR REPLACE FUNCTION pg_catalog.worker_change_sequence_dependency(
|
||||||
|
sequence regclass,
|
||||||
|
source_table regclass,
|
||||||
|
target_table regclass)
|
||||||
|
RETURNS VOID
|
||||||
|
LANGUAGE C STRICT
|
||||||
|
AS 'MODULE_PATHNAME', $$worker_change_sequence_dependency$$;
|
||||||
|
|
||||||
|
COMMENT ON FUNCTION pg_catalog.worker_change_sequence_dependency(
|
||||||
|
sequence regclass,
|
||||||
|
source_table regclass,
|
||||||
|
target_table regclass)
|
||||||
|
IS 'changes sequence''s dependency from source table to target table';
|
|
@ -79,6 +79,18 @@ typedef struct ColumnarOptions
|
||||||
} ColumnarOptions;
|
} ColumnarOptions;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ColumnarTableDDLContext holds the instance variable for the TableDDLCommandFunction
|
||||||
|
* instance described below.
|
||||||
|
*/
|
||||||
|
typedef struct ColumnarTableDDLContext
|
||||||
|
{
|
||||||
|
char *schemaName;
|
||||||
|
char *relationName;
|
||||||
|
ColumnarOptions options;
|
||||||
|
} ColumnarTableDDLContext;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* StripeMetadata represents information about a stripe. This information is
|
* StripeMetadata represents information about a stripe. This information is
|
||||||
* stored in the cstore file's footer.
|
* stored in the cstore file's footer.
|
||||||
|
|
|
@ -21,4 +21,5 @@ extern TableScanDesc cstore_beginscan_extended(Relation relation, Snapshot snaps
|
||||||
|
|
||||||
extern bool IsCStoreTableAmTable(Oid relationId);
|
extern bool IsCStoreTableAmTable(Oid relationId);
|
||||||
extern TableDDLCommand * ColumnarGetTableOptionsDDL(Oid relationId);
|
extern TableDDLCommand * ColumnarGetTableOptionsDDL(Oid relationId);
|
||||||
|
extern char * GetShardedTableDDLCommandColumnar(uint64 shardId, void *context);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,7 +30,8 @@ extern Oid get_extension_schema(Oid ext_oid);
|
||||||
extern char * pg_get_serverdef_string(Oid tableRelationId);
|
extern char * pg_get_serverdef_string(Oid tableRelationId);
|
||||||
extern char * pg_get_sequencedef_string(Oid sequenceRelid);
|
extern char * pg_get_sequencedef_string(Oid sequenceRelid);
|
||||||
extern Form_pg_sequence pg_get_sequencedef(Oid sequenceRelationId);
|
extern Form_pg_sequence pg_get_sequencedef(Oid sequenceRelationId);
|
||||||
extern char * pg_get_tableschemadef_string(Oid tableRelationId, bool forShardCreation);
|
extern char * pg_get_tableschemadef_string(Oid tableRelationId, bool forShardCreation,
|
||||||
|
char *accessMethod);
|
||||||
extern void EnsureRelationKindSupported(Oid relationId);
|
extern void EnsureRelationKindSupported(Oid relationId);
|
||||||
extern char * pg_get_tablecolumnoptionsdef_string(Oid tableRelationId);
|
extern char * pg_get_tablecolumnoptionsdef_string(Oid tableRelationId);
|
||||||
extern void deparse_shard_index_statement(IndexStmt *origStmt, Oid distrelid,
|
extern void deparse_shard_index_statement(IndexStmt *origStmt, Oid distrelid,
|
||||||
|
|
|
@ -163,6 +163,9 @@ extern bool ColumnReferencedByAnyForeignKey(char *columnName, Oid relationId);
|
||||||
extern bool ColumnAppearsInForeignKeyToReferenceTable(char *columnName, Oid
|
extern bool ColumnAppearsInForeignKeyToReferenceTable(char *columnName, Oid
|
||||||
relationId);
|
relationId);
|
||||||
extern List * GetReferencingForeignConstaintCommands(Oid relationOid);
|
extern List * GetReferencingForeignConstaintCommands(Oid relationOid);
|
||||||
|
extern List * GetForeignConstraintToReferenceTablesCommands(Oid relationId);
|
||||||
|
extern List * GetForeignConstraintToDistributedTablesCommands(Oid relationId);
|
||||||
|
extern List * GetForeignConstraintFromDistributedTablesCommands(Oid relationId);
|
||||||
extern bool HasForeignKeyToCitusLocalTable(Oid relationId);
|
extern bool HasForeignKeyToCitusLocalTable(Oid relationId);
|
||||||
extern bool HasForeignKeyToReferenceTable(Oid relationOid);
|
extern bool HasForeignKeyToReferenceTable(Oid relationOid);
|
||||||
extern bool TableReferenced(Oid relationOid);
|
extern bool TableReferenced(Oid relationOid);
|
||||||
|
@ -399,10 +402,10 @@ typedef enum CascadeOperationType
|
||||||
INVALID_OPERATION = 1 << 0,
|
INVALID_OPERATION = 1 << 0,
|
||||||
|
|
||||||
/* execute UndistributeTable on each relation */
|
/* execute UndistributeTable on each relation */
|
||||||
UNDISTRIBUTE_TABLE = 1 << 1,
|
CASCADE_FKEY_UNDISTRIBUTE_TABLE = 1 << 1,
|
||||||
|
|
||||||
/* execute CreateCitusLocalTable on each relation */
|
/* execute CreateCitusLocalTable on each relation */
|
||||||
CREATE_CITUS_LOCAL_TABLE = 1 << 2,
|
CASCADE_FKEY_CREATE_CITUS_LOCAL_TABLE = 1 << 2,
|
||||||
} CascadeOperationType;
|
} CascadeOperationType;
|
||||||
|
|
||||||
extern void CascadeOperationForConnectedRelations(Oid relationId, LOCKMODE relLockMode,
|
extern void CascadeOperationForConnectedRelations(Oid relationId, LOCKMODE relLockMode,
|
||||||
|
|
|
@ -177,9 +177,10 @@ extern uint64 GetNextShardId(void);
|
||||||
extern uint64 GetNextPlacementId(void);
|
extern uint64 GetNextPlacementId(void);
|
||||||
extern Oid ResolveRelationId(text *relationName, bool missingOk);
|
extern Oid ResolveRelationId(text *relationName, bool missingOk);
|
||||||
extern List * GetFullTableCreationCommands(Oid relationId, bool includeSequenceDefaults);
|
extern List * GetFullTableCreationCommands(Oid relationId, bool includeSequenceDefaults);
|
||||||
extern List * GetPostLoadTableCreationCommands(Oid relationId);
|
extern List * GetPostLoadTableCreationCommands(Oid relationId, bool includeIndexes);
|
||||||
extern List * GetPreLoadTableCreationCommands(Oid relationId,
|
extern List * GetPreLoadTableCreationCommands(Oid relationId,
|
||||||
bool includeSequenceDefaults);
|
bool includeSequenceDefaults,
|
||||||
|
char *accessMethod);
|
||||||
extern List * GetTableIndexAndConstraintCommands(Oid relationId);
|
extern List * GetTableIndexAndConstraintCommands(Oid relationId);
|
||||||
extern bool IndexImpliedByAConstraint(Form_pg_index indexForm);
|
extern bool IndexImpliedByAConstraint(Form_pg_index indexForm);
|
||||||
extern char ShardStorageType(Oid relationId);
|
extern char ShardStorageType(Oid relationId);
|
||||||
|
|
|
@ -90,6 +90,74 @@ typedef struct ShardPlacement
|
||||||
} ShardPlacement;
|
} ShardPlacement;
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum CascadeToColocatedOption
|
||||||
|
{
|
||||||
|
CASCADE_TO_COLOCATED_UNSPECIFIED,
|
||||||
|
CASCADE_TO_COLOCATED_YES,
|
||||||
|
CASCADE_TO_COLOCATED_NO,
|
||||||
|
CASCADE_TO_COLOCATED_NO_ALREADY_CASCADED
|
||||||
|
}CascadeToColocatedOption;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TableConversionParameters are the parameters that are given to
|
||||||
|
* table conversion UDFs: undistribute_table, alter_distributed_table,
|
||||||
|
* alter_table_set_access_method.
|
||||||
|
*
|
||||||
|
* When passing a TableConversionParameters object to one of the table
|
||||||
|
* conversion functions some of the parameters needs to be set:
|
||||||
|
* UndistributeTable: relationId
|
||||||
|
* AlterDistributedTable: relationId, distributionColumn, shardCountIsNull,
|
||||||
|
* shardCount, colocateWith, cascadeToColocated
|
||||||
|
* AlterTableSetAccessMethod: relationId, accessMethod
|
||||||
|
*
|
||||||
|
* conversionType parameter will be automatically set by the function.
|
||||||
|
*
|
||||||
|
* TableConversionState objects can be created using TableConversionParameters
|
||||||
|
* objects with CreateTableConversion function.
|
||||||
|
*/
|
||||||
|
typedef struct TableConversionParameters
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Determines type of conversion: UNDISTRIBUTE_TABLE,
|
||||||
|
* ALTER_DISTRIBUTED_TABLE, ALTER_TABLE_SET_ACCESS_METHOD.
|
||||||
|
*/
|
||||||
|
char conversionType;
|
||||||
|
|
||||||
|
/* Oid of the table to do conversion on */
|
||||||
|
Oid relationId;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Options to do conversions on the table
|
||||||
|
* distributionColumn is the name of the new distribution column,
|
||||||
|
* shardCountIsNull is if the shardCount variable is not given
|
||||||
|
* shardCount is the new shard count,
|
||||||
|
* colocateWith is the name of the table to colocate with, 'none', or
|
||||||
|
* 'default'
|
||||||
|
* accessMethod is the name of the new accessMethod for the table
|
||||||
|
*/
|
||||||
|
char *distributionColumn;
|
||||||
|
bool shardCountIsNull;
|
||||||
|
int shardCount;
|
||||||
|
char *colocateWith;
|
||||||
|
char *accessMethod;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cascadeToColocated determines whether the shardCount and
|
||||||
|
* colocateWith will be cascaded to the currently colocated tables
|
||||||
|
*/
|
||||||
|
CascadeToColocatedOption cascadeToColocated;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cascadeViaForeignKeys determines if the conversion operation
|
||||||
|
* will be cascaded to the graph connected with foreign keys
|
||||||
|
* to the table
|
||||||
|
*/
|
||||||
|
bool cascadeViaForeignKeys;
|
||||||
|
} TableConversionParameters;
|
||||||
|
|
||||||
|
typedef struct TableConversionReturn TableConversionReturn;
|
||||||
|
|
||||||
|
|
||||||
/* Config variable managed via guc.c */
|
/* Config variable managed via guc.c */
|
||||||
extern int ReplicationModel;
|
extern int ReplicationModel;
|
||||||
|
|
||||||
|
@ -138,10 +206,10 @@ extern void MarkShardPlacementInactive(ShardPlacement *shardPlacement);
|
||||||
extern void UpdateShardPlacementState(uint64 placementId, char shardState);
|
extern void UpdateShardPlacementState(uint64 placementId, char shardState);
|
||||||
extern void DeleteShardPlacementRow(uint64 placementId);
|
extern void DeleteShardPlacementRow(uint64 placementId);
|
||||||
extern void CreateDistributedTable(Oid relationId, Var *distributionColumn,
|
extern void CreateDistributedTable(Oid relationId, Var *distributionColumn,
|
||||||
char distributionMethod, char *colocateWithTableName,
|
char distributionMethod, int shardCount,
|
||||||
bool viaDeprecatedAPI);
|
char *colocateWithTableName, bool viaDeprecatedAPI);
|
||||||
extern void CreateTruncateTrigger(Oid relationId);
|
extern void CreateTruncateTrigger(Oid relationId);
|
||||||
extern void UndistributeTable(Oid relationId, bool cascadeViaForeignKeys);
|
extern TableConversionReturn * UndistributeTable(TableConversionParameters *params);
|
||||||
|
|
||||||
extern void EnsureDependenciesExistOnAllNodes(const ObjectAddress *target);
|
extern void EnsureDependenciesExistOnAllNodes(const ObjectAddress *target);
|
||||||
extern List * GetDistributableDependenciesForObject(const ObjectAddress *target);
|
extern List * GetDistributableDependenciesForObject(const ObjectAddress *target);
|
||||||
|
@ -160,6 +228,7 @@ extern void EnsureSuperUser(void);
|
||||||
extern void ErrorIfTableIsACatalogTable(Relation relation);
|
extern void ErrorIfTableIsACatalogTable(Relation relation);
|
||||||
extern void EnsureTableNotDistributed(Oid relationId);
|
extern void EnsureTableNotDistributed(Oid relationId);
|
||||||
extern void EnsureReplicationSettings(Oid relationId, char replicationModel);
|
extern void EnsureReplicationSettings(Oid relationId, char replicationModel);
|
||||||
|
extern void EnsureRelationExists(Oid relationId);
|
||||||
extern bool RegularTable(Oid relationId);
|
extern bool RegularTable(Oid relationId);
|
||||||
extern char * ConstructQualifiedShardName(ShardInterval *shardInterval);
|
extern char * ConstructQualifiedShardName(ShardInterval *shardInterval);
|
||||||
extern uint64 GetFirstShardId(Oid relationId);
|
extern uint64 GetFirstShardId(Oid relationId);
|
||||||
|
|
|
@ -0,0 +1,812 @@
|
||||||
|
SHOW server_version \gset
|
||||||
|
SELECT substring(:'server_version', '\d+')::int > 11 AS server_version_above_eleven;
|
||||||
|
server_version_above_eleven
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\gset
|
||||||
|
CREATE SCHEMA alter_distributed_table;
|
||||||
|
SET search_path TO alter_distributed_table;
|
||||||
|
SET citus.shard_count TO 4;
|
||||||
|
SET citus.shard_replication_factor TO 1;
|
||||||
|
CREATE TABLE dist_table (a INT, b INT);
|
||||||
|
SELECT create_distributed_table ('dist_table', 'a', colocate_with := 'none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
INSERT INTO dist_table VALUES (1, 1), (2, 2), (3, 3);
|
||||||
|
CREATE TABLE colocation_table (a INT, b INT);
|
||||||
|
SELECT create_distributed_table ('colocation_table', 'a', colocate_with := 'none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE colocation_table_2 (a INT, b INT);
|
||||||
|
SELECT create_distributed_table ('colocation_table_2', 'a', colocate_with := 'none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2');
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table | distributed | a | 4
|
||||||
|
colocation_table_2 | distributed | a | 4
|
||||||
|
dist_table | distributed | a | 4
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2') GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table
|
||||||
|
colocation_table_2
|
||||||
|
dist_table
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
-- test altering distribution column
|
||||||
|
SELECT alter_distributed_table('dist_table', distribution_column := 'b');
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2');
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table | distributed | a | 4
|
||||||
|
colocation_table_2 | distributed | a | 4
|
||||||
|
dist_table | distributed | b | 4
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2') GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table
|
||||||
|
colocation_table_2
|
||||||
|
dist_table
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
-- test altering shard count
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 6);
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2');
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table | distributed | a | 4
|
||||||
|
colocation_table_2 | distributed | a | 4
|
||||||
|
dist_table | distributed | b | 6
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2') GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table
|
||||||
|
colocation_table_2
|
||||||
|
dist_table
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
-- test altering colocation, note that shard count will also change
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'alter_distributed_table.colocation_table');
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2');
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table | distributed | a | 4
|
||||||
|
colocation_table_2 | distributed | a | 4
|
||||||
|
dist_table | distributed | b | 4
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2') GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table, dist_table
|
||||||
|
colocation_table_2
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- test altering shard count with cascading, note that the colocation will be kept
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 8, cascade_to_colocated := true);
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.colocation_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.colocation_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.colocation_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.colocation_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2');
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table | distributed | a | 8
|
||||||
|
colocation_table_2 | distributed | a | 4
|
||||||
|
dist_table | distributed | b | 8
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2') GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table, dist_table
|
||||||
|
colocation_table_2
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- test altering shard count without cascading, note that the colocation will be broken
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 10, cascade_to_colocated := false);
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2');
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table | distributed | a | 8
|
||||||
|
colocation_table_2 | distributed | a | 4
|
||||||
|
dist_table | distributed | b | 10
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2') GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table
|
||||||
|
colocation_table_2
|
||||||
|
dist_table
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
-- test partitions
|
||||||
|
CREATE TABLE partitioned_table (id INT, a INT) PARTITION BY RANGE (id);
|
||||||
|
SELECT create_distributed_table('partitioned_table', 'id', colocate_with := 'none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE partitioned_table_1_5 PARTITION OF partitioned_table FOR VALUES FROM (1) TO (5);
|
||||||
|
CREATE TABLE partitioned_table_6_10 PARTITION OF partitioned_table FOR VALUES FROM (6) TO (10);
|
||||||
|
INSERT INTO partitioned_table VALUES (2, 12), (7, 2);
|
||||||
|
SELECT logicalrelid::text FROM pg_dist_partition WHERE logicalrelid::regclass::text LIKE 'partitioned\_table%' ORDER BY 1;
|
||||||
|
logicalrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table
|
||||||
|
partitioned_table_1_5
|
||||||
|
partitioned_table_6_10
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT run_command_on_workers($$SELECT COUNT(*) FROM pg_catalog.pg_class WHERE relname LIKE 'partitioned\_table%'$$);
|
||||||
|
run_command_on_workers
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
(localhost,57637,t,6)
|
||||||
|
(localhost,57638,t,6)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits WHERE inhparent = 'partitioned_table'::regclass ORDER BY 1;
|
||||||
|
inhrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table_1_5
|
||||||
|
partitioned_table_6_10
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT "Name"::text, "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'partitioned\_table%' ORDER BY 1;
|
||||||
|
Name | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table | id | 4
|
||||||
|
partitioned_table_1_5 | id | 4
|
||||||
|
partitioned_table_6_10 | id | 4
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT * FROM partitioned_table ORDER BY 1, 2;
|
||||||
|
id | a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
2 | 12
|
||||||
|
7 | 2
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT * FROM partitioned_table_1_5 ORDER BY 1, 2;
|
||||||
|
id | a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
2 | 12
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM partitioned_table_6_10 ORDER BY 1, 2;
|
||||||
|
id | a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
7 | 2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- test altering the parent table
|
||||||
|
SELECT alter_distributed_table('partitioned_table', shard_count := 10, distribution_column := 'a');
|
||||||
|
NOTICE: converting the partitions of alter_distributed_table.partitioned_table
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.partitioned_table_1_5
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.partitioned_table_1_5
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.partitioned_table_1_5
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.partitioned_table_1_5
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.partitioned_table_6_10
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.partitioned_table_6_10
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.partitioned_table_6_10
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.partitioned_table_6_10
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.partitioned_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.partitioned_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.partitioned_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- test altering the partition
|
||||||
|
SELECT alter_distributed_table('partitioned_table_1_5', shard_count := 10, distribution_column := 'a');
|
||||||
|
ERROR: cannot complete operation because table is a partition
|
||||||
|
HINT: the parent table is "partitioned_table"
|
||||||
|
SELECT logicalrelid::text FROM pg_dist_partition WHERE logicalrelid::regclass::text LIKE 'partitioned\_table%' ORDER BY 1;
|
||||||
|
logicalrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table
|
||||||
|
partitioned_table_1_5
|
||||||
|
partitioned_table_6_10
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT run_command_on_workers($$SELECT COUNT(*) FROM pg_catalog.pg_class WHERE relname LIKE 'partitioned\_table%'$$);
|
||||||
|
run_command_on_workers
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
(localhost,57637,t,15)
|
||||||
|
(localhost,57638,t,15)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits WHERE inhparent = 'partitioned_table'::regclass ORDER BY 1;
|
||||||
|
inhrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table_1_5
|
||||||
|
partitioned_table_6_10
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT "Name"::text, "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'partitioned\_table%' ORDER BY 1;
|
||||||
|
Name | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table | a | 10
|
||||||
|
partitioned_table_1_5 | a | 10
|
||||||
|
partitioned_table_6_10 | a | 10
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT * FROM partitioned_table ORDER BY 1, 2;
|
||||||
|
id | a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
2 | 12
|
||||||
|
7 | 2
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT * FROM partitioned_table_1_5 ORDER BY 1, 2;
|
||||||
|
id | a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
2 | 12
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM partitioned_table_6_10 ORDER BY 1, 2;
|
||||||
|
id | a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
7 | 2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- test references
|
||||||
|
CREATE TABLE referenced_dist_table (a INT UNIQUE);
|
||||||
|
CREATE TABLE referenced_ref_table (a INT UNIQUE);
|
||||||
|
CREATE TABLE table_with_references (a1 INT UNIQUE REFERENCES referenced_dist_table(a), a2 INT REFERENCES referenced_ref_table(a));
|
||||||
|
CREATE TABLE referencing_dist_table (a INT REFERENCES table_with_references(a1));
|
||||||
|
SELECT create_distributed_table('referenced_dist_table', 'a', colocate_with:='none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_reference_table('referenced_ref_table');
|
||||||
|
create_reference_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('table_with_references', 'a1', colocate_with:='referenced_dist_table');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('referencing_dist_table', 'a', colocate_with:='referenced_dist_table');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'table_with_references' OR confrelid::regclass::text = 'table_with_references') AND contype = 'f' ORDER BY 1;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
referencing_dist_table | FOREIGN KEY (a) REFERENCES table_with_references(a1)
|
||||||
|
table_with_references | FOREIGN KEY (a1) REFERENCES referenced_dist_table(a)
|
||||||
|
table_with_references | FOREIGN KEY (a2) REFERENCES referenced_ref_table(a)
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('table_with_references', shard_count := 12, cascade_to_colocated := true);
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'table_with_references' OR confrelid::regclass::text = 'table_with_references') AND contype = 'f' ORDER BY 1;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
referencing_dist_table | FOREIGN KEY (a) REFERENCES table_with_references(a1)
|
||||||
|
table_with_references | FOREIGN KEY (a2) REFERENCES referenced_ref_table(a)
|
||||||
|
table_with_references | FOREIGN KEY (a1) REFERENCES referenced_dist_table(a)
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('table_with_references', shard_count := 10, cascade_to_colocated := false);
|
||||||
|
WARNING: foreign key table_with_references_a1_fkey will be dropped
|
||||||
|
WARNING: foreign key referencing_dist_table_a_fkey will be dropped
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'table_with_references' OR confrelid::regclass::text = 'table_with_references') AND contype = 'f' ORDER BY 1;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
table_with_references | FOREIGN KEY (a2) REFERENCES referenced_ref_table(a)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- check when multi shard modify mode is set to sequential
|
||||||
|
SELECT alter_distributed_table('referenced_dist_table', colocate_with:='none');
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE ref_to_dist_table(a INT REFERENCES referenced_dist_table(a));
|
||||||
|
CREATE TABLE ref_to_ref_table(a INT REFERENCES referenced_ref_table(a));
|
||||||
|
SELECT create_distributed_table('ref_to_dist_table', 'a', colocate_with:='referenced_dist_table');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('ref_to_ref_table', 'a', colocate_with:='none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- alter a table referencing a reference table
|
||||||
|
SELECT alter_distributed_table('ref_to_ref_table', shard_count:=6);
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- let's create a table that is not colocated with a table that references a reference table
|
||||||
|
CREATE TABLE col_with_ref_to_dist (a INT);
|
||||||
|
SELECT create_distributed_table('col_with_ref_to_dist', 'a', colocate_with:='ref_to_dist_table');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- and create a table colocated with a table that references a reference table
|
||||||
|
CREATE TABLE col_with_ref_to_ref (a INT);
|
||||||
|
SELECT alter_distributed_table('ref_to_ref_table', colocate_with:='none');
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('col_with_ref_to_ref', 'a', colocate_with:='ref_to_ref_table');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- alter a table colocated with a table referencing a reference table with cascading
|
||||||
|
SELECT alter_distributed_table('col_with_ref_to_ref', shard_count:=8, cascade_to_colocated:=true);
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- alter a table colocated with a table referencing a reference table without cascading
|
||||||
|
SELECT alter_distributed_table('col_with_ref_to_ref', shard_count:=10, cascade_to_colocated:=false);
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- alter a table not colocated with a table referencing a reference table with cascading
|
||||||
|
SELECT alter_distributed_table('col_with_ref_to_dist', shard_count:=6, cascade_to_colocated:=true);
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\if :server_version_above_eleven
|
||||||
|
-- test altering columnar table
|
||||||
|
CREATE TABLE columnar_table (a INT) USING columnar;
|
||||||
|
SELECT create_distributed_table('columnar_table', 'a', colocate_with:='none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name"::text, "Shard Count", "Access Method" FROM public.citus_tables WHERE "Name"::text = 'columnar_table';
|
||||||
|
Name | Shard Count | Access Method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
columnar_table | 4 | columnar
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('columnar_table', shard_count:=6);
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name"::text, "Shard Count", "Access Method" FROM public.citus_tables WHERE "Name"::text = 'columnar_table';
|
||||||
|
Name | Shard Count | Access Method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
columnar_table | 6 | columnar
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\endif
|
||||||
|
-- test with metadata sync
|
||||||
|
SET citus.replication_model TO 'streaming';
|
||||||
|
SELECT start_metadata_sync_to_node('localhost', :worker_1_port);
|
||||||
|
start_metadata_sync_to_node
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE metadata_sync_table (a BIGSERIAL);
|
||||||
|
SELECT create_distributed_table('metadata_sync_table', 'a', colocate_with:='none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('metadata_sync_table', shard_count:=6);
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('metadata_sync_table', shard_count:=8);
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name", "Shard Count" FROM public.citus_tables WHERE "Name"::text = 'metadata_sync_table';
|
||||||
|
Name | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
metadata_sync_table | 8
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SET citus.replication_model TO DEFAULT;
|
||||||
|
SELECT stop_metadata_sync_to_node('localhost', :worker_1_port);
|
||||||
|
stop_metadata_sync_to_node
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- test complex cascade operations
|
||||||
|
CREATE TABLE cas_1 (a INT UNIQUE);
|
||||||
|
CREATE TABLE cas_2 (a INT UNIQUE);
|
||||||
|
CREATE TABLE cas_3 (a INT UNIQUE);
|
||||||
|
CREATE TABLE cas_4 (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);
|
||||||
|
CREATE TABLE cas_col (a INT UNIQUE);
|
||||||
|
-- add foreign keys from and to partitions
|
||||||
|
ALTER TABLE cas_par_1 ADD CONSTRAINT fkey_from_par_1 FOREIGN KEY (a) REFERENCES cas_1(a);
|
||||||
|
ALTER TABLE cas_2 ADD CONSTRAINT fkey_to_par_1 FOREIGN KEY (a) REFERENCES cas_par_1(a);
|
||||||
|
ALTER TABLE cas_par ADD CONSTRAINT fkey_from_par FOREIGN KEY (a) REFERENCES cas_3(a);
|
||||||
|
ALTER TABLE cas_4 ADD CONSTRAINT fkey_to_par FOREIGN KEY (a) REFERENCES cas_par(a);
|
||||||
|
-- distribute all the tables
|
||||||
|
SELECT create_distributed_table('cas_1', 'a', colocate_with:='none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('cas_3', 'a', colocate_with:='cas_1');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('cas_par', 'a', colocate_with:='cas_1');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('cas_2', 'a', colocate_with:='cas_1');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('cas_4', 'a', colocate_with:='cas_1');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('cas_col', 'a', colocate_with:='cas_1');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'cas_par_1' OR confrelid::regclass::text = 'cas_par_1') ORDER BY 1, 2;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
cas_2 | FOREIGN KEY (a) REFERENCES cas_par_1(a)
|
||||||
|
cas_4 | FOREIGN KEY (a) REFERENCES cas_par_1(a)
|
||||||
|
cas_par_1 | FOREIGN KEY (a) REFERENCES cas_1(a)
|
||||||
|
cas_par_1 | FOREIGN KEY (a) REFERENCES cas_3(a)
|
||||||
|
cas_par_1 | UNIQUE (a)
|
||||||
|
(5 rows)
|
||||||
|
|
||||||
|
SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits WHERE inhparent = 'cas_par'::regclass ORDER BY 1;
|
||||||
|
inhrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
cas_par_1
|
||||||
|
cas_par_2
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- alter the cas_col and cascade the change
|
||||||
|
SELECT alter_distributed_table('cas_col', shard_count:=6, cascade_to_colocated:=true);
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'cas_par_1' OR confrelid::regclass::text = 'cas_par_1') ORDER BY 1, 2;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
cas_2 | FOREIGN KEY (a) REFERENCES cas_par_1(a)
|
||||||
|
cas_4 | FOREIGN KEY (a) REFERENCES cas_par_1(a)
|
||||||
|
cas_par_1 | FOREIGN KEY (a) REFERENCES cas_1(a)
|
||||||
|
cas_par_1 | FOREIGN KEY (a) REFERENCES cas_3(a)
|
||||||
|
cas_par_1 | UNIQUE (a)
|
||||||
|
(5 rows)
|
||||||
|
|
||||||
|
SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits WHERE inhparent = 'cas_par'::regclass ORDER BY 1;
|
||||||
|
inhrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
cas_par_1
|
||||||
|
cas_par_2
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SET client_min_messages TO DEFAULT;
|
||||||
|
-- test changing dist column and colocating partitioned table without changing shard count
|
||||||
|
CREATE TABLE col_table (a INT);
|
||||||
|
SELECT create_distributed_table('col_table', 'a', colocate_with:='none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE par_table (a BIGINT, b INT) PARTITION BY RANGE (a);
|
||||||
|
SELECT create_distributed_table('par_table', 'a', colocate_with:='none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE par_table_1 (a BIGINT, b INT);
|
||||||
|
SELECT create_distributed_table('par_table_1', 'a', colocate_with:='par_table');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
ALTER TABLE par_table ATTACH PARTITION par_table_1 FOR VALUES FROM (1) TO (5);
|
||||||
|
SELECT alter_distributed_table('par_table', distribution_column:='b', colocate_with:='col_table');
|
||||||
|
NOTICE: converting the partitions of alter_distributed_table.par_table
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.par_table_1
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.par_table_1
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.par_table_1
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.par_table_1
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.par_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.par_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.par_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- test messages
|
||||||
|
-- test nothing to change
|
||||||
|
SELECT alter_distributed_table('dist_table');
|
||||||
|
ERROR: you have to specify at least one of the distribution_column, shard_count or colocate_with parameters
|
||||||
|
SELECT alter_distributed_table('dist_table', cascade_to_colocated := false);
|
||||||
|
ERROR: you have to specify at least one of the distribution_column, shard_count or colocate_with parameters
|
||||||
|
-- no operation UDF calls
|
||||||
|
SELECT alter_distributed_table('dist_table', distribution_column := 'b');
|
||||||
|
ERROR: this call doesn't change any properties of the table
|
||||||
|
HINT: check citus_tables view to see current properties of the table
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 10);
|
||||||
|
ERROR: this call doesn't change any properties of the table
|
||||||
|
HINT: check citus_tables view to see current properties of the table
|
||||||
|
-- first colocate the tables, then try to re-colococate
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'colocation_table');
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'colocation_table');
|
||||||
|
ERROR: this call doesn't change any properties of the table
|
||||||
|
HINT: check citus_tables view to see current properties of the table
|
||||||
|
-- test some changes while keeping others same
|
||||||
|
-- shouldn't error but should have notices about no-change parameters
|
||||||
|
SELECT alter_distributed_table('dist_table', distribution_column:='b', shard_count:=4, cascade_to_colocated:=false);
|
||||||
|
NOTICE: table is already distributed by b
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count:=4, colocate_with:='colocation_table_2');
|
||||||
|
NOTICE: shard count of the table is already 4
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with:='colocation_table_2', distribution_column:='a');
|
||||||
|
NOTICE: table is already colocated with colocation_table_2
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- test cascading distribution column, should error
|
||||||
|
SELECT alter_distributed_table('dist_table', distribution_column := 'b', cascade_to_colocated := true);
|
||||||
|
ERROR: distribution_column cannot be cascaded to colocated tables
|
||||||
|
SELECT alter_distributed_table('dist_table', distribution_column := 'b', shard_count:=12, colocate_with:='colocation_table_2', cascade_to_colocated := true);
|
||||||
|
ERROR: distribution_column cannot be cascaded to colocated tables
|
||||||
|
-- test nothing to cascade
|
||||||
|
SELECT alter_distributed_table('dist_table', cascade_to_colocated := true);
|
||||||
|
ERROR: shard_count or colocate_with is necessary for cascading to colocated tables
|
||||||
|
-- test cascading colocate_with := 'none'
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'none', cascade_to_colocated := true);
|
||||||
|
ERROR: colocate_with := 'none' cannot be cascaded to colocated tables
|
||||||
|
-- test changing shard count of a colocated table without cascade_to_colocated, should error
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 14);
|
||||||
|
ERROR: cascade_to_colocated parameter is necessary
|
||||||
|
DETAIL: this table is colocated with some other tables
|
||||||
|
HINT: cascade_to_colocated := false will break the current colocation, cascade_to_colocated := true will change the shard count of colocated tables too.
|
||||||
|
-- test changing shard count of a non-colocated table without cascade_to_colocated, shouldn't error
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'none');
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 14);
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- test altering a table into colocating with a table but giving a different shard count
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'colocation_table', shard_count := 16);
|
||||||
|
ERROR: shard_count cannot be different than the shard count of the table in colocate_with
|
||||||
|
HINT: if no shard_count is specified shard count will be same with colocate_with table's
|
||||||
|
-- test colocation with distribution columns with different data types
|
||||||
|
CREATE TABLE different_type_table (a TEXT);
|
||||||
|
SELECT create_distributed_table('different_type_table', 'a');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'different_type_table');
|
||||||
|
ERROR: cannot colocate with different_type_table because data type of its distribution column is different than dist_table
|
||||||
|
SELECT alter_distributed_table('dist_table', distribution_column := 'a', colocate_with := 'different_type_table');
|
||||||
|
ERROR: cannot colocate with different_type_table and change distribution column to a because data type of column a is different then the distribution column of the different_type_table
|
||||||
|
-- test shard_count := 0
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 0);
|
||||||
|
ERROR: shard_count cannot be 0
|
||||||
|
HINT: if you no longer want this to be a distributed table you can try undistribute_table() function
|
||||||
|
-- test colocating with non-distributed table
|
||||||
|
CREATE TABLE reference_table (a INT);
|
||||||
|
SELECT create_reference_table('reference_table');
|
||||||
|
create_reference_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with:='reference_table');
|
||||||
|
ERROR: cannot colocate with reference_table because it is not a distributed table
|
||||||
|
-- test append table
|
||||||
|
CREATE TABLE append_table (a INT);
|
||||||
|
SELECT create_distributed_table('append_table', 'a', 'append');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('append_table', shard_count:=6);
|
||||||
|
ERROR: relation append_table should be a hash distributed table
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
DROP SCHEMA alter_distributed_table CASCADE;
|
|
@ -0,0 +1,791 @@
|
||||||
|
SHOW server_version \gset
|
||||||
|
SELECT substring(:'server_version', '\d+')::int > 11 AS server_version_above_eleven;
|
||||||
|
server_version_above_eleven
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\gset
|
||||||
|
CREATE SCHEMA alter_distributed_table;
|
||||||
|
SET search_path TO alter_distributed_table;
|
||||||
|
SET citus.shard_count TO 4;
|
||||||
|
SET citus.shard_replication_factor TO 1;
|
||||||
|
CREATE TABLE dist_table (a INT, b INT);
|
||||||
|
SELECT create_distributed_table ('dist_table', 'a', colocate_with := 'none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
INSERT INTO dist_table VALUES (1, 1), (2, 2), (3, 3);
|
||||||
|
CREATE TABLE colocation_table (a INT, b INT);
|
||||||
|
SELECT create_distributed_table ('colocation_table', 'a', colocate_with := 'none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE colocation_table_2 (a INT, b INT);
|
||||||
|
SELECT create_distributed_table ('colocation_table_2', 'a', colocate_with := 'none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2');
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table | distributed | a | 4
|
||||||
|
colocation_table_2 | distributed | a | 4
|
||||||
|
dist_table | distributed | a | 4
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2') GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table
|
||||||
|
colocation_table_2
|
||||||
|
dist_table
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
-- test altering distribution column
|
||||||
|
SELECT alter_distributed_table('dist_table', distribution_column := 'b');
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2');
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table | distributed | a | 4
|
||||||
|
colocation_table_2 | distributed | a | 4
|
||||||
|
dist_table | distributed | b | 4
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2') GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table
|
||||||
|
colocation_table_2
|
||||||
|
dist_table
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
-- test altering shard count
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 6);
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2');
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table | distributed | a | 4
|
||||||
|
colocation_table_2 | distributed | a | 4
|
||||||
|
dist_table | distributed | b | 6
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2') GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table
|
||||||
|
colocation_table_2
|
||||||
|
dist_table
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
-- test altering colocation, note that shard count will also change
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'alter_distributed_table.colocation_table');
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2');
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table | distributed | a | 4
|
||||||
|
colocation_table_2 | distributed | a | 4
|
||||||
|
dist_table | distributed | b | 4
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2') GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table, dist_table
|
||||||
|
colocation_table_2
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- test altering shard count with cascading, note that the colocation will be kept
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 8, cascade_to_colocated := true);
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.colocation_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.colocation_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.colocation_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.colocation_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2');
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table | distributed | a | 8
|
||||||
|
colocation_table_2 | distributed | a | 4
|
||||||
|
dist_table | distributed | b | 8
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2') GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table, dist_table
|
||||||
|
colocation_table_2
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- test altering shard count without cascading, note that the colocation will be broken
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 10, cascade_to_colocated := false);
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2');
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table | distributed | a | 8
|
||||||
|
colocation_table_2 | distributed | a | 4
|
||||||
|
dist_table | distributed | b | 10
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2') GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
colocation_table
|
||||||
|
colocation_table_2
|
||||||
|
dist_table
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
-- test partitions
|
||||||
|
CREATE TABLE partitioned_table (id INT, a INT) PARTITION BY RANGE (id);
|
||||||
|
SELECT create_distributed_table('partitioned_table', 'id', colocate_with := 'none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE partitioned_table_1_5 PARTITION OF partitioned_table FOR VALUES FROM (1) TO (5);
|
||||||
|
CREATE TABLE partitioned_table_6_10 PARTITION OF partitioned_table FOR VALUES FROM (6) TO (10);
|
||||||
|
INSERT INTO partitioned_table VALUES (2, 12), (7, 2);
|
||||||
|
SELECT logicalrelid::text FROM pg_dist_partition WHERE logicalrelid::regclass::text LIKE 'partitioned\_table%' ORDER BY 1;
|
||||||
|
logicalrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table
|
||||||
|
partitioned_table_1_5
|
||||||
|
partitioned_table_6_10
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT run_command_on_workers($$SELECT COUNT(*) FROM pg_catalog.pg_class WHERE relname LIKE 'partitioned\_table%'$$);
|
||||||
|
run_command_on_workers
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
(localhost,57637,t,6)
|
||||||
|
(localhost,57638,t,6)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits WHERE inhparent = 'partitioned_table'::regclass ORDER BY 1;
|
||||||
|
inhrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table_1_5
|
||||||
|
partitioned_table_6_10
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT "Name"::text, "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'partitioned\_table%' ORDER BY 1;
|
||||||
|
Name | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table | id | 4
|
||||||
|
partitioned_table_1_5 | id | 4
|
||||||
|
partitioned_table_6_10 | id | 4
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT * FROM partitioned_table ORDER BY 1, 2;
|
||||||
|
id | a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
2 | 12
|
||||||
|
7 | 2
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT * FROM partitioned_table_1_5 ORDER BY 1, 2;
|
||||||
|
id | a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
2 | 12
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM partitioned_table_6_10 ORDER BY 1, 2;
|
||||||
|
id | a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
7 | 2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- test altering the parent table
|
||||||
|
SELECT alter_distributed_table('partitioned_table', shard_count := 10, distribution_column := 'a');
|
||||||
|
NOTICE: converting the partitions of alter_distributed_table.partitioned_table
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.partitioned_table_1_5
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.partitioned_table_1_5
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.partitioned_table_1_5
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.partitioned_table_1_5
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.partitioned_table_6_10
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.partitioned_table_6_10
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.partitioned_table_6_10
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.partitioned_table_6_10
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.partitioned_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.partitioned_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.partitioned_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- test altering the partition
|
||||||
|
SELECT alter_distributed_table('partitioned_table_1_5', shard_count := 10, distribution_column := 'a');
|
||||||
|
ERROR: cannot complete operation because table is a partition
|
||||||
|
HINT: the parent table is "partitioned_table"
|
||||||
|
SELECT logicalrelid::text FROM pg_dist_partition WHERE logicalrelid::regclass::text LIKE 'partitioned\_table%' ORDER BY 1;
|
||||||
|
logicalrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table
|
||||||
|
partitioned_table_1_5
|
||||||
|
partitioned_table_6_10
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT run_command_on_workers($$SELECT COUNT(*) FROM pg_catalog.pg_class WHERE relname LIKE 'partitioned\_table%'$$);
|
||||||
|
run_command_on_workers
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
(localhost,57637,t,15)
|
||||||
|
(localhost,57638,t,15)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits WHERE inhparent = 'partitioned_table'::regclass ORDER BY 1;
|
||||||
|
inhrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table_1_5
|
||||||
|
partitioned_table_6_10
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT "Name"::text, "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'partitioned\_table%' ORDER BY 1;
|
||||||
|
Name | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table | a | 10
|
||||||
|
partitioned_table_1_5 | a | 10
|
||||||
|
partitioned_table_6_10 | a | 10
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT * FROM partitioned_table ORDER BY 1, 2;
|
||||||
|
id | a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
2 | 12
|
||||||
|
7 | 2
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT * FROM partitioned_table_1_5 ORDER BY 1, 2;
|
||||||
|
id | a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
2 | 12
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM partitioned_table_6_10 ORDER BY 1, 2;
|
||||||
|
id | a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
7 | 2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- test references
|
||||||
|
CREATE TABLE referenced_dist_table (a INT UNIQUE);
|
||||||
|
CREATE TABLE referenced_ref_table (a INT UNIQUE);
|
||||||
|
CREATE TABLE table_with_references (a1 INT UNIQUE REFERENCES referenced_dist_table(a), a2 INT REFERENCES referenced_ref_table(a));
|
||||||
|
CREATE TABLE referencing_dist_table (a INT REFERENCES table_with_references(a1));
|
||||||
|
SELECT create_distributed_table('referenced_dist_table', 'a', colocate_with:='none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_reference_table('referenced_ref_table');
|
||||||
|
create_reference_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('table_with_references', 'a1', colocate_with:='referenced_dist_table');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('referencing_dist_table', 'a', colocate_with:='referenced_dist_table');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'table_with_references' OR confrelid::regclass::text = 'table_with_references') AND contype = 'f' ORDER BY 1;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
referencing_dist_table | FOREIGN KEY (a) REFERENCES table_with_references(a1)
|
||||||
|
table_with_references | FOREIGN KEY (a1) REFERENCES referenced_dist_table(a)
|
||||||
|
table_with_references | FOREIGN KEY (a2) REFERENCES referenced_ref_table(a)
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('table_with_references', shard_count := 12, cascade_to_colocated := true);
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'table_with_references' OR confrelid::regclass::text = 'table_with_references') AND contype = 'f' ORDER BY 1;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
referencing_dist_table | FOREIGN KEY (a) REFERENCES table_with_references(a1)
|
||||||
|
table_with_references | FOREIGN KEY (a2) REFERENCES referenced_ref_table(a)
|
||||||
|
table_with_references | FOREIGN KEY (a1) REFERENCES referenced_dist_table(a)
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('table_with_references', shard_count := 10, cascade_to_colocated := false);
|
||||||
|
WARNING: foreign key table_with_references_a1_fkey will be dropped
|
||||||
|
WARNING: foreign key referencing_dist_table_a_fkey will be dropped
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'table_with_references' OR confrelid::regclass::text = 'table_with_references') AND contype = 'f' ORDER BY 1;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
table_with_references | FOREIGN KEY (a2) REFERENCES referenced_ref_table(a)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- check when multi shard modify mode is set to sequential
|
||||||
|
SELECT alter_distributed_table('referenced_dist_table', colocate_with:='none');
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE ref_to_dist_table(a INT REFERENCES referenced_dist_table(a));
|
||||||
|
CREATE TABLE ref_to_ref_table(a INT REFERENCES referenced_ref_table(a));
|
||||||
|
SELECT create_distributed_table('ref_to_dist_table', 'a', colocate_with:='referenced_dist_table');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('ref_to_ref_table', 'a', colocate_with:='none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- alter a table referencing a reference table
|
||||||
|
SELECT alter_distributed_table('ref_to_ref_table', shard_count:=6);
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- let's create a table that is not colocated with a table that references a reference table
|
||||||
|
CREATE TABLE col_with_ref_to_dist (a INT);
|
||||||
|
SELECT create_distributed_table('col_with_ref_to_dist', 'a', colocate_with:='ref_to_dist_table');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- and create a table colocated with a table that references a reference table
|
||||||
|
CREATE TABLE col_with_ref_to_ref (a INT);
|
||||||
|
SELECT alter_distributed_table('ref_to_ref_table', colocate_with:='none');
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('col_with_ref_to_ref', 'a', colocate_with:='ref_to_ref_table');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- alter a table colocated with a table referencing a reference table with cascading
|
||||||
|
SELECT alter_distributed_table('col_with_ref_to_ref', shard_count:=8, cascade_to_colocated:=true);
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- alter a table colocated with a table referencing a reference table without cascading
|
||||||
|
SELECT alter_distributed_table('col_with_ref_to_ref', shard_count:=10, cascade_to_colocated:=false);
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- alter a table not colocated with a table referencing a reference table with cascading
|
||||||
|
SELECT alter_distributed_table('col_with_ref_to_dist', shard_count:=6, cascade_to_colocated:=true);
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\if :server_version_above_eleven
|
||||||
|
-- test altering columnar table
|
||||||
|
CREATE TABLE columnar_table (a INT) USING columnar;
|
||||||
|
SELECT create_distributed_table('columnar_table', 'a', colocate_with:='none');
|
||||||
|
SELECT "Name"::text, "Shard Count", "Access Method" FROM public.citus_tables WHERE "Name"::text = 'columnar_table';
|
||||||
|
SELECT alter_distributed_table('columnar_table', shard_count:=6);
|
||||||
|
SELECT "Name"::text, "Shard Count", "Access Method" FROM public.citus_tables WHERE "Name"::text = 'columnar_table';
|
||||||
|
\endif
|
||||||
|
-- test with metadata sync
|
||||||
|
SET citus.replication_model TO 'streaming';
|
||||||
|
SELECT start_metadata_sync_to_node('localhost', :worker_1_port);
|
||||||
|
start_metadata_sync_to_node
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE metadata_sync_table (a BIGSERIAL);
|
||||||
|
SELECT create_distributed_table('metadata_sync_table', 'a', colocate_with:='none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('metadata_sync_table', shard_count:=6);
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('metadata_sync_table', shard_count:=8);
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name", "Shard Count" FROM public.citus_tables WHERE "Name"::text = 'metadata_sync_table';
|
||||||
|
Name | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
metadata_sync_table | 8
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SET citus.replication_model TO DEFAULT;
|
||||||
|
SELECT stop_metadata_sync_to_node('localhost', :worker_1_port);
|
||||||
|
stop_metadata_sync_to_node
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- test complex cascade operations
|
||||||
|
CREATE TABLE cas_1 (a INT UNIQUE);
|
||||||
|
CREATE TABLE cas_2 (a INT UNIQUE);
|
||||||
|
CREATE TABLE cas_3 (a INT UNIQUE);
|
||||||
|
CREATE TABLE cas_4 (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);
|
||||||
|
CREATE TABLE cas_col (a INT UNIQUE);
|
||||||
|
-- add foreign keys from and to partitions
|
||||||
|
ALTER TABLE cas_par_1 ADD CONSTRAINT fkey_from_par_1 FOREIGN KEY (a) REFERENCES cas_1(a);
|
||||||
|
ALTER TABLE cas_2 ADD CONSTRAINT fkey_to_par_1 FOREIGN KEY (a) REFERENCES cas_par_1(a);
|
||||||
|
ALTER TABLE cas_par ADD CONSTRAINT fkey_from_par FOREIGN KEY (a) REFERENCES cas_3(a);
|
||||||
|
ALTER TABLE cas_4 ADD CONSTRAINT fkey_to_par FOREIGN KEY (a) REFERENCES cas_par(a);
|
||||||
|
ERROR: cannot reference partitioned table "cas_par"
|
||||||
|
-- distribute all the tables
|
||||||
|
SELECT create_distributed_table('cas_1', 'a', colocate_with:='none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('cas_3', 'a', colocate_with:='cas_1');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('cas_par', 'a', colocate_with:='cas_1');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('cas_2', 'a', colocate_with:='cas_1');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('cas_4', 'a', colocate_with:='cas_1');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('cas_col', 'a', colocate_with:='cas_1');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'cas_par_1' OR confrelid::regclass::text = 'cas_par_1') ORDER BY 1, 2;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
cas_2 | FOREIGN KEY (a) REFERENCES cas_par_1(a)
|
||||||
|
cas_par_1 | FOREIGN KEY (a) REFERENCES cas_1(a)
|
||||||
|
cas_par_1 | FOREIGN KEY (a) REFERENCES cas_3(a)
|
||||||
|
cas_par_1 | UNIQUE (a)
|
||||||
|
(4 rows)
|
||||||
|
|
||||||
|
SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits WHERE inhparent = 'cas_par'::regclass ORDER BY 1;
|
||||||
|
inhrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
cas_par_1
|
||||||
|
cas_par_2
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- alter the cas_col and cascade the change
|
||||||
|
SELECT alter_distributed_table('cas_col', shard_count:=6, cascade_to_colocated:=true);
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'cas_par_1' OR confrelid::regclass::text = 'cas_par_1') ORDER BY 1, 2;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
cas_2 | FOREIGN KEY (a) REFERENCES cas_par_1(a)
|
||||||
|
cas_par_1 | FOREIGN KEY (a) REFERENCES cas_1(a)
|
||||||
|
cas_par_1 | FOREIGN KEY (a) REFERENCES cas_3(a)
|
||||||
|
cas_par_1 | UNIQUE (a)
|
||||||
|
(4 rows)
|
||||||
|
|
||||||
|
SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits WHERE inhparent = 'cas_par'::regclass ORDER BY 1;
|
||||||
|
inhrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
cas_par_1
|
||||||
|
cas_par_2
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SET client_min_messages TO DEFAULT;
|
||||||
|
-- test changing dist column and colocating partitioned table without changing shard count
|
||||||
|
CREATE TABLE col_table (a INT);
|
||||||
|
SELECT create_distributed_table('col_table', 'a', colocate_with:='none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE par_table (a BIGINT, b INT) PARTITION BY RANGE (a);
|
||||||
|
SELECT create_distributed_table('par_table', 'a', colocate_with:='none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE par_table_1 (a BIGINT, b INT);
|
||||||
|
SELECT create_distributed_table('par_table_1', 'a', colocate_with:='par_table');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
ALTER TABLE par_table ATTACH PARTITION par_table_1 FOR VALUES FROM (1) TO (5);
|
||||||
|
SELECT alter_distributed_table('par_table', distribution_column:='b', colocate_with:='col_table');
|
||||||
|
NOTICE: converting the partitions of alter_distributed_table.par_table
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.par_table_1
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.par_table_1
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.par_table_1
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.par_table_1
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.par_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.par_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.par_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- test messages
|
||||||
|
-- test nothing to change
|
||||||
|
SELECT alter_distributed_table('dist_table');
|
||||||
|
ERROR: you have to specify at least one of the distribution_column, shard_count or colocate_with parameters
|
||||||
|
SELECT alter_distributed_table('dist_table', cascade_to_colocated := false);
|
||||||
|
ERROR: you have to specify at least one of the distribution_column, shard_count or colocate_with parameters
|
||||||
|
-- no operation UDF calls
|
||||||
|
SELECT alter_distributed_table('dist_table', distribution_column := 'b');
|
||||||
|
ERROR: this call doesn't change any properties of the table
|
||||||
|
HINT: check citus_tables view to see current properties of the table
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 10);
|
||||||
|
ERROR: this call doesn't change any properties of the table
|
||||||
|
HINT: check citus_tables view to see current properties of the table
|
||||||
|
-- first colocate the tables, then try to re-colococate
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'colocation_table');
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'colocation_table');
|
||||||
|
ERROR: this call doesn't change any properties of the table
|
||||||
|
HINT: check citus_tables view to see current properties of the table
|
||||||
|
-- test some changes while keeping others same
|
||||||
|
-- shouldn't error but should have notices about no-change parameters
|
||||||
|
SELECT alter_distributed_table('dist_table', distribution_column:='b', shard_count:=4, cascade_to_colocated:=false);
|
||||||
|
NOTICE: table is already distributed by b
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count:=4, colocate_with:='colocation_table_2');
|
||||||
|
NOTICE: shard count of the table is already 4
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with:='colocation_table_2', distribution_column:='a');
|
||||||
|
NOTICE: table is already colocated with colocation_table_2
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- test cascading distribution column, should error
|
||||||
|
SELECT alter_distributed_table('dist_table', distribution_column := 'b', cascade_to_colocated := true);
|
||||||
|
ERROR: distribution_column cannot be cascaded to colocated tables
|
||||||
|
SELECT alter_distributed_table('dist_table', distribution_column := 'b', shard_count:=12, colocate_with:='colocation_table_2', cascade_to_colocated := true);
|
||||||
|
ERROR: distribution_column cannot be cascaded to colocated tables
|
||||||
|
-- test nothing to cascade
|
||||||
|
SELECT alter_distributed_table('dist_table', cascade_to_colocated := true);
|
||||||
|
ERROR: shard_count or colocate_with is necessary for cascading to colocated tables
|
||||||
|
-- test cascading colocate_with := 'none'
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'none', cascade_to_colocated := true);
|
||||||
|
ERROR: colocate_with := 'none' cannot be cascaded to colocated tables
|
||||||
|
-- test changing shard count of a colocated table without cascade_to_colocated, should error
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 14);
|
||||||
|
ERROR: cascade_to_colocated parameter is necessary
|
||||||
|
DETAIL: this table is colocated with some other tables
|
||||||
|
HINT: cascade_to_colocated := false will break the current colocation, cascade_to_colocated := true will change the shard count of colocated tables too.
|
||||||
|
-- test changing shard count of a non-colocated table without cascade_to_colocated, shouldn't error
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'none');
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 14);
|
||||||
|
NOTICE: creating a new table for alter_distributed_table.dist_table
|
||||||
|
NOTICE: Moving the data of alter_distributed_table.dist_table
|
||||||
|
NOTICE: Dropping the old alter_distributed_table.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_distributed_table.dist_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- test altering a table into colocating with a table but giving a different shard count
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'colocation_table', shard_count := 16);
|
||||||
|
ERROR: shard_count cannot be different than the shard count of the table in colocate_with
|
||||||
|
HINT: if no shard_count is specified shard count will be same with colocate_with table's
|
||||||
|
-- test colocation with distribution columns with different data types
|
||||||
|
CREATE TABLE different_type_table (a TEXT);
|
||||||
|
SELECT create_distributed_table('different_type_table', 'a');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'different_type_table');
|
||||||
|
ERROR: cannot colocate with different_type_table because data type of its distribution column is different than dist_table
|
||||||
|
SELECT alter_distributed_table('dist_table', distribution_column := 'a', colocate_with := 'different_type_table');
|
||||||
|
ERROR: cannot colocate with different_type_table and change distribution column to a because data type of column a is different then the distribution column of the different_type_table
|
||||||
|
-- test shard_count := 0
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 0);
|
||||||
|
ERROR: shard_count cannot be 0
|
||||||
|
HINT: if you no longer want this to be a distributed table you can try undistribute_table() function
|
||||||
|
-- test colocating with non-distributed table
|
||||||
|
CREATE TABLE reference_table (a INT);
|
||||||
|
SELECT create_reference_table('reference_table');
|
||||||
|
create_reference_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with:='reference_table');
|
||||||
|
ERROR: cannot colocate with reference_table because it is not a distributed table
|
||||||
|
-- test append table
|
||||||
|
CREATE TABLE append_table (a INT);
|
||||||
|
SELECT create_distributed_table('append_table', 'a', 'append');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('append_table', shard_count:=6);
|
||||||
|
ERROR: relation append_table should be a hash distributed table
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
DROP SCHEMA alter_distributed_table CASCADE;
|
|
@ -0,0 +1,394 @@
|
||||||
|
SHOW server_version \gset
|
||||||
|
SELECT substring(:'server_version', '\d+')::int > 11 AS server_version_above_eleven
|
||||||
|
\gset
|
||||||
|
\if :server_version_above_eleven
|
||||||
|
\else
|
||||||
|
\q
|
||||||
|
\endif
|
||||||
|
CREATE SCHEMA alter_table_set_access_method;
|
||||||
|
SET search_path TO alter_table_set_access_method;
|
||||||
|
SET citus.shard_count TO 4;
|
||||||
|
SET citus.shard_replication_factor TO 1;
|
||||||
|
SELECT public.run_command_on_coordinator_and_workers($Q$
|
||||||
|
CREATE FUNCTION fake_am_handler(internal)
|
||||||
|
RETURNS table_am_handler
|
||||||
|
AS 'citus'
|
||||||
|
LANGUAGE C;
|
||||||
|
CREATE ACCESS METHOD fake_am TYPE TABLE HANDLER fake_am_handler;
|
||||||
|
$Q$);
|
||||||
|
run_command_on_coordinator_and_workers
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE dist_table (a INT, b INT);
|
||||||
|
SELECT create_distributed_table ('dist_table', 'a');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
INSERT INTO dist_table VALUES (1, 1), (2, 2), (3, 3);
|
||||||
|
SELECT "Name", "Access Method" FROM public.citus_tables WHERE "Name"::text = 'dist_table' ORDER BY 1;
|
||||||
|
Name | Access Method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
dist_table | heap
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_table_set_access_method('dist_table', 'columnar');
|
||||||
|
NOTICE: any index will be dropped, because columnar tables cannot have indexes
|
||||||
|
NOTICE: creating a new table for alter_table_set_access_method.dist_table
|
||||||
|
NOTICE: Moving the data of alter_table_set_access_method.dist_table
|
||||||
|
NOTICE: Dropping the old alter_table_set_access_method.dist_table
|
||||||
|
NOTICE: Renaming the new table to alter_table_set_access_method.dist_table
|
||||||
|
alter_table_set_access_method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name", "Access Method" FROM public.citus_tables WHERE "Name"::text = 'dist_table' ORDER BY 1;
|
||||||
|
Name | Access Method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
dist_table | columnar
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- test partitions
|
||||||
|
CREATE TABLE partitioned_table (id INT, a INT) PARTITION BY RANGE (id);
|
||||||
|
CREATE TABLE partitioned_table_1_5 PARTITION OF partitioned_table FOR VALUES FROM (1) TO (5);
|
||||||
|
CREATE TABLE partitioned_table_6_10 PARTITION OF partitioned_table FOR VALUES FROM (6) TO (10);
|
||||||
|
SELECT create_distributed_table('partitioned_table', 'id');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
INSERT INTO partitioned_table VALUES (2, 12), (7, 2);
|
||||||
|
SELECT logicalrelid::text FROM pg_dist_partition WHERE logicalrelid::regclass::text LIKE 'partitioned\_table%' ORDER BY 1;
|
||||||
|
logicalrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table
|
||||||
|
partitioned_table_1_5
|
||||||
|
partitioned_table_6_10
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT run_command_on_workers($$SELECT COUNT(*) FROM pg_catalog.pg_class WHERE relname LIKE 'partitioned\_table%'$$);
|
||||||
|
run_command_on_workers
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
(localhost,57637,t,6)
|
||||||
|
(localhost,57638,t,6)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits WHERE inhparent = 'partitioned_table'::regclass ORDER BY 1;
|
||||||
|
inhrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table_1_5
|
||||||
|
partitioned_table_6_10
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT "Name"::text, "Access Method" FROM public.citus_tables WHERE "Name"::text LIKE 'partitioned\_table%' ORDER BY 1;
|
||||||
|
Name | Access Method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table |
|
||||||
|
partitioned_table_1_5 | heap
|
||||||
|
partitioned_table_6_10 | heap
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT * FROM partitioned_table ORDER BY 1, 2;
|
||||||
|
id | a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
2 | 12
|
||||||
|
7 | 2
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT * FROM partitioned_table_1_5 ORDER BY 1, 2;
|
||||||
|
id | a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
2 | 12
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM partitioned_table_6_10 ORDER BY 1, 2;
|
||||||
|
id | a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
7 | 2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- altering partitioned tables' access methods is not supported
|
||||||
|
SELECT alter_table_set_access_method('partitioned_table', 'columnar');
|
||||||
|
ERROR: you cannot alter access method of a partitioned table
|
||||||
|
-- test altering the partition's access method
|
||||||
|
SELECT alter_table_set_access_method('partitioned_table_1_5', 'columnar');
|
||||||
|
NOTICE: any index will be dropped, because columnar tables cannot have indexes
|
||||||
|
NOTICE: creating a new table for alter_table_set_access_method.partitioned_table_1_5
|
||||||
|
NOTICE: Moving the data of alter_table_set_access_method.partitioned_table_1_5
|
||||||
|
NOTICE: Dropping the old alter_table_set_access_method.partitioned_table_1_5
|
||||||
|
NOTICE: Renaming the new table to alter_table_set_access_method.partitioned_table_1_5
|
||||||
|
alter_table_set_access_method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT logicalrelid::text FROM pg_dist_partition WHERE logicalrelid::regclass::text LIKE 'partitioned\_table%' ORDER BY 1;
|
||||||
|
logicalrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table
|
||||||
|
partitioned_table_1_5
|
||||||
|
partitioned_table_6_10
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT run_command_on_workers($$SELECT COUNT(*) FROM pg_catalog.pg_class WHERE relname LIKE 'partitioned\_table%'$$);
|
||||||
|
run_command_on_workers
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
(localhost,57637,t,6)
|
||||||
|
(localhost,57638,t,6)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits WHERE inhparent = 'partitioned_table'::regclass ORDER BY 1;
|
||||||
|
inhrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table_1_5
|
||||||
|
partitioned_table_6_10
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT "Name"::text, "Access Method" FROM public.citus_tables WHERE "Name"::text LIKE 'partitioned\_table%' ORDER BY 1;
|
||||||
|
Name | Access Method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table |
|
||||||
|
partitioned_table_1_5 | columnar
|
||||||
|
partitioned_table_6_10 | heap
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT * FROM partitioned_table ORDER BY 1, 2;
|
||||||
|
id | a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
2 | 12
|
||||||
|
7 | 2
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT * FROM partitioned_table_1_5 ORDER BY 1, 2;
|
||||||
|
id | a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
2 | 12
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM partitioned_table_6_10 ORDER BY 1, 2;
|
||||||
|
id | a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
7 | 2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- test altering a table with index to columnar
|
||||||
|
-- the index will be dropped
|
||||||
|
CREATE TABLE index_table (a INT) ;
|
||||||
|
CREATE INDEX idx1 ON index_table (a);
|
||||||
|
SELECT indexname FROM pg_indexes WHERE schemaname = 'alter_table_set_access_method' AND tablename = 'index_table';
|
||||||
|
indexname
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
idx1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT a.amname FROM pg_class c, pg_am a where c.relname = 'index_table' AND c.relnamespace = 'alter_table_set_access_method'::regnamespace AND c.relam = a.oid;
|
||||||
|
amname
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
heap
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_table_set_access_method('index_table', 'columnar');
|
||||||
|
NOTICE: any index will be dropped, because columnar tables cannot have indexes
|
||||||
|
NOTICE: creating a new table for alter_table_set_access_method.index_table
|
||||||
|
NOTICE: Moving the data of alter_table_set_access_method.index_table
|
||||||
|
NOTICE: Dropping the old alter_table_set_access_method.index_table
|
||||||
|
NOTICE: Renaming the new table to alter_table_set_access_method.index_table
|
||||||
|
alter_table_set_access_method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT indexname FROM pg_indexes WHERE schemaname = 'alter_table_set_access_method' AND tablename = 'index_table';
|
||||||
|
indexname
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
SELECT a.amname FROM pg_class c, pg_am a where c.relname = 'index_table' AND c.relnamespace = 'alter_table_set_access_method'::regnamespace AND c.relam = a.oid;
|
||||||
|
amname
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
columnar
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- test different table types
|
||||||
|
SET client_min_messages to WARNING;
|
||||||
|
SELECT 1 FROM master_add_node('localhost', :master_port, groupId := 0);
|
||||||
|
?column?
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SET client_min_messages to DEFAULT;
|
||||||
|
CREATE TABLE table_type_dist (a INT);
|
||||||
|
SELECT create_distributed_table('table_type_dist', 'a');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE table_type_ref (a INT);
|
||||||
|
SELECT create_reference_table('table_type_ref');
|
||||||
|
create_reference_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE table_type_citus_local(a INT);
|
||||||
|
SELECT create_citus_local_table('table_type_citus_local');
|
||||||
|
create_citus_local_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE table_type_pg_local (a INT);
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count", "Access Method" FROM public.citus_tables WHERE "Name"::text LIKE 'table\_type%' ORDER BY 1;
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count | Access Method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
table_type_dist | distributed | a | 4 | heap
|
||||||
|
table_type_ref | reference | <none> | 1 | heap
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT c.relname, a.amname FROM pg_class c, pg_am a where c.relname SIMILAR TO 'table_type\D*' AND c.relnamespace = 'alter_table_set_access_method'::regnamespace AND c.relam = a.oid;
|
||||||
|
relname | amname
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
table_type_citus_local | heap
|
||||||
|
table_type_dist | heap
|
||||||
|
table_type_pg_local | heap
|
||||||
|
table_type_ref | heap
|
||||||
|
(4 rows)
|
||||||
|
|
||||||
|
SELECT alter_table_set_access_method('table_type_dist', 'fake_am');
|
||||||
|
NOTICE: creating a new table for alter_table_set_access_method.table_type_dist
|
||||||
|
WARNING: fake_scan_getnextslot
|
||||||
|
CONTEXT: SQL statement "SELECT EXISTS (SELECT 1 FROM alter_table_set_access_method.table_type_dist_1533505599)"
|
||||||
|
WARNING: fake_scan_getnextslot
|
||||||
|
NOTICE: Moving the data of alter_table_set_access_method.table_type_dist
|
||||||
|
NOTICE: Dropping the old alter_table_set_access_method.table_type_dist
|
||||||
|
NOTICE: Renaming the new table to alter_table_set_access_method.table_type_dist
|
||||||
|
alter_table_set_access_method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_table_set_access_method('table_type_ref', 'fake_am');
|
||||||
|
NOTICE: creating a new table for alter_table_set_access_method.table_type_ref
|
||||||
|
WARNING: fake_scan_getnextslot
|
||||||
|
CONTEXT: SQL statement "SELECT EXISTS (SELECT 1 FROM alter_table_set_access_method.table_type_ref_1037855087)"
|
||||||
|
WARNING: fake_scan_getnextslot
|
||||||
|
NOTICE: Moving the data of alter_table_set_access_method.table_type_ref
|
||||||
|
NOTICE: Dropping the old alter_table_set_access_method.table_type_ref
|
||||||
|
NOTICE: Renaming the new table to alter_table_set_access_method.table_type_ref
|
||||||
|
alter_table_set_access_method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_table_set_access_method('table_type_pg_local', 'fake_am');
|
||||||
|
NOTICE: creating a new table for alter_table_set_access_method.table_type_pg_local
|
||||||
|
NOTICE: Moving the data of alter_table_set_access_method.table_type_pg_local
|
||||||
|
NOTICE: Dropping the old alter_table_set_access_method.table_type_pg_local
|
||||||
|
NOTICE: Renaming the new table to alter_table_set_access_method.table_type_pg_local
|
||||||
|
alter_table_set_access_method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_table_set_access_method('table_type_citus_local', 'fake_am');
|
||||||
|
NOTICE: creating a new table for alter_table_set_access_method.table_type_citus_local
|
||||||
|
NOTICE: Moving the data of alter_table_set_access_method.table_type_citus_local
|
||||||
|
NOTICE: Dropping the old alter_table_set_access_method.table_type_citus_local
|
||||||
|
NOTICE: Renaming the new table to alter_table_set_access_method.table_type_citus_local
|
||||||
|
alter_table_set_access_method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count", "Access Method" FROM public.citus_tables WHERE "Name"::text LIKE 'table\_type%' ORDER BY 1;
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count | Access Method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
table_type_dist | distributed | a | 4 | fake_am
|
||||||
|
table_type_ref | reference | <none> | 1 | fake_am
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT c.relname, a.amname FROM pg_class c, pg_am a where c.relname SIMILAR TO 'table_type\D*' AND c.relnamespace = 'alter_table_set_access_method'::regnamespace AND c.relam = a.oid;
|
||||||
|
relname | amname
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
table_type_citus_local | fake_am
|
||||||
|
table_type_dist | fake_am
|
||||||
|
table_type_pg_local | fake_am
|
||||||
|
table_type_ref | fake_am
|
||||||
|
(4 rows)
|
||||||
|
|
||||||
|
-- test when the parent of a partition has foreign key to a reference table
|
||||||
|
CREATE TABLE ref_table (a INT UNIQUE);
|
||||||
|
SELECT create_reference_table('ref_table');
|
||||||
|
create_reference_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
INSERT INTO ref_table VALUES (2), (12);
|
||||||
|
ALTER TABLE partitioned_table ADD CONSTRAINT fkey_to_ref FOREIGN KEY (a) REFERENCES ref_table(a);
|
||||||
|
SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits WHERE inhparent = 'partitioned_table'::regclass ORDER BY 1;
|
||||||
|
inhrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table_1_5
|
||||||
|
partitioned_table_6_10
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT "Name", "Access Method" FROM public.citus_tables WHERE "Name"::text = 'partitioned_table_6_10';
|
||||||
|
Name | Access Method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table_6_10 | heap
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'partitioned_table_6_10') ORDER BY 1, 2;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table_6_10 | FOREIGN KEY (a) REFERENCES ref_table(a)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT alter_table_set_access_method('partitioned_table_6_10', 'columnar');
|
||||||
|
NOTICE: any index will be dropped, because columnar tables cannot have indexes
|
||||||
|
NOTICE: creating a new table for alter_table_set_access_method.partitioned_table_6_10
|
||||||
|
NOTICE: Moving the data of alter_table_set_access_method.partitioned_table_6_10
|
||||||
|
NOTICE: Dropping the old alter_table_set_access_method.partitioned_table_6_10
|
||||||
|
NOTICE: Renaming the new table to alter_table_set_access_method.partitioned_table_6_10
|
||||||
|
alter_table_set_access_method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits WHERE inhparent = 'partitioned_table'::regclass ORDER BY 1;
|
||||||
|
inhrelid
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table_1_5
|
||||||
|
partitioned_table_6_10
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT "Name", "Access Method" FROM public.citus_tables WHERE "Name"::text = 'partitioned_table_6_10';
|
||||||
|
Name | Access Method
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table_6_10 | columnar
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'partitioned_table_6_10') ORDER BY 1, 2;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
partitioned_table_6_10 | FOREIGN KEY (a) REFERENCES ref_table(a)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
DROP SCHEMA alter_table_set_access_method CASCADE;
|
||||||
|
SELECT 1 FROM master_remove_node('localhost', :master_port);
|
||||||
|
?column?
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
SHOW server_version \gset
|
||||||
|
SELECT substring(:'server_version', '\d+')::int > 11 AS server_version_above_eleven
|
||||||
|
\gset
|
||||||
|
\if :server_version_above_eleven
|
||||||
|
\else
|
||||||
|
\q
|
|
@ -330,7 +330,7 @@ ERROR: Table 'citus_local_table_1' is a citus local table. Replicating shard of
|
||||||
-- undistribute_table is supported
|
-- undistribute_table is supported
|
||||||
BEGIN;
|
BEGIN;
|
||||||
SELECT undistribute_table('citus_local_table_1');
|
SELECT undistribute_table('citus_local_table_1');
|
||||||
NOTICE: creating a new local 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_1504027 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
|
||||||
|
|
|
@ -618,6 +618,166 @@ SELECT 1 AS created WHERE EXISTS(SELECT * FROM pg_indexes WHERE indexname LIKE '
|
||||||
1
|
1
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- test alter_distributed_table UDF
|
||||||
|
SET citus.shard_count TO 4;
|
||||||
|
CREATE TABLE adt_table (a INT, b INT);
|
||||||
|
CREATE TABLE adt_col (a INT UNIQUE, b INT);
|
||||||
|
CREATE TABLE adt_ref (a INT REFERENCES adt_col(a));
|
||||||
|
SELECT create_distributed_table('adt_table', 'a', colocate_with:='none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('adt_col', 'a', colocate_with:='adt_table');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('adt_ref', 'a', colocate_with:='adt_table');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
INSERT INTO adt_table VALUES (1, 2), (3, 4), (5, 6);
|
||||||
|
NOTICE: executing the command locally: INSERT INTO coordinator_shouldhaveshards.adt_table_1503060 AS citus_table_alias (a, b) VALUES (1,2), (5,6)
|
||||||
|
INSERT INTO adt_col VALUES (3, 4), (5, 6), (7, 8);
|
||||||
|
NOTICE: executing the command locally: INSERT INTO coordinator_shouldhaveshards.adt_col_1503064 AS citus_table_alias (a, b) VALUES (5,6)
|
||||||
|
INSERT INTO adt_ref VALUES (3), (5);
|
||||||
|
NOTICE: executing the command locally: INSERT INTO coordinator_shouldhaveshards.adt_ref_1503068 AS citus_table_alias (a) VALUES (5)
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%';
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col | distributed | a | 4
|
||||||
|
adt_ref | distributed | a | 4
|
||||||
|
adt_table | distributed | a | 4
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%' GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col, adt_ref, adt_table
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'adt_col' OR confrelid::regclass::text = 'adt_col') ORDER BY 1;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col | UNIQUE (a)
|
||||||
|
adt_ref | FOREIGN KEY (a) REFERENCES adt_col(a)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
SELECT alter_distributed_table('adt_table', shard_count:=6, cascade_to_colocated:=true);
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SET client_min_messages TO DEFAULT;
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%';
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col | distributed | a | 6
|
||||||
|
adt_ref | distributed | a | 6
|
||||||
|
adt_table | distributed | a | 6
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%' GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col, adt_ref, adt_table
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'adt_col' OR confrelid::regclass::text = 'adt_col') ORDER BY 1;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col | UNIQUE (a)
|
||||||
|
adt_ref | FOREIGN KEY (a) REFERENCES adt_col(a)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('adt_table', distribution_column:='b', colocate_with:='none');
|
||||||
|
NOTICE: creating a new table for coordinator_shouldhaveshards.adt_table
|
||||||
|
NOTICE: Moving the data of coordinator_shouldhaveshards.adt_table
|
||||||
|
NOTICE: Dropping the old coordinator_shouldhaveshards.adt_table
|
||||||
|
NOTICE: Renaming the new table to coordinator_shouldhaveshards.adt_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%';
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col | distributed | a | 6
|
||||||
|
adt_ref | distributed | a | 6
|
||||||
|
adt_table | distributed | b | 6
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%' GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col, adt_ref
|
||||||
|
adt_table
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'adt_col' OR confrelid::regclass::text = 'adt_col') ORDER BY 1;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col | UNIQUE (a)
|
||||||
|
adt_ref | FOREIGN KEY (a) REFERENCES adt_col(a)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT * FROM adt_table ORDER BY 1;
|
||||||
|
a | b
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1 | 2
|
||||||
|
3 | 4
|
||||||
|
5 | 6
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT * FROM adt_col ORDER BY 1;
|
||||||
|
a | b
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
3 | 4
|
||||||
|
5 | 6
|
||||||
|
7 | 8
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT * FROM adt_ref ORDER BY 1;
|
||||||
|
a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
3
|
||||||
|
5
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO adt_table SELECT x, x+1 FROM generate_series(1, 1000) x;
|
||||||
|
SELECT alter_distributed_table('adt_table', distribution_column:='a');
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT COUNT(*) FROM adt_table;
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1003
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
END;
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text = 'adt_table';
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_table | distributed | a | 6
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SET client_min_messages TO DEFAULT;
|
||||||
\set VERBOSITY terse
|
\set VERBOSITY terse
|
||||||
DROP TABLE ref_table;
|
DROP TABLE ref_table;
|
||||||
NOTICE: executing the command locally: DROP TABLE IF EXISTS coordinator_shouldhaveshards.ref_table_xxxxx CASCADE
|
NOTICE: executing the command locally: DROP TABLE IF EXISTS coordinator_shouldhaveshards.ref_table_xxxxx CASCADE
|
||||||
|
@ -628,7 +788,7 @@ DROP TABLE ref;
|
||||||
NOTICE: executing the command locally: DROP TABLE IF EXISTS coordinator_shouldhaveshards.ref_xxxxx CASCADE
|
NOTICE: executing the command locally: DROP TABLE IF EXISTS coordinator_shouldhaveshards.ref_xxxxx CASCADE
|
||||||
DROP TABLE test_append_table;
|
DROP TABLE test_append_table;
|
||||||
DROP SCHEMA coordinator_shouldhaveshards CASCADE;
|
DROP SCHEMA coordinator_shouldhaveshards CASCADE;
|
||||||
NOTICE: drop cascades to 4 other objects
|
NOTICE: drop cascades to 13 other objects
|
||||||
SELECT 1 FROM master_set_node_property('localhost', :master_port, 'shouldhaveshards', false);
|
SELECT 1 FROM master_set_node_property('localhost', :master_port, 'shouldhaveshards', false);
|
||||||
?column?
|
?column?
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
|
|
|
@ -17,7 +17,7 @@ step s1-commit:
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
step s2-undistribute: <... completed>
|
step s2-undistribute: <... completed>
|
||||||
error in steps s1-commit s2-undistribute: ERROR: cannot undistribute table
|
error in steps s1-commit s2-undistribute: ERROR: cannot complete operation because no such table exists
|
||||||
|
|
||||||
starting permutation: s1-begin s1-undistribute s2-select s1-commit
|
starting permutation: s1-begin s1-undistribute s2-select s1-commit
|
||||||
step s1-begin:
|
step s1-begin:
|
||||||
|
|
|
@ -463,6 +463,8 @@ SELECT * FROM print_extension_changes();
|
||||||
| access method columnar
|
| access method columnar
|
||||||
| function alter_columnar_table_reset(regclass,boolean,boolean,boolean,boolean)
|
| function alter_columnar_table_reset(regclass,boolean,boolean,boolean,boolean)
|
||||||
| function alter_columnar_table_set(regclass,integer,integer,name,integer)
|
| function alter_columnar_table_set(regclass,integer,integer,name,integer)
|
||||||
|
| function alter_distributed_table(regclass,text,integer,text,boolean)
|
||||||
|
| function alter_table_set_access_method(regclass,text)
|
||||||
| function citus_activate_node(text,integer)
|
| function citus_activate_node(text,integer)
|
||||||
| function citus_add_inactive_node(text,integer,integer,noderole,name)
|
| function citus_add_inactive_node(text,integer,integer,noderole,name)
|
||||||
| function citus_add_node(text,integer,integer,noderole,name)
|
| function citus_add_node(text,integer,integer,noderole,name)
|
||||||
|
@ -493,6 +495,7 @@ SELECT * FROM print_extension_changes();
|
||||||
| function create_citus_local_table(regclass,boolean)
|
| function create_citus_local_table(regclass,boolean)
|
||||||
| function time_partition_range(regclass)
|
| function time_partition_range(regclass)
|
||||||
| function undistribute_table(regclass,boolean)
|
| function undistribute_table(regclass,boolean)
|
||||||
|
| function worker_change_sequence_dependency(regclass,regclass,regclass)
|
||||||
| schema columnar
|
| schema columnar
|
||||||
| sequence columnar.storageid_seq
|
| sequence columnar.storageid_seq
|
||||||
| table columnar.columnar_skipnodes
|
| table columnar.columnar_skipnodes
|
||||||
|
@ -501,7 +504,7 @@ SELECT * FROM print_extension_changes();
|
||||||
| view citus_shards
|
| view citus_shards
|
||||||
| view citus_tables
|
| view citus_tables
|
||||||
| view time_partitions
|
| view time_partitions
|
||||||
(56 rows)
|
(59 rows)
|
||||||
|
|
||||||
DROP TABLE prev_objects, extension_diff;
|
DROP TABLE prev_objects, extension_diff;
|
||||||
-- show running version
|
-- show running version
|
||||||
|
|
|
@ -460,6 +460,8 @@ SELECT * FROM print_extension_changes();
|
||||||
function master_modify_multiple_shards(text) |
|
function master_modify_multiple_shards(text) |
|
||||||
function undistribute_table(regclass) |
|
function undistribute_table(regclass) |
|
||||||
function upgrade_to_reference_table(regclass) |
|
function upgrade_to_reference_table(regclass) |
|
||||||
|
| function alter_distributed_table(regclass,text,integer,text,boolean)
|
||||||
|
| function alter_table_set_access_method(regclass,text)
|
||||||
| function citus_activate_node(text,integer)
|
| function citus_activate_node(text,integer)
|
||||||
| function citus_add_inactive_node(text,integer,integer,noderole,name)
|
| function citus_add_inactive_node(text,integer,integer,noderole,name)
|
||||||
| function citus_add_node(text,integer,integer,noderole,name)
|
| function citus_add_node(text,integer,integer,noderole,name)
|
||||||
|
@ -489,6 +491,7 @@ SELECT * FROM print_extension_changes();
|
||||||
| function create_citus_local_table(regclass,boolean)
|
| function create_citus_local_table(regclass,boolean)
|
||||||
| function time_partition_range(regclass)
|
| function time_partition_range(regclass)
|
||||||
| function undistribute_table(regclass,boolean)
|
| function undistribute_table(regclass,boolean)
|
||||||
|
| function worker_change_sequence_dependency(regclass,regclass,regclass)
|
||||||
| schema columnar
|
| schema columnar
|
||||||
| sequence columnar.storageid_seq
|
| sequence columnar.storageid_seq
|
||||||
| table columnar.columnar_skipnodes
|
| table columnar.columnar_skipnodes
|
||||||
|
@ -497,7 +500,7 @@ SELECT * FROM print_extension_changes();
|
||||||
| view citus_shards
|
| view citus_shards
|
||||||
| view citus_tables
|
| view citus_tables
|
||||||
| view time_partitions
|
| view time_partitions
|
||||||
(52 rows)
|
(55 rows)
|
||||||
|
|
||||||
DROP TABLE prev_objects, extension_diff;
|
DROP TABLE prev_objects, extension_diff;
|
||||||
-- show running version
|
-- show running version
|
||||||
|
|
|
@ -0,0 +1,163 @@
|
||||||
|
CREATE SCHEMA mx_alter_distributed_table;
|
||||||
|
SET search_path TO mx_alter_distributed_table;
|
||||||
|
SET citus.shard_replication_factor TO 1;
|
||||||
|
-- test alter_distributed_table UDF
|
||||||
|
CREATE TABLE adt_table (a INT, b INT);
|
||||||
|
CREATE TABLE adt_col (a INT UNIQUE, b INT);
|
||||||
|
CREATE TABLE adt_ref (a INT REFERENCES adt_col(a));
|
||||||
|
SELECT create_distributed_table('adt_table', 'a', colocate_with:='none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('adt_col', 'a', colocate_with:='adt_table');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('adt_ref', 'a', colocate_with:='adt_table');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
INSERT INTO adt_table VALUES (1, 2), (3, 4), (5, 6);
|
||||||
|
INSERT INTO adt_col VALUES (3, 4), (5, 6), (7, 8);
|
||||||
|
INSERT INTO adt_ref VALUES (3), (5);
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%';
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col | distributed | a | 4
|
||||||
|
adt_ref | distributed | a | 4
|
||||||
|
adt_table | distributed | a | 4
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%' GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col, adt_ref, adt_table
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'adt_col' OR confrelid::regclass::text = 'adt_col') ORDER BY 1;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col | UNIQUE (a)
|
||||||
|
adt_ref | FOREIGN KEY (a) REFERENCES adt_col(a)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
SELECT alter_distributed_table('adt_table', shard_count:=6, cascade_to_colocated:=true);
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SET client_min_messages TO DEFAULT;
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%';
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col | distributed | a | 6
|
||||||
|
adt_ref | distributed | a | 6
|
||||||
|
adt_table | distributed | a | 6
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%' GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col, adt_ref, adt_table
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'adt_col' OR confrelid::regclass::text = 'adt_col') ORDER BY 1;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col | UNIQUE (a)
|
||||||
|
adt_ref | FOREIGN KEY (a) REFERENCES adt_col(a)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('adt_table', distribution_column:='b', colocate_with:='none');
|
||||||
|
NOTICE: creating a new table for mx_alter_distributed_table.adt_table
|
||||||
|
NOTICE: Moving the data of mx_alter_distributed_table.adt_table
|
||||||
|
NOTICE: Dropping the old mx_alter_distributed_table.adt_table
|
||||||
|
NOTICE: Renaming the new table to mx_alter_distributed_table.adt_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%';
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col | distributed | a | 6
|
||||||
|
adt_ref | distributed | a | 6
|
||||||
|
adt_table | distributed | b | 6
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%' GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col, adt_ref
|
||||||
|
adt_table
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'adt_col' OR confrelid::regclass::text = 'adt_col') ORDER BY 1;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col | UNIQUE (a)
|
||||||
|
adt_ref | FOREIGN KEY (a) REFERENCES adt_col(a)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT * FROM adt_table ORDER BY 1;
|
||||||
|
a | b
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1 | 2
|
||||||
|
3 | 4
|
||||||
|
5 | 6
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT * FROM adt_col ORDER BY 1;
|
||||||
|
a | b
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
3 | 4
|
||||||
|
5 | 6
|
||||||
|
7 | 8
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT * FROM adt_ref ORDER BY 1;
|
||||||
|
a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
3
|
||||||
|
5
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO adt_table SELECT x, x+1 FROM generate_series(1, 1000) x;
|
||||||
|
SELECT alter_distributed_table('adt_table', distribution_column:='a');
|
||||||
|
NOTICE: creating a new table for mx_alter_distributed_table.adt_table
|
||||||
|
NOTICE: Moving the data of mx_alter_distributed_table.adt_table
|
||||||
|
NOTICE: Dropping the old mx_alter_distributed_table.adt_table
|
||||||
|
NOTICE: Renaming the new table to mx_alter_distributed_table.adt_table
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT COUNT(*) FROM adt_table;
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1003
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
END;
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text = 'adt_table';
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_table | distributed | a | 6
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
DROP SCHEMA mx_alter_distributed_table CASCADE;
|
|
@ -154,7 +154,7 @@ SELECT * FROM with_ties_table_2 ORDER BY a, b;
|
||||||
TRUNCATE with_ties_table_2;
|
TRUNCATE with_ties_table_2;
|
||||||
-- test INSERT SELECTs into distributed table with a different distribution column
|
-- test INSERT SELECTs into distributed table with a different distribution column
|
||||||
SELECT undistribute_table('with_ties_table_2');
|
SELECT undistribute_table('with_ties_table_2');
|
||||||
NOTICE: creating a new local table for public.with_ties_table_2
|
NOTICE: creating a new table for public.with_ties_table_2
|
||||||
NOTICE: Moving the data of public.with_ties_table_2
|
NOTICE: Moving the data of public.with_ties_table_2
|
||||||
NOTICE: Dropping the old public.with_ties_table_2
|
NOTICE: Dropping the old public.with_ties_table_2
|
||||||
NOTICE: Renaming the new table to public.with_ties_table_2
|
NOTICE: Renaming the new table to public.with_ties_table_2
|
||||||
|
|
|
@ -280,7 +280,7 @@ INSERT INTO upsert_test (part_key, other_col) SELECT part_key, other_col FROM up
|
||||||
COMMIT;
|
COMMIT;
|
||||||
-- to test citus local tables
|
-- to test citus local tables
|
||||||
select undistribute_table('upsert_test');
|
select undistribute_table('upsert_test');
|
||||||
NOTICE: creating a new local table for single_node.upsert_test
|
NOTICE: creating a new table for single_node.upsert_test
|
||||||
NOTICE: Moving the data of single_node.upsert_test
|
NOTICE: Moving the data of single_node.upsert_test
|
||||||
NOTICE: Dropping the old single_node.upsert_test
|
NOTICE: Dropping the old single_node.upsert_test
|
||||||
NOTICE: Renaming the new table to single_node.upsert_test
|
NOTICE: Renaming the new table to single_node.upsert_test
|
||||||
|
@ -1116,7 +1116,7 @@ RESET citus.task_executor_type;
|
||||||
-- make sure undistribute table works fine
|
-- make sure undistribute table works fine
|
||||||
ALTER TABLE test DROP CONSTRAINT foreign_key;
|
ALTER TABLE test DROP CONSTRAINT foreign_key;
|
||||||
SELECT undistribute_table('test_2');
|
SELECT undistribute_table('test_2');
|
||||||
NOTICE: creating a new local table for single_node.test_2
|
NOTICE: creating a new table for single_node.test_2
|
||||||
NOTICE: Moving the data of single_node.test_2
|
NOTICE: Moving the data of single_node.test_2
|
||||||
NOTICE: Dropping the old single_node.test_2
|
NOTICE: Dropping the old single_node.test_2
|
||||||
NOTICE: Renaming the new table to single_node.test_2
|
NOTICE: Renaming the new table to single_node.test_2
|
||||||
|
@ -1166,28 +1166,27 @@ ALTER TABLE distributed_table_1 ADD CONSTRAINT fkey_3 FOREIGN KEY (col_1) REFERE
|
||||||
ALTER TABLE citus_local_table_1 ADD CONSTRAINT fkey_4 FOREIGN KEY (col_1) REFERENCES reference_table_1(col_2);
|
ALTER TABLE citus_local_table_1 ADD CONSTRAINT fkey_4 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);
|
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: undistributing the partitions of single_node.partitioned_table_1
|
NOTICE: converting the partitions of single_node.partitioned_table_1
|
||||||
NOTICE: creating a new local table for single_node.partitioned_table_1_100_200
|
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: Moving the data of single_node.partitioned_table_1_100_200
|
||||||
NOTICE: Dropping the old 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: Renaming the new table to single_node.partitioned_table_1_100_200
|
||||||
NOTICE: creating a new local table for single_node.partitioned_table_1_200_300
|
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: Moving the data of single_node.partitioned_table_1_200_300
|
||||||
NOTICE: Dropping the old 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: Renaming the new table to single_node.partitioned_table_1_200_300
|
||||||
NOTICE: creating a new local table for single_node.partitioned_table_1
|
NOTICE: creating a new table for single_node.partitioned_table_1
|
||||||
NOTICE: Moving the data of 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
|
||||||
NOTICE: creating a new local table for single_node.reference_table_1
|
NOTICE: creating a new table for single_node.reference_table_1
|
||||||
NOTICE: Moving the data of single_node.reference_table_1
|
NOTICE: Moving the data of single_node.reference_table_1
|
||||||
NOTICE: Dropping the old single_node.reference_table_1
|
NOTICE: Dropping the old single_node.reference_table_1
|
||||||
NOTICE: Renaming the new table to single_node.reference_table_1
|
NOTICE: Renaming the new table to single_node.reference_table_1
|
||||||
NOTICE: creating a new local table for single_node.distributed_table_1
|
NOTICE: creating a new table for single_node.distributed_table_1
|
||||||
NOTICE: Moving the data of single_node.distributed_table_1
|
NOTICE: Moving the data of single_node.distributed_table_1
|
||||||
NOTICE: Dropping the old single_node.distributed_table_1
|
NOTICE: Dropping the old single_node.distributed_table_1
|
||||||
NOTICE: Renaming the new table to single_node.distributed_table_1
|
NOTICE: Renaming the new table to single_node.distributed_table_1
|
||||||
NOTICE: creating a new local table for single_node.citus_local_table_1
|
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
|
||||||
|
@ -1289,6 +1288,154 @@ SELECT pg_reload_conf();
|
||||||
t
|
t
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- test alter_distributed_table UDF
|
||||||
|
CREATE TABLE adt_table (a INT, b INT);
|
||||||
|
CREATE TABLE adt_col (a INT UNIQUE, b INT);
|
||||||
|
CREATE TABLE adt_ref (a INT REFERENCES adt_col(a));
|
||||||
|
SELECT create_distributed_table('adt_table', 'a', colocate_with:='none');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('adt_col', 'a', colocate_with:='adt_table');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT create_distributed_table('adt_ref', 'a', colocate_with:='adt_table');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
INSERT INTO adt_table VALUES (1, 2), (3, 4), (5, 6);
|
||||||
|
INSERT INTO adt_col VALUES (3, 4), (5, 6), (7, 8);
|
||||||
|
INSERT INTO adt_ref VALUES (3), (5);
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%';
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col | distributed | a | 4
|
||||||
|
adt_ref | distributed | a | 4
|
||||||
|
adt_table | distributed | a | 4
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%' GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col, adt_ref, adt_table
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'adt_col' OR confrelid::regclass::text = 'adt_col') ORDER BY 1;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col | UNIQUE (a)
|
||||||
|
adt_ref | FOREIGN KEY (a) REFERENCES adt_col(a)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('adt_table', shard_count:=6, cascade_to_colocated:=true);
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%';
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col | distributed | a | 6
|
||||||
|
adt_ref | distributed | a | 6
|
||||||
|
adt_table | distributed | a | 6
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%' GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col, adt_ref, adt_table
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'adt_col' OR confrelid::regclass::text = 'adt_col') ORDER BY 1;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col | UNIQUE (a)
|
||||||
|
adt_ref | FOREIGN KEY (a) REFERENCES adt_col(a)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('adt_table', distribution_column:='b', colocate_with:='none');
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%';
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col | distributed | a | 6
|
||||||
|
adt_ref | distributed | a | 6
|
||||||
|
adt_table | distributed | b | 6
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%' GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
Colocation Groups
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col, adt_ref
|
||||||
|
adt_table
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'adt_col' OR confrelid::regclass::text = 'adt_col') ORDER BY 1;
|
||||||
|
Referencing Table | Definition
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_col | UNIQUE (a)
|
||||||
|
adt_ref | FOREIGN KEY (a) REFERENCES adt_col(a)
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT * FROM adt_table ORDER BY 1;
|
||||||
|
a | b
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1 | 2
|
||||||
|
3 | 4
|
||||||
|
5 | 6
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT * FROM adt_col ORDER BY 1;
|
||||||
|
a | b
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
3 | 4
|
||||||
|
5 | 6
|
||||||
|
7 | 8
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT * FROM adt_ref ORDER BY 1;
|
||||||
|
a
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
3
|
||||||
|
5
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO adt_table SELECT x, x+1 FROM generate_series(1, 1000) x;
|
||||||
|
SELECT alter_distributed_table('adt_table', distribution_column:='a');
|
||||||
|
alter_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT COUNT(*) FROM adt_table;
|
||||||
|
count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
1003
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
END;
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text = 'adt_table';
|
||||||
|
Name | Citus Table Type | Distribution Column | Shard Count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
adt_table | distributed | a | 6
|
||||||
|
(1 row)
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
-- sometimes Postgres is a little slow to terminate the backends
|
-- sometimes Postgres is a little slow to terminate the backends
|
||||||
-- even if PGFinish is sent. So, to prevent any flaky tests, sleep
|
-- even if PGFinish is sent. So, to prevent any flaky tests, sleep
|
||||||
|
|
|
@ -34,13 +34,13 @@ SELECT * FROM dist_table ORDER BY 1, 2, 3;
|
||||||
-- we cannot immediately convert in the same statement, because
|
-- we cannot immediately convert in the same statement, because
|
||||||
-- the name->OID conversion happens at parse time.
|
-- the name->OID conversion happens at parse time.
|
||||||
SELECT undistribute_table('dist_table'), create_distributed_table('dist_table', 'a');
|
SELECT undistribute_table('dist_table'), create_distributed_table('dist_table', 'a');
|
||||||
NOTICE: creating a new local table for undistribute_table.dist_table
|
NOTICE: creating a new table for undistribute_table.dist_table
|
||||||
NOTICE: Moving the data of undistribute_table.dist_table
|
NOTICE: Moving the data of undistribute_table.dist_table
|
||||||
NOTICE: Dropping the old undistribute_table.dist_table
|
NOTICE: Dropping the old undistribute_table.dist_table
|
||||||
NOTICE: Renaming the new table to undistribute_table.dist_table
|
NOTICE: Renaming the new table to undistribute_table.dist_table
|
||||||
ERROR: relation with OID XXXX does not exist
|
ERROR: relation with OID XXXX does not exist
|
||||||
SELECT undistribute_table('dist_table');
|
SELECT undistribute_table('dist_table');
|
||||||
NOTICE: creating a new local table for undistribute_table.dist_table
|
NOTICE: creating a new table for undistribute_table.dist_table
|
||||||
NOTICE: Moving the data of undistribute_table.dist_table
|
NOTICE: Moving the data of undistribute_table.dist_table
|
||||||
NOTICE: Dropping the old undistribute_table.dist_table
|
NOTICE: Dropping the old undistribute_table.dist_table
|
||||||
NOTICE: Renaming the new table to undistribute_table.dist_table
|
NOTICE: Renaming the new table to undistribute_table.dist_table
|
||||||
|
@ -87,7 +87,7 @@ SELECT * FROM pg_indexes WHERE tablename = 'dist_table';
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT undistribute_table('dist_table');
|
SELECT undistribute_table('dist_table');
|
||||||
NOTICE: creating a new local table for undistribute_table.dist_table
|
NOTICE: creating a new table for undistribute_table.dist_table
|
||||||
NOTICE: Moving the data of undistribute_table.dist_table
|
NOTICE: Moving the data of undistribute_table.dist_table
|
||||||
NOTICE: Dropping the old undistribute_table.dist_table
|
NOTICE: Dropping the old undistribute_table.dist_table
|
||||||
NOTICE: Renaming the new table to undistribute_table.dist_table
|
NOTICE: Renaming the new table to undistribute_table.dist_table
|
||||||
|
@ -122,10 +122,10 @@ SELECT create_distributed_table('referencing_table', 'id');
|
||||||
|
|
||||||
INSERT INTO referencing_table VALUES (4, 6, 'cba'), (1, 1, 'dcba'), (2, 3, 'aaa');
|
INSERT INTO referencing_table VALUES (4, 6, 'cba'), (1, 1, 'dcba'), (2, 3, 'aaa');
|
||||||
SELECT undistribute_table('referenced_table');
|
SELECT undistribute_table('referenced_table');
|
||||||
ERROR: cannot undistribute table because a foreign key references to it
|
ERROR: cannot complete operation because table referenced_table is referenced by a foreign key
|
||||||
HINT: Use cascade option to undistribute all the relations involved in a foreign key relationship with undistribute_table.referenced_table by executing SELECT undistribute_table($$undistribute_table.referenced_table$$, cascade_via_foreign_keys=>true)
|
HINT: Use cascade option to undistribute all the relations involved in a foreign key relationship with undistribute_table.referenced_table by executing SELECT undistribute_table($$undistribute_table.referenced_table$$, cascade_via_foreign_keys=>true)
|
||||||
SELECT undistribute_table('referencing_table');
|
SELECT undistribute_table('referencing_table');
|
||||||
ERROR: cannot undistribute table because it has a foreign key
|
ERROR: cannot complete operation because table referencing_table has a foreign key
|
||||||
HINT: Use cascade option to undistribute all the relations involved in a foreign key relationship with undistribute_table.referencing_table by executing SELECT undistribute_table($$undistribute_table.referencing_table$$, cascade_via_foreign_keys=>true)
|
HINT: Use cascade option to undistribute all the relations involved in a foreign key relationship with undistribute_table.referencing_table by executing SELECT undistribute_table($$undistribute_table.referencing_table$$, cascade_via_foreign_keys=>true)
|
||||||
DROP TABLE referenced_table, referencing_table;
|
DROP TABLE referenced_table, referencing_table;
|
||||||
-- test distributed foreign tables
|
-- test distributed foreign tables
|
||||||
|
@ -142,7 +142,7 @@ NOTICE: foreign-data wrapper "fake_fdw" does not have an extension defined
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT undistribute_table('foreign_table');
|
SELECT undistribute_table('foreign_table');
|
||||||
ERROR: cannot undistribute table because it is a foreign table
|
ERROR: cannot complete operation because it is a foreign table
|
||||||
DROP FOREIGN TABLE foreign_table;
|
DROP FOREIGN TABLE foreign_table;
|
||||||
-- test partitioned tables
|
-- test partitioned tables
|
||||||
CREATE TABLE partitioned_table (id INT, a INT) PARTITION BY RANGE (id);
|
CREATE TABLE partitioned_table (id INT, a INT) PARTITION BY RANGE (id);
|
||||||
|
@ -198,21 +198,20 @@ SELECT * FROM partitioned_table_6_10 ORDER BY 1, 2;
|
||||||
|
|
||||||
-- undistributing partitions are not supported
|
-- undistributing partitions are not supported
|
||||||
SELECT undistribute_table('partitioned_table_1_5');
|
SELECT undistribute_table('partitioned_table_1_5');
|
||||||
ERROR: cannot undistribute table because it is a partition
|
ERROR: cannot complete operation because table is a partition
|
||||||
HINT: undistribute the partitioned table "partitioned_table" instead
|
HINT: the parent table is "partitioned_table"
|
||||||
-- we can undistribute partitioned parent tables
|
-- we can undistribute partitioned parent tables
|
||||||
SELECT undistribute_table('partitioned_table');
|
SELECT undistribute_table('partitioned_table');
|
||||||
NOTICE: undistributing the partitions of undistribute_table.partitioned_table
|
NOTICE: converting the partitions of undistribute_table.partitioned_table
|
||||||
NOTICE: creating a new local table for undistribute_table.partitioned_table_1_5
|
NOTICE: creating a new table for undistribute_table.partitioned_table_1_5
|
||||||
NOTICE: Moving the data of undistribute_table.partitioned_table_1_5
|
NOTICE: Moving the data of undistribute_table.partitioned_table_1_5
|
||||||
NOTICE: Dropping the old undistribute_table.partitioned_table_1_5
|
NOTICE: Dropping the old undistribute_table.partitioned_table_1_5
|
||||||
NOTICE: Renaming the new table to undistribute_table.partitioned_table_1_5
|
NOTICE: Renaming the new table to undistribute_table.partitioned_table_1_5
|
||||||
NOTICE: creating a new local table for undistribute_table.partitioned_table_6_10
|
NOTICE: creating a new table for undistribute_table.partitioned_table_6_10
|
||||||
NOTICE: Moving the data of undistribute_table.partitioned_table_6_10
|
NOTICE: Moving the data of undistribute_table.partitioned_table_6_10
|
||||||
NOTICE: Dropping the old undistribute_table.partitioned_table_6_10
|
NOTICE: Dropping the old undistribute_table.partitioned_table_6_10
|
||||||
NOTICE: Renaming the new table to undistribute_table.partitioned_table_6_10
|
NOTICE: Renaming the new table to undistribute_table.partitioned_table_6_10
|
||||||
NOTICE: creating a new local table for undistribute_table.partitioned_table
|
NOTICE: creating a new table for undistribute_table.partitioned_table
|
||||||
NOTICE: Moving the data of undistribute_table.partitioned_table
|
|
||||||
NOTICE: Dropping the old undistribute_table.partitioned_table
|
NOTICE: Dropping the old undistribute_table.partitioned_table
|
||||||
NOTICE: Renaming the new table to undistribute_table.partitioned_table
|
NOTICE: Renaming the new table to undistribute_table.partitioned_table
|
||||||
undistribute_table
|
undistribute_table
|
||||||
|
@ -283,7 +282,7 @@ SELECT * FROM seq_table ORDER BY a;
|
||||||
(3 rows)
|
(3 rows)
|
||||||
|
|
||||||
SELECT undistribute_table('seq_table');
|
SELECT undistribute_table('seq_table');
|
||||||
NOTICE: creating a new local table for undistribute_table.seq_table
|
NOTICE: creating a new table for undistribute_table.seq_table
|
||||||
NOTICE: Moving the data of undistribute_table.seq_table
|
NOTICE: Moving the data of undistribute_table.seq_table
|
||||||
NOTICE: Dropping the old undistribute_table.seq_table
|
NOTICE: Dropping the old undistribute_table.seq_table
|
||||||
NOTICE: Renaming the new table to undistribute_table.seq_table
|
NOTICE: Renaming the new table to undistribute_table.seq_table
|
||||||
|
@ -348,7 +347,7 @@ SELECT * FROM another_schema.undis_view3 ORDER BY 1, 2;
|
||||||
(3 rows)
|
(3 rows)
|
||||||
|
|
||||||
SELECT undistribute_table('view_table');
|
SELECT undistribute_table('view_table');
|
||||||
NOTICE: creating a new local table for undistribute_table.view_table
|
NOTICE: creating a new table for undistribute_table.view_table
|
||||||
NOTICE: Moving the data of undistribute_table.view_table
|
NOTICE: Moving the data of undistribute_table.view_table
|
||||||
NOTICE: Dropping the old undistribute_table.view_table
|
NOTICE: Dropping the old undistribute_table.view_table
|
||||||
NOTICE: drop cascades to 3 other objects
|
NOTICE: drop cascades to 3 other objects
|
||||||
|
|
|
@ -80,11 +80,11 @@ ALTER TABLE distributed_table_2 ADD CONSTRAINT fkey_11 FOREIGN KEY (col_1) REFER
|
||||||
ALTER TABLE reference_table_1 ADD CONSTRAINT fkey_12 FOREIGN KEY (col_2) REFERENCES reference_table_1(col_1);
|
ALTER TABLE reference_table_1 ADD CONSTRAINT fkey_12 FOREIGN KEY (col_2) REFERENCES reference_table_1(col_1);
|
||||||
-- show that all of below fails as we didn't provide cascade=true
|
-- show that all of below fails as we didn't provide cascade=true
|
||||||
SELECT undistribute_table('distributed_table_1');
|
SELECT undistribute_table('distributed_table_1');
|
||||||
ERROR: cannot undistribute table because it has a foreign key
|
ERROR: cannot complete operation because table distributed_table_1 has a foreign key
|
||||||
SELECT undistribute_table('citus_local_table_1', cascade_via_foreign_keys=>false);
|
SELECT undistribute_table('citus_local_table_1', cascade_via_foreign_keys=>false);
|
||||||
ERROR: cannot undistribute table because it has a foreign key
|
ERROR: cannot complete operation because table citus_local_table_1 has a foreign key
|
||||||
SELECT undistribute_table('reference_table_2');
|
SELECT undistribute_table('reference_table_2');
|
||||||
ERROR: cannot undistribute table because it has a foreign key
|
ERROR: cannot complete operation because table reference_table_2 has a foreign key
|
||||||
-- In each of below transation blocks, show that we preserve foreign keys.
|
-- In each of below transation blocks, show that we preserve foreign keys.
|
||||||
-- Also show that we don't have any citus tables in current schema after
|
-- Also show that we don't have any citus tables in current schema after
|
||||||
-- undistribute_table(cascade).
|
-- undistribute_table(cascade).
|
||||||
|
@ -304,6 +304,17 @@ SELECT create_reference_table('reference_table_3');
|
||||||
|
|
||||||
ALTER TABLE partitioned_table_1 ADD CONSTRAINT fkey_9 FOREIGN KEY (col_1) REFERENCES reference_table_3(col_2);
|
ALTER TABLE partitioned_table_1 ADD CONSTRAINT fkey_9 FOREIGN KEY (col_1) REFERENCES reference_table_3(col_2);
|
||||||
ALTER TABLE partitioned_table_2 ADD CONSTRAINT fkey_10 FOREIGN KEY (col_1) REFERENCES reference_table_3(col_2);
|
ALTER TABLE partitioned_table_2 ADD CONSTRAINT fkey_10 FOREIGN KEY (col_1) REFERENCES reference_table_3(col_2);
|
||||||
|
-- show that we properly handle cases where undistribute_table is not supported
|
||||||
|
-- error out when table is a partition table
|
||||||
|
SELECT undistribute_table('partitioned_table_2_100_200', cascade_via_foreign_keys=>true);
|
||||||
|
ERROR: cannot complete operation because table is a partition
|
||||||
|
-- error if table does not exist
|
||||||
|
SELECT undistribute_table('non_existent_table', cascade_via_foreign_keys=>true);
|
||||||
|
ERROR: relation "non_existent_table" does not exist at character 27
|
||||||
|
-- error if table is a postgres table
|
||||||
|
CREATE TABLE local_table(a int);
|
||||||
|
SELECT undistribute_table('local_table', cascade_via_foreign_keys=>true);
|
||||||
|
ERROR: cannot undistribute table because the table is not distributed
|
||||||
-- as pg < 12 doesn't support foreign keys between partitioned tables,
|
-- as pg < 12 doesn't support foreign keys between partitioned tables,
|
||||||
-- define below foreign key conditionally instead of adding another
|
-- define below foreign key conditionally instead of adding another
|
||||||
-- test output
|
-- test output
|
||||||
|
@ -376,7 +387,7 @@ BEGIN;
|
||||||
set citus.multi_shard_modify_mode to 'sequential';
|
set citus.multi_shard_modify_mode to 'sequential';
|
||||||
ALTER TABLE partitioned_table_1_100_200 ADD CONSTRAINT non_inherited_fkey FOREIGN KEY(col_1) REFERENCES partitioned_table_2_100_200(col_1);
|
ALTER TABLE partitioned_table_1_100_200 ADD CONSTRAINT non_inherited_fkey FOREIGN KEY(col_1) REFERENCES partitioned_table_2_100_200(col_1);
|
||||||
SELECT undistribute_table('partitioned_table_2', cascade_via_foreign_keys=>true);
|
SELECT undistribute_table('partitioned_table_2', cascade_via_foreign_keys=>true);
|
||||||
ERROR: cannot cascade operation via foreign keys as partition table undistribute_table_cascade.partitioned_table_1_100_200 involved in a foreign key relationship that is not inherited from it's parent table
|
ERROR: cannot cascade operation via foreign keys as partition table undistribute_table_cascade.partitioned_table_2_100_200 involved in a foreign key relationship that is not inherited from it's parent table
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
BEGIN;
|
BEGIN;
|
||||||
set citus.multi_shard_modify_mode to 'sequential';
|
set citus.multi_shard_modify_mode to 'sequential';
|
||||||
|
|
|
@ -20,7 +20,9 @@ ORDER BY 1;
|
||||||
event trigger citus_cascade_to_partition
|
event trigger citus_cascade_to_partition
|
||||||
function alter_columnar_table_reset(regclass,boolean,boolean,boolean,boolean)
|
function alter_columnar_table_reset(regclass,boolean,boolean,boolean,boolean)
|
||||||
function alter_columnar_table_set(regclass,integer,integer,name,integer)
|
function alter_columnar_table_set(regclass,integer,integer,name,integer)
|
||||||
|
function alter_distributed_table(regclass,text,integer,text,boolean)
|
||||||
function alter_role_if_exists(text,text)
|
function alter_role_if_exists(text,text)
|
||||||
|
function alter_table_set_access_method(regclass,text)
|
||||||
function any_value(anyelement)
|
function any_value(anyelement)
|
||||||
function any_value_agg(anyelement,anyelement)
|
function any_value_agg(anyelement,anyelement)
|
||||||
function array_cat_agg(anyarray)
|
function array_cat_agg(anyarray)
|
||||||
|
@ -175,6 +177,7 @@ ORDER BY 1;
|
||||||
function worker_apply_sequence_command(text,regtype)
|
function worker_apply_sequence_command(text,regtype)
|
||||||
function worker_apply_shard_ddl_command(bigint,text)
|
function worker_apply_shard_ddl_command(bigint,text)
|
||||||
function worker_apply_shard_ddl_command(bigint,text,text)
|
function worker_apply_shard_ddl_command(bigint,text,text)
|
||||||
|
function worker_change_sequence_dependency(regclass,regclass,regclass)
|
||||||
function worker_cleanup_job_schema_cache()
|
function worker_cleanup_job_schema_cache()
|
||||||
function worker_create_or_alter_role(text,text,text)
|
function worker_create_or_alter_role(text,text,text)
|
||||||
function worker_create_or_replace_object(text)
|
function worker_create_or_replace_object(text)
|
||||||
|
@ -233,5 +236,5 @@ ORDER BY 1;
|
||||||
view citus_worker_stat_activity
|
view citus_worker_stat_activity
|
||||||
view pg_dist_shard_placement
|
view pg_dist_shard_placement
|
||||||
view time_partitions
|
view time_partitions
|
||||||
(217 rows)
|
(220 rows)
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,9 @@ ORDER BY 1;
|
||||||
description
|
description
|
||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
event trigger citus_cascade_to_partition
|
event trigger citus_cascade_to_partition
|
||||||
|
function alter_distributed_table(regclass,text,integer,text,boolean)
|
||||||
function alter_role_if_exists(text,text)
|
function alter_role_if_exists(text,text)
|
||||||
|
function alter_table_set_access_method(regclass,text)
|
||||||
function any_value(anyelement)
|
function any_value(anyelement)
|
||||||
function any_value_agg(anyelement,anyelement)
|
function any_value_agg(anyelement,anyelement)
|
||||||
function array_cat_agg(anyarray)
|
function array_cat_agg(anyarray)
|
||||||
|
@ -171,6 +173,7 @@ ORDER BY 1;
|
||||||
function worker_apply_sequence_command(text,regtype)
|
function worker_apply_sequence_command(text,regtype)
|
||||||
function worker_apply_shard_ddl_command(bigint,text)
|
function worker_apply_shard_ddl_command(bigint,text)
|
||||||
function worker_apply_shard_ddl_command(bigint,text,text)
|
function worker_apply_shard_ddl_command(bigint,text,text)
|
||||||
|
function worker_change_sequence_dependency(regclass,regclass,regclass)
|
||||||
function worker_cleanup_job_schema_cache()
|
function worker_cleanup_job_schema_cache()
|
||||||
function worker_create_or_alter_role(text,text,text)
|
function worker_create_or_alter_role(text,text,text)
|
||||||
function worker_create_or_replace_object(text)
|
function worker_create_or_replace_object(text)
|
||||||
|
@ -229,5 +232,5 @@ ORDER BY 1;
|
||||||
view citus_worker_stat_activity
|
view citus_worker_stat_activity
|
||||||
view pg_dist_shard_placement
|
view pg_dist_shard_placement
|
||||||
view time_partitions
|
view time_partitions
|
||||||
(213 rows)
|
(216 rows)
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ test: multi_mx_explain
|
||||||
test: multi_mx_reference_table
|
test: multi_mx_reference_table
|
||||||
test: multi_mx_insert_select_repartition
|
test: multi_mx_insert_select_repartition
|
||||||
test: locally_execute_intermediate_results
|
test: locally_execute_intermediate_results
|
||||||
|
test: multi_mx_alter_distributed_table
|
||||||
|
|
||||||
# test that no tests leaked intermediate results. This should always be last
|
# test that no tests leaked intermediate results. This should always be last
|
||||||
test: ensure_no_intermediate_data_leak
|
test: ensure_no_intermediate_data_leak
|
||||||
|
|
|
@ -124,6 +124,8 @@ test: multi_task_assignment_policy multi_cross_shard
|
||||||
test: multi_utility_statements
|
test: multi_utility_statements
|
||||||
test: multi_dropped_column_aliases foreign_key_restriction_enforcement
|
test: multi_dropped_column_aliases foreign_key_restriction_enforcement
|
||||||
test: multi_binary_master_copy_format binary_protocol
|
test: multi_binary_master_copy_format binary_protocol
|
||||||
|
test: alter_table_set_access_method
|
||||||
|
test: alter_distributed_table
|
||||||
|
|
||||||
# ----------
|
# ----------
|
||||||
# Parallel TPC-H tests to check our distributed execution behavior
|
# Parallel TPC-H tests to check our distributed execution behavior
|
||||||
|
|
|
@ -0,0 +1,276 @@
|
||||||
|
SHOW server_version \gset
|
||||||
|
SELECT substring(:'server_version', '\d+')::int > 11 AS server_version_above_eleven;
|
||||||
|
\gset
|
||||||
|
|
||||||
|
CREATE SCHEMA alter_distributed_table;
|
||||||
|
SET search_path TO alter_distributed_table;
|
||||||
|
SET citus.shard_count TO 4;
|
||||||
|
SET citus.shard_replication_factor TO 1;
|
||||||
|
|
||||||
|
CREATE TABLE dist_table (a INT, b INT);
|
||||||
|
SELECT create_distributed_table ('dist_table', 'a', colocate_with := 'none');
|
||||||
|
INSERT INTO dist_table VALUES (1, 1), (2, 2), (3, 3);
|
||||||
|
|
||||||
|
CREATE TABLE colocation_table (a INT, b INT);
|
||||||
|
SELECT create_distributed_table ('colocation_table', 'a', colocate_with := 'none');
|
||||||
|
|
||||||
|
CREATE TABLE colocation_table_2 (a INT, b INT);
|
||||||
|
SELECT create_distributed_table ('colocation_table_2', 'a', colocate_with := 'none');
|
||||||
|
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2');
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2') GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
|
||||||
|
-- test altering distribution column
|
||||||
|
SELECT alter_distributed_table('dist_table', distribution_column := 'b');
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2');
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2') GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
|
||||||
|
-- test altering shard count
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 6);
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2');
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2') GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
|
||||||
|
-- test altering colocation, note that shard count will also change
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'alter_distributed_table.colocation_table');
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2');
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2') GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
|
||||||
|
-- test altering shard count with cascading, note that the colocation will be kept
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 8, cascade_to_colocated := true);
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2');
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2') GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
|
||||||
|
-- test altering shard count without cascading, note that the colocation will be broken
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 10, cascade_to_colocated := false);
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2');
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables
|
||||||
|
WHERE "Name" IN ('dist_table', 'colocation_table', 'colocation_table_2') GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
|
||||||
|
|
||||||
|
-- test partitions
|
||||||
|
CREATE TABLE partitioned_table (id INT, a INT) PARTITION BY RANGE (id);
|
||||||
|
SELECT create_distributed_table('partitioned_table', 'id', colocate_with := 'none');
|
||||||
|
CREATE TABLE partitioned_table_1_5 PARTITION OF partitioned_table FOR VALUES FROM (1) TO (5);
|
||||||
|
CREATE TABLE partitioned_table_6_10 PARTITION OF partitioned_table FOR VALUES FROM (6) TO (10);
|
||||||
|
INSERT INTO partitioned_table VALUES (2, 12), (7, 2);
|
||||||
|
|
||||||
|
SELECT logicalrelid::text FROM pg_dist_partition WHERE logicalrelid::regclass::text LIKE 'partitioned\_table%' ORDER BY 1;
|
||||||
|
SELECT run_command_on_workers($$SELECT COUNT(*) FROM pg_catalog.pg_class WHERE relname LIKE 'partitioned\_table%'$$);
|
||||||
|
SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits WHERE inhparent = 'partitioned_table'::regclass ORDER BY 1;
|
||||||
|
SELECT "Name"::text, "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'partitioned\_table%' ORDER BY 1;
|
||||||
|
SELECT * FROM partitioned_table ORDER BY 1, 2;
|
||||||
|
SELECT * FROM partitioned_table_1_5 ORDER BY 1, 2;
|
||||||
|
SELECT * FROM partitioned_table_6_10 ORDER BY 1, 2;
|
||||||
|
|
||||||
|
-- test altering the parent table
|
||||||
|
SELECT alter_distributed_table('partitioned_table', shard_count := 10, distribution_column := 'a');
|
||||||
|
|
||||||
|
-- test altering the partition
|
||||||
|
SELECT alter_distributed_table('partitioned_table_1_5', shard_count := 10, distribution_column := 'a');
|
||||||
|
|
||||||
|
SELECT logicalrelid::text FROM pg_dist_partition WHERE logicalrelid::regclass::text LIKE 'partitioned\_table%' ORDER BY 1;
|
||||||
|
SELECT run_command_on_workers($$SELECT COUNT(*) FROM pg_catalog.pg_class WHERE relname LIKE 'partitioned\_table%'$$);
|
||||||
|
SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits WHERE inhparent = 'partitioned_table'::regclass ORDER BY 1;
|
||||||
|
SELECT "Name"::text, "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'partitioned\_table%' ORDER BY 1;
|
||||||
|
SELECT * FROM partitioned_table ORDER BY 1, 2;
|
||||||
|
SELECT * FROM partitioned_table_1_5 ORDER BY 1, 2;
|
||||||
|
SELECT * FROM partitioned_table_6_10 ORDER BY 1, 2;
|
||||||
|
|
||||||
|
|
||||||
|
-- test references
|
||||||
|
CREATE TABLE referenced_dist_table (a INT UNIQUE);
|
||||||
|
CREATE TABLE referenced_ref_table (a INT UNIQUE);
|
||||||
|
CREATE TABLE table_with_references (a1 INT UNIQUE REFERENCES referenced_dist_table(a), a2 INT REFERENCES referenced_ref_table(a));
|
||||||
|
CREATE TABLE referencing_dist_table (a INT REFERENCES table_with_references(a1));
|
||||||
|
|
||||||
|
SELECT create_distributed_table('referenced_dist_table', 'a', colocate_with:='none');
|
||||||
|
SELECT create_reference_table('referenced_ref_table');
|
||||||
|
SELECT create_distributed_table('table_with_references', 'a1', colocate_with:='referenced_dist_table');
|
||||||
|
SELECT create_distributed_table('referencing_dist_table', 'a', colocate_with:='referenced_dist_table');
|
||||||
|
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'table_with_references' OR confrelid::regclass::text = 'table_with_references') AND contype = 'f' ORDER BY 1;
|
||||||
|
SELECT alter_distributed_table('table_with_references', shard_count := 12, cascade_to_colocated := true);
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'table_with_references' OR confrelid::regclass::text = 'table_with_references') AND contype = 'f' ORDER BY 1;
|
||||||
|
SELECT alter_distributed_table('table_with_references', shard_count := 10, cascade_to_colocated := false);
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'table_with_references' OR confrelid::regclass::text = 'table_with_references') AND contype = 'f' ORDER BY 1;
|
||||||
|
|
||||||
|
|
||||||
|
-- check when multi shard modify mode is set to sequential
|
||||||
|
SELECT alter_distributed_table('referenced_dist_table', colocate_with:='none');
|
||||||
|
CREATE TABLE ref_to_dist_table(a INT REFERENCES referenced_dist_table(a));
|
||||||
|
CREATE TABLE ref_to_ref_table(a INT REFERENCES referenced_ref_table(a));
|
||||||
|
SELECT create_distributed_table('ref_to_dist_table', 'a', colocate_with:='referenced_dist_table');
|
||||||
|
SELECT create_distributed_table('ref_to_ref_table', 'a', colocate_with:='none');
|
||||||
|
|
||||||
|
-- alter a table referencing a reference table
|
||||||
|
SELECT alter_distributed_table('ref_to_ref_table', shard_count:=6);
|
||||||
|
|
||||||
|
-- let's create a table that is not colocated with a table that references a reference table
|
||||||
|
CREATE TABLE col_with_ref_to_dist (a INT);
|
||||||
|
SELECT create_distributed_table('col_with_ref_to_dist', 'a', colocate_with:='ref_to_dist_table');
|
||||||
|
-- and create a table colocated with a table that references a reference table
|
||||||
|
CREATE TABLE col_with_ref_to_ref (a INT);
|
||||||
|
SELECT alter_distributed_table('ref_to_ref_table', colocate_with:='none');
|
||||||
|
SELECT create_distributed_table('col_with_ref_to_ref', 'a', colocate_with:='ref_to_ref_table');
|
||||||
|
|
||||||
|
-- alter a table colocated with a table referencing a reference table with cascading
|
||||||
|
SELECT alter_distributed_table('col_with_ref_to_ref', shard_count:=8, cascade_to_colocated:=true);
|
||||||
|
-- alter a table colocated with a table referencing a reference table without cascading
|
||||||
|
SELECT alter_distributed_table('col_with_ref_to_ref', shard_count:=10, cascade_to_colocated:=false);
|
||||||
|
-- alter a table not colocated with a table referencing a reference table with cascading
|
||||||
|
SELECT alter_distributed_table('col_with_ref_to_dist', shard_count:=6, cascade_to_colocated:=true);
|
||||||
|
|
||||||
|
|
||||||
|
\if :server_version_above_eleven
|
||||||
|
-- test altering columnar table
|
||||||
|
CREATE TABLE columnar_table (a INT) USING columnar;
|
||||||
|
SELECT create_distributed_table('columnar_table', 'a', colocate_with:='none');
|
||||||
|
SELECT "Name"::text, "Shard Count", "Access Method" FROM public.citus_tables WHERE "Name"::text = 'columnar_table';
|
||||||
|
SELECT alter_distributed_table('columnar_table', shard_count:=6);
|
||||||
|
SELECT "Name"::text, "Shard Count", "Access Method" FROM public.citus_tables WHERE "Name"::text = 'columnar_table';
|
||||||
|
\endif
|
||||||
|
|
||||||
|
|
||||||
|
-- test with metadata sync
|
||||||
|
SET citus.replication_model TO 'streaming';
|
||||||
|
SELECT start_metadata_sync_to_node('localhost', :worker_1_port);
|
||||||
|
|
||||||
|
CREATE TABLE metadata_sync_table (a BIGSERIAL);
|
||||||
|
SELECT create_distributed_table('metadata_sync_table', 'a', colocate_with:='none');
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('metadata_sync_table', shard_count:=6);
|
||||||
|
SELECT alter_distributed_table('metadata_sync_table', shard_count:=8);
|
||||||
|
|
||||||
|
SELECT "Name", "Shard Count" FROM public.citus_tables WHERE "Name"::text = 'metadata_sync_table';
|
||||||
|
|
||||||
|
SET citus.replication_model TO DEFAULT;
|
||||||
|
SELECT stop_metadata_sync_to_node('localhost', :worker_1_port);
|
||||||
|
|
||||||
|
-- test complex cascade operations
|
||||||
|
CREATE TABLE cas_1 (a INT UNIQUE);
|
||||||
|
CREATE TABLE cas_2 (a INT UNIQUE);
|
||||||
|
|
||||||
|
CREATE TABLE cas_3 (a INT UNIQUE);
|
||||||
|
CREATE TABLE cas_4 (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);
|
||||||
|
|
||||||
|
CREATE TABLE cas_col (a INT UNIQUE);
|
||||||
|
|
||||||
|
-- add foreign keys from and to partitions
|
||||||
|
ALTER TABLE cas_par_1 ADD CONSTRAINT fkey_from_par_1 FOREIGN KEY (a) REFERENCES cas_1(a);
|
||||||
|
ALTER TABLE cas_2 ADD CONSTRAINT fkey_to_par_1 FOREIGN KEY (a) REFERENCES cas_par_1(a);
|
||||||
|
|
||||||
|
ALTER TABLE cas_par ADD CONSTRAINT fkey_from_par FOREIGN KEY (a) REFERENCES cas_3(a);
|
||||||
|
ALTER TABLE cas_4 ADD CONSTRAINT fkey_to_par FOREIGN KEY (a) REFERENCES cas_par(a);
|
||||||
|
|
||||||
|
-- distribute all the tables
|
||||||
|
SELECT create_distributed_table('cas_1', 'a', colocate_with:='none');
|
||||||
|
SELECT create_distributed_table('cas_3', 'a', colocate_with:='cas_1');
|
||||||
|
SELECT create_distributed_table('cas_par', 'a', colocate_with:='cas_1');
|
||||||
|
SELECT create_distributed_table('cas_2', 'a', colocate_with:='cas_1');
|
||||||
|
SELECT create_distributed_table('cas_4', 'a', colocate_with:='cas_1');
|
||||||
|
SELECT create_distributed_table('cas_col', 'a', colocate_with:='cas_1');
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'cas_par_1' OR confrelid::regclass::text = 'cas_par_1') ORDER BY 1, 2;
|
||||||
|
SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits WHERE inhparent = 'cas_par'::regclass ORDER BY 1;
|
||||||
|
|
||||||
|
-- alter the cas_col and cascade the change
|
||||||
|
SELECT alter_distributed_table('cas_col', shard_count:=6, cascade_to_colocated:=true);
|
||||||
|
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'cas_par_1' OR confrelid::regclass::text = 'cas_par_1') ORDER BY 1, 2;
|
||||||
|
SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits WHERE inhparent = 'cas_par'::regclass ORDER BY 1;
|
||||||
|
SET client_min_messages TO DEFAULT;
|
||||||
|
|
||||||
|
|
||||||
|
-- test changing dist column and colocating partitioned table without changing shard count
|
||||||
|
CREATE TABLE col_table (a INT);
|
||||||
|
SELECT create_distributed_table('col_table', 'a', colocate_with:='none');
|
||||||
|
CREATE TABLE par_table (a BIGINT, b INT) PARTITION BY RANGE (a);
|
||||||
|
SELECT create_distributed_table('par_table', 'a', colocate_with:='none');
|
||||||
|
CREATE TABLE par_table_1 (a BIGINT, b INT);
|
||||||
|
SELECT create_distributed_table('par_table_1', 'a', colocate_with:='par_table');
|
||||||
|
ALTER TABLE par_table ATTACH PARTITION par_table_1 FOR VALUES FROM (1) TO (5);
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('par_table', distribution_column:='b', colocate_with:='col_table');
|
||||||
|
|
||||||
|
-- test messages
|
||||||
|
-- test nothing to change
|
||||||
|
SELECT alter_distributed_table('dist_table');
|
||||||
|
SELECT alter_distributed_table('dist_table', cascade_to_colocated := false);
|
||||||
|
|
||||||
|
-- no operation UDF calls
|
||||||
|
SELECT alter_distributed_table('dist_table', distribution_column := 'b');
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 10);
|
||||||
|
-- first colocate the tables, then try to re-colococate
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'colocation_table');
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'colocation_table');
|
||||||
|
|
||||||
|
-- test some changes while keeping others same
|
||||||
|
-- shouldn't error but should have notices about no-change parameters
|
||||||
|
SELECT alter_distributed_table('dist_table', distribution_column:='b', shard_count:=4, cascade_to_colocated:=false);
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count:=4, colocate_with:='colocation_table_2');
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with:='colocation_table_2', distribution_column:='a');
|
||||||
|
|
||||||
|
-- test cascading distribution column, should error
|
||||||
|
SELECT alter_distributed_table('dist_table', distribution_column := 'b', cascade_to_colocated := true);
|
||||||
|
SELECT alter_distributed_table('dist_table', distribution_column := 'b', shard_count:=12, colocate_with:='colocation_table_2', cascade_to_colocated := true);
|
||||||
|
|
||||||
|
-- test nothing to cascade
|
||||||
|
SELECT alter_distributed_table('dist_table', cascade_to_colocated := true);
|
||||||
|
|
||||||
|
-- test cascading colocate_with := 'none'
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'none', cascade_to_colocated := true);
|
||||||
|
|
||||||
|
-- test changing shard count of a colocated table without cascade_to_colocated, should error
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 14);
|
||||||
|
|
||||||
|
-- test changing shard count of a non-colocated table without cascade_to_colocated, shouldn't error
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'none');
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 14);
|
||||||
|
|
||||||
|
-- test altering a table into colocating with a table but giving a different shard count
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'colocation_table', shard_count := 16);
|
||||||
|
|
||||||
|
-- test colocation with distribution columns with different data types
|
||||||
|
CREATE TABLE different_type_table (a TEXT);
|
||||||
|
SELECT create_distributed_table('different_type_table', 'a');
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with := 'different_type_table');
|
||||||
|
SELECT alter_distributed_table('dist_table', distribution_column := 'a', colocate_with := 'different_type_table');
|
||||||
|
|
||||||
|
-- test shard_count := 0
|
||||||
|
SELECT alter_distributed_table('dist_table', shard_count := 0);
|
||||||
|
|
||||||
|
-- test colocating with non-distributed table
|
||||||
|
CREATE TABLE reference_table (a INT);
|
||||||
|
SELECT create_reference_table('reference_table');
|
||||||
|
SELECT alter_distributed_table('dist_table', colocate_with:='reference_table');
|
||||||
|
|
||||||
|
-- test append table
|
||||||
|
CREATE TABLE append_table (a INT);
|
||||||
|
SELECT create_distributed_table('append_table', 'a', 'append');
|
||||||
|
SELECT alter_distributed_table('append_table', shard_count:=6);
|
||||||
|
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
DROP SCHEMA alter_distributed_table CASCADE;
|
|
@ -0,0 +1,115 @@
|
||||||
|
SHOW server_version \gset
|
||||||
|
SELECT substring(:'server_version', '\d+')::int > 11 AS server_version_above_eleven
|
||||||
|
\gset
|
||||||
|
\if :server_version_above_eleven
|
||||||
|
\else
|
||||||
|
\q
|
||||||
|
\endif
|
||||||
|
|
||||||
|
|
||||||
|
CREATE SCHEMA alter_table_set_access_method;
|
||||||
|
SET search_path TO alter_table_set_access_method;
|
||||||
|
SET citus.shard_count TO 4;
|
||||||
|
SET citus.shard_replication_factor TO 1;
|
||||||
|
|
||||||
|
SELECT public.run_command_on_coordinator_and_workers($Q$
|
||||||
|
CREATE FUNCTION fake_am_handler(internal)
|
||||||
|
RETURNS table_am_handler
|
||||||
|
AS 'citus'
|
||||||
|
LANGUAGE C;
|
||||||
|
CREATE ACCESS METHOD fake_am TYPE TABLE HANDLER fake_am_handler;
|
||||||
|
$Q$);
|
||||||
|
|
||||||
|
CREATE TABLE dist_table (a INT, b INT);
|
||||||
|
SELECT create_distributed_table ('dist_table', 'a');
|
||||||
|
INSERT INTO dist_table VALUES (1, 1), (2, 2), (3, 3);
|
||||||
|
|
||||||
|
SELECT "Name", "Access Method" FROM public.citus_tables WHERE "Name"::text = 'dist_table' ORDER BY 1;
|
||||||
|
SELECT alter_table_set_access_method('dist_table', 'columnar');
|
||||||
|
SELECT "Name", "Access Method" FROM public.citus_tables WHERE "Name"::text = 'dist_table' ORDER BY 1;
|
||||||
|
|
||||||
|
|
||||||
|
-- test partitions
|
||||||
|
CREATE TABLE partitioned_table (id INT, a INT) PARTITION BY RANGE (id);
|
||||||
|
CREATE TABLE partitioned_table_1_5 PARTITION OF partitioned_table FOR VALUES FROM (1) TO (5);
|
||||||
|
CREATE TABLE partitioned_table_6_10 PARTITION OF partitioned_table FOR VALUES FROM (6) TO (10);
|
||||||
|
SELECT create_distributed_table('partitioned_table', 'id');
|
||||||
|
INSERT INTO partitioned_table VALUES (2, 12), (7, 2);
|
||||||
|
|
||||||
|
SELECT logicalrelid::text FROM pg_dist_partition WHERE logicalrelid::regclass::text LIKE 'partitioned\_table%' ORDER BY 1;
|
||||||
|
SELECT run_command_on_workers($$SELECT COUNT(*) FROM pg_catalog.pg_class WHERE relname LIKE 'partitioned\_table%'$$);
|
||||||
|
SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits WHERE inhparent = 'partitioned_table'::regclass ORDER BY 1;
|
||||||
|
SELECT "Name"::text, "Access Method" FROM public.citus_tables WHERE "Name"::text LIKE 'partitioned\_table%' ORDER BY 1;
|
||||||
|
SELECT * FROM partitioned_table ORDER BY 1, 2;
|
||||||
|
SELECT * FROM partitioned_table_1_5 ORDER BY 1, 2;
|
||||||
|
SELECT * FROM partitioned_table_6_10 ORDER BY 1, 2;
|
||||||
|
|
||||||
|
-- altering partitioned tables' access methods is not supported
|
||||||
|
SELECT alter_table_set_access_method('partitioned_table', 'columnar');
|
||||||
|
-- test altering the partition's access method
|
||||||
|
SELECT alter_table_set_access_method('partitioned_table_1_5', 'columnar');
|
||||||
|
|
||||||
|
SELECT logicalrelid::text FROM pg_dist_partition WHERE logicalrelid::regclass::text LIKE 'partitioned\_table%' ORDER BY 1;
|
||||||
|
SELECT run_command_on_workers($$SELECT COUNT(*) FROM pg_catalog.pg_class WHERE relname LIKE 'partitioned\_table%'$$);
|
||||||
|
SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits WHERE inhparent = 'partitioned_table'::regclass ORDER BY 1;
|
||||||
|
SELECT "Name"::text, "Access Method" FROM public.citus_tables WHERE "Name"::text LIKE 'partitioned\_table%' ORDER BY 1;
|
||||||
|
SELECT * FROM partitioned_table ORDER BY 1, 2;
|
||||||
|
SELECT * FROM partitioned_table_1_5 ORDER BY 1, 2;
|
||||||
|
SELECT * FROM partitioned_table_6_10 ORDER BY 1, 2;
|
||||||
|
|
||||||
|
|
||||||
|
-- test altering a table with index to columnar
|
||||||
|
-- the index will be dropped
|
||||||
|
CREATE TABLE index_table (a INT) USING heap;
|
||||||
|
CREATE INDEX idx1 ON index_table (a);
|
||||||
|
SELECT indexname FROM pg_indexes WHERE schemaname = 'alter_table_set_access_method' AND tablename = 'index_table';
|
||||||
|
SELECT a.amname FROM pg_class c, pg_am a where c.relname = 'index_table' AND c.relnamespace = 'alter_table_set_access_method'::regnamespace AND c.relam = a.oid;
|
||||||
|
SELECT alter_table_set_access_method('index_table', 'columnar');
|
||||||
|
SELECT indexname FROM pg_indexes WHERE schemaname = 'alter_table_set_access_method' AND tablename = 'index_table';
|
||||||
|
SELECT a.amname FROM pg_class c, pg_am a where c.relname = 'index_table' AND c.relnamespace = 'alter_table_set_access_method'::regnamespace AND c.relam = a.oid;
|
||||||
|
|
||||||
|
|
||||||
|
-- test different table types
|
||||||
|
SET client_min_messages to WARNING;
|
||||||
|
SELECT 1 FROM master_add_node('localhost', :master_port, groupId := 0);
|
||||||
|
SET client_min_messages to DEFAULT;
|
||||||
|
CREATE TABLE table_type_dist (a INT);
|
||||||
|
SELECT create_distributed_table('table_type_dist', 'a');
|
||||||
|
CREATE TABLE table_type_ref (a INT);
|
||||||
|
SELECT create_reference_table('table_type_ref');
|
||||||
|
CREATE TABLE table_type_citus_local(a INT);
|
||||||
|
SELECT create_citus_local_table('table_type_citus_local');
|
||||||
|
CREATE TABLE table_type_pg_local (a INT);
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count", "Access Method" FROM public.citus_tables WHERE "Name"::text LIKE 'table\_type%' ORDER BY 1;
|
||||||
|
SELECT c.relname, a.amname FROM pg_class c, pg_am a where c.relname SIMILAR TO 'table_type\D*' AND c.relnamespace = 'alter_table_set_access_method'::regnamespace AND c.relam = a.oid;
|
||||||
|
|
||||||
|
SELECT alter_table_set_access_method('table_type_dist', 'fake_am');
|
||||||
|
SELECT alter_table_set_access_method('table_type_ref', 'fake_am');
|
||||||
|
SELECT alter_table_set_access_method('table_type_pg_local', 'fake_am');
|
||||||
|
SELECT alter_table_set_access_method('table_type_citus_local', 'fake_am');
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count", "Access Method" FROM public.citus_tables WHERE "Name"::text LIKE 'table\_type%' ORDER BY 1;
|
||||||
|
SELECT c.relname, a.amname FROM pg_class c, pg_am a where c.relname SIMILAR TO 'table_type\D*' AND c.relnamespace = 'alter_table_set_access_method'::regnamespace AND c.relam = a.oid;
|
||||||
|
|
||||||
|
-- test when the parent of a partition has foreign key to a reference table
|
||||||
|
CREATE TABLE ref_table (a INT UNIQUE);
|
||||||
|
SELECT create_reference_table('ref_table');
|
||||||
|
INSERT INTO ref_table VALUES (2), (12);
|
||||||
|
ALTER TABLE partitioned_table ADD CONSTRAINT fkey_to_ref FOREIGN KEY (a) REFERENCES ref_table(a);
|
||||||
|
|
||||||
|
SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits WHERE inhparent = 'partitioned_table'::regclass ORDER BY 1;
|
||||||
|
SELECT "Name", "Access Method" FROM public.citus_tables WHERE "Name"::text = 'partitioned_table_6_10';
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'partitioned_table_6_10') ORDER BY 1, 2;
|
||||||
|
|
||||||
|
SELECT alter_table_set_access_method('partitioned_table_6_10', 'columnar');
|
||||||
|
|
||||||
|
SELECT inhrelid::regclass::text FROM pg_catalog.pg_inherits WHERE inhparent = 'partitioned_table'::regclass ORDER BY 1;
|
||||||
|
SELECT "Name", "Access Method" FROM public.citus_tables WHERE "Name"::text = 'partitioned_table_6_10';
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'partitioned_table_6_10') ORDER BY 1, 2;
|
||||||
|
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
DROP SCHEMA alter_table_set_access_method CASCADE;
|
||||||
|
SELECT 1 FROM master_remove_node('localhost', :master_port);
|
|
@ -272,6 +272,57 @@ CREATE INDEX ix_test_index_creation5 ON test_index_creation1
|
||||||
-- test if indexes are created
|
-- test if indexes are created
|
||||||
SELECT 1 AS created WHERE EXISTS(SELECT * FROM pg_indexes WHERE indexname LIKE '%test_index_creation%');
|
SELECT 1 AS created WHERE EXISTS(SELECT * FROM pg_indexes WHERE indexname LIKE '%test_index_creation%');
|
||||||
|
|
||||||
|
|
||||||
|
-- test alter_distributed_table UDF
|
||||||
|
SET citus.shard_count TO 4;
|
||||||
|
CREATE TABLE adt_table (a INT, b INT);
|
||||||
|
CREATE TABLE adt_col (a INT UNIQUE, b INT);
|
||||||
|
CREATE TABLE adt_ref (a INT REFERENCES adt_col(a));
|
||||||
|
|
||||||
|
SELECT create_distributed_table('adt_table', 'a', colocate_with:='none');
|
||||||
|
SELECT create_distributed_table('adt_col', 'a', colocate_with:='adt_table');
|
||||||
|
SELECT create_distributed_table('adt_ref', 'a', colocate_with:='adt_table');
|
||||||
|
|
||||||
|
INSERT INTO adt_table VALUES (1, 2), (3, 4), (5, 6);
|
||||||
|
INSERT INTO adt_col VALUES (3, 4), (5, 6), (7, 8);
|
||||||
|
INSERT INTO adt_ref VALUES (3), (5);
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%';
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%' GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'adt_col' OR confrelid::regclass::text = 'adt_col') ORDER BY 1;
|
||||||
|
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
SELECT alter_distributed_table('adt_table', shard_count:=6, cascade_to_colocated:=true);
|
||||||
|
SET client_min_messages TO DEFAULT;
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%';
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%' GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'adt_col' OR confrelid::regclass::text = 'adt_col') ORDER BY 1;
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('adt_table', distribution_column:='b', colocate_with:='none');
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%';
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%' GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'adt_col' OR confrelid::regclass::text = 'adt_col') ORDER BY 1;
|
||||||
|
|
||||||
|
SELECT * FROM adt_table ORDER BY 1;
|
||||||
|
SELECT * FROM adt_col ORDER BY 1;
|
||||||
|
SELECT * FROM adt_ref ORDER BY 1;
|
||||||
|
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO adt_table SELECT x, x+1 FROM generate_series(1, 1000) x;
|
||||||
|
SELECT alter_distributed_table('adt_table', distribution_column:='a');
|
||||||
|
SELECT COUNT(*) FROM adt_table;
|
||||||
|
END;
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text = 'adt_table';
|
||||||
|
SET client_min_messages TO DEFAULT;
|
||||||
|
|
||||||
|
|
||||||
\set VERBOSITY terse
|
\set VERBOSITY terse
|
||||||
DROP TABLE ref_table;
|
DROP TABLE ref_table;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
CREATE SCHEMA mx_alter_distributed_table;
|
||||||
|
SET search_path TO mx_alter_distributed_table;
|
||||||
|
SET citus.shard_replication_factor TO 1;
|
||||||
|
|
||||||
|
-- test alter_distributed_table UDF
|
||||||
|
CREATE TABLE adt_table (a INT, b INT);
|
||||||
|
CREATE TABLE adt_col (a INT UNIQUE, b INT);
|
||||||
|
CREATE TABLE adt_ref (a INT REFERENCES adt_col(a));
|
||||||
|
|
||||||
|
SELECT create_distributed_table('adt_table', 'a', colocate_with:='none');
|
||||||
|
SELECT create_distributed_table('adt_col', 'a', colocate_with:='adt_table');
|
||||||
|
SELECT create_distributed_table('adt_ref', 'a', colocate_with:='adt_table');
|
||||||
|
|
||||||
|
INSERT INTO adt_table VALUES (1, 2), (3, 4), (5, 6);
|
||||||
|
INSERT INTO adt_col VALUES (3, 4), (5, 6), (7, 8);
|
||||||
|
INSERT INTO adt_ref VALUES (3), (5);
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%';
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%' GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'adt_col' OR confrelid::regclass::text = 'adt_col') ORDER BY 1;
|
||||||
|
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
SELECT alter_distributed_table('adt_table', shard_count:=6, cascade_to_colocated:=true);
|
||||||
|
SET client_min_messages TO DEFAULT;
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%';
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%' GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'adt_col' OR confrelid::regclass::text = 'adt_col') ORDER BY 1;
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('adt_table', distribution_column:='b', colocate_with:='none');
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%';
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%' GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'adt_col' OR confrelid::regclass::text = 'adt_col') ORDER BY 1;
|
||||||
|
|
||||||
|
SELECT * FROM adt_table ORDER BY 1;
|
||||||
|
SELECT * FROM adt_col ORDER BY 1;
|
||||||
|
SELECT * FROM adt_ref ORDER BY 1;
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO adt_table SELECT x, x+1 FROM generate_series(1, 1000) x;
|
||||||
|
SELECT alter_distributed_table('adt_table', distribution_column:='a');
|
||||||
|
SELECT COUNT(*) FROM adt_table;
|
||||||
|
END;
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text = 'adt_table';
|
||||||
|
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
DROP SCHEMA mx_alter_distributed_table CASCADE;
|
|
@ -701,6 +701,50 @@ SELECT pg_sleep(0.1);
|
||||||
ALTER SYSTEM SET citus.recover_2pc_interval TO '-1';
|
ALTER SYSTEM SET citus.recover_2pc_interval TO '-1';
|
||||||
SELECT pg_reload_conf();
|
SELECT pg_reload_conf();
|
||||||
|
|
||||||
|
-- test alter_distributed_table UDF
|
||||||
|
CREATE TABLE adt_table (a INT, b INT);
|
||||||
|
CREATE TABLE adt_col (a INT UNIQUE, b INT);
|
||||||
|
CREATE TABLE adt_ref (a INT REFERENCES adt_col(a));
|
||||||
|
|
||||||
|
SELECT create_distributed_table('adt_table', 'a', colocate_with:='none');
|
||||||
|
SELECT create_distributed_table('adt_col', 'a', colocate_with:='adt_table');
|
||||||
|
SELECT create_distributed_table('adt_ref', 'a', colocate_with:='adt_table');
|
||||||
|
|
||||||
|
INSERT INTO adt_table VALUES (1, 2), (3, 4), (5, 6);
|
||||||
|
INSERT INTO adt_col VALUES (3, 4), (5, 6), (7, 8);
|
||||||
|
INSERT INTO adt_ref VALUES (3), (5);
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%';
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%' GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'adt_col' OR confrelid::regclass::text = 'adt_col') ORDER BY 1;
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('adt_table', shard_count:=6, cascade_to_colocated:=true);
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%';
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%' GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'adt_col' OR confrelid::regclass::text = 'adt_col') ORDER BY 1;
|
||||||
|
|
||||||
|
SELECT alter_distributed_table('adt_table', distribution_column:='b', colocate_with:='none');
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%';
|
||||||
|
SELECT STRING_AGG("Name"::text, ', ' ORDER BY 1) AS "Colocation Groups" FROM public.citus_tables WHERE "Name"::text LIKE 'adt%' GROUP BY "Colocation ID" ORDER BY 1;
|
||||||
|
SELECT conrelid::regclass::text AS "Referencing Table", pg_get_constraintdef(oid, true) AS "Definition" FROM pg_constraint
|
||||||
|
WHERE (conrelid::regclass::text = 'adt_col' OR confrelid::regclass::text = 'adt_col') ORDER BY 1;
|
||||||
|
|
||||||
|
SELECT * FROM adt_table ORDER BY 1;
|
||||||
|
SELECT * FROM adt_col ORDER BY 1;
|
||||||
|
SELECT * FROM adt_ref ORDER BY 1;
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO adt_table SELECT x, x+1 FROM generate_series(1, 1000) x;
|
||||||
|
SELECT alter_distributed_table('adt_table', distribution_column:='a');
|
||||||
|
SELECT COUNT(*) FROM adt_table;
|
||||||
|
END;
|
||||||
|
|
||||||
|
SELECT "Name", "Citus Table Type", "Distribution Column", "Shard Count" FROM public.citus_tables WHERE "Name"::text = 'adt_table';
|
||||||
|
|
||||||
|
|
||||||
\c - - - :master_port
|
\c - - - :master_port
|
||||||
-- sometimes Postgres is a little slow to terminate the backends
|
-- sometimes Postgres is a little slow to terminate the backends
|
||||||
|
|
|
@ -175,6 +175,15 @@ SELECT create_reference_table('reference_table_3');
|
||||||
ALTER TABLE partitioned_table_1 ADD CONSTRAINT fkey_9 FOREIGN KEY (col_1) REFERENCES reference_table_3(col_2);
|
ALTER TABLE partitioned_table_1 ADD CONSTRAINT fkey_9 FOREIGN KEY (col_1) REFERENCES reference_table_3(col_2);
|
||||||
ALTER TABLE partitioned_table_2 ADD CONSTRAINT fkey_10 FOREIGN KEY (col_1) REFERENCES reference_table_3(col_2);
|
ALTER TABLE partitioned_table_2 ADD CONSTRAINT fkey_10 FOREIGN KEY (col_1) REFERENCES reference_table_3(col_2);
|
||||||
|
|
||||||
|
-- show that we properly handle cases where undistribute_table is not supported
|
||||||
|
-- error out when table is a partition table
|
||||||
|
SELECT undistribute_table('partitioned_table_2_100_200', cascade_via_foreign_keys=>true);
|
||||||
|
-- error if table does not exist
|
||||||
|
SELECT undistribute_table('non_existent_table', cascade_via_foreign_keys=>true);
|
||||||
|
-- error if table is a postgres table
|
||||||
|
CREATE TABLE local_table(a int);
|
||||||
|
SELECT undistribute_table('local_table', cascade_via_foreign_keys=>true);
|
||||||
|
|
||||||
-- as pg < 12 doesn't support foreign keys between partitioned tables,
|
-- as pg < 12 doesn't support foreign keys between partitioned tables,
|
||||||
-- define below foreign key conditionally instead of adding another
|
-- define below foreign key conditionally instead of adding another
|
||||||
-- test output
|
-- test output
|
||||||
|
|
Loading…
Reference in New Issue