Merge pull request #5397 from citusdata/naisila/fix-partitioned-index

Run fix_partition_shard_index_names after each wrong naming command
pull/5445/head
Önder Kalacı 2021-11-08 11:09:08 +01:00 committed by GitHub
commit 65911ce162
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 966 additions and 398 deletions

View File

@ -1625,6 +1625,18 @@ AlterTableCommandTypeIsTrigger(AlterTableType alterTableType)
}
/*
* ConstrTypeUsesIndex returns true if the given constraint type uses an index
*/
bool
ConstrTypeUsesIndex(ConstrType constrType)
{
return constrType == CONSTR_PRIMARY ||
constrType == CONSTR_UNIQUE ||
constrType == CONSTR_EXCLUSION;
}
/*
* AlterTableDropsForeignKey returns true if the given AlterTableStmt drops
* a foreign key. False otherwise.
@ -2125,6 +2137,73 @@ PostprocessAlterTableStmt(AlterTableStmt *alterTableStatement)
}
/*
* FixAlterTableStmtIndexNames runs after the ALTER TABLE command
* has already run on the coordinator, and also after the distributed DDL
* Jobs have been executed on the workers.
*
* We might have wrong index names generated on indexes of shards of partitions,
* see https://github.com/citusdata/citus/pull/5397 for the details. So we
* perform the relevant checks and index renaming here.
*/
void
FixAlterTableStmtIndexNames(AlterTableStmt *alterTableStatement)
{
LOCKMODE lockmode = AlterTableGetLockLevel(alterTableStatement->cmds);
Oid relationId = AlterTableLookupRelation(alterTableStatement, lockmode);
if (!(OidIsValid(relationId) && IsCitusTable(relationId) &&
PartitionedTable(relationId)))
{
/* we are only interested in partitioned Citus tables */
return;
}
List *commandList = alterTableStatement->cmds;
AlterTableCmd *command = NULL;
foreach_ptr(command, commandList)
{
AlterTableType alterTableType = command->subtype;
/*
* If this a partitioned table, and the constraint type uses an index
* UNIQUE, PRIMARY KEY, EXCLUDE constraint,
* we have wrong index names generated on indexes of shards of
* partitions of this table, so we should fix them
*/
Constraint *constraint = (Constraint *) command->def;
if (alterTableType == AT_AddConstraint &&
ConstrTypeUsesIndex(constraint->contype))
{
bool missingOk = false;
const char *constraintName = constraint->conname;
Oid constraintId =
get_relation_constraint_oid(relationId, constraintName, missingOk);
/* fix only the relevant index */
Oid parentIndexOid = get_constraint_index(constraintId);
FixPartitionShardIndexNames(relationId, parentIndexOid);
}
/*
* If this is an ALTER TABLE .. ATTACH PARTITION command
* we have wrong index names generated on indexes of shards of
* the current partition being attached, so we should fix them
*/
else if (alterTableType == AT_AttachPartition)
{
PartitionCmd *partitionCommand = (PartitionCmd *) command->def;
bool partitionMissingOk = false;
Oid partitionRelationId =
RangeVarGetRelid(partitionCommand->name, lockmode,
partitionMissingOk);
Oid parentIndexOid = InvalidOid; /* fix all the indexes */
FixPartitionShardIndexNames(partitionRelationId, parentIndexOid);
}
}
}
/*
* GetSequenceOid returns the oid of the sequence used as default value
* of the attribute with given attnum of the given table relationId

View File

@ -649,6 +649,17 @@ ProcessUtilityInternal(PlannedStmt *pstmt,
ExecuteDistributedDDLJob(ddlJob);
}
if (IsA(parsetree, AlterTableStmt))
{
/*
* This postprocess needs to be done after the distributed ddl jobs have
* been executed in the workers, hence is separate from PostprocessAlterTableStmt.
* We might have wrong index names generated on indexes of shards of partitions,
* so we perform the relevant checks and index renaming here.
*/
FixAlterTableStmtIndexNames(castNode(AlterTableStmt, parsetree));
}
/*
* For CREATE/DROP/REINDEX CONCURRENTLY we mark the index as valid
* after successfully completing the distributed DDL job.
@ -662,6 +673,27 @@ ProcessUtilityInternal(PlannedStmt *pstmt,
/* no failures during CONCURRENTLY, mark the index as valid */
MarkIndexValid(indexStmt);
}
/*
* We make sure schema name is not null in the PreprocessIndexStmt.
*/
Oid schemaId = get_namespace_oid(indexStmt->relation->schemaname, true);
Oid relationId = get_relname_relid(indexStmt->relation->relname, schemaId);
/*
* If this a partitioned table, and CREATE INDEX was not run with ONLY,
* we have wrong index names generated on indexes of shards of
* partitions of this table, so we should fix them.
*/
if (IsCitusTable(relationId) && PartitionedTable(relationId) &&
indexStmt->relation->inh)
{
/* only fix this specific index */
Oid indexRelationId =
get_relname_relid(indexStmt->idxname, schemaId);
FixPartitionShardIndexNames(relationId, indexRelationId);
}
}
}

View File

@ -53,15 +53,20 @@ static Relation try_relation_open_nolock(Oid relationId);
static List * CreateFixPartitionConstraintsTaskList(Oid relationId);
static List * WorkerFixPartitionConstraintCommandList(Oid relationId, uint64 shardId,
List *checkConstraintList);
static List * CreateFixPartitionShardIndexNamesTaskList(Oid parentRelationId);
static List * CreateFixPartitionShardIndexNamesTaskList(Oid parentRelationId,
Oid partitionRelationId,
Oid parentIndexOid);
static List * WorkerFixPartitionShardIndexNamesCommandList(uint64 parentShardId,
List *indexIdList);
List *indexIdList,
Oid partitionRelationId);
static List * WorkerFixPartitionShardIndexNamesCommandListForParentShardIndex(
char *qualifiedParentShardIndexName, Oid parentIndexId);
char *qualifiedParentShardIndexName, Oid parentIndexId, Oid partitionRelationId);
static List * WorkerFixPartitionShardIndexNamesCommandListForPartitionIndex(Oid
partitionIndexId,
char *
qualifiedParentShardIndexName);
qualifiedParentShardIndexName,
Oid
partitionId);
static List * CheckConstraintNameListForRelation(Oid relationId);
static bool RelationHasConstraint(Oid relationId, char *constraintName);
static char * RenameConstraintCommand(Oid relationId, char *constraintName,
@ -149,7 +154,8 @@ worker_fix_pre_citus10_partitioned_table_constraint_names(PG_FUNCTION_ARGS)
/*
* fix_partition_shard_index_names fixes the index names of shards of partitions of
* partitioned tables on workers.
* partitioned tables on workers. If the input is a partition rather than a partitioned
* table, we only fix the index names of shards of that particular partition.
*
* When running CREATE INDEX on parent_table, we didn't explicitly create the index on
* each partition as well. Postgres created indexes for partitions in the coordinator,
@ -163,6 +169,7 @@ worker_fix_pre_citus10_partitioned_table_constraint_names(PG_FUNCTION_ARGS)
* fix_partition_shard_index_names renames indexes of shards of partition tables to include
* the shardId at the end of the name, regardless of whether index name was long or short
* As a result there will be no index name ending in _idx, rather all will end in _{shardid}
*
* Algorithm is:
* foreach parentShard in shardListOfParentTableId:
* foreach parentIndex on parent:
@ -186,48 +193,17 @@ fix_partition_shard_index_names(PG_FUNCTION_ARGS)
EnsureCoordinator();
Oid relationId = PG_GETARG_OID(0);
Relation relation = try_relation_open(relationId, AccessExclusiveLock);
if (relation == NULL)
{
ereport(NOTICE, (errmsg("relation with OID %u does not exist, skipping",
relationId)));
PG_RETURN_VOID();
}
if (relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
{
relation_close(relation, NoLock);
ereport(ERROR, (errmsg(
"Fixing shard index names is only applicable to partitioned"
" tables, and \"%s\" is not a partitioned table",
RelationGetRelationName(relation))));
}
Oid parentIndexOid = InvalidOid; /* fix all the indexes */
if (!IsCitusTable(relationId))
{
relation_close(relation, NoLock);
ereport(ERROR, (errmsg("fix_partition_shard_index_names can "
"only be called for distributed partitioned tables")));
ereport(ERROR, (errmsg("fix_partition_shard_index_names can only be called "
"for Citus tables")));
}
EnsureTableOwner(relationId);
List *taskList = CreateFixPartitionShardIndexNamesTaskList(relationId);
/* do not do anything if there are no index names to fix */
if (taskList != NIL)
{
bool localExecutionSupported = true;
RowModifyLevel modLevel = ROW_MODIFY_NONE;
ExecutionParams *execParams = CreateBasicExecutionParams(modLevel, taskList,
MaxAdaptiveExecutorPoolSize,
localExecutionSupported);
ExecuteTaskListExtended(execParams);
}
relation_close(relation, NoLock);
FixPartitionShardIndexNames(relationId, parentIndexOid);
PG_RETURN_VOID();
}
@ -308,6 +284,67 @@ worker_fix_partition_shard_index_names(PG_FUNCTION_ARGS)
}
/*
* FixPartitionShardIndexNames gets a relationId. The input relationId should be
* either a parent or partition table. If it is a parent table, then all the
* index names on all the partitions are fixed. If it is a partition, only the
* specific partition is fixed.
*
* The second parentIndexOid parameter is optional. If provided a valid Oid, only
* that specific index name is fixed.
*/
void
FixPartitionShardIndexNames(Oid relationId, Oid parentIndexOid)
{
Relation relation = try_relation_open(relationId, AccessShareLock);
if (relation == NULL)
{
ereport(NOTICE, (errmsg("relation with OID %u does not exist, skipping",
relationId)));
return;
}
/* at this point, we should only be dealing with Citus tables */
Assert(IsCitusTable(relationId));
Oid parentRelationId = InvalidOid;
Oid partitionRelationId = InvalidOid;
if (relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
{
parentRelationId = relationId;
}
else if (PartitionTable(relationId))
{
parentRelationId = PartitionParentOid(relationId);
partitionRelationId = relationId;
}
else
{
relation_close(relation, NoLock);
ereport(ERROR, (errmsg("Fixing shard index names is only applicable to "
"partitioned tables or partitions, "
"and \"%s\" is neither",
RelationGetRelationName(relation))));
}
List *taskList =
CreateFixPartitionShardIndexNamesTaskList(parentRelationId,
partitionRelationId,
parentIndexOid);
/* do not do anything if there are no index names to fix */
if (taskList != NIL)
{
bool localExecutionSupported = true;
ExecuteUtilityTaskList(taskList, localExecutionSupported);
}
relation_close(relation, NoLock);
}
/*
* CreateFixPartitionConstraintsTaskList goes over all the partitions of a distributed
* partitioned table, and creates the list of tasks to execute
@ -436,72 +473,110 @@ WorkerFixPartitionConstraintCommandList(Oid relationId, uint64 shardId,
/*
* CreateFixPartitionShardIndexNamesTaskList goes over all the indexes of a distributed
* partitioned table, and creates the list of tasks to execute
* worker_fix_partition_shard_index_names UDF on worker nodes.
* CreateFixPartitionShardIndexNamesTaskList goes over all the
* indexes of a distributed partitioned table unless parentIndexOid
* is valid. If it is valid, only the given index is processed.
*
* We create parent_table_shard_count tasks,
* each task with parent_indexes_count x parent_partitions_count query strings.
* The function creates the list of tasks to execute
* worker_fix_partition_shard_index_names() on worker nodes.
*
* When the partitionRelationId is a valid Oid, the function only operates on the
* given partition. Otherwise, the function create tasks for all the partitions.
*
* So, for example, if a new partition is created, we only need to fix only for the
* new partition, hence partitionRelationId should be a valid Oid. However, if a new
* index/constraint is created on the parent, we should fix all the partitions, hence
* partitionRelationId should be InvalidOid.
*
* As a reflection of the above, we always create parent_table_shard_count tasks.
* When we need to fix all the partitions, each task with parent_indexes_count
* times partition_count query strings. When we need to fix a single
* partition each task will have parent_indexes_count query strings. When we need
* to fix a single index, parent_indexes_count becomes 1.
*/
static List *
CreateFixPartitionShardIndexNamesTaskList(Oid parentRelationId)
CreateFixPartitionShardIndexNamesTaskList(Oid parentRelationId, Oid partitionRelationId,
Oid parentIndexOid)
{
List *taskList = NIL;
/* enumerate the tasks when putting them to the taskList */
int taskId = 1;
List *partitionList = PartitionList(parentRelationId);
if (partitionList == NIL)
{
/* early exit if the parent relation does not have any partitions */
return NIL;
}
Relation parentRelation = RelationIdGetRelation(parentRelationId);
List *parentIndexIdList = NIL;
List *parentIndexIdList = RelationGetIndexList(parentRelation);
if (parentIndexOid != InvalidOid)
{
parentIndexIdList = list_make1_oid(parentIndexOid);
}
else
{
parentIndexIdList = RelationGetIndexList(parentRelation);
}
/* early exit if the parent relation does not have any indexes */
if (parentIndexIdList == NIL)
{
/* early exit if the parent relation does not have any indexes */
RelationClose(parentRelation);
return NIL;
}
List *partitionList = PartitionList(parentRelationId);
/* early exit if the parent relation does not have any partitions */
if (partitionList == NIL)
/*
* Lock shard metadata, if a specific partition is provided, lock that. Otherwise,
* lock all partitions.
*/
if (OidIsValid(partitionRelationId))
{
RelationClose(parentRelation);
return NIL;
/* if a partition was provided we only need to lock that partition's metadata */
List *partitionShardIntervalList = LoadShardIntervalList(partitionRelationId);
LockShardListMetadata(partitionShardIntervalList, ShareLock);
}
else
{
Oid partitionId = InvalidOid;
foreach_oid(partitionId, partitionList)
{
List *partitionShardIntervalList = LoadShardIntervalList(partitionId);
LockShardListMetadata(partitionShardIntervalList, ShareLock);
}
}
List *parentShardIntervalList = LoadShardIntervalList(parentRelationId);
/* lock metadata before getting placement lists */
LockShardListMetadata(parentShardIntervalList, ShareLock);
Oid partitionId = InvalidOid;
foreach_oid(partitionId, partitionList)
{
List *partitionShardIntervalList = LoadShardIntervalList(partitionId);
LockShardListMetadata(partitionShardIntervalList, ShareLock);
}
int taskId = 1;
List *taskList = NIL;
ShardInterval *parentShardInterval = NULL;
foreach_ptr(parentShardInterval, parentShardIntervalList)
{
uint64 parentShardId = parentShardInterval->shardId;
List *queryStringList = WorkerFixPartitionShardIndexNamesCommandList(
parentShardId, parentIndexIdList);
List *queryStringList =
WorkerFixPartitionShardIndexNamesCommandList(parentShardId,
parentIndexIdList,
partitionRelationId);
Task *task = CitusMakeNode(Task);
task->jobId = INVALID_JOB_ID;
task->taskId = taskId++;
if (queryStringList != NIL)
{
Task *task = CitusMakeNode(Task);
task->jobId = INVALID_JOB_ID;
task->taskId = taskId++;
task->taskType = DDL_TASK;
SetTaskQueryStringList(task, queryStringList);
task->dependentTaskList = NULL;
task->replicationModel = REPLICATION_MODEL_INVALID;
task->anchorShardId = parentShardId;
task->taskPlacementList = ActiveShardPlacementList(parentShardId);
task->taskType = DDL_TASK;
SetTaskQueryStringList(task, queryStringList);
task->dependentTaskList = NULL;
task->replicationModel = REPLICATION_MODEL_INVALID;
task->anchorShardId = parentShardId;
task->taskPlacementList = ActiveShardPlacementList(parentShardId);
taskList = lappend(taskList, task);
taskList = lappend(taskList, task);
}
}
RelationClose(parentRelation);
@ -516,7 +591,8 @@ CreateFixPartitionShardIndexNamesTaskList(Oid parentRelationId)
*/
static List *
WorkerFixPartitionShardIndexNamesCommandList(uint64 parentShardId,
List *parentIndexIdList)
List *parentIndexIdList,
Oid partitionRelationId)
{
List *commandList = NIL;
Oid parentIndexId = InvalidOid;
@ -539,7 +615,7 @@ WorkerFixPartitionShardIndexNamesCommandList(uint64 parentShardId,
char *qualifiedParentShardIndexName = quote_qualified_identifier(schemaName,
parentShardIndexName);
List *commands = WorkerFixPartitionShardIndexNamesCommandListForParentShardIndex(
qualifiedParentShardIndexName, parentIndexId);
qualifiedParentShardIndexName, parentIndexId, partitionRelationId);
commandList = list_concat(commandList, commands);
}
@ -548,12 +624,17 @@ WorkerFixPartitionShardIndexNamesCommandList(uint64 parentShardId,
/*
* WorkerFixPartitionShardIndexNamesCommandListForParentShardIndex creates a list of queries that will fix
* all child index names of given index on shard of parent partitioned table.
* WorkerFixPartitionShardIndexNamesCommandListForParentShardIndex creates a list
* of queries that will fix the child index names of given index on shard
* of parent partitioned table.
*
* In case a partition was provided as argument (partitionRelationId isn't InvalidOid)
* the list of queries will include only the child indexes whose relation is the
* given partition. Otherwise, all the partitions are included.
*/
static List *
WorkerFixPartitionShardIndexNamesCommandListForParentShardIndex(
char *qualifiedParentShardIndexName, Oid parentIndexId)
char *qualifiedParentShardIndexName, Oid parentIndexId, Oid partitionRelationId)
{
List *commandList = NIL;
@ -561,14 +642,21 @@ WorkerFixPartitionShardIndexNamesCommandListForParentShardIndex(
* Get the list of all partition indexes that are children of current
* index on parent
*/
List *partitionIndexIds = find_inheritance_children(parentIndexId,
ShareRowExclusiveLock);
List *partitionIndexIds =
find_inheritance_children(parentIndexId, ShareRowExclusiveLock);
bool addAllPartitions = (partitionRelationId == InvalidOid);
Oid partitionIndexId = InvalidOid;
foreach_oid(partitionIndexId, partitionIndexIds)
{
List *commands = WorkerFixPartitionShardIndexNamesCommandListForPartitionIndex(
partitionIndexId, qualifiedParentShardIndexName);
commandList = list_concat(commandList, commands);
Oid partitionId = IndexGetRelation(partitionIndexId, false);
if (addAllPartitions || partitionId == partitionRelationId)
{
List *commands =
WorkerFixPartitionShardIndexNamesCommandListForPartitionIndex(
partitionIndexId, qualifiedParentShardIndexName, partitionId);
commandList = list_concat(commandList, commands);
}
}
return commandList;
}
@ -577,18 +665,18 @@ WorkerFixPartitionShardIndexNamesCommandListForParentShardIndex(
/*
* WorkerFixPartitionShardIndexNamesCommandListForPartitionIndex creates a list of queries that will fix
* all child index names of given index on shard of parent partitioned table, whose table relation is a shard
* of the partition that is the table relation of given partitionIndexId
* of the partition that is the table relation of given partitionIndexId, which is partitionId
*/
static List *
WorkerFixPartitionShardIndexNamesCommandListForPartitionIndex(Oid partitionIndexId,
char *
qualifiedParentShardIndexName)
qualifiedParentShardIndexName,
Oid partitionId)
{
List *commandList = NIL;
/* get info for this partition relation of this index*/
char *partitionIndexName = get_rel_name(partitionIndexId);
Oid partitionId = IndexGetRelation(partitionIndexId, false);
char *partitionName = get_rel_name(partitionId);
char *partitionSchemaName = get_namespace_name(get_rel_namespace(partitionId));
List *partitionShardIntervalList = LoadShardIntervalList(partitionId);

View File

@ -414,6 +414,7 @@ extern Node * SkipForeignKeyValidationIfConstraintIsFkey(AlterTableStmt *alterTa
extern bool IsAlterTableRenameStmt(RenameStmt *renameStmt);
extern void ErrorIfAlterDropsPartitionColumn(AlterTableStmt *alterTableStatement);
extern void PostprocessAlterTableStmt(AlterTableStmt *pStmt);
extern void FixAlterTableStmtIndexNames(AlterTableStmt *pStmt);
extern void ErrorUnsupportedAlterTableAddColumn(Oid relationId, AlterTableCmd *command,
Constraint *constraint);
extern void ErrorIfUnsupportedConstraint(Relation relation, char distributionMethod,
@ -423,6 +424,7 @@ extern ObjectAddress AlterTableSchemaStmtObjectAddress(Node *stmt,
bool missing_ok);
extern List * MakeNameListFromRangeVar(const RangeVar *rel);
extern Oid GetSequenceOid(Oid relationId, AttrNumber attnum);
extern bool ConstrTypeUsesIndex(ConstrType constrType);
/* truncate.c - forward declarations */

View File

@ -29,6 +29,6 @@ extern List * GenerateAttachPartitionCommandRelationIdList(List *relationIds);
extern char * GeneratePartitioningInformation(Oid tableId);
extern void FixPartitionConstraintsOnWorkers(Oid relationId);
extern void FixLocalPartitionConstraints(Oid relationId, int64 shardId);
extern void FixPartitionShardIndexNames(Oid relationId, Oid parentIndexOid);
#endif /* MULTI_PARTITIONING_UTILS_H_ */

View File

@ -2,3 +2,4 @@ test: intermediate_result_pruning_create
test: prepared_statements_create_load ch_benchmarks_create_load
test: dropped_columns_create_load distributed_planning_create_load
test: local_dist_join_load
test: partitioned_indexes_create

View File

@ -457,6 +457,7 @@ ALTER TABLE par_another_citus_local_table ADD CONSTRAINT fkey_self FOREIGN KEY(v
ALTER TABLE par_citus_local_table ADD CONSTRAINT fkey_c_to_c FOREIGN KEY(val) REFERENCES par_another_citus_local_table(val) ON UPDATE CASCADE;
SELECT citus_add_local_table_to_metadata('par_another_citus_local_table', cascade_via_foreign_keys=>true);
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (1507011, 'citus_local_table_triggers', 1507012, 'citus_local_table_triggers', 'ALTER TABLE citus_local_table_triggers.par_another_citus_local_table ATTACH PARTITION citus_local_table_triggers.par_another_citus_local_table_1 FOR VALUES FROM (1) TO (10000);')
NOTICE: executing the command locally: SELECT worker_fix_partition_shard_index_names('citus_local_table_triggers.par_another_citus_local_table_val_key_1507011'::regclass, 'citus_local_table_triggers.par_another_citus_local_table_1_1507012', 'par_another_citus_local_table_1_val_key_1507012')
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (1507013, 'citus_local_table_triggers', 1507014, 'citus_local_table_triggers', 'ALTER TABLE citus_local_table_triggers.par_citus_local_table ATTACH PARTITION citus_local_table_triggers.par_citus_local_table_1 FOR VALUES FROM (1) TO (10000);')
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (1507011, 'citus_local_table_triggers', 1507011, 'citus_local_table_triggers', 'ALTER TABLE citus_local_table_triggers.par_another_citus_local_table ADD CONSTRAINT fkey_self FOREIGN KEY (val) REFERENCES citus_local_table_triggers.par_another_citus_local_table(val)')
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (1507013, 'citus_local_table_triggers', 1507011, 'citus_local_table_triggers', 'ALTER TABLE citus_local_table_triggers.par_citus_local_table ADD CONSTRAINT fkey_c_to_c FOREIGN KEY (val) REFERENCES citus_local_table_triggers.par_another_citus_local_table(val) ON UPDATE CASCADE')

View File

@ -624,8 +624,10 @@ select create_distributed_table('test_index_creation1', 'tenant_id');
CREATE INDEX ix_test_index_creation5 ON test_index_creation1
USING btree(tenant_id, timeperiod)
INCLUDE (field1) WHERE (tenant_id = 100);
NOTICE: executing the command locally: CREATE INDEX ix_test_index_creation5_1503042 ON coordinator_shouldhaveshards.test_index_creation1_1503042 USING btree (tenant_id ,timeperiod ) INCLUDE (field1 )WHERE (tenant_id = 100)
NOTICE: executing the command locally: CREATE INDEX ix_test_index_creation5_1503045 ON coordinator_shouldhaveshards.test_index_creation1_1503045 USING btree (tenant_id ,timeperiod ) INCLUDE (field1 )WHERE (tenant_id = 100)
NOTICE: executing the command locally: CREATE INDEX ix_test_index_creation5_1503042 ON coordinator_shouldhaveshards.test_index_creation1_1503042 USING btree (tenant_id ,timeperiod ) INCLUDE (field1 ) WHERE (tenant_id = 100)
NOTICE: executing the command locally: CREATE INDEX ix_test_index_creation5_1503045 ON coordinator_shouldhaveshards.test_index_creation1_1503045 USING btree (tenant_id ,timeperiod ) INCLUDE (field1 ) WHERE (tenant_id = 100)
NOTICE: executing the command locally: SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503042'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_26_1503048', 'test_index_creation1_p2020_09_2_tenant_id_time_6020e8f8_1503048');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503042'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_26_1503049', 'test_index_creation1_p2020_09_2_tenant_id_time_6020e8f8_1503049');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503042'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_26_1503050', 'test_index_creation1_p2020_09_2_tenant_id_time_6020e8f8_1503050');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503042'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_26_1503051', 'test_index_creation1_p2020_09_2_tenant_id_time_6020e8f8_1503051');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503042'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_26_1503052', 'test_index_creation1_p2020_09_2_tenant_id_time_6020e8f8_1503052');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503042'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_26_1503053', 'test_index_creation1_p2020_09_2_tenant_id_time_6020e8f8_1503053');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503042'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_27_1503054', 'test_index_creation1_p2020_09__tenant_id_timep_624f7e94_1503054');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503042'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_27_1503055', 'test_index_creation1_p2020_09__tenant_id_timep_624f7e94_1503055');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503042'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_27_1503056', 'test_index_creation1_p2020_09__tenant_id_timep_624f7e94_1503056');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503042'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_27_1503057', 'test_index_creation1_p2020_09__tenant_id_timep_624f7e94_1503057');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503042'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_27_1503058', 'test_index_creation1_p2020_09__tenant_id_timep_624f7e94_1503058');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503042'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_27_1503059', 'test_index_creation1_p2020_09__tenant_id_timep_624f7e94_1503059')
NOTICE: executing the command locally: SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503045'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_26_1503048', 'test_index_creation1_p2020_09_2_tenant_id_time_6020e8f8_1503048');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503045'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_26_1503049', 'test_index_creation1_p2020_09_2_tenant_id_time_6020e8f8_1503049');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503045'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_26_1503050', 'test_index_creation1_p2020_09_2_tenant_id_time_6020e8f8_1503050');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503045'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_26_1503051', 'test_index_creation1_p2020_09_2_tenant_id_time_6020e8f8_1503051');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503045'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_26_1503052', 'test_index_creation1_p2020_09_2_tenant_id_time_6020e8f8_1503052');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503045'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_26_1503053', 'test_index_creation1_p2020_09_2_tenant_id_time_6020e8f8_1503053');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503045'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_27_1503054', 'test_index_creation1_p2020_09__tenant_id_timep_624f7e94_1503054');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503045'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_27_1503055', 'test_index_creation1_p2020_09__tenant_id_timep_624f7e94_1503055');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503045'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_27_1503056', 'test_index_creation1_p2020_09__tenant_id_timep_624f7e94_1503056');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503045'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_27_1503057', 'test_index_creation1_p2020_09__tenant_id_timep_624f7e94_1503057');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503045'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_27_1503058', 'test_index_creation1_p2020_09__tenant_id_timep_624f7e94_1503058');SELECT worker_fix_partition_shard_index_names('coordinator_shouldhaveshards.ix_test_index_creation5_1503045'::regclass, 'coordinator_shouldhaveshards.test_index_creation1_p2020_09_27_1503059', 'test_index_creation1_p2020_09__tenant_id_timep_624f7e94_1503059')
-- test if indexes are created
SELECT 1 AS created WHERE EXISTS(SELECT * FROM pg_indexes WHERE indexname LIKE '%test_index_creation%');
created

View File

@ -52,3 +52,177 @@ step s2-commit:
COMMIT;
step s1-drop-table: <... completed>
starting permutation: s2-begin s2-create-index s1-select-from-table s2-commit
create_distributed_table
---------------------------------------------------------------------
(1 row)
step s2-begin:
BEGIN;
step s2-create-index:
CREATE INDEX ON dist_partitioned_table USING btree(a);
step s1-select-from-table:
SELECT * FROM dist_partitioned_table;
a|created_at
---------------------------------------------------------------------
(0 rows)
step s2-commit:
COMMIT;
starting permutation: s2-begin s2-create-index s1-insert-into-table s2-commit
create_distributed_table
---------------------------------------------------------------------
(1 row)
step s2-begin:
BEGIN;
step s2-create-index:
CREATE INDEX ON dist_partitioned_table USING btree(a);
step s1-insert-into-table:
INSERT INTO dist_partitioned_table VALUES (0, '2019-01-01');
<waiting ...>
step s2-commit:
COMMIT;
step s1-insert-into-table: <... completed>
starting permutation: s1-begin s1-select-from-table s2-create-index-concurrently s1-commit
create_distributed_table
---------------------------------------------------------------------
(1 row)
step s1-begin:
BEGIN;
step s1-select-from-table:
SELECT * FROM dist_partitioned_table;
a|created_at
---------------------------------------------------------------------
(0 rows)
step s2-create-index-concurrently:
CREATE INDEX CONCURRENTLY ON dist_partitioned_table USING btree(a);
ERROR: cannot create index on partitioned table "dist_partitioned_table" concurrently
step s1-commit:
COMMIT;
starting permutation: s1-begin s1-insert-into-table s2-create-index-concurrently s1-commit
create_distributed_table
---------------------------------------------------------------------
(1 row)
step s1-begin:
BEGIN;
step s1-insert-into-table:
INSERT INTO dist_partitioned_table VALUES (0, '2019-01-01');
step s2-create-index-concurrently:
CREATE INDEX CONCURRENTLY ON dist_partitioned_table USING btree(a);
ERROR: cannot create index on partitioned table "dist_partitioned_table" concurrently
step s1-commit:
COMMIT;
starting permutation: s1-begin s1-select-from-table s2-create-index s1-commit
create_distributed_table
---------------------------------------------------------------------
(1 row)
step s1-begin:
BEGIN;
step s1-select-from-table:
SELECT * FROM dist_partitioned_table;
a|created_at
---------------------------------------------------------------------
(0 rows)
step s2-create-index:
CREATE INDEX ON dist_partitioned_table USING btree(a);
step s1-commit:
COMMIT;
starting permutation: s1-begin s1-insert-into-table s2-create-index s1-commit
create_distributed_table
---------------------------------------------------------------------
(1 row)
step s1-begin:
BEGIN;
step s1-insert-into-table:
INSERT INTO dist_partitioned_table VALUES (0, '2019-01-01');
step s2-create-index:
CREATE INDEX ON dist_partitioned_table USING btree(a);
<waiting ...>
step s1-commit:
COMMIT;
step s2-create-index: <... completed>
starting permutation: s2-begin s2-create-index-concurrently s1-select-from-table s2-commit
create_distributed_table
---------------------------------------------------------------------
(1 row)
step s2-begin:
BEGIN;
step s2-create-index-concurrently:
CREATE INDEX CONCURRENTLY ON dist_partitioned_table USING btree(a);
ERROR: CREATE INDEX CONCURRENTLY cannot run inside a transaction block
step s1-select-from-table:
SELECT * FROM dist_partitioned_table;
a|created_at
---------------------------------------------------------------------
(0 rows)
step s2-commit:
COMMIT;
starting permutation: s2-begin s2-create-index-concurrently s1-insert-into-table s2-commit
create_distributed_table
---------------------------------------------------------------------
(1 row)
step s2-begin:
BEGIN;
step s2-create-index-concurrently:
CREATE INDEX CONCURRENTLY ON dist_partitioned_table USING btree(a);
ERROR: CREATE INDEX CONCURRENTLY cannot run inside a transaction block
step s1-insert-into-table:
INSERT INTO dist_partitioned_table VALUES (0, '2019-01-01');
step s2-commit:
COMMIT;

View File

@ -33,12 +33,12 @@ SELECT create_distributed_table('not_partitioned', 'id');
(1 row)
SELECT fix_partition_shard_index_names('not_partitioned'::regclass);
ERROR: Fixing shard index names is only applicable to partitioned tables, and "not_partitioned" is not a partitioned table
ERROR: Fixing shard index names is only applicable to partitioned tables or partitions, and "not_partitioned" is neither
-- fix_partition_shard_index_names cannot be called for partitioned
-- and not distributed tables
CREATE TABLE not_distributed(created_at timestamptz) PARTITION BY RANGE (created_at);
SELECT fix_partition_shard_index_names('not_distributed'::regclass);
ERROR: fix_partition_shard_index_names can only be called for distributed partitioned tables
ERROR: fix_partition_shard_index_names can only be called for Citus tables
-- test with proper table
CREATE TABLE dist_partitioned_table (dist_col int, another_col int, partition_col timestamp) PARTITION BY RANGE (partition_col);
SELECT create_distributed_table('dist_partitioned_table', 'dist_col');
@ -53,6 +53,8 @@ CREATE TABLE p PARTITION OF dist_partitioned_table FOR VALUES FROM ('2019-01-01'
-- create an index on parent table
-- we will see that it doesn't matter whether we name the index on parent or not
-- indexes auto-generated on partitions will not use this name
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE INDEX short ON dist_partitioned_table USING btree (another_col, partition_col);
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
tablename | indexname
@ -63,34 +65,7 @@ SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' O
(3 rows)
\c - - - :worker_1_port
-- Note that, the shell table from above partition_table_with_very_long_name
-- and its shard partition_table_with_very_long_name_910008
-- have the same index name: partition_table_with_very_long_na_another_col_partition_col_idx
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
tablename | indexname
---------------------------------------------------------------------
dist_partitioned_table_910004 | short_910004
dist_partitioned_table_910006 | short_910006
p_910012 | p_910012_another_col_partition_col_idx
p_910014 | p_910014_another_col_partition_col_idx
partition_table_with_very_long_name_910008 | partition_table_with_very_long_na_another_col_partition_col_idx
partition_table_with_very_long_name_910010 | partition_table_with_very_long_n_another_col_partition_col_idx1
(6 rows)
\c - - - :master_port
-- this should fail because of the name clash explained above
SELECT start_metadata_sync_to_node('localhost', :worker_1_port);
ERROR: relation "partition_table_with_very_long_na_another_col_partition_col_idx" already exists
CONTEXT: while executing command on localhost:xxxxx
-- let's fix the problematic table
SET search_path TO fix_idx_names, public;
SELECT fix_partition_shard_index_names('dist_partitioned_table'::regclass);
fix_partition_shard_index_names
---------------------------------------------------------------------
(1 row)
\c - - - :worker_1_port
-- the names are generated correctly
-- shard id has been appended to all index names which didn't end in shard id
-- this goes in line with Citus's way of naming indexes of shards: always append shardid to the end
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
@ -105,15 +80,32 @@ SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' O
(6 rows)
\c - - - :master_port
SET search_path TO fix_idx_names, public;
-- this should now work
-- this should work properly
SELECT start_metadata_sync_to_node('localhost', :worker_1_port);
start_metadata_sync_to_node
---------------------------------------------------------------------
(1 row)
-- if we run this command again, the names will not change anymore since shardid is appended to them
\c - - - :worker_1_port
-- we have no clashes
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
tablename | indexname
---------------------------------------------------------------------
dist_partitioned_table | short
dist_partitioned_table_910004 | short_910004
dist_partitioned_table_910006 | short_910006
p | p_another_col_partition_col_idx
p_910012 | p_another_col_partition_col_idx_910012
p_910014 | p_another_col_partition_col_idx_910014
partition_table_with_very_long_name | partition_table_with_very_long_na_another_col_partition_col_idx
partition_table_with_very_long_name_910008 | partition_table_with_very_long_na_another_col_p_dd884a3b_910008
partition_table_with_very_long_name_910010 | partition_table_with_very_long_na_another_col_p_dd884a3b_910010
(9 rows)
\c - - - :master_port
SET search_path TO fix_idx_names, public;
-- if we run this command again, the names will not change since shardid is appended to them
SELECT fix_partition_shard_index_names('dist_partitioned_table'::regclass);
fix_partition_shard_index_names
---------------------------------------------------------------------
@ -242,10 +234,14 @@ DROP INDEX short;
DROP TABLE yet_another_partition_table, another_partition_table_with_very_long_name;
-- this will create constraint1 index on parent
SET citus.max_adaptive_executor_pool_size TO 1;
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the ADD CONSTRAINT command
ALTER TABLE dist_partitioned_table ADD CONSTRAINT constraint1 UNIQUE (dist_col, partition_col);
RESET citus.max_adaptive_executor_pool_size;
CREATE TABLE fk_table (id int, fk_column timestamp, FOREIGN KEY (id, fk_column) REFERENCES dist_partitioned_table (dist_col, partition_col));
-- try creating index to foreign key
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE INDEX ON dist_partitioned_table USING btree (dist_col, partition_col);
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
tablename | indexname
@ -259,34 +255,7 @@ SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' O
(6 rows)
\c - - - :worker_1_port
-- index names don't end in shardid for partitions
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
tablename | indexname
---------------------------------------------------------------------
dist_partitioned_table_910004 | constraint1_910004
dist_partitioned_table_910004 | dist_partitioned_table_dist_col_partition_col_idx_910004
dist_partitioned_table_910006 | constraint1_910006
dist_partitioned_table_910006 | dist_partitioned_table_dist_col_partition_col_idx_910006
p_910012 | p_910012_dist_col_partition_col_idx
p_910012 | p_910012_dist_col_partition_col_key
p_910014 | p_910014_dist_col_partition_col_idx
p_910014 | p_910014_dist_col_partition_col_key
partition_table_with_very_long_name_910008 | partition_table_with_very_long_name__dist_col_partition_col_idx
partition_table_with_very_long_name_910008 | partition_table_with_very_long_name__dist_col_partition_col_key
partition_table_with_very_long_name_910010 | partition_table_with_very_long_name_dist_col_partition_col_idx1
partition_table_with_very_long_name_910010 | partition_table_with_very_long_name_dist_col_partition_col_key1
(12 rows)
\c - - - :master_port
SET search_path TO fix_idx_names, public;
SELECT fix_all_partition_shard_index_names();
fix_all_partition_shard_index_names
---------------------------------------------------------------------
dist_partitioned_table
(1 row)
\c - - - :worker_1_port
-- now index names end in shardid
-- index names end in shardid for partitions
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
tablename | indexname
---------------------------------------------------------------------
@ -317,6 +286,8 @@ CREATE INDEX short_parent ON ONLY dist_partitioned_table USING hash (dist_col);
-- only another_partition will have the index on dist_col inherited from short_parent
-- hence short_parent will still be invalid
CREATE TABLE another_partition (dist_col int, another_col int, partition_col timestamp);
-- SELECT fix_partition_shard_index_names('another_partition') will be executed
-- automatically at the end of the ATTACH PARTITION command
ALTER TABLE dist_partitioned_table ATTACH PARTITION another_partition FOR VALUES FROM ('2017-01-01') TO ('2018-01-01');
SELECT c.relname AS indexname
FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n, pg_catalog.pg_index i
@ -337,31 +308,7 @@ SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' O
(3 rows)
\c - - - :worker_1_port
-- index names are already correct except for inherited index for another_partition
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
tablename | indexname
---------------------------------------------------------------------
another_partition_361176 | another_partition_361176_dist_col_idx
another_partition_361178 | another_partition_361178_dist_col_idx
dist_partitioned_table_910004 | short_parent_910004
dist_partitioned_table_910006 | short_parent_910006
p_910012 | short_child_910012
p_910014 | short_child_910014
(6 rows)
\c - - - :master_port
SET search_path TO fix_idx_names, public;
-- this will fix inherited index for another_partition
SELECT fix_partition_shard_index_names('dist_partitioned_table'::regclass);
fix_partition_shard_index_names
---------------------------------------------------------------------
(1 row)
-- this will error out becuase p is not partitioned, it is rather a partition
SELECT fix_partition_shard_index_names('p'::regclass);
ERROR: Fixing shard index names is only applicable to partitioned tables, and "p" is not a partitioned table
\c - - - :worker_1_port
-- index names are already correct, including inherited index for another_partition
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
tablename | indexname
---------------------------------------------------------------------
@ -378,9 +325,13 @@ SET search_path TO fix_idx_names, public;
DROP INDEX short_parent;
DROP INDEX short_child;
DROP TABLE another_partition;
-- expression indexes have the same problem with naming
-- try with expression indexes
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE INDEX expression_index ON dist_partitioned_table ((dist_col || ' ' || another_col));
-- try with statistics on index
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE INDEX statistics_on_index on dist_partitioned_table ((dist_col+another_col), (dist_col-another_col));
ALTER INDEX statistics_on_index ALTER COLUMN 1 SET STATISTICS 3737;
ALTER INDEX statistics_on_index ALTER COLUMN 2 SET STATISTICS 3737;
@ -396,32 +347,7 @@ SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' O
(6 rows)
\c - - - :worker_1_port
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
tablename | indexname
---------------------------------------------------------------------
dist_partitioned_table_910004 | expression_index_910004
dist_partitioned_table_910004 | statistics_on_index_910004
dist_partitioned_table_910006 | expression_index_910006
dist_partitioned_table_910006 | statistics_on_index_910006
p_910012 | p_910012_expr_expr1_idx
p_910012 | p_910012_expr_idx
p_910014 | p_910014_expr_expr1_idx
p_910014 | p_910014_expr_idx
partition_table_with_very_long_name_910008 | partition_table_with_very_long_name_910008_expr_expr1_idx
partition_table_with_very_long_name_910008 | partition_table_with_very_long_name_910008_expr_idx
partition_table_with_very_long_name_910010 | partition_table_with_very_long_name_910010_expr_expr1_idx
partition_table_with_very_long_name_910010 | partition_table_with_very_long_name_910010_expr_idx
(12 rows)
\c - - - :master_port
SET search_path TO fix_idx_names, public;
SELECT fix_partition_shard_index_names('dist_partitioned_table'::regclass);
fix_partition_shard_index_names
---------------------------------------------------------------------
(1 row)
\c - - - :worker_1_port
-- we have correct names
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
tablename | indexname
---------------------------------------------------------------------
@ -487,6 +413,8 @@ SELECT create_distributed_table('dist_partitioned_table', 'dist_col');
-- create a partition with a long name
CREATE TABLE partition_table_with_very_long_name PARTITION OF dist_partitioned_table FOR VALUES FROM ('2018-01-01') TO ('2019-01-01');
-- create an index on parent table
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE INDEX index_rep_factor_2 ON dist_partitioned_table USING btree (another_col, partition_col);
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
tablename | indexname
@ -496,29 +424,7 @@ SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' O
(2 rows)
\c - - - :worker_2_port
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
tablename | indexname
---------------------------------------------------------------------
dist_partitioned_table_910050 | index_rep_factor_2_910050
dist_partitioned_table_910051 | index_rep_factor_2_910051
dist_partitioned_table_910052 | index_rep_factor_2_910052
dist_partitioned_table_910053 | index_rep_factor_2_910053
partition_table_with_very_long_name_910054 | partition_table_with_very_long_na_another_col_partition_col_idx
partition_table_with_very_long_name_910055 | partition_table_with_very_long_n_another_col_partition_col_idx1
partition_table_with_very_long_name_910056 | partition_table_with_very_long_n_another_col_partition_col_idx2
partition_table_with_very_long_name_910057 | partition_table_with_very_long_n_another_col_partition_col_idx3
(8 rows)
\c - - - :master_port
-- let's fix the problematic table
SET search_path TO fix_idx_names, public;
SELECT fix_partition_shard_index_names('dist_partitioned_table'::regclass);
fix_partition_shard_index_names
---------------------------------------------------------------------
(1 row)
\c - - - :worker_2_port
-- index names are correct
-- shard id has been appended to all index names which didn't end in shard id
-- this goes in line with Citus's way of naming indexes of shards: always append shardid to the end
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
@ -548,9 +454,8 @@ ERROR: permission denied for schema fix_idx_names
RESET ROLE;
SET search_path TO fix_idx_names, public;
DROP TABLE dist_partitioned_table;
-- also, we cannot do any further operations (e.g. rename) on the indexes of partitions because
-- the index names on shards of partitions have been generated by Postgres, not Citus
-- it doesn't matter here whether the partition name is long or short
-- We can do any further operations (e.g. rename) on the indexes of partitions because
-- the index names on shards of partitions have Citus naming, hence are reachable
-- replicate scenario from above but this time with one shard so that this test isn't flaky
SET citus.shard_count TO 1;
SET citus.shard_replication_factor TO 1;
@ -564,55 +469,15 @@ SELECT create_distributed_table('dist_partitioned_table', 'dist_col');
CREATE TABLE partition_table_with_very_long_name PARTITION OF dist_partitioned_table FOR VALUES FROM ('2018-01-01') TO ('2019-01-01');
CREATE TABLE p PARTITION OF dist_partitioned_table FOR VALUES FROM ('2019-01-01') TO ('2020-01-01');
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE INDEX short ON dist_partitioned_table USING btree (another_col, partition_col);
-- rename shouldn't work
-- rename works!
ALTER INDEX partition_table_with_very_long_na_another_col_partition_col_idx RENAME TO partition_table_with_very_long_name_idx;
ERROR: relation "fix_idx_names.partition_table_with_very_long_na_another_col_p_dd884a3b_910031" does not exist
CONTEXT: while executing command on localhost:xxxxx
-- we currently can't drop index on detached partition
-- we can drop index on detached partition
-- https://github.com/citusdata/citus/issues/5138
ALTER TABLE dist_partitioned_table DETACH PARTITION p;
DROP INDEX p_another_col_partition_col_idx;
ERROR: index "p_another_col_partition_col_idx_910032" does not exist
CONTEXT: while executing command on localhost:xxxxx
-- let's reattach and retry after fixing index names
ALTER TABLE dist_partitioned_table ATTACH PARTITION p FOR VALUES FROM ('2019-01-01') TO ('2020-01-01');
\c - - - :worker_1_port
-- check the current broken index names
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
tablename | indexname
---------------------------------------------------------------------
dist_partitioned_table_910030 | short_910030
p_910032 | p_910032_another_col_partition_col_idx
partition_table_with_very_long_name_910031 | partition_table_with_very_long_na_another_col_partition_col_idx
(3 rows)
\c - - - :master_port
SET search_path TO fix_idx_names, public;
-- fix index names
SELECT fix_all_partition_shard_index_names();
fix_all_partition_shard_index_names
---------------------------------------------------------------------
dist_partitioned_table
(1 row)
\c - - - :worker_1_port
-- check the fixed index names
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
tablename | indexname
---------------------------------------------------------------------
dist_partitioned_table_910030 | short_910030
p_910032 | p_another_col_partition_col_idx_910032
partition_table_with_very_long_name_910031 | partition_table_with_very_long_na_another_col_p_dd884a3b_910031
(3 rows)
\c - - - :master_port
SET search_path TO fix_idx_names, public;
-- should now work
ALTER INDEX partition_table_with_very_long_na_another_col_partition_col_idx RENAME TO partition_table_with_very_long_name_idx;
-- now we can drop index on detached partition
ALTER TABLE dist_partitioned_table DETACH PARTITION p;
DROP INDEX p_another_col_partition_col_idx;
\c - - - :worker_1_port
-- check that indexes have been renamed
-- and that index on p has been dropped (it won't appear)
@ -625,13 +490,150 @@ SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' O
\c - - - :master_port
SET search_path TO fix_idx_names, public;
DROP TABLE dist_partitioned_table;
-- test with citus local table
SET client_min_messages TO WARNING;
SELECT 1 FROM citus_add_node('localhost', :master_port, groupid=>0);
?column?
---------------------------------------------------------------------
1
(1 row)
RESET client_min_messages;
CREATE TABLE date_partitioned_citus_local_table(
measureid integer,
eventdate date,
measure_data jsonb) PARTITION BY RANGE(eventdate);
SELECT citus_add_local_table_to_metadata('date_partitioned_citus_local_table');
citus_add_local_table_to_metadata
---------------------------------------------------------------------
(1 row)
CREATE TABLE partition_local_table PARTITION OF date_partitioned_citus_local_table FOR VALUES FROM ('2018-01-01') TO ('2019-01-01');
-- SELECT fix_partition_shard_index_names('date_partitioned_citus_local_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE INDEX ON date_partitioned_citus_local_table USING btree(measureid);
-- check that index names are correct
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
tablename | indexname
---------------------------------------------------------------------
date_partitioned_citus_local_table | date_partitioned_citus_local_table_measureid_idx
date_partitioned_citus_local_table_361377 | date_partitioned_citus_local_table_measureid_idx_361377
partition_local_table | partition_local_table_measureid_idx
partition_local_table_361378 | partition_local_table_measureid_idx_361378
(4 rows)
-- creating a single object should only need to trigger fixing the single object
-- for example, if a partitioned table has already many indexes and we create a new
-- index, only the new index should be fixed
-- create only one shard & one partition so that the output easier to check
SET citus.next_shard_id TO 915000;
SET citus.shard_count TO 1;
SET citus.shard_replication_factor TO 1;
CREATE TABLE parent_table (dist_col int, another_col int, partition_col timestamp, name text) PARTITION BY RANGE (partition_col);
SELECT create_distributed_table('parent_table', 'dist_col');
create_distributed_table
---------------------------------------------------------------------
(1 row)
CREATE TABLE p1 PARTITION OF parent_table FOR VALUES FROM ('2018-01-01') TO ('2019-01-01');
CREATE INDEX i1 ON parent_table(dist_col);
CREATE INDEX i2 ON parent_table(dist_col);
CREATE INDEX i3 ON parent_table(dist_col);
SET citus.log_remote_commands TO ON;
-- only fix i4
CREATE INDEX i4 ON parent_table(dist_col);
NOTICE: issuing BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED;SELECT assign_distributed_transaction_id(xx, xx, 'xxxxxxx');
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing CREATE INDEX i4_915000 ON fix_idx_names.parent_table_915000 USING btree (dist_col )
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT worker_fix_partition_shard_index_names('fix_idx_names.i4_915000'::regclass, 'fix_idx_names.p1_915001', 'p1_dist_col_idx3_915001')
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing PREPARE TRANSACTION 'citus_xx_xx_xx_xx'
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing COMMIT PREPARED 'citus_xx_xx_xx_xx'
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
-- only fix the index backing the pkey
ALTER TABLE parent_table ADD CONSTRAINT pkey_cst PRIMARY KEY (dist_col, partition_col);
NOTICE: issuing BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED;SELECT assign_distributed_transaction_id(xx, xx, 'xxxxxxx');
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT worker_apply_shard_ddl_command (915000, 'fix_idx_names', 'ALTER TABLE parent_table ADD CONSTRAINT pkey_cst PRIMARY KEY (dist_col, partition_col);')
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT worker_fix_partition_shard_index_names('fix_idx_names.pkey_cst_915000'::regclass, 'fix_idx_names.p1_915001', 'p1_pkey_915001')
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing PREPARE TRANSACTION 'citus_xx_xx_xx_xx'
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing COMMIT PREPARED 'citus_xx_xx_xx_xx'
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
ALTER TABLE parent_table ADD CONSTRAINT unique_cst UNIQUE (dist_col, partition_col);
NOTICE: issuing BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED;SELECT assign_distributed_transaction_id(xx, xx, 'xxxxxxx');
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT worker_apply_shard_ddl_command (915000, 'fix_idx_names', 'ALTER TABLE parent_table ADD CONSTRAINT unique_cst UNIQUE (dist_col, partition_col);')
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT worker_fix_partition_shard_index_names('fix_idx_names.unique_cst_915000'::regclass, 'fix_idx_names.p1_915001', 'p1_dist_col_partition_col_key_915001')
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing PREPARE TRANSACTION 'citus_xx_xx_xx_xx'
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing COMMIT PREPARED 'citus_xx_xx_xx_xx'
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
RESET citus.log_remote_commands;
-- we should also be able to alter/drop these indexes
ALTER INDEX i4 RENAME TO i4_renamed;
ALTER INDEX p1_dist_col_idx3 RENAME TO p1_dist_col_idx3_renamed;
ALTER INDEX p1_pkey RENAME TO p1_pkey_renamed;
ALTER INDEX p1_dist_col_partition_col_key RENAME TO p1_dist_col_partition_col_key_renamed;
ALTER INDEX p1_dist_col_idx RENAME TO p1_dist_col_idx_renamed;
-- should be able to create a new partition that is columnar
SET citus.log_remote_commands TO ON;
CREATE TABLE p2(dist_col int NOT NULL, another_col int, partition_col timestamp NOT NULL, name text) USING columnar;
ALTER TABLE parent_table ATTACH PARTITION p2 FOR VALUES FROM ('2019-01-01') TO ('2020-01-01');
NOTICE: issuing SELECT worker_apply_shard_ddl_command (915002, 'fix_idx_names', 'CREATE TABLE fix_idx_names.p2 (dist_col integer NOT NULL, another_col integer, partition_col timestamp without time zone NOT NULL, name text) USING columnar')
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT alter_columnar_table_set('fix_idx_names.p2_915002', chunk_group_row_limit => 10000, stripe_row_limit => 150000, compression_level => 3, compression => 'zstd');
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT worker_apply_shard_ddl_command (915002, 'fix_idx_names', 'ALTER TABLE fix_idx_names.p2 OWNER TO postgres')
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED;SELECT assign_distributed_transaction_id(xx, xx, 'xxxxxxx');
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT worker_apply_inter_shard_ddl_command (915000, 'fix_idx_names', 915002, 'fix_idx_names', 'ALTER TABLE parent_table ATTACH PARTITION p2 FOR VALUES FROM (''2019-01-01'') TO (''2020-01-01'');')
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT worker_fix_partition_shard_index_names('fix_idx_names.i1_915000'::regclass, 'fix_idx_names.p2_915002', 'p2_dist_col_idx_915002')
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT worker_fix_partition_shard_index_names('fix_idx_names.i2_915000'::regclass, 'fix_idx_names.p2_915002', 'p2_dist_col_idx1_915002')
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT worker_fix_partition_shard_index_names('fix_idx_names.i3_915000'::regclass, 'fix_idx_names.p2_915002', 'p2_dist_col_idx2_915002')
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT worker_fix_partition_shard_index_names('fix_idx_names.i4_renamed_915000'::regclass, 'fix_idx_names.p2_915002', 'p2_dist_col_idx3_915002')
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT worker_fix_partition_shard_index_names('fix_idx_names.pkey_cst_915000'::regclass, 'fix_idx_names.p2_915002', 'p2_pkey_915002')
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing SELECT worker_fix_partition_shard_index_names('fix_idx_names.unique_cst_915000'::regclass, 'fix_idx_names.p2_915002', 'p2_dist_col_partition_col_key_915002')
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing PREPARE TRANSACTION 'citus_xx_xx_xx_xx'
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
NOTICE: issuing COMMIT PREPARED 'citus_xx_xx_xx_xx'
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
RESET citus.log_remote_commands;
DROP INDEX i4_renamed CASCADE;
ALTER TABLE parent_table DROP CONSTRAINT pkey_cst CASCADE;
ALTER TABLE parent_table DROP CONSTRAINT unique_cst CASCADE;
DROP SCHEMA fix_idx_names CASCADE;
NOTICE: drop cascades to 5 other objects
NOTICE: drop cascades to 7 other objects
DETAIL: drop cascades to table not_partitioned
drop cascades to table not_distributed
drop cascades to table fk_table
drop cascades to table dist_partitioned_table
drop cascades to table p
drop cascades to table date_partitioned_citus_local_table_361377
drop cascades to table date_partitioned_citus_local_table
drop cascades to table parent_table
SELECT citus_remove_node('localhost', :master_port);
citus_remove_node
---------------------------------------------------------------------
(1 row)
SELECT run_command_on_workers($$ DROP SCHEMA IF EXISTS fix_idx_names CASCADE $$);
run_command_on_workers
---------------------------------------------------------------------

View File

@ -4275,32 +4275,16 @@ SELECT create_distributed_table('part_table_with_very_long_name', 'dist_col');
CREATE INDEX ON part_table_with_very_long_name
USING btree (long_named_integer_col, long_named_part_col);
-- shouldn't work
SELECT start_metadata_sync_to_node('localhost', :worker_1_port);
ERROR: relation "part_table_with_long_long_lon_long_named_integer_col_long_n_idx" already exists
CONTEXT: while executing command on localhost:xxxxx
\c - - - :worker_1_port
-- index is created
SELECT tablename, indexname FROM pg_indexes
WHERE schemaname = 'partitioning_schema' AND tablename ilike '%part_table_with_%' ORDER BY 1, 2;
tablename | indexname
tablename | indexname
---------------------------------------------------------------------
part_table_with_long_long_long_long_name_361172 | part_table_with_long_long_lon_long_named_integer_col_long_n_idx
part_table_with_long_long_long_long_name_361174 | part_table_with_long_long_lon_long_named_integer_col_long__idx1
part_table_with_very_long_name_361168 | part_table_with_very_long_nam_long_named_intege_73d4b078_361168
part_table_with_very_long_name_361170 | part_table_with_very_long_nam_long_named_intege_73d4b078_361170
(4 rows)
part_table_with_long_long_long_long_name | part_table_with_long_long_lon_long_named_integer_col_long_n_idx
part_table_with_very_long_name | part_table_with_very_long_nam_long_named_integer_col_long_n_idx
(2 rows)
\c - - - :master_port
SET citus.shard_replication_factor TO 1;
SET search_path = partitioning_schema;
-- fix problematic table
SELECT fix_partition_shard_index_names('part_table_with_very_long_name'::regclass);
fix_partition_shard_index_names
---------------------------------------------------------------------
(1 row)
-- should work
-- should work properly - no names clashes
SELECT start_metadata_sync_to_node('localhost', :worker_1_port);
start_metadata_sync_to_node
---------------------------------------------------------------------
@ -4308,7 +4292,7 @@ SELECT start_metadata_sync_to_node('localhost', :worker_1_port);
(1 row)
\c - - - :worker_1_port
-- check that indexes are renamed
-- check that indexes are named properly
SELECT tablename, indexname FROM pg_indexes
WHERE schemaname = 'partitioning_schema' AND tablename ilike '%part_table_with_%' ORDER BY 1, 2;
tablename | indexname

View File

@ -0,0 +1,80 @@
CREATE SCHEMA "partitioned indexes";
SET search_path TO "partitioned indexes";
-- test with proper table
CREATE TABLE dist_partitioned_table (dist_col int, another_col int, partition_col timestamp) PARTITION BY RANGE (partition_col);
SELECT create_distributed_table('dist_partitioned_table', 'dist_col');
create_distributed_table
---------------------------------------------------------------------
(1 row)
-- create a partition with a long name and another with a short name
CREATE TABLE partition_table_with_very_long_name PARTITION OF dist_partitioned_table FOR VALUES FROM ('2018-01-01') TO ('2019-01-01');
CREATE TABLE p PARTITION OF dist_partitioned_table FOR VALUES FROM ('2019-01-01') TO ('2020-01-01');
-- create an index on parent table
-- we will see that it doesn't matter whether we name the index on parent or not
-- indexes auto-generated on partitions will not use this name
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE UNIQUE INDEX short ON dist_partitioned_table USING btree (dist_col, partition_col);
-- if we explicitly create index on partition-to-be table, Citus handles the naming
-- hence we would have no broken index names
CREATE TABLE another_partition_table_with_very_long_name (dist_col int, another_col int, partition_col timestamp);
SELECT create_distributed_table('another_partition_table_with_very_long_name', 'dist_col');
create_distributed_table
---------------------------------------------------------------------
(1 row)
CREATE INDEX ON another_partition_table_with_very_long_name USING btree (another_col, partition_col);
-- normally, in arbitrary tests, we DO NOT any of the paramaters, they are managed by the test suite
-- however, due to the issue https://github.com/citusdata/citus/issues/4845 we have to switch to
-- sequential execution on this test. Because this test covers an important case, and the pool size
-- here does not really matter, so we set it to 1 for this transaction block
BEGIN;
SET LOCAL citus.max_adaptive_executor_pool_size TO 1;
ALTER TABLE dist_partitioned_table ATTACH PARTITION another_partition_table_with_very_long_name FOR VALUES FROM ('2020-01-01') TO ('2021-01-01');
COMMIT;
-- check it works even if we give a weird index name
CREATE TABLE yet_another_partition_table (dist_col int, another_col int, partition_col timestamp);
SELECT create_distributed_table('yet_another_partition_table', 'dist_col');
create_distributed_table
---------------------------------------------------------------------
(1 row)
CREATE INDEX "really weird index name !!" ON yet_another_partition_table USING btree (another_col, partition_col);
ALTER TABLE dist_partitioned_table ATTACH PARTITION yet_another_partition_table FOR VALUES FROM ('2021-01-01') TO ('2022-01-01');
-- rename & create partition to trigger
-- fix_partition_shard_index_names on an index that a foreign key relies
ALTER INDEX short RENAME TO little_long;
CREATE TABLE p2 PARTITION OF dist_partitioned_table FOR VALUES FROM ('2022-01-01') TO ('2023-01-01');
-- try creating index to foreign key
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE INDEX ON dist_partitioned_table USING btree (dist_col, partition_col);
-- try with index on only parent
-- this is also an invalid index
-- also try with hash method, not btree
CREATE INDEX short_parent ON ONLY dist_partitioned_table USING hash (dist_col);
-- only another_partition will have the index on dist_col inherited from short_parent
-- hence short_parent will still be invalid
CREATE TABLE another_partition (dist_col int, another_col int, partition_col timestamp);
-- SELECT fix_partition_shard_index_names('another_partition') will be executed
-- automatically at the end of the ATTACH PARTITION command
ALTER TABLE dist_partitioned_table ATTACH PARTITION another_partition FOR VALUES FROM ('2017-01-01') TO ('2018-01-01');
-- try with expression indexes
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE INDEX expression_index ON dist_partitioned_table ((dist_col || ' ' || another_col)) INCLUDE(another_col) WITH(fillfactor 80) WHERE (dist_col > 10);
ERROR: syntax error at or near "80"
-- try with statistics on index
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE INDEX statistics_on_index on dist_partitioned_table ((dist_col+another_col), (dist_col-another_col));
ALTER INDEX statistics_on_index ALTER COLUMN 1 SET STATISTICS 3737;
ALTER INDEX statistics_on_index ALTER COLUMN 2 SET STATISTICS 3737;
-- we can drop index on detached partition
-- https://github.com/citusdata/citus/issues/5138
ALTER TABLE dist_partitioned_table DETACH PARTITION p;
DROP INDEX p_dist_col_partition_col_idx;

View File

@ -88,14 +88,14 @@ ORDER BY 1,2,3;
part_table_p202008_1690008 | ck_012345678901234567890123456789012345678901234567890123456789 | CHECK (my_seq > 10)
part_table_p202008_1690008 | dist_fk_1690000 | FOREIGN KEY (seq) REFERENCES test_3970.dist_1690004(seq)
part_table_p202008_1690008 | my_seq | CHECK (my_seq > 0)
part_table_p202008_1690008 | part_table_p202008_1690008_seq_work_ymdt_key | UNIQUE (seq, work_ymdt)
part_table_p202008_1690008 | part_table_p202008_pkey_1690008 | PRIMARY KEY (seq, work_ymdt)
part_table_p202008_1690008 | part_table_p202008_seq_work_ymdt_key_1690008 | UNIQUE (seq, work_ymdt)
part_table_p202008_1690008 | work_memo_check | CHECK (octet_length(work_memo::text) <= 150)
part_table_p202008_1690010 | ck_012345678901234567890123456789012345678901234567890123456789 | CHECK (my_seq > 10)
part_table_p202008_1690010 | dist_fk_1690002 | FOREIGN KEY (seq) REFERENCES test_3970.dist_1690006(seq)
part_table_p202008_1690010 | my_seq | CHECK (my_seq > 0)
part_table_p202008_1690010 | part_table_p202008_1690010_seq_work_ymdt_key | UNIQUE (seq, work_ymdt)
part_table_p202008_1690010 | part_table_p202008_pkey_1690010 | PRIMARY KEY (seq, work_ymdt)
part_table_p202008_1690010 | part_table_p202008_seq_work_ymdt_key_1690010 | UNIQUE (seq, work_ymdt)
part_table_p202008_1690010 | work_memo_check | CHECK (octet_length(work_memo::text) <= 150)
part_table_p202009_1690012 | ck_012345678901234567890123456789012345678901234567890123456789 | CHECK (my_seq > 10)
part_table_p202009_1690012 | dist_fk_1690000 | FOREIGN KEY (seq) REFERENCES test_3970.dist_1690004(seq)

View File

@ -1,6 +1,7 @@
setup
{
CREATE TABLE dist_partitioned_table(a INT, created_at timestamptz) PARTITION BY RANGE (created_at);
CREATE TABLE p PARTITION OF dist_partitioned_table FOR VALUES FROM ('2019-01-01') TO ('2020-01-01');
SELECT create_distributed_table('dist_partitioned_table', 'a');
}
@ -16,6 +17,16 @@ step "s1-begin"
BEGIN;
}
step "s1-select-from-table"
{
SELECT * FROM dist_partitioned_table;
}
step "s1-insert-into-table"
{
INSERT INTO dist_partitioned_table VALUES (0, '2019-01-01');
}
step "s1-drop-table"
{
DROP TABLE dist_partitioned_table;
@ -39,6 +50,16 @@ step "s2-fix-partition-shard-index-names"
SELECT fix_partition_shard_index_names('dist_partitioned_table'::regclass);
}
step "s2-create-index"
{
CREATE INDEX ON dist_partitioned_table USING btree(a);
}
step "s2-create-index-concurrently"
{
CREATE INDEX CONCURRENTLY ON dist_partitioned_table USING btree(a);
}
step "s2-commit"
{
COMMIT;
@ -46,3 +67,18 @@ step "s2-commit"
permutation "s1-begin" "s1-drop-table" "s2-fix-partition-shard-index-names" "s1-commit"
permutation "s2-begin" "s2-fix-partition-shard-index-names" "s1-drop-table" "s2-commit"
// CREATE INDEX should not block concurrent reads but should block concurrent writes
permutation "s2-begin" "s2-create-index" "s1-select-from-table" "s2-commit"
permutation "s2-begin" "s2-create-index" "s1-insert-into-table" "s2-commit"
// CREATE INDEX CONCURRENTLY is currently not supported for partitioned tables in PG
// when it's supported, we would want to not block any concurrent reads or writes
permutation "s1-begin" "s1-select-from-table" "s2-create-index-concurrently" "s1-commit"
permutation "s1-begin" "s1-insert-into-table" "s2-create-index-concurrently" "s1-commit"
// running the following just for consistency
permutation "s1-begin" "s1-select-from-table" "s2-create-index" "s1-commit"
permutation "s1-begin" "s1-insert-into-table" "s2-create-index" "s1-commit"
permutation "s2-begin" "s2-create-index-concurrently" "s1-select-from-table" "s2-commit"
permutation "s2-begin" "s2-create-index-concurrently" "s1-insert-into-table" "s2-commit"

View File

@ -37,36 +37,30 @@ CREATE TABLE p PARTITION OF dist_partitioned_table FOR VALUES FROM ('2019-01-01'
-- create an index on parent table
-- we will see that it doesn't matter whether we name the index on parent or not
-- indexes auto-generated on partitions will not use this name
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE INDEX short ON dist_partitioned_table USING btree (another_col, partition_col);
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
\c - - - :worker_1_port
-- Note that, the shell table from above partition_table_with_very_long_name
-- and its shard partition_table_with_very_long_name_910008
-- have the same index name: partition_table_with_very_long_na_another_col_partition_col_idx
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
\c - - - :master_port
-- this should fail because of the name clash explained above
SELECT start_metadata_sync_to_node('localhost', :worker_1_port);
-- let's fix the problematic table
SET search_path TO fix_idx_names, public;
SELECT fix_partition_shard_index_names('dist_partitioned_table'::regclass);
\c - - - :worker_1_port
-- the names are generated correctly
-- shard id has been appended to all index names which didn't end in shard id
-- this goes in line with Citus's way of naming indexes of shards: always append shardid to the end
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
\c - - - :master_port
SET search_path TO fix_idx_names, public;
-- this should now work
-- this should work properly
SELECT start_metadata_sync_to_node('localhost', :worker_1_port);
-- if we run this command again, the names will not change anymore since shardid is appended to them
\c - - - :worker_1_port
-- we have no clashes
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
\c - - - :master_port
SET search_path TO fix_idx_names, public;
-- if we run this command again, the names will not change since shardid is appended to them
SELECT fix_partition_shard_index_names('dist_partitioned_table'::regclass);
SELECT fix_all_partition_shard_index_names();
@ -113,24 +107,20 @@ DROP INDEX short;
DROP TABLE yet_another_partition_table, another_partition_table_with_very_long_name;
-- this will create constraint1 index on parent
SET citus.max_adaptive_executor_pool_size TO 1;
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the ADD CONSTRAINT command
ALTER TABLE dist_partitioned_table ADD CONSTRAINT constraint1 UNIQUE (dist_col, partition_col);
RESET citus.max_adaptive_executor_pool_size;
CREATE TABLE fk_table (id int, fk_column timestamp, FOREIGN KEY (id, fk_column) REFERENCES dist_partitioned_table (dist_col, partition_col));
-- try creating index to foreign key
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE INDEX ON dist_partitioned_table USING btree (dist_col, partition_col);
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
\c - - - :worker_1_port
-- index names don't end in shardid for partitions
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
\c - - - :master_port
SET search_path TO fix_idx_names, public;
SELECT fix_all_partition_shard_index_names();
\c - - - :worker_1_port
-- now index names end in shardid
-- index names end in shardid for partitions
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
\c - - - :master_port
@ -147,6 +137,8 @@ CREATE INDEX short_parent ON ONLY dist_partitioned_table USING hash (dist_col);
-- only another_partition will have the index on dist_col inherited from short_parent
-- hence short_parent will still be invalid
CREATE TABLE another_partition (dist_col int, another_col int, partition_col timestamp);
-- SELECT fix_partition_shard_index_names('another_partition') will be executed
-- automatically at the end of the ATTACH PARTITION command
ALTER TABLE dist_partitioned_table ATTACH PARTITION another_partition FOR VALUES FROM ('2017-01-01') TO ('2018-01-01');
SELECT c.relname AS indexname
@ -158,17 +150,7 @@ CREATE INDEX short_child ON ONLY p USING hash (dist_col);
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
\c - - - :worker_1_port
-- index names are already correct except for inherited index for another_partition
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
\c - - - :master_port
SET search_path TO fix_idx_names, public;
-- this will fix inherited index for another_partition
SELECT fix_partition_shard_index_names('dist_partitioned_table'::regclass);
-- this will error out becuase p is not partitioned, it is rather a partition
SELECT fix_partition_shard_index_names('p'::regclass);
\c - - - :worker_1_port
-- index names are already correct, including inherited index for another_partition
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
\c - - - :master_port
@ -178,9 +160,13 @@ DROP INDEX short_parent;
DROP INDEX short_child;
DROP TABLE another_partition;
-- expression indexes have the same problem with naming
-- try with expression indexes
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE INDEX expression_index ON dist_partitioned_table ((dist_col || ' ' || another_col));
-- try with statistics on index
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE INDEX statistics_on_index on dist_partitioned_table ((dist_col+another_col), (dist_col-another_col));
ALTER INDEX statistics_on_index ALTER COLUMN 1 SET STATISTICS 3737;
ALTER INDEX statistics_on_index ALTER COLUMN 2 SET STATISTICS 3737;
@ -188,13 +174,7 @@ ALTER INDEX statistics_on_index ALTER COLUMN 2 SET STATISTICS 3737;
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
\c - - - :worker_1_port
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
\c - - - :master_port
SET search_path TO fix_idx_names, public;
SELECT fix_partition_shard_index_names('dist_partitioned_table'::regclass);
\c - - - :worker_1_port
-- we have correct names
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
\c - - - :master_port
@ -230,19 +210,14 @@ SELECT create_distributed_table('dist_partitioned_table', 'dist_col');
CREATE TABLE partition_table_with_very_long_name PARTITION OF dist_partitioned_table FOR VALUES FROM ('2018-01-01') TO ('2019-01-01');
-- create an index on parent table
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE INDEX index_rep_factor_2 ON dist_partitioned_table USING btree (another_col, partition_col);
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
\c - - - :worker_2_port
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
\c - - - :master_port
-- let's fix the problematic table
SET search_path TO fix_idx_names, public;
SELECT fix_partition_shard_index_names('dist_partitioned_table'::regclass);
\c - - - :worker_2_port
-- index names are correct
-- shard id has been appended to all index names which didn't end in shard id
-- this goes in line with Citus's way of naming indexes of shards: always append shardid to the end
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
@ -264,11 +239,10 @@ RESET ROLE;
SET search_path TO fix_idx_names, public;
DROP TABLE dist_partitioned_table;
-- also, we cannot do any further operations (e.g. rename) on the indexes of partitions because
-- the index names on shards of partitions have been generated by Postgres, not Citus
-- it doesn't matter here whether the partition name is long or short
-- We can do any further operations (e.g. rename) on the indexes of partitions because
-- the index names on shards of partitions have Citus naming, hence are reachable
-- replicate scenario from above but this time with one shard so that this test isn't flaky
SET citus.shard_count TO 1;
SET citus.shard_replication_factor TO 1;
SET citus.next_shard_id TO 910030;
@ -277,41 +251,18 @@ CREATE TABLE dist_partitioned_table (dist_col int, another_col int, partition_co
SELECT create_distributed_table('dist_partitioned_table', 'dist_col');
CREATE TABLE partition_table_with_very_long_name PARTITION OF dist_partitioned_table FOR VALUES FROM ('2018-01-01') TO ('2019-01-01');
CREATE TABLE p PARTITION OF dist_partitioned_table FOR VALUES FROM ('2019-01-01') TO ('2020-01-01');
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE INDEX short ON dist_partitioned_table USING btree (another_col, partition_col);
-- rename shouldn't work
-- rename works!
ALTER INDEX partition_table_with_very_long_na_another_col_partition_col_idx RENAME TO partition_table_with_very_long_name_idx;
-- we currently can't drop index on detached partition
-- we can drop index on detached partition
-- https://github.com/citusdata/citus/issues/5138
ALTER TABLE dist_partitioned_table DETACH PARTITION p;
DROP INDEX p_another_col_partition_col_idx;
-- let's reattach and retry after fixing index names
ALTER TABLE dist_partitioned_table ATTACH PARTITION p FOR VALUES FROM ('2019-01-01') TO ('2020-01-01');
\c - - - :worker_1_port
-- check the current broken index names
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
\c - - - :master_port
SET search_path TO fix_idx_names, public;
-- fix index names
SELECT fix_all_partition_shard_index_names();
\c - - - :worker_1_port
-- check the fixed index names
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
\c - - - :master_port
SET search_path TO fix_idx_names, public;
-- should now work
ALTER INDEX partition_table_with_very_long_na_another_col_partition_col_idx RENAME TO partition_table_with_very_long_name_idx;
-- now we can drop index on detached partition
ALTER TABLE dist_partitioned_table DETACH PARTITION p;
DROP INDEX p_another_col_partition_col_idx;
\c - - - :worker_1_port
-- check that indexes have been renamed
-- and that index on p has been dropped (it won't appear)
@ -319,6 +270,74 @@ SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' O
\c - - - :master_port
SET search_path TO fix_idx_names, public;
DROP TABLE dist_partitioned_table;
-- test with citus local table
SET client_min_messages TO WARNING;
SELECT 1 FROM citus_add_node('localhost', :master_port, groupid=>0);
RESET client_min_messages;
CREATE TABLE date_partitioned_citus_local_table(
measureid integer,
eventdate date,
measure_data jsonb) PARTITION BY RANGE(eventdate);
SELECT citus_add_local_table_to_metadata('date_partitioned_citus_local_table');
CREATE TABLE partition_local_table PARTITION OF date_partitioned_citus_local_table FOR VALUES FROM ('2018-01-01') TO ('2019-01-01');
-- SELECT fix_partition_shard_index_names('date_partitioned_citus_local_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE INDEX ON date_partitioned_citus_local_table USING btree(measureid);
-- check that index names are correct
SELECT tablename, indexname FROM pg_indexes WHERE schemaname = 'fix_idx_names' ORDER BY 1, 2;
-- creating a single object should only need to trigger fixing the single object
-- for example, if a partitioned table has already many indexes and we create a new
-- index, only the new index should be fixed
-- create only one shard & one partition so that the output easier to check
SET citus.next_shard_id TO 915000;
SET citus.shard_count TO 1;
SET citus.shard_replication_factor TO 1;
CREATE TABLE parent_table (dist_col int, another_col int, partition_col timestamp, name text) PARTITION BY RANGE (partition_col);
SELECT create_distributed_table('parent_table', 'dist_col');
CREATE TABLE p1 PARTITION OF parent_table FOR VALUES FROM ('2018-01-01') TO ('2019-01-01');
CREATE INDEX i1 ON parent_table(dist_col);
CREATE INDEX i2 ON parent_table(dist_col);
CREATE INDEX i3 ON parent_table(dist_col);
SET citus.log_remote_commands TO ON;
-- only fix i4
CREATE INDEX i4 ON parent_table(dist_col);
-- only fix the index backing the pkey
ALTER TABLE parent_table ADD CONSTRAINT pkey_cst PRIMARY KEY (dist_col, partition_col);
ALTER TABLE parent_table ADD CONSTRAINT unique_cst UNIQUE (dist_col, partition_col);
RESET citus.log_remote_commands;
-- we should also be able to alter/drop these indexes
ALTER INDEX i4 RENAME TO i4_renamed;
ALTER INDEX p1_dist_col_idx3 RENAME TO p1_dist_col_idx3_renamed;
ALTER INDEX p1_pkey RENAME TO p1_pkey_renamed;
ALTER INDEX p1_dist_col_partition_col_key RENAME TO p1_dist_col_partition_col_key_renamed;
ALTER INDEX p1_dist_col_idx RENAME TO p1_dist_col_idx_renamed;
-- should be able to create a new partition that is columnar
SET citus.log_remote_commands TO ON;
CREATE TABLE p2(dist_col int NOT NULL, another_col int, partition_col timestamp NOT NULL, name text) USING columnar;
ALTER TABLE parent_table ATTACH PARTITION p2 FOR VALUES FROM ('2019-01-01') TO ('2020-01-01');
RESET citus.log_remote_commands;
DROP INDEX i4_renamed CASCADE;
ALTER TABLE parent_table DROP CONSTRAINT pkey_cst CASCADE;
ALTER TABLE parent_table DROP CONSTRAINT unique_cst CASCADE;
DROP SCHEMA fix_idx_names CASCADE;
SELECT citus_remove_node('localhost', :master_port);
SELECT run_command_on_workers($$ DROP SCHEMA IF EXISTS fix_idx_names CASCADE $$);

View File

@ -1986,23 +1986,15 @@ SELECT create_distributed_table('part_table_with_very_long_name', 'dist_col');
CREATE INDEX ON part_table_with_very_long_name
USING btree (long_named_integer_col, long_named_part_col);
-- shouldn't work
SELECT start_metadata_sync_to_node('localhost', :worker_1_port);
\c - - - :worker_1_port
-- index is created
SELECT tablename, indexname FROM pg_indexes
WHERE schemaname = 'partitioning_schema' AND tablename ilike '%part_table_with_%' ORDER BY 1, 2;
\c - - - :master_port
SET citus.shard_replication_factor TO 1;
SET search_path = partitioning_schema;
-- fix problematic table
SELECT fix_partition_shard_index_names('part_table_with_very_long_name'::regclass);
-- should work
-- should work properly - no names clashes
SELECT start_metadata_sync_to_node('localhost', :worker_1_port);
\c - - - :worker_1_port
-- check that indexes are renamed
-- check that indexes are named properly
SELECT tablename, indexname FROM pg_indexes
WHERE schemaname = 'partitioning_schema' AND tablename ilike '%part_table_with_%' ORDER BY 1, 2;

View File

@ -0,0 +1,76 @@
CREATE SCHEMA "partitioned indexes";
SET search_path TO "partitioned indexes";
-- test with proper table
CREATE TABLE dist_partitioned_table (dist_col int, another_col int, partition_col timestamp) PARTITION BY RANGE (partition_col);
SELECT create_distributed_table('dist_partitioned_table', 'dist_col');
-- create a partition with a long name and another with a short name
CREATE TABLE partition_table_with_very_long_name PARTITION OF dist_partitioned_table FOR VALUES FROM ('2018-01-01') TO ('2019-01-01');
CREATE TABLE p PARTITION OF dist_partitioned_table FOR VALUES FROM ('2019-01-01') TO ('2020-01-01');
-- create an index on parent table
-- we will see that it doesn't matter whether we name the index on parent or not
-- indexes auto-generated on partitions will not use this name
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE UNIQUE INDEX short ON dist_partitioned_table USING btree (dist_col, partition_col);
-- if we explicitly create index on partition-to-be table, Citus handles the naming
-- hence we would have no broken index names
CREATE TABLE another_partition_table_with_very_long_name (dist_col int, another_col int, partition_col timestamp);
SELECT create_distributed_table('another_partition_table_with_very_long_name', 'dist_col');
CREATE INDEX ON another_partition_table_with_very_long_name USING btree (another_col, partition_col);
-- normally, in arbitrary tests, we DO NOT any of the paramaters, they are managed by the test suite
-- however, due to the issue https://github.com/citusdata/citus/issues/4845 we have to switch to
-- sequential execution on this test. Because this test covers an important case, and the pool size
-- here does not really matter, so we set it to 1 for this transaction block
BEGIN;
SET LOCAL citus.max_adaptive_executor_pool_size TO 1;
ALTER TABLE dist_partitioned_table ATTACH PARTITION another_partition_table_with_very_long_name FOR VALUES FROM ('2020-01-01') TO ('2021-01-01');
COMMIT;
-- check it works even if we give a weird index name
CREATE TABLE yet_another_partition_table (dist_col int, another_col int, partition_col timestamp);
SELECT create_distributed_table('yet_another_partition_table', 'dist_col');
CREATE INDEX "really weird index name !!" ON yet_another_partition_table USING btree (another_col, partition_col);
ALTER TABLE dist_partitioned_table ATTACH PARTITION yet_another_partition_table FOR VALUES FROM ('2021-01-01') TO ('2022-01-01');
-- rename & create partition to trigger
-- fix_partition_shard_index_names on an index that a foreign key relies
ALTER INDEX short RENAME TO little_long;
CREATE TABLE p2 PARTITION OF dist_partitioned_table FOR VALUES FROM ('2022-01-01') TO ('2023-01-01');
-- try creating index to foreign key
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE INDEX ON dist_partitioned_table USING btree (dist_col, partition_col);
-- try with index on only parent
-- this is also an invalid index
-- also try with hash method, not btree
CREATE INDEX short_parent ON ONLY dist_partitioned_table USING hash (dist_col);
-- only another_partition will have the index on dist_col inherited from short_parent
-- hence short_parent will still be invalid
CREATE TABLE another_partition (dist_col int, another_col int, partition_col timestamp);
-- SELECT fix_partition_shard_index_names('another_partition') will be executed
-- automatically at the end of the ATTACH PARTITION command
ALTER TABLE dist_partitioned_table ATTACH PARTITION another_partition FOR VALUES FROM ('2017-01-01') TO ('2018-01-01');
-- try with expression indexes
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE INDEX expression_index ON dist_partitioned_table ((dist_col || ' ' || another_col)) INCLUDE(another_col) WITH(fillfactor 80) WHERE (dist_col > 10);
-- try with statistics on index
-- SELECT fix_partition_shard_index_names('dist_partitioned_table') will be executed
-- automatically at the end of the CREATE INDEX command
CREATE INDEX statistics_on_index on dist_partitioned_table ((dist_col+another_col), (dist_col-another_col));
ALTER INDEX statistics_on_index ALTER COLUMN 1 SET STATISTICS 3737;
ALTER INDEX statistics_on_index ALTER COLUMN 2 SET STATISTICS 3737;
-- we can drop index on detached partition
-- https://github.com/citusdata/citus/issues/5138
ALTER TABLE dist_partitioned_table DETACH PARTITION p;
DROP INDEX p_dist_col_partition_col_idx;