mirror of https://github.com/citusdata/citus.git
Adds alter_distributed_table and alter_table_set_access_method UDFs
parent
1299895e71
commit
2be14cce2e
|
@ -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
|
||||
* 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
|
||||
* options of the shard to the same options as the relation the shard is based on.
|
||||
*/
|
||||
static char *
|
||||
char *
|
||||
GetShardedTableDDLCommandColumnar(uint64 shardId, void *context)
|
||||
{
|
||||
ColumnarTableDDLContext *tableDDLContext = (ColumnarTableDDLContext *) context;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -27,9 +27,6 @@
|
|||
#include "utils/lsyscache.h"
|
||||
|
||||
|
||||
typedef void (*CascadeOperationFunction)(Oid, bool);
|
||||
|
||||
|
||||
static void EnsureSequentialModeForCitusTableCascadeFunction(List *relationIdList);
|
||||
static bool RelationIdListHasReferenceTable(List *relationIdList);
|
||||
static void LockRelationsWithLockMode(List *relationIdList, LOCKMODE lockMode);
|
||||
|
@ -42,8 +39,6 @@ static char * GetDropFkeyCascadeCommand(Oid relationId, Oid foreignKeyId);
|
|||
static void ExecuteCascadeOperationForRelationIdList(List *relationIdList,
|
||||
CascadeOperationType
|
||||
cascadeOperationType);
|
||||
static CascadeOperationFunction GetCascadeOperationFunction(CascadeOperationType
|
||||
cascadeOperationType);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -342,36 +337,27 @@ ExecuteCascadeOperationForRelationIdList(List *relationIdList,
|
|||
Oid relationId = InvalidOid;
|
||||
foreach_oid(relationId, relationIdList)
|
||||
{
|
||||
CascadeOperationFunction cascadeOperationFunction =
|
||||
GetCascadeOperationFunction(cascadeOperationType);
|
||||
|
||||
/*
|
||||
* Caller already passed the relations that we should operate on,
|
||||
* so we should not cascade here.
|
||||
*/
|
||||
bool cascadeViaForeignKeys = false;
|
||||
cascadeOperationFunction(relationId, cascadeViaForeignKeys);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* GetCascadeOperationFunction returns c api for citus table operation according
|
||||
* to given CascadeOperationType.
|
||||
*/
|
||||
static CascadeOperationFunction
|
||||
GetCascadeOperationFunction(CascadeOperationType cascadeOperationType)
|
||||
{
|
||||
switch (cascadeOperationType)
|
||||
{
|
||||
case UNDISTRIBUTE_TABLE:
|
||||
case CASCADE_FKEY_UNDISTRIBUTE_TABLE:
|
||||
{
|
||||
return UndistributeTable;
|
||||
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:
|
||||
|
@ -384,6 +370,7 @@ GetCascadeOperationFunction(CascadeOperationType cascadeOperationType)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -139,7 +139,7 @@ CreateCitusLocalTable(Oid relationId, bool cascadeViaForeignKeys)
|
|||
if (tableHasExternalForeignKeys && cascadeViaForeignKeys)
|
||||
{
|
||||
CascadeOperationForConnectedRelations(relationId, lockMode,
|
||||
CREATE_CITUS_LOCAL_TABLE);
|
||||
CASCADE_FKEY_CREATE_CITUS_LOCAL_TABLE);
|
||||
|
||||
/*
|
||||
* We converted every foreign key connected table in our subgraph
|
||||
|
|
|
@ -86,10 +86,6 @@
|
|||
*/
|
||||
#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 */
|
||||
int ReplicationModel = REPLICATION_MODEL_COORDINATOR;
|
||||
|
@ -97,11 +93,12 @@ int ReplicationModel = REPLICATION_MODEL_COORDINATOR;
|
|||
|
||||
/* local function forward declarations */
|
||||
static char DecideReplicationModel(char distributionMethod, bool viaDeprecatedAPI);
|
||||
static void CreateHashDistributedTableShards(Oid relationId, Oid colocatedTableId,
|
||||
bool localTableEmpty);
|
||||
static void CreateHashDistributedTableShards(Oid relationId, int shardCount,
|
||||
Oid colocatedTableId, bool localTableEmpty);
|
||||
static uint32 ColocationIdForNewTable(Oid relationId, Var *distributionColumn,
|
||||
char distributionMethod, char replicationModel,
|
||||
char *colocateWithTableName, bool viaDeprecatedAPI);
|
||||
int shardCount, char *colocateWithTableName,
|
||||
bool viaDeprecatedAPI);
|
||||
static void EnsureRelationCanBeDistributed(Oid relationId, Var *distributionColumn,
|
||||
char distributionMethod, uint32 colocationId,
|
||||
char replicationModel, bool viaDeprecatedAPI);
|
||||
|
@ -117,7 +114,6 @@ static void EnsureLocalTableEmptyIfNecessary(Oid relationId, char distributionMe
|
|||
static bool ShouldLocalTableBeEmpty(Oid relationId, char distributionMethod, bool
|
||||
viaDeprecatedAPI);
|
||||
static void EnsureCitusTableCanBeCreated(Oid relationOid);
|
||||
static void EnsureRelationExists(Oid relationId);
|
||||
static bool LocalTableEmpty(Oid tableId);
|
||||
static void CopyLocalDataIntoShards(Oid relationId);
|
||||
static List * TupleDescColumnNameList(TupleDesc tupleDescriptor);
|
||||
|
@ -129,14 +125,11 @@ static void DoCopyFromLocalTableIntoShards(Relation distributedRelation,
|
|||
DestReceiver *copyDest,
|
||||
TupleTableSlot *slot,
|
||||
EState *estate);
|
||||
static List * GetViewCreationCommandsOfTable(Oid relationId);
|
||||
static void ReplaceTable(Oid sourceId, Oid targetId);
|
||||
|
||||
/* exports for SQL callable functions */
|
||||
PG_FUNCTION_INFO_V1(master_create_distributed_table);
|
||||
PG_FUNCTION_INFO_V1(create_distributed_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);
|
||||
|
||||
CreateDistributedTable(relationId, distributionColumn, distributionMethod,
|
||||
colocateWithTableName, viaDeprecatedAPI);
|
||||
ShardCount, colocateWithTableName, viaDeprecatedAPI);
|
||||
|
||||
relation_close(relation, NoLock);
|
||||
|
||||
|
@ -232,7 +225,7 @@ create_distributed_table(PG_FUNCTION_ARGS)
|
|||
char *colocateWithTableName = text_to_cstring(colocateWithTableNameText);
|
||||
|
||||
CreateDistributedTable(relationId, distributionColumn, distributionMethod,
|
||||
colocateWithTableName, viaDeprecatedAPI);
|
||||
ShardCount, colocateWithTableName, viaDeprecatedAPI);
|
||||
|
||||
relation_close(relation, NoLock);
|
||||
|
||||
|
@ -283,7 +276,7 @@ create_reference_table(PG_FUNCTION_ARGS)
|
|||
}
|
||||
|
||||
CreateDistributedTable(relationId, distributionColumn, DISTRIBUTE_BY_NONE,
|
||||
colocateWithTableName, viaDeprecatedAPI);
|
||||
ShardCount, colocateWithTableName, viaDeprecatedAPI);
|
||||
|
||||
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
|
||||
* - we are on the coordinator
|
||||
|
@ -335,7 +310,7 @@ EnsureCitusTableCanBeCreated(Oid relationOid)
|
|||
* EnsureRelationExists does a basic check on whether the OID belongs to
|
||||
* an existing relation.
|
||||
*/
|
||||
static void
|
||||
void
|
||||
EnsureRelationExists(Oid relationId)
|
||||
{
|
||||
if (!RelationExists(relationId))
|
||||
|
@ -361,7 +336,7 @@ EnsureRelationExists(Oid relationId)
|
|||
*/
|
||||
void
|
||||
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
|
||||
|
@ -382,7 +357,7 @@ CreateDistributedTable(Oid relationId, Var *distributionColumn, char distributio
|
|||
*/
|
||||
uint32 colocationId = ColocationIdForNewTable(relationId, distributionColumn,
|
||||
distributionMethod, replicationModel,
|
||||
colocateWithTableName,
|
||||
shardCount, colocateWithTableName,
|
||||
viaDeprecatedAPI);
|
||||
|
||||
EnsureRelationCanBeDistributed(relationId, distributionColumn, distributionMethod,
|
||||
|
@ -421,7 +396,8 @@ CreateDistributedTable(Oid relationId, Var *distributionColumn, char distributio
|
|||
/* create shards for hash distributed and reference tables */
|
||||
if (distributionMethod == DISTRIBUTE_BY_HASH)
|
||||
{
|
||||
CreateHashDistributedTableShards(relationId, colocatedTableId, localTableEmpty);
|
||||
CreateHashDistributedTableShards(relationId, shardCount, colocatedTableId,
|
||||
localTableEmpty);
|
||||
}
|
||||
else if (distributionMethod == DISTRIBUTE_BY_NONE)
|
||||
{
|
||||
|
@ -450,8 +426,8 @@ CreateDistributedTable(Oid relationId, Var *distributionColumn, char distributio
|
|||
foreach_oid(partitionRelationId, partitionList)
|
||||
{
|
||||
CreateDistributedTable(partitionRelationId, distributionColumn,
|
||||
distributionMethod, colocateWithTableName,
|
||||
viaDeprecatedAPI);
|
||||
distributionMethod, shardCount,
|
||||
colocateWithTableName, viaDeprecatedAPI);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -519,8 +495,8 @@ DecideReplicationModel(char distributionMethod, bool viaDeprecatedAPI)
|
|||
* CreateHashDistributedTableShards creates shards of given hash distributed table.
|
||||
*/
|
||||
static void
|
||||
CreateHashDistributedTableShards(Oid relationId, Oid colocatedTableId,
|
||||
bool localTableEmpty)
|
||||
CreateHashDistributedTableShards(Oid relationId, int shardCount,
|
||||
Oid colocatedTableId, bool localTableEmpty)
|
||||
{
|
||||
bool useExclusiveConnection = false;
|
||||
|
||||
|
@ -545,10 +521,9 @@ CreateHashDistributedTableShards(Oid relationId, Oid colocatedTableId,
|
|||
/*
|
||||
* This path is only reached by create_distributed_table for the distributed
|
||||
* tables which will not be part of an existing colocation group. Therefore,
|
||||
* we can directly use ShardCount and ShardReplicationFactor global variables
|
||||
* here.
|
||||
* we can directly use ShardReplicationFactor global variable here.
|
||||
*/
|
||||
CreateShardsWithRoundRobinPolicy(relationId, ShardCount, ShardReplicationFactor,
|
||||
CreateShardsWithRoundRobinPolicy(relationId, shardCount, ShardReplicationFactor,
|
||||
useExclusiveConnection);
|
||||
}
|
||||
}
|
||||
|
@ -568,7 +543,8 @@ CreateHashDistributedTableShards(Oid relationId, Oid colocatedTableId,
|
|||
static uint32
|
||||
ColocationIdForNewTable(Oid relationId, Var *distributionColumn,
|
||||
char distributionMethod, char replicationModel,
|
||||
char *colocateWithTableName, bool viaDeprecatedAPI)
|
||||
int shardCount, char *colocateWithTableName,
|
||||
bool viaDeprecatedAPI)
|
||||
{
|
||||
uint32 colocationId = INVALID_COLOCATION_ID;
|
||||
|
||||
|
@ -611,13 +587,13 @@ ColocationIdForNewTable(Oid relationId, Var *distributionColumn,
|
|||
if (pg_strncasecmp(colocateWithTableName, "default", NAMEDATALEN) == 0)
|
||||
{
|
||||
/* check for default colocation group */
|
||||
colocationId = ColocationId(ShardCount, ShardReplicationFactor,
|
||||
colocationId = ColocationId(shardCount, ShardReplicationFactor,
|
||||
distributionColumnType,
|
||||
distributionColumnCollation);
|
||||
|
||||
if (colocationId == INVALID_COLOCATION_ID)
|
||||
{
|
||||
colocationId = CreateColocationGroup(ShardCount, ShardReplicationFactor,
|
||||
colocationId = CreateColocationGroup(shardCount, ShardReplicationFactor,
|
||||
distributionColumnType,
|
||||
distributionColumnCollation);
|
||||
createdColocationGroup = true;
|
||||
|
@ -1543,295 +1519,3 @@ DistributionColumnUsesGeneratedStoredColumn(TupleDesc relationDesc,
|
|||
|
||||
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
|
||||
* DDL commands to recreate the foreign key constraints returned by
|
||||
|
|
|
@ -225,8 +225,8 @@ PostprocessCreateTableStmtPartitionOf(CreateStmt *createStatement, const
|
|||
bool viaDeprecatedAPI = false;
|
||||
|
||||
CreateDistributedTable(relationId, parentDistributionColumn,
|
||||
parentDistributionMethod, parentRelationName,
|
||||
viaDeprecatedAPI);
|
||||
parentDistributionMethod, ShardCount,
|
||||
parentRelationName, viaDeprecatedAPI);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -299,8 +299,8 @@ PostprocessAlterTableStmtAttachPartition(AlterTableStmt *alterTableStatement,
|
|||
bool viaDeprecatedAPI = false;
|
||||
|
||||
CreateDistributedTable(partitionRelationId, distributionColumn,
|
||||
distributionMethod, parentRelationName,
|
||||
viaDeprecatedAPI);
|
||||
distributionMethod, ShardCount,
|
||||
parentRelationName, viaDeprecatedAPI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -248,7 +248,8 @@ pg_get_sequencedef(Oid sequenceRelationId)
|
|||
* DEFAULT clauses for columns getting their default values from a sequence.
|
||||
*/
|
||||
char *
|
||||
pg_get_tableschemadef_string(Oid tableRelationId, bool includeSequenceDefaults)
|
||||
pg_get_tableschemadef_string(Oid tableRelationId, bool includeSequenceDefaults,
|
||||
char *accessMethod)
|
||||
{
|
||||
char relationKind = 0;
|
||||
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
|
||||
* 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(
|
||||
relation->rd_rel->relam));
|
||||
|
|
|
@ -540,12 +540,12 @@ GetFullTableCreationCommands(Oid relationId, bool includeSequenceDefaults)
|
|||
List *tableDDLEventList = NIL;
|
||||
|
||||
List *preLoadCreationCommandList =
|
||||
GetPreLoadTableCreationCommands(relationId, includeSequenceDefaults);
|
||||
GetPreLoadTableCreationCommands(relationId, includeSequenceDefaults, NULL);
|
||||
|
||||
tableDDLEventList = list_concat(tableDDLEventList, preLoadCreationCommandList);
|
||||
|
||||
List *postLoadCreationCommandList =
|
||||
GetPostLoadTableCreationCommands(relationId);
|
||||
GetPostLoadTableCreationCommands(relationId, true);
|
||||
|
||||
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.
|
||||
*/
|
||||
List *
|
||||
GetPostLoadTableCreationCommands(Oid relationId)
|
||||
GetPostLoadTableCreationCommands(Oid relationId, bool includeIndexes)
|
||||
{
|
||||
List *tableDDLEventList = NIL;
|
||||
|
||||
List *indexAndConstraintCommandList = GetTableIndexAndConstraintCommands(relationId);
|
||||
if (includeIndexes)
|
||||
{
|
||||
List *indexAndConstraintCommandList =
|
||||
GetTableIndexAndConstraintCommands(relationId);
|
||||
tableDDLEventList = list_concat(tableDDLEventList, indexAndConstraintCommandList);
|
||||
}
|
||||
|
||||
List *replicaIdentityEvents = GetTableReplicaIdentityCommand(relationId);
|
||||
tableDDLEventList = list_concat(tableDDLEventList, replicaIdentityEvents);
|
||||
|
@ -616,7 +620,8 @@ GetTableReplicaIdentityCommand(Oid relationId)
|
|||
* to facilitate faster data load.
|
||||
*/
|
||||
List *
|
||||
GetPreLoadTableCreationCommands(Oid relationId, bool includeSequenceDefaults)
|
||||
GetPreLoadTableCreationCommands(Oid relationId, bool includeSequenceDefaults,
|
||||
char *accessMethod)
|
||||
{
|
||||
List *tableDDLEventList = NIL;
|
||||
|
||||
|
@ -640,7 +645,8 @@ GetPreLoadTableCreationCommands(Oid relationId, bool includeSequenceDefaults)
|
|||
|
||||
/* fetch table schema and column option definitions */
|
||||
char *tableSchemaDef = pg_get_tableschemadef_string(relationId,
|
||||
includeSequenceDefaults);
|
||||
includeSequenceDefaults,
|
||||
accessMethod);
|
||||
char *tableColumnOptionsDef = pg_get_tablecolumnoptionsdef_string(relationId);
|
||||
|
||||
tableDDLEventList = lappend(tableDDLEventList, makeTableDDLCommandString(
|
||||
|
@ -654,7 +660,7 @@ GetPreLoadTableCreationCommands(Oid relationId, bool includeSequenceDefaults)
|
|||
#if PG_VERSION_NUM >= 120000
|
||||
|
||||
/* add columnar options for cstore tables */
|
||||
if (IsCStoreTableAmTable(relationId))
|
||||
if (accessMethod == NULL && IsCStoreTableAmTable(relationId))
|
||||
{
|
||||
TableDDLCommand *cstoreOptionsDDL = ColumnarGetTableOptionsDDL(relationId);
|
||||
if (cstoreOptionsDDL != NULL)
|
||||
|
|
|
@ -937,7 +937,7 @@ CopyShardCommandList(ShardInterval *shardInterval, const char *sourceNodeName,
|
|||
copyShardDataCommand->data);
|
||||
}
|
||||
|
||||
List *indexCommandList = GetPostLoadTableCreationCommands(relationId);
|
||||
List *indexCommandList = GetPostLoadTableCreationCommands(relationId, true);
|
||||
indexCommandList = WorkerApplyShardDDLCommandList(indexCommandList, shardId);
|
||||
|
||||
copyShardToNodeCommandsList = list_concat(copyShardToNodeCommandsList,
|
||||
|
@ -1143,7 +1143,8 @@ RecreateTableDDLCommandList(Oid relationId)
|
|||
|
||||
List *dropCommandList = list_make1(makeTableDDLCommandString(dropCommand->data));
|
||||
List *createCommandList = GetPreLoadTableCreationCommands(relationId,
|
||||
includeSequenceDefaults);
|
||||
includeSequenceDefaults,
|
||||
NULL);
|
||||
List *recreateCommandList = list_concat(dropCommandList, createCommandList);
|
||||
|
||||
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_tables/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/create_citus_local_table/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_move_shard_placement/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"
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "../../../columnar/sql/downgrades/columnar--10.0-1--9.5-1.sql"
|
||||
|
||||
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.undistribute_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.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)
|
||||
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;
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
* 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 TableDDLCommand * ColumnarGetTableOptionsDDL(Oid relationId);
|
||||
extern char * GetShardedTableDDLCommandColumnar(uint64 shardId, void *context);
|
||||
#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_sequencedef_string(Oid sequenceRelid);
|
||||
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 char * pg_get_tablecolumnoptionsdef_string(Oid tableRelationId);
|
||||
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
|
||||
relationId);
|
||||
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 HasForeignKeyToReferenceTable(Oid relationOid);
|
||||
extern bool TableReferenced(Oid relationOid);
|
||||
|
@ -399,10 +402,10 @@ typedef enum CascadeOperationType
|
|||
INVALID_OPERATION = 1 << 0,
|
||||
|
||||
/* execute UndistributeTable on each relation */
|
||||
UNDISTRIBUTE_TABLE = 1 << 1,
|
||||
CASCADE_FKEY_UNDISTRIBUTE_TABLE = 1 << 1,
|
||||
|
||||
/* execute CreateCitusLocalTable on each relation */
|
||||
CREATE_CITUS_LOCAL_TABLE = 1 << 2,
|
||||
CASCADE_FKEY_CREATE_CITUS_LOCAL_TABLE = 1 << 2,
|
||||
} CascadeOperationType;
|
||||
|
||||
extern void CascadeOperationForConnectedRelations(Oid relationId, LOCKMODE relLockMode,
|
||||
|
|
|
@ -177,9 +177,10 @@ extern uint64 GetNextShardId(void);
|
|||
extern uint64 GetNextPlacementId(void);
|
||||
extern Oid ResolveRelationId(text *relationName, bool missingOk);
|
||||
extern List * GetFullTableCreationCommands(Oid relationId, bool includeSequenceDefaults);
|
||||
extern List * GetPostLoadTableCreationCommands(Oid relationId);
|
||||
extern List * GetPostLoadTableCreationCommands(Oid relationId, bool includeIndexes);
|
||||
extern List * GetPreLoadTableCreationCommands(Oid relationId,
|
||||
bool includeSequenceDefaults);
|
||||
bool includeSequenceDefaults,
|
||||
char *accessMethod);
|
||||
extern List * GetTableIndexAndConstraintCommands(Oid relationId);
|
||||
extern bool IndexImpliedByAConstraint(Form_pg_index indexForm);
|
||||
extern char ShardStorageType(Oid relationId);
|
||||
|
|
|
@ -90,6 +90,74 @@ typedef struct 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 */
|
||||
extern int ReplicationModel;
|
||||
|
||||
|
@ -138,10 +206,10 @@ extern void MarkShardPlacementInactive(ShardPlacement *shardPlacement);
|
|||
extern void UpdateShardPlacementState(uint64 placementId, char shardState);
|
||||
extern void DeleteShardPlacementRow(uint64 placementId);
|
||||
extern void CreateDistributedTable(Oid relationId, Var *distributionColumn,
|
||||
char distributionMethod, char *colocateWithTableName,
|
||||
bool viaDeprecatedAPI);
|
||||
char distributionMethod, int shardCount,
|
||||
char *colocateWithTableName, bool viaDeprecatedAPI);
|
||||
extern void CreateTruncateTrigger(Oid relationId);
|
||||
extern void UndistributeTable(Oid relationId, bool cascadeViaForeignKeys);
|
||||
extern TableConversionReturn * UndistributeTable(TableConversionParameters *params);
|
||||
|
||||
extern void EnsureDependenciesExistOnAllNodes(const ObjectAddress *target);
|
||||
extern List * GetDistributableDependenciesForObject(const ObjectAddress *target);
|
||||
|
@ -160,6 +228,7 @@ extern void EnsureSuperUser(void);
|
|||
extern void ErrorIfTableIsACatalogTable(Relation relation);
|
||||
extern void EnsureTableNotDistributed(Oid relationId);
|
||||
extern void EnsureReplicationSettings(Oid relationId, char replicationModel);
|
||||
extern void EnsureRelationExists(Oid relationId);
|
||||
extern bool RegularTable(Oid relationId);
|
||||
extern char * ConstructQualifiedShardName(ShardInterval *shardInterval);
|
||||
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
|
||||
BEGIN;
|
||||
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: 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
|
||||
|
|
|
@ -618,6 +618,166 @@ SELECT 1 AS created WHERE EXISTS(SELECT * FROM pg_indexes WHERE indexname LIKE '
|
|||
1
|
||||
(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
|
||||
DROP TABLE ref_table;
|
||||
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
|
||||
DROP TABLE test_append_table;
|
||||
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);
|
||||
?column?
|
||||
---------------------------------------------------------------------
|
||||
|
|
|
@ -17,7 +17,7 @@ step s1-commit:
|
|||
COMMIT;
|
||||
|
||||
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
|
||||
step s1-begin:
|
||||
|
|
|
@ -463,6 +463,8 @@ SELECT * FROM print_extension_changes();
|
|||
| access method columnar
|
||||
| function alter_columnar_table_reset(regclass,boolean,boolean,boolean,boolean)
|
||||
| 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_add_inactive_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 time_partition_range(regclass)
|
||||
| function undistribute_table(regclass,boolean)
|
||||
| function worker_change_sequence_dependency(regclass,regclass,regclass)
|
||||
| schema columnar
|
||||
| sequence columnar.storageid_seq
|
||||
| table columnar.columnar_skipnodes
|
||||
|
@ -501,7 +504,7 @@ SELECT * FROM print_extension_changes();
|
|||
| view citus_shards
|
||||
| view citus_tables
|
||||
| view time_partitions
|
||||
(56 rows)
|
||||
(59 rows)
|
||||
|
||||
DROP TABLE prev_objects, extension_diff;
|
||||
-- show running version
|
||||
|
|
|
@ -460,6 +460,8 @@ SELECT * FROM print_extension_changes();
|
|||
function master_modify_multiple_shards(text) |
|
||||
function undistribute_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_add_inactive_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 time_partition_range(regclass)
|
||||
| function undistribute_table(regclass,boolean)
|
||||
| function worker_change_sequence_dependency(regclass,regclass,regclass)
|
||||
| schema columnar
|
||||
| sequence columnar.storageid_seq
|
||||
| table columnar.columnar_skipnodes
|
||||
|
@ -497,7 +500,7 @@ SELECT * FROM print_extension_changes();
|
|||
| view citus_shards
|
||||
| view citus_tables
|
||||
| view time_partitions
|
||||
(52 rows)
|
||||
(55 rows)
|
||||
|
||||
DROP TABLE prev_objects, extension_diff;
|
||||
-- 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;
|
||||
-- test INSERT SELECTs into distributed table with a different distribution column
|
||||
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: Dropping the old 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;
|
||||
-- to test citus local tables
|
||||
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: Dropping the old 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
|
||||
ALTER TABLE test DROP CONSTRAINT foreign_key;
|
||||
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: Dropping the old 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 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);
|
||||
NOTICE: undistributing the partitions of single_node.partitioned_table_1
|
||||
NOTICE: creating a new local table for single_node.partitioned_table_1_100_200
|
||||
NOTICE: converting the partitions of single_node.partitioned_table_1
|
||||
NOTICE: creating a new table for single_node.partitioned_table_1_100_200
|
||||
NOTICE: Moving the data of single_node.partitioned_table_1_100_200
|
||||
NOTICE: Dropping the old single_node.partitioned_table_1_100_200
|
||||
NOTICE: Renaming the new table to single_node.partitioned_table_1_100_200
|
||||
NOTICE: creating a new 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: Dropping the old single_node.partitioned_table_1_200_300
|
||||
NOTICE: Renaming the new table to single_node.partitioned_table_1_200_300
|
||||
NOTICE: creating a new local table for single_node.partitioned_table_1
|
||||
NOTICE: Moving the data of single_node.partitioned_table_1
|
||||
NOTICE: creating a new table for single_node.partitioned_table_1
|
||||
NOTICE: Dropping the old single_node.partitioned_table_1
|
||||
NOTICE: 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: Dropping the old 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: Dropping the old 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: Dropping the old 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
|
||||
(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
|
||||
-- sometimes Postgres is a little slow to terminate the backends
|
||||
-- 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
|
||||
-- the name->OID conversion happens at parse time.
|
||||
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: Dropping the old undistribute_table.dist_table
|
||||
NOTICE: Renaming the new table to undistribute_table.dist_table
|
||||
ERROR: relation with OID XXXX does not exist
|
||||
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: Dropping the old 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)
|
||||
|
||||
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: Dropping the old 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');
|
||||
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)
|
||||
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)
|
||||
DROP TABLE referenced_table, referencing_table;
|
||||
-- test distributed foreign tables
|
||||
|
@ -142,7 +142,7 @@ NOTICE: foreign-data wrapper "fake_fdw" does not have an extension defined
|
|||
(1 row)
|
||||
|
||||
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;
|
||||
-- test partitioned tables
|
||||
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
|
||||
SELECT undistribute_table('partitioned_table_1_5');
|
||||
ERROR: cannot undistribute table because it is a partition
|
||||
HINT: undistribute the partitioned table "partitioned_table" instead
|
||||
ERROR: cannot complete operation because table is a partition
|
||||
HINT: the parent table is "partitioned_table"
|
||||
-- we can undistribute partitioned parent tables
|
||||
SELECT undistribute_table('partitioned_table');
|
||||
NOTICE: undistributing the partitions of undistribute_table.partitioned_table
|
||||
NOTICE: creating a new local table for undistribute_table.partitioned_table_1_5
|
||||
NOTICE: converting the partitions of undistribute_table.partitioned_table
|
||||
NOTICE: creating a new table for 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: 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: Dropping the old 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: Moving the data of undistribute_table.partitioned_table
|
||||
NOTICE: creating a new table for undistribute_table.partitioned_table
|
||||
NOTICE: Dropping the old undistribute_table.partitioned_table
|
||||
NOTICE: Renaming the new table to undistribute_table.partitioned_table
|
||||
undistribute_table
|
||||
|
@ -283,7 +282,7 @@ SELECT * FROM seq_table ORDER BY a;
|
|||
(3 rows)
|
||||
|
||||
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: Dropping the old 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)
|
||||
|
||||
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: Dropping the old undistribute_table.view_table
|
||||
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);
|
||||
-- show that all of below fails as we didn't provide cascade=true
|
||||
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);
|
||||
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');
|
||||
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.
|
||||
-- Also show that we don't have any citus tables in current schema after
|
||||
-- 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_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,
|
||||
-- define below foreign key conditionally instead of adding another
|
||||
-- test output
|
||||
|
@ -376,7 +387,7 @@ BEGIN;
|
|||
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);
|
||||
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;
|
||||
BEGIN;
|
||||
set citus.multi_shard_modify_mode to 'sequential';
|
||||
|
|
|
@ -20,7 +20,9 @@ ORDER BY 1;
|
|||
event trigger citus_cascade_to_partition
|
||||
function alter_columnar_table_reset(regclass,boolean,boolean,boolean,boolean)
|
||||
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_table_set_access_method(regclass,text)
|
||||
function any_value(anyelement)
|
||||
function any_value_agg(anyelement,anyelement)
|
||||
function array_cat_agg(anyarray)
|
||||
|
@ -175,6 +177,7 @@ ORDER BY 1;
|
|||
function worker_apply_sequence_command(text,regtype)
|
||||
function worker_apply_shard_ddl_command(bigint,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_create_or_alter_role(text,text,text)
|
||||
function worker_create_or_replace_object(text)
|
||||
|
@ -233,5 +236,5 @@ ORDER BY 1;
|
|||
view citus_worker_stat_activity
|
||||
view pg_dist_shard_placement
|
||||
view time_partitions
|
||||
(217 rows)
|
||||
(220 rows)
|
||||
|
||||
|
|
|
@ -17,7 +17,9 @@ ORDER BY 1;
|
|||
description
|
||||
---------------------------------------------------------------------
|
||||
event trigger citus_cascade_to_partition
|
||||
function alter_distributed_table(regclass,text,integer,text,boolean)
|
||||
function alter_role_if_exists(text,text)
|
||||
function alter_table_set_access_method(regclass,text)
|
||||
function any_value(anyelement)
|
||||
function any_value_agg(anyelement,anyelement)
|
||||
function array_cat_agg(anyarray)
|
||||
|
@ -171,6 +173,7 @@ ORDER BY 1;
|
|||
function worker_apply_sequence_command(text,regtype)
|
||||
function worker_apply_shard_ddl_command(bigint,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_create_or_alter_role(text,text,text)
|
||||
function worker_create_or_replace_object(text)
|
||||
|
@ -229,5 +232,5 @@ ORDER BY 1;
|
|||
view citus_worker_stat_activity
|
||||
view pg_dist_shard_placement
|
||||
view time_partitions
|
||||
(213 rows)
|
||||
(216 rows)
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ test: multi_mx_explain
|
|||
test: multi_mx_reference_table
|
||||
test: multi_mx_insert_select_repartition
|
||||
test: locally_execute_intermediate_results
|
||||
test: multi_mx_alter_distributed_table
|
||||
|
||||
# test that no tests leaked intermediate results. This should always be last
|
||||
test: ensure_no_intermediate_data_leak
|
||||
|
|
|
@ -124,6 +124,8 @@ test: multi_task_assignment_policy multi_cross_shard
|
|||
test: multi_utility_statements
|
||||
test: multi_dropped_column_aliases foreign_key_restriction_enforcement
|
||||
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
|
||||
|
|
|
@ -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
|
||||
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
|
||||
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';
|
||||
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
|
||||
-- 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_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,
|
||||
-- define below foreign key conditionally instead of adding another
|
||||
-- test output
|
||||
|
|
Loading…
Reference in New Issue