From 9a792ef841a286cfbca15355dc946d7d8f9f8b28 Mon Sep 17 00:00:00 2001 From: Hanefi Onaldi Date: Wed, 24 Feb 2021 02:48:21 +0300 Subject: [PATCH] Remove length limitations for table renames --- .../distributed/commands/alter_table.c | 109 ++++++++++++++++++ src/backend/distributed/commands/index.c | 9 +- src/backend/distributed/commands/rename.c | 7 ++ .../distributed/relay/relay_event_utility.c | 24 ---- .../utils/multi_partitioning_utils.c | 15 +-- src/backend/distributed/utils/shard_utils.c | 19 +++ src/include/distributed/commands.h | 4 + .../distributed/multi_partitioning_utils.h | 2 +- src/include/distributed/shard_utils.h | 1 + .../expected/alter_distributed_table.out | 38 ++++-- .../expected/alter_distributed_table_0.out | 38 ++++-- .../alter_table_set_access_method.out | 12 +- .../expected/multi_generate_ddl_commands.out | 42 ++++--- .../regress/expected/multi_name_lengths.out | 54 ++++----- 14 files changed, 269 insertions(+), 105 deletions(-) diff --git a/src/backend/distributed/commands/alter_table.c b/src/backend/distributed/commands/alter_table.c index ade2fe0bd..0e4ab0251 100644 --- a/src/backend/distributed/commands/alter_table.c +++ b/src/backend/distributed/commands/alter_table.c @@ -49,6 +49,8 @@ #include "distributed/multi_logical_planner.h" #include "distributed/multi_partitioning_utils.h" #include "distributed/reference_table_utils.h" +#include "distributed/relation_access_tracking.h" +#include "distributed/shard_utils.h" #include "distributed/worker_protocol.h" #include "distributed/worker_transaction.h" #include "executor/spi.h" @@ -175,6 +177,8 @@ static TableConversionReturn * AlterDistributedTable(TableConversionParameters * static TableConversionReturn * AlterTableSetAccessMethod( TableConversionParameters *params); static TableConversionReturn * ConvertTable(TableConversionState *con); +static bool SwitchToSequentialAndLocalExecutionIfShardNameTooLong(char *relationName, + char *longestShardName); static void EnsureTableNotReferencing(Oid relationId, char conversionType); static void EnsureTableNotReferenced(Oid relationId, char conversionType); static void EnsureTableNotForeign(Oid relationId); @@ -511,6 +515,10 @@ ConvertTable(TableConversionState *con) bool oldEnableLocalReferenceForeignKeys = EnableLocalReferenceForeignKeys; SetLocalEnableLocalReferenceForeignKeys(false); + /* switch to sequential execution if shard names will be too long */ + SwitchToSequentialAndLocalExecutionIfRelationNameTooLong(con->relationId, + con->relationName); + if (con->conversionType == UNDISTRIBUTE_TABLE && con->cascadeViaForeignKeys && (TableReferencing(con->relationId) || TableReferenced(con->relationId))) { @@ -1572,3 +1580,104 @@ ExecuteQueryViaSPI(char *query, int SPIOK) ereport(ERROR, (errmsg("could not finish SPI connection"))); } } + + +/* + * SwitchToSequentialAndLocalExecutionIfRelationNameTooLong generates the longest shard name + * on the shards of a distributed table, and if exceeds the limit switches to sequential and + * local execution to prevent self-deadlocks. + * + * In case of a RENAME, the relation name parameter should store the new table name, so + * that the function can generate shard names of the renamed relations + */ +void +SwitchToSequentialAndLocalExecutionIfRelationNameTooLong(Oid relationId, + char *finalRelationName) +{ + if (!IsCitusTable(relationId)) + { + return; + } + + if (ShardIntervalCount(relationId) == 0) + { + /* + * Relation has no shards, so we cannot run into "long shard relation + * name" issue. + */ + return; + } + + char *longestShardName = GetLongestShardName(relationId, finalRelationName); + bool switchedToSequentialAndLocalExecution = + SwitchToSequentialAndLocalExecutionIfShardNameTooLong(finalRelationName, + longestShardName); + + if (switchedToSequentialAndLocalExecution) + { + return; + } + + if (PartitionedTable(relationId)) + { + Oid longestNamePartitionId = PartitionWithLongestNameRelationId(relationId); + if (!OidIsValid(longestNamePartitionId)) + { + /* no partitions have been created yet */ + return; + } + + char *longestPartitionName = get_rel_name(longestNamePartitionId); + char *longestPartitionShardName = GetLongestShardName(longestNamePartitionId, + longestPartitionName); + + SwitchToSequentialAndLocalExecutionIfShardNameTooLong(longestPartitionName, + longestPartitionShardName); + } +} + + +/* + * SwitchToSequentialAndLocalExecutionIfShardNameTooLong switches to sequential and local + * execution if the shard name is too long. + * + * returns true if switched to sequential and local execution. + */ +static bool +SwitchToSequentialAndLocalExecutionIfShardNameTooLong(char *relationName, + char *longestShardName) +{ + if (strlen(longestShardName) >= NAMEDATALEN - 1) + { + if (ParallelQueryExecutedInTransaction()) + { + /* + * If there has already been a parallel query executed, the sequential mode + * would still use the already opened parallel connections to the workers, + * thus contradicting our purpose of using sequential mode. + */ + ereport(ERROR, (errmsg( + "Shard name (%s) for table (%s) is too long and could " + "lead to deadlocks when executed in a transaction " + "block after a parallel query", longestShardName, + relationName), + errhint("Try re-running the transaction with " + "\"SET LOCAL citus.multi_shard_modify_mode TO " + "\'sequential\';\""))); + } + else + { + elog(DEBUG1, "the name of the shard (%s) for relation (%s) is too long, " + "switching to sequential and local execution mode to prevent " + "self deadlocks", + longestShardName, relationName); + + SetLocalMultiShardModifyModeToSequential(); + SetLocalExecutionStatus(LOCAL_EXECUTION_REQUIRED); + + return true; + } + } + + return false; +} diff --git a/src/backend/distributed/commands/index.c b/src/backend/distributed/commands/index.c index 415ef5419..8404dc0c1 100644 --- a/src/backend/distributed/commands/index.c +++ b/src/backend/distributed/commands/index.c @@ -410,15 +410,16 @@ static char * GenerateLongestShardPartitionIndexName(IndexStmt *createIndexStatement) { Oid relationId = CreateIndexStmtGetRelationId(createIndexStatement); - char *longestPartitionName = LongestPartitionName(relationId); - if (longestPartitionName == NULL) + Oid longestNamePartitionId = PartitionWithLongestNameRelationId(relationId); + if (!OidIsValid(longestNamePartitionId)) { /* no partitions have been created yet */ return NULL; } - char *longestPartitionShardName = pstrdup(longestPartitionName); - ShardInterval *shardInterval = LoadShardIntervalWithLongestShardName(relationId); + char *longestPartitionShardName = get_rel_name(longestNamePartitionId); + ShardInterval *shardInterval = LoadShardIntervalWithLongestShardName( + longestNamePartitionId); AppendShardIdToName(&longestPartitionShardName, shardInterval->shardId); IndexStmt *createLongestShardIndexStmt = copyObject(createIndexStatement); diff --git a/src/backend/distributed/commands/rename.c b/src/backend/distributed/commands/rename.c index 8af5639b5..98fee7e6c 100644 --- a/src/backend/distributed/commands/rename.c +++ b/src/backend/distributed/commands/rename.c @@ -109,6 +109,13 @@ PreprocessRenameStmt(Node *node, const char *renameCommand, */ ErrorIfUnsupportedRenameStmt(renameStmt); + if (renameStmt->renameType == OBJECT_TABLE || + renameStmt->renameType == OBJECT_FOREIGN_TABLE) + { + SwitchToSequentialAndLocalExecutionIfRelationNameTooLong(tableRelationId, + renameStmt->newname); + } + DDLJob *ddlJob = palloc0(sizeof(DDLJob)); ddlJob->targetRelationId = tableRelationId; ddlJob->concurrentIndexCmd = false; diff --git a/src/backend/distributed/relay/relay_event_utility.c b/src/backend/distributed/relay/relay_event_utility.c index 39d5c6005..1120422b7 100644 --- a/src/backend/distributed/relay/relay_event_utility.c +++ b/src/backend/distributed/relay/relay_event_utility.c @@ -556,30 +556,6 @@ RelayEventExtendNames(Node *parseTree, char *schemaName, uint64 shardId) AppendShardIdToName(oldRelationName, shardId); AppendShardIdToName(newRelationName, shardId); - - /* - * PostgreSQL creates array types for each ordinary table, with - * the same name plus a prefix of '_'. - * - * ALTER TABLE ... RENAME TO ... also renames the underlying - * array type, and the DDL is run in parallel connections over - * all the placements and shards at once. Concurrent access - * here deadlocks. - * - * Let's provide an easier to understand error message here - * than the deadlock one. - * - * See also https://github.com/citusdata/citus/issues/1664 - */ - int newRelationNameLength = strlen(*newRelationName); - if (newRelationNameLength >= (NAMEDATALEN - 1)) - { - ereport(ERROR, - (errcode(ERRCODE_NAME_TOO_LONG), - errmsg( - "shard name %s exceeds %d characters", - *newRelationName, NAMEDATALEN - 1))); - } } else if (objectType == OBJECT_COLUMN) { diff --git a/src/backend/distributed/utils/multi_partitioning_utils.c b/src/backend/distributed/utils/multi_partitioning_utils.c index ae26f1e7a..764545fca 100644 --- a/src/backend/distributed/utils/multi_partitioning_utils.c +++ b/src/backend/distributed/utils/multi_partitioning_utils.c @@ -548,13 +548,14 @@ PartitionParentOid(Oid partitionOid) /* - * LongestPartitionName is a uitility function that returns the partition - * name which is the longest in terms of number of characters. + * PartitionWithLongestNameRelationId is a utility function that returns the + * oid of the partition table that has the longest name in terms of number of + * characters. */ -char * -LongestPartitionName(Oid parentRelationId) +Oid +PartitionWithLongestNameRelationId(Oid parentRelationId) { - char *longestName = NULL; + Oid longestNamePartitionId = InvalidOid; int longestNameLength = 0; List *partitionList = PartitionList(parentRelationId); @@ -565,12 +566,12 @@ LongestPartitionName(Oid parentRelationId) int partitionNameLength = strnlen(partitionName, NAMEDATALEN); if (partitionNameLength > longestNameLength) { - longestName = partitionName; + longestNamePartitionId = partitionRelationId; longestNameLength = partitionNameLength; } } - return longestName; + return longestNamePartitionId; } diff --git a/src/backend/distributed/utils/shard_utils.c b/src/backend/distributed/utils/shard_utils.c index 4af3d8801..b0301d24f 100644 --- a/src/backend/distributed/utils/shard_utils.c +++ b/src/backend/distributed/utils/shard_utils.c @@ -12,6 +12,7 @@ #include "postgres.h" #include "utils/lsyscache.h" +#include "distributed/metadata_utility.h" #include "distributed/relay_utility.h" #include "distributed/shard_utils.h" @@ -36,3 +37,21 @@ GetTableLocalShardOid(Oid citusTableOid, uint64 shardId) return shardRelationOid; } + + +/* + * GetLongestShardName is a utility function that returns the name of the shard of a + * table that has the longest name in terms of number of characters. + * + * Both the Oid and name of the table are required so we can create longest shard names + * after a RENAME. + */ +char * +GetLongestShardName(Oid citusTableOid, char *finalRelationName) +{ + char *longestShardName = pstrdup(finalRelationName); + ShardInterval *shardInterval = LoadShardIntervalWithLongestShardName(citusTableOid); + AppendShardIdToName(&longestShardName, shardInterval->shardId); + + return longestShardName; +} diff --git a/src/include/distributed/commands.h b/src/include/distributed/commands.h index 365030aa2..1249cac90 100644 --- a/src/include/distributed/commands.h +++ b/src/include/distributed/commands.h @@ -24,6 +24,10 @@ /* controlled via GUC, should be accessed via EnableLocalReferenceForeignKeys() */ extern bool EnableLocalReferenceForeignKeys; +extern void SwitchToSequentialAndLocalExecutionIfRelationNameTooLong(Oid relationId, + char * + finalRelationName); + /* * DistributeObjectOps specifies handlers for node/object type pairs. diff --git a/src/include/distributed/multi_partitioning_utils.h b/src/include/distributed/multi_partitioning_utils.h index db83dc7aa..bb08fb1c4 100644 --- a/src/include/distributed/multi_partitioning_utils.h +++ b/src/include/distributed/multi_partitioning_utils.h @@ -19,7 +19,7 @@ extern bool PartitionTableNoLock(Oid relationId); extern bool IsChildTable(Oid relationId); extern bool IsParentTable(Oid relationId); extern Oid PartitionParentOid(Oid partitionOid); -extern char * LongestPartitionName(Oid parentRelationId); +extern Oid PartitionWithLongestNameRelationId(Oid parentRelationId); extern List * PartitionList(Oid parentRelationId); extern char * GenerateDetachPartitionCommand(Oid partitionTableId); extern char * GenerateAttachShardPartitionCommand(ShardInterval *shardInterval); diff --git a/src/include/distributed/shard_utils.h b/src/include/distributed/shard_utils.h index 89f4b8eb2..2ae159017 100644 --- a/src/include/distributed/shard_utils.h +++ b/src/include/distributed/shard_utils.h @@ -14,5 +14,6 @@ #include "postgres.h" extern Oid GetTableLocalShardOid(Oid citusTableOid, uint64 shardId); +extern char * GetLongestShardName(Oid citusTableOid, char *finalRelationName); #endif /* SHARD_UTILS_H */ diff --git a/src/test/regress/expected/alter_distributed_table.out b/src/test/regress/expected/alter_distributed_table.out index 3ed921dc2..f9cd497f0 100644 --- a/src/test/regress/expected/alter_distributed_table.out +++ b/src/test/regress/expected/alter_distributed_table.out @@ -848,6 +848,7 @@ SELECT create_distributed_table('abcde_01234567890123456789012345678901234567890 (1 row) SELECT alter_distributed_table('abcde_0123456789012345678901234567890123456789012345678901234567890123456789', distribution_column := 'y'); +DEBUG: the name of the shard (abcde_01234567890123456789012345678901234567890_f7ff6612_xxxxxx) for relation (abcde_012345678901234567890123456789012345678901234567890123456) is too long, switching to sequential and local execution mode to prevent self deadlocks NOTICE: creating a new table for alter_distributed_table.abcde_012345678901234567890123456789012345678901234567890123456 NOTICE: Moving the data of alter_distributed_table.abcde_012345678901234567890123456789012345678901234567890123456 DEBUG: cannot perform distributed INSERT INTO ... SELECT because the partition columns in the source table and subquery do not match @@ -858,9 +859,13 @@ CONTEXT: SQL statement "INSERT INTO alter_distributed_table.abcde_0123456789012 NOTICE: Dropping the old alter_distributed_table.abcde_012345678901234567890123456789012345678901234567890123456 CONTEXT: SQL statement "DROP TABLE alter_distributed_table.abcde_012345678901234567890123456789012345678901234567890123456 CASCADE" NOTICE: Renaming the new table to alter_distributed_table.abcde_012345678901234567890123456789012345678901234567890123456 -ERROR: shard name abcde_01234567890123456789012345678901234567890_f7ff6612_361345 exceeds 63 characters -CONTEXT: while executing command on localhost:xxxxx -SQL statement "ALTER TABLE alter_distributed_table.abcde_0123456789012345678901234567890123456_f7ff6612_4160710162 RENAME TO abcde_012345678901234567890123456789012345678901234567890123456" +DEBUG: the name of the shard (abcde_01234567890123456789012345678901234567890_f7ff6612_xxxxxx) for relation (abcde_012345678901234567890123456789012345678901234567890123456) is too long, switching to sequential and local execution mode to prevent self deadlocks +CONTEXT: SQL statement "ALTER TABLE alter_distributed_table.abcde_0123456789012345678901234567890123456_f7ff6612_4160710162 RENAME TO abcde_012345678901234567890123456789012345678901234567890123456" + alter_distributed_table +--------------------------------------------------------------------- + +(1 row) + RESET client_min_messages; -- test long partitioned table names CREATE TABLE partition_lengths @@ -884,18 +889,33 @@ NOTICE: creating a new table for alter_distributed_table.partition_lengths_p202 NOTICE: Moving the data of alter_distributed_table.partition_lengths_p2020_09_28_123456789012345678901234567890123 NOTICE: Dropping the old alter_distributed_table.partition_lengths_p2020_09_28_123456789012345678901234567890123 NOTICE: Renaming the new table to alter_distributed_table.partition_lengths_p2020_09_28_123456789012345678901234567890123 -ERROR: shard name partition_lengths_p2020_09_28_12345678901234567_6d0d7fee_361356 exceeds 63 characters -CONTEXT: while executing command on localhost:xxxxx -SQL statement "ALTER TABLE alter_distributed_table.partition_lengths_p2020_09_28_1234567890123_6d0d7fee_1829601262 RENAME TO partition_lengths_p2020_09_28_123456789012345678901234567890123" +NOTICE: creating a new table for alter_distributed_table.partition_lengths +NOTICE: Dropping the old alter_distributed_table.partition_lengths +NOTICE: Renaming the new table to alter_distributed_table.partition_lengths + alter_distributed_table +--------------------------------------------------------------------- + +(1 row) + -- test long partition table names ALTER TABLE partition_lengths_p2020_09_28_12345678901234567890123456789012345678901234567890 RENAME TO partition_lengths_p2020_09_28; NOTICE: identifier "partition_lengths_p2020_09_28_12345678901234567890123456789012345678901234567890" will be truncated to "partition_lengths_p2020_09_28_123456789012345678901234567890123" ALTER TABLE partition_lengths RENAME TO partition_lengths_12345678901234567890123456789012345678901234567890; NOTICE: identifier "partition_lengths_12345678901234567890123456789012345678901234567890" will be truncated to "partition_lengths_123456789012345678901234567890123456789012345" -ERROR: shard name partition_lengths_12345678901234567890123456789_f3bd8571_361348 exceeds 63 characters -CONTEXT: while executing command on localhost:xxxxx -- verify alter_distributed_table works with long partitioned table names SELECT alter_distributed_table('partition_lengths_12345678901234567890123456789012345678901234567890', shard_count := 17, cascade_to_colocated := false); -ERROR: relation "partition_lengths_123456789012345678901234567890123456789012345" does not exist +NOTICE: converting the partitions of alter_distributed_table.partition_lengths_123456789012345678901234567890123456789012345 +NOTICE: creating a new table for alter_distributed_table.partition_lengths_p2020_09_28 +NOTICE: Moving the data of alter_distributed_table.partition_lengths_p2020_09_28 +NOTICE: Dropping the old alter_distributed_table.partition_lengths_p2020_09_28 +NOTICE: Renaming the new table to alter_distributed_table.partition_lengths_p2020_09_28 +NOTICE: creating a new table for alter_distributed_table.partition_lengths_123456789012345678901234567890123456789012345 +NOTICE: Dropping the old alter_distributed_table.partition_lengths_123456789012345678901234567890123456789012345 +NOTICE: Renaming the new table to alter_distributed_table.partition_lengths_123456789012345678901234567890123456789012345 + alter_distributed_table +--------------------------------------------------------------------- + +(1 row) + SET client_min_messages TO WARNING; DROP SCHEMA alter_distributed_table CASCADE; diff --git a/src/test/regress/expected/alter_distributed_table_0.out b/src/test/regress/expected/alter_distributed_table_0.out index 2b0a2c503..2eea9fdee 100644 --- a/src/test/regress/expected/alter_distributed_table_0.out +++ b/src/test/regress/expected/alter_distributed_table_0.out @@ -827,6 +827,7 @@ SELECT create_distributed_table('abcde_01234567890123456789012345678901234567890 (1 row) SELECT alter_distributed_table('abcde_0123456789012345678901234567890123456789012345678901234567890123456789', distribution_column := 'y'); +DEBUG: the name of the shard (abcde_01234567890123456789012345678901234567890_f7ff6612_xxxxxx) for relation (abcde_012345678901234567890123456789012345678901234567890123456) is too long, switching to sequential and local execution mode to prevent self deadlocks NOTICE: creating a new table for alter_distributed_table.abcde_012345678901234567890123456789012345678901234567890123456 NOTICE: Moving the data of alter_distributed_table.abcde_012345678901234567890123456789012345678901234567890123456 DEBUG: cannot perform distributed INSERT INTO ... SELECT because the partition columns in the source table and subquery do not match @@ -837,9 +838,13 @@ CONTEXT: SQL statement "INSERT INTO alter_distributed_table.abcde_0123456789012 NOTICE: Dropping the old alter_distributed_table.abcde_012345678901234567890123456789012345678901234567890123456 CONTEXT: SQL statement "DROP TABLE alter_distributed_table.abcde_012345678901234567890123456789012345678901234567890123456 CASCADE" NOTICE: Renaming the new table to alter_distributed_table.abcde_012345678901234567890123456789012345678901234567890123456 -ERROR: shard name abcde_01234567890123456789012345678901234567890_f7ff6612_361221 exceeds 63 characters -CONTEXT: while executing command on localhost:xxxxx -SQL statement "ALTER TABLE alter_distributed_table.abcde_0123456789012345678901234567890123456_f7ff6612_4160710162 RENAME TO abcde_012345678901234567890123456789012345678901234567890123456" +DEBUG: the name of the shard (abcde_01234567890123456789012345678901234567890_f7ff6612_xxxxxx) for relation (abcde_012345678901234567890123456789012345678901234567890123456) is too long, switching to sequential and local execution mode to prevent self deadlocks +CONTEXT: SQL statement "ALTER TABLE alter_distributed_table.abcde_0123456789012345678901234567890123456_f7ff6612_4160710162 RENAME TO abcde_012345678901234567890123456789012345678901234567890123456" + alter_distributed_table +--------------------------------------------------------------------- + +(1 row) + RESET client_min_messages; -- test long partitioned table names CREATE TABLE partition_lengths @@ -863,18 +868,33 @@ NOTICE: creating a new table for alter_distributed_table.partition_lengths_p202 NOTICE: Moving the data of alter_distributed_table.partition_lengths_p2020_09_28_123456789012345678901234567890123 NOTICE: Dropping the old alter_distributed_table.partition_lengths_p2020_09_28_123456789012345678901234567890123 NOTICE: Renaming the new table to alter_distributed_table.partition_lengths_p2020_09_28_123456789012345678901234567890123 -ERROR: shard name partition_lengths_p2020_09_28_12345678901234567_6d0d7fee_361233 exceeds 63 characters -CONTEXT: while executing command on localhost:xxxxx -SQL statement "ALTER TABLE alter_distributed_table.partition_lengths_p2020_09_28_1234567890123_6d0d7fee_1829601262 RENAME TO partition_lengths_p2020_09_28_123456789012345678901234567890123" +NOTICE: creating a new table for alter_distributed_table.partition_lengths +NOTICE: Dropping the old alter_distributed_table.partition_lengths +NOTICE: Renaming the new table to alter_distributed_table.partition_lengths + alter_distributed_table +--------------------------------------------------------------------- + +(1 row) + -- test long partition table names ALTER TABLE partition_lengths_p2020_09_28_12345678901234567890123456789012345678901234567890 RENAME TO partition_lengths_p2020_09_28; NOTICE: identifier "partition_lengths_p2020_09_28_12345678901234567890123456789012345678901234567890" will be truncated to "partition_lengths_p2020_09_28_123456789012345678901234567890123" ALTER TABLE partition_lengths RENAME TO partition_lengths_12345678901234567890123456789012345678901234567890; NOTICE: identifier "partition_lengths_12345678901234567890123456789012345678901234567890" will be truncated to "partition_lengths_123456789012345678901234567890123456789012345" -ERROR: shard name partition_lengths_12345678901234567890123456789_f3bd8571_361225 exceeds 63 characters -CONTEXT: while executing command on localhost:xxxxx -- verify alter_distributed_table works with long partitioned table names SELECT alter_distributed_table('partition_lengths_12345678901234567890123456789012345678901234567890', shard_count := 17, cascade_to_colocated := false); -ERROR: relation "partition_lengths_123456789012345678901234567890123456789012345" does not exist +NOTICE: converting the partitions of alter_distributed_table.partition_lengths_123456789012345678901234567890123456789012345 +NOTICE: creating a new table for alter_distributed_table.partition_lengths_p2020_09_28 +NOTICE: Moving the data of alter_distributed_table.partition_lengths_p2020_09_28 +NOTICE: Dropping the old alter_distributed_table.partition_lengths_p2020_09_28 +NOTICE: Renaming the new table to alter_distributed_table.partition_lengths_p2020_09_28 +NOTICE: creating a new table for alter_distributed_table.partition_lengths_123456789012345678901234567890123456789012345 +NOTICE: Dropping the old alter_distributed_table.partition_lengths_123456789012345678901234567890123456789012345 +NOTICE: Renaming the new table to alter_distributed_table.partition_lengths_123456789012345678901234567890123456789012345 + alter_distributed_table +--------------------------------------------------------------------- + +(1 row) + SET client_min_messages TO WARNING; DROP SCHEMA alter_distributed_table CASCADE; diff --git a/src/test/regress/expected/alter_table_set_access_method.out b/src/test/regress/expected/alter_table_set_access_method.out index 6f97e7d90..f6539da64 100644 --- a/src/test/regress/expected/alter_table_set_access_method.out +++ b/src/test/regress/expected/alter_table_set_access_method.out @@ -692,6 +692,7 @@ SELECT create_distributed_table('abcde_01234567890123456789012345678901234567890 (1 row) SELECT alter_table_set_access_method('abcde_0123456789012345678901234567890123456789012345678901234567890123456789', 'columnar'); +DEBUG: the name of the shard (abcde_01234567890123456789012345678901234567890_f7ff6612_xxxxxx) for relation (abcde_012345678901234567890123456789012345678901234567890123456) is too long, switching to sequential and local execution mode to prevent self deadlocks NOTICE: creating a new table for alter_table_set_access_method.abcde_012345678901234567890123456789012345678901234567890123456 DEBUG: pathlist hook for columnar table am CONTEXT: SQL statement "SELECT EXISTS (SELECT 1 FROM alter_table_set_access_method.abcde_0123456789012345678901234567890123456_f7ff6612_4160710162)" @@ -699,11 +700,16 @@ NOTICE: Moving the data of alter_table_set_access_method.abcde_0123456789012345 NOTICE: Dropping the old alter_table_set_access_method.abcde_012345678901234567890123456789012345678901234567890123456 CONTEXT: SQL statement "DROP TABLE alter_table_set_access_method.abcde_012345678901234567890123456789012345678901234567890123456 CASCADE" NOTICE: Renaming the new table to alter_table_set_access_method.abcde_012345678901234567890123456789012345678901234567890123456 -ERROR: shard name abcde_01234567890123456789012345678901234567890_f7ff6612_360901 exceeds 63 characters -CONTEXT: while executing command on localhost:xxxxx -SQL statement "ALTER TABLE alter_table_set_access_method.abcde_0123456789012345678901234567890123456_f7ff6612_4160710162 RENAME TO abcde_012345678901234567890123456789012345678901234567890123456" +DEBUG: the name of the shard (abcde_01234567890123456789012345678901234567890_f7ff6612_xxxxxx) for relation (abcde_012345678901234567890123456789012345678901234567890123456) is too long, switching to sequential and local execution mode to prevent self deadlocks +CONTEXT: SQL statement "ALTER TABLE alter_table_set_access_method.abcde_0123456789012345678901234567890123456_f7ff6612_4160710162 RENAME TO abcde_012345678901234567890123456789012345678901234567890123456" + alter_table_set_access_method +--------------------------------------------------------------------- + +(1 row) + SELECT * FROM abcde_0123456789012345678901234567890123456789012345678901234567890123456789; NOTICE: identifier "abcde_0123456789012345678901234567890123456789012345678901234567890123456789" will be truncated to "abcde_012345678901234567890123456789012345678901234567890123456" +DEBUG: pathlist hook for columnar table am x | y --------------------------------------------------------------------- (0 rows) diff --git a/src/test/regress/expected/multi_generate_ddl_commands.out b/src/test/regress/expected/multi_generate_ddl_commands.out index 811ee6750..525df0138 100644 --- a/src/test/regress/expected/multi_generate_ddl_commands.out +++ b/src/test/regress/expected/multi_generate_ddl_commands.out @@ -9,7 +9,7 @@ CREATE TABLE simple_table ( id bigint ); SELECT master_get_table_ddl_events('simple_table'); - master_get_table_ddl_events + master_get_table_ddl_events --------------------------------------------------------------------- CREATE TABLE public.simple_table (first_name text, last_name text, id bigint) ALTER TABLE public.simple_table OWNER TO postgres @@ -21,7 +21,7 @@ CREATE TABLE not_null_table ( id bigint not null ); SELECT master_get_table_ddl_events('not_null_table'); - master_get_table_ddl_events + master_get_table_ddl_events --------------------------------------------------------------------- CREATE TABLE public.not_null_table (city text, id bigint NOT NULL) ALTER TABLE public.not_null_table OWNER TO postgres @@ -34,7 +34,7 @@ CREATE TABLE column_constraint_table ( age int CONSTRAINT non_negative_age CHECK (age >= 0) ); SELECT master_get_table_ddl_events('column_constraint_table'); - master_get_table_ddl_events + master_get_table_ddl_events --------------------------------------------------------------------- CREATE TABLE public.column_constraint_table (first_name text, last_name text, age integer, CONSTRAINT non_negative_age CHECK ((age >= 0))) ALTER TABLE public.column_constraint_table OWNER TO postgres @@ -48,7 +48,7 @@ CREATE TABLE table_constraint_table ( CONSTRAINT bids_ordered CHECK (min_bid > max_bid) ); SELECT master_get_table_ddl_events('table_constraint_table'); - master_get_table_ddl_events + master_get_table_ddl_events --------------------------------------------------------------------- CREATE TABLE public.table_constraint_table (bid_item_id bigint, min_bid numeric NOT NULL, max_bid numeric NOT NULL, CONSTRAINT bids_ordered CHECK ((min_bid > max_bid))) ALTER TABLE public.table_constraint_table OWNER TO postgres @@ -67,7 +67,7 @@ SELECT create_distributed_table('check_constraint_table_1', 'id'); (1 row) SELECT master_get_table_ddl_events('check_constraint_table_1'); - master_get_table_ddl_events + master_get_table_ddl_events --------------------------------------------------------------------- CREATE TABLE public.check_constraint_table_1 (id integer, b boolean, CONSTRAINT check_constraint_table_1_b_check CHECK (b)) ALTER TABLE public.check_constraint_table_1 OWNER TO postgres @@ -84,7 +84,7 @@ SELECT create_distributed_table('check_constraint_table_2', 'id'); (1 row) SELECT master_get_table_ddl_events('check_constraint_table_2'); - master_get_table_ddl_events + master_get_table_ddl_events --------------------------------------------------------------------- CREATE TABLE public.check_constraint_table_2 (id integer, CONSTRAINT check_constraint_table_2_check CHECK (true)) ALTER TABLE public.check_constraint_table_2 OWNER TO postgres @@ -96,7 +96,7 @@ CREATE TABLE default_value_table ( price decimal default 0.00 ); SELECT master_get_table_ddl_events('default_value_table'); - master_get_table_ddl_events + master_get_table_ddl_events --------------------------------------------------------------------- CREATE TABLE public.default_value_table (name text, price numeric DEFAULT 0.00) ALTER TABLE public.default_value_table OWNER TO postgres @@ -109,7 +109,7 @@ CREATE TABLE pkey_table ( id bigint PRIMARY KEY ); SELECT master_get_table_ddl_events('pkey_table'); - master_get_table_ddl_events + master_get_table_ddl_events --------------------------------------------------------------------- CREATE TABLE public.pkey_table (first_name text, last_name text, id bigint NOT NULL) ALTER TABLE public.pkey_table OWNER TO postgres @@ -122,7 +122,7 @@ CREATE TABLE unique_table ( username text UNIQUE not null ); SELECT master_get_table_ddl_events('unique_table'); - master_get_table_ddl_events + master_get_table_ddl_events --------------------------------------------------------------------- CREATE TABLE public.unique_table (user_id bigint NOT NULL, username text NOT NULL) ALTER TABLE public.unique_table OWNER TO postgres @@ -137,7 +137,7 @@ CREATE TABLE clustered_table ( CREATE INDEX clustered_time_idx ON clustered_table (received_at); CLUSTER clustered_table USING clustered_time_idx; SELECT master_get_table_ddl_events('clustered_table'); - master_get_table_ddl_events + master_get_table_ddl_events --------------------------------------------------------------------- CREATE TABLE public.clustered_table (data json NOT NULL, received_at timestamp without time zone NOT NULL) ALTER TABLE public.clustered_table OWNER TO postgres @@ -180,26 +180,33 @@ NOTICE: foreign-data wrapper "fake_fdw" does not have an extension defined ALTER FOREIGN TABLE foreign_table rename to renamed_foreign_table_with_long_name_12345678901234567890123456789012345678901234567890; NOTICE: identifier "renamed_foreign_table_with_long_name_12345678901234567890123456789012345678901234567890" will be truncated to "renamed_foreign_table_with_long_name_12345678901234567890123456" -ERROR: shard name renamed_foreign_table_with_long_name_1234567890_6a8dd6f8_610008 exceeds 63 characters -CONTEXT: while executing command on localhost:xxxxx ALTER FOREIGN TABLE renamed_foreign_table_with_long_name_12345678901234567890123456789012345678901234567890 rename full_name to rename_name; NOTICE: identifier "renamed_foreign_table_with_long_name_12345678901234567890123456789012345678901234567890" will be truncated to "renamed_foreign_table_with_long_name_12345678901234567890123456" -ERROR: relation "renamed_foreign_table_with_long_name_12345678901234567890123456" does not exist ALTER FOREIGN TABLE renamed_foreign_table_with_long_name_12345678901234567890123456789012345678901234567890 alter rename_name type char(8); NOTICE: identifier "renamed_foreign_table_with_long_name_12345678901234567890123456789012345678901234567890" will be truncated to "renamed_foreign_table_with_long_name_12345678901234567890123456" -ERROR: relation "renamed_foreign_table_with_long_name_12345678901234567890123456" does not exist \c - - :public_worker_1_host :worker_1_port select table_name, column_name, data_type from information_schema.columns where table_schema='public' and table_name like 'renamed_foreign_table_%' and column_name <> 'id' order by table_name; - table_name | column_name | data_type + table_name | column_name | data_type --------------------------------------------------------------------- -(0 rows) + renamed_foreign_table_with_long_name_1234567890_6a8dd6f8_610008 | rename_name | character + renamed_foreign_table_with_long_name_1234567890_6a8dd6f8_610009 | rename_name | character + renamed_foreign_table_with_long_name_1234567890_6a8dd6f8_610010 | rename_name | character + renamed_foreign_table_with_long_name_1234567890_6a8dd6f8_610011 | rename_name | character +(4 rows) \c - - :master_host :master_port SELECT master_get_table_ddl_events('renamed_foreign_table_with_long_name_12345678901234567890123456789012345678901234567890'); -ERROR: relation "renamed_foreign_table_with_long_name_12345678901234567890123456" does not exist +NOTICE: foreign-data wrapper "fake_fdw" does not have an extension defined + master_get_table_ddl_events +--------------------------------------------------------------------- + CREATE SERVER IF NOT EXISTS fake_fdw_server FOREIGN DATA WRAPPER fake_fdw + CREATE FOREIGN TABLE public.renamed_foreign_table_with_long_name_12345678901234567890123456 (id bigint NOT NULL, rename_name character(8) DEFAULT ''::text NOT NULL) SERVER fake_fdw_server OPTIONS (encoding 'utf-8', compression 'true') + ALTER TABLE public.renamed_foreign_table_with_long_name_12345678901234567890123456 OWNER TO postgres +(3 rows) + -- propagating views is not supported CREATE VIEW local_view AS SELECT * FROM simple_table; SELECT master_get_table_ddl_events('local_view'); @@ -208,7 +215,6 @@ ERROR: local_view is not a regular, foreign or partitioned table DROP VIEW IF EXISTS local_view; DROP FOREIGN TABLE IF EXISTS renamed_foreign_table_with_long_name_12345678901234567890123456789012345678901234567890; NOTICE: identifier "renamed_foreign_table_with_long_name_12345678901234567890123456789012345678901234567890" will be truncated to "renamed_foreign_table_with_long_name_12345678901234567890123456" -NOTICE: foreign table "renamed_foreign_table_with_long_name_12345678901234567890123456" does not exist, skipping \c - - :public_worker_1_host :worker_1_port select table_name, column_name, data_type from information_schema.columns diff --git a/src/test/regress/expected/multi_name_lengths.out b/src/test/regress/expected/multi_name_lengths.out index 5b6573b57..76c4e914c 100644 --- a/src/test/regress/expected/multi_name_lengths.out +++ b/src/test/regress/expected/multi_name_lengths.out @@ -129,13 +129,13 @@ SELECT "Constraint", "Definition" FROM table_checks WHERE relid='public.name_len SET client_min_messages TO DEBUG1; SET citus.force_max_query_parallelization TO ON; ALTER TABLE name_lengths RENAME TO name_len_12345678901234567890123456789012345678901234567890; -ERROR: shard name name_len_12345678901234567890123456789012345678_fcd8ab6f_xxxxx exceeds 63 characters -CONTEXT: while executing command on localhost:xxxxx +DEBUG: the name of the shard (name_len_12345678901234567890123456789012345678_fcd8ab6f_xxxxx) for relation (name_len_12345678901234567890123456789012345678901234567890) is too long, switching to sequential and local execution mode to prevent self deadlocks SELECT * FROM name_len_12345678901234567890123456789012345678901234567890; -DEBUG: relation "name_len_12345678901234567890123456789012345678901234567890" does not exist -ERROR: relation "name_len_12345678901234567890123456789012345678901234567890" does not exist + col1 | col2 | float_col_12345678901234567890123456789012345678901234567890 | date_col_12345678901234567890123456789012345678901234567890 | int_col_12345678901234567890123456789012345678901234567890 +--------------------------------------------------------------------- +(0 rows) + ALTER TABLE name_len_12345678901234567890123456789012345678901234567890 RENAME TO name_lengths; -ERROR: relation "name_len_12345678901234567890123456789012345678901234567890" does not exist SELECT * FROM name_lengths; col1 | col2 | float_col_12345678901234567890123456789012345678901234567890 | date_col_12345678901234567890123456789012345678901234567890 | int_col_12345678901234567890123456789012345678901234567890 --------------------------------------------------------------------- @@ -155,16 +155,15 @@ NOTICE: identifier "append_zero_shard_table_12345678901234567890123456789012345 BEGIN; ALTER TABLE name_lengths rename col1 to new_column_name; ALTER TABLE name_lengths RENAME TO name_len_12345678901234567890123456789012345678901234567890; -ERROR: shard name name_len_12345678901234567890123456789012345678_fcd8ab6f_xxxxx exceeds 63 characters -CONTEXT: while executing command on localhost:xxxxx +ERROR: Shard name (name_len_12345678901234567890123456789012345678_fcd8ab6f_xxxxx) for table (name_len_12345678901234567890123456789012345678901234567890) is too long and could lead to deadlocks when executed in a transaction block after a parallel query +HINT: Try re-running the transaction with "SET LOCAL citus.multi_shard_modify_mode TO 'sequential';" ROLLBACK; -- The same operation will work when sequential mode is set BEGIN; SET LOCAL citus.multi_shard_modify_mode TO 'sequential'; ALTER TABLE name_lengths rename col1 to new_column_name; ALTER TABLE name_lengths RENAME TO name_len_12345678901234567890123456789012345678901234567890; -ERROR: shard name name_len_12345678901234567890123456789012345678_fcd8ab6f_xxxxx exceeds 63 characters -CONTEXT: while executing command on localhost:xxxxx +DEBUG: the name of the shard (name_len_12345678901234567890123456789012345678_fcd8ab6f_xxxxx) for relation (name_len_12345678901234567890123456789012345678901234567890) is too long, switching to sequential and local execution mode to prevent self deadlocks ROLLBACK; RESET client_min_messages; -- test long partitioned table renames @@ -184,28 +183,23 @@ CREATE TABLE partition_lengths_p2020_09_28 PARTITION OF partition_lengths FOR VA -- verify that we can rename partitioned tables and partitions to too-long names ALTER TABLE partition_lengths RENAME TO partition_lengths_12345678901234567890123456789012345678901234567890; NOTICE: identifier "partition_lengths_12345678901234567890123456789012345678901234567890" will be truncated to "partition_lengths_123456789012345678901234567890123456789012345" -ERROR: shard name partition_lengths_12345678901234567890123456789_f3bd8571_225005 exceeds 63 characters -CONTEXT: while executing command on localhost:xxxxx -- verify that we can rename partitioned tables and partitions with too-long names ALTER TABLE partition_lengths_12345678901234567890123456789012345678901234567890 RENAME TO partition_lengths; NOTICE: identifier "partition_lengths_12345678901234567890123456789012345678901234567890" will be truncated to "partition_lengths_123456789012345678901234567890123456789012345" -ERROR: relation "partition_lengths_123456789012345678901234567890123456789012345" does not exist -- Placeholders for unsupported operations \set VERBOSITY TERSE -- renaming distributed table partitions ALTER TABLE partition_lengths_p2020_09_28 RENAME TO partition_lengths_p2020_09_28_12345678901234567890123456789012345678901234567890; NOTICE: identifier "partition_lengths_p2020_09_28_12345678901234567890123456789012345678901234567890" will be truncated to "partition_lengths_p2020_09_28_123456789012345678901234567890123" -ERROR: shard name partition_lengths_p2020_09_28_12345678901234567_6d0d7fee_225008 exceeds 63 characters -- creating or attaching new partitions with long names create deadlocks CREATE TABLE partition_lengths_p2020_09_29_12345678901234567890123456789012345678901234567890 (LIKE partition_lengths_p2020_09_28_12345678901234567890123456789012345678901234567890); NOTICE: identifier "partition_lengths_p2020_09_29_12345678901234567890123456789012345678901234567890" will be truncated to "partition_lengths_p2020_09_29_123456789012345678901234567890123" NOTICE: identifier "partition_lengths_p2020_09_28_12345678901234567890123456789012345678901234567890" will be truncated to "partition_lengths_p2020_09_28_123456789012345678901234567890123" -ERROR: relation "partition_lengths_p2020_09_28_123456789012345678901234567890123" does not exist at character 101 ALTER TABLE partition_lengths ATTACH PARTITION partition_lengths_p2020_09_29_12345678901234567890123456789012345678901234567890 FOR VALUES FROM ('2020-09-29 00:00:00') TO ('2020-09-30 00:00:00'); NOTICE: identifier "partition_lengths_p2020_09_29_12345678901234567890123456789012345678901234567890" will be truncated to "partition_lengths_p2020_09_29_123456789012345678901234567890123" -ERROR: relation "partition_lengths_p2020_09_29_123456789012345678901234567890123" does not exist +ERROR: canceling the transaction since it was involved in a distributed deadlock CREATE TABLE partition_lengths_p2020_09_30_12345678901234567890123456789012345678901234567890 PARTITION OF partition_lengths FOR VALUES FROM ('2020-09-30 00:00:00') TO ('2020-10-01 00:00:00'); @@ -213,24 +207,20 @@ NOTICE: identifier "partition_lengths_p2020_09_30_12345678901234567890123456789 ERROR: canceling the transaction since it was involved in a distributed deadlock DROP TABLE partition_lengths_p2020_09_29_12345678901234567890123456789012345678901234567890; NOTICE: identifier "partition_lengths_p2020_09_29_12345678901234567890123456789012345678901234567890" will be truncated to "partition_lengths_p2020_09_29_123456789012345678901234567890123" -ERROR: table "partition_lengths_p2020_09_29_123456789012345678901234567890123" does not exist -- creating or attaching new partitions with long names work when using sequential shard modify mode BEGIN; SET LOCAL citus.multi_shard_modify_mode = sequential; CREATE TABLE partition_lengths_p2020_09_29_12345678901234567890123456789012345678901234567890 (LIKE partition_lengths_p2020_09_28_12345678901234567890123456789012345678901234567890); NOTICE: identifier "partition_lengths_p2020_09_29_12345678901234567890123456789012345678901234567890" will be truncated to "partition_lengths_p2020_09_29_123456789012345678901234567890123" NOTICE: identifier "partition_lengths_p2020_09_28_12345678901234567890123456789012345678901234567890" will be truncated to "partition_lengths_p2020_09_28_123456789012345678901234567890123" -ERROR: relation "partition_lengths_p2020_09_28_123456789012345678901234567890123" does not exist at character 101 ALTER TABLE partition_lengths ATTACH PARTITION partition_lengths_p2020_09_29_12345678901234567890123456789012345678901234567890 FOR VALUES FROM ('2020-09-29 00:00:00') TO ('2020-09-30 00:00:00'); NOTICE: identifier "partition_lengths_p2020_09_29_12345678901234567890123456789012345678901234567890" will be truncated to "partition_lengths_p2020_09_29_123456789012345678901234567890123" -ERROR: current transaction is aborted, commands ignored until end of transaction block CREATE TABLE partition_lengths_p2020_09_30_12345678901234567890123456789012345678901234567890 PARTITION OF partition_lengths FOR VALUES FROM ('2020-09-30 00:00:00') TO ('2020-10-01 00:00:00'); NOTICE: identifier "partition_lengths_p2020_09_30_12345678901234567890123456789012345678901234567890" will be truncated to "partition_lengths_p2020_09_30_123456789012345678901234567890123" -ERROR: current transaction is aborted, commands ignored until end of transaction block ROLLBACK; -- renaming distributed table constraints are not supported ALTER TABLE name_lengths RENAME CONSTRAINT unique_12345678901234567890123456789012345678901234567890 TO unique2_12345678901234567890123456789012345678901234567890; @@ -261,17 +251,15 @@ NOTICE: identifier "tmp_idx_123456789012345678901234567890123456789012345678901 ALTER INDEX tmp_idx_123456789012345678901234567890123456789012345678901234567890 RENAME TO tmp_idx_newname_123456789012345678901234567890123456789012345678901234567890; NOTICE: identifier "tmp_idx_123456789012345678901234567890123456789012345678901234567890" will be truncated to "tmp_idx_1234567890123456789012345678901234567890123456789012345" NOTICE: identifier "tmp_idx_newname_123456789012345678901234567890123456789012345678901234567890" will be truncated to "tmp_idx_newname_12345678901234567890123456789012345678901234567" -ERROR: shard name tmp_idx_newname_1234567890123456789012345678901_c54e849b_225002 exceeds 63 characters -CONTEXT: while executing command on localhost:xxxxx \c - - :public_worker_1_host :worker_1_port SELECT "relname", "Column", "Type", "Definition" FROM index_attrs WHERE relname LIKE 'tmp_idx_%' ORDER BY 1 DESC, 2 DESC, 3 DESC, 4 DESC; relname | Column | Type | Definition --------------------------------------------------------------------- + tmp_idx_newname_1234567890123456789012345678901_c54e849b_225003 | col2 | integer | col2 + tmp_idx_newname_1234567890123456789012345678901_c54e849b_225002 | col2 | integer | col2 tmp_idx_123456789012345678901234567890123456789_5e470afa_225003 | col2 | integer | col2 tmp_idx_123456789012345678901234567890123456789_5e470afa_225002 | col2 | integer | col2 - tmp_idx_123456789012345678901234567890123456789_599636aa_225003 | col2 | integer | col2 - tmp_idx_123456789012345678901234567890123456789_599636aa_225002 | col2 | integer | col2 (4 rows) \c - - :master_host :master_port @@ -324,13 +312,18 @@ SELECT master_create_worker_shards('sneaky_name_lengths', '2', '2'); \c - - :public_worker_1_host :worker_1_port \di public.sneaky*225030 - List of relations - Schema | Name | Type | Owner | Table + List of relations + Schema | Name | Type | Owner | Table --------------------------------------------------------------------- -(0 rows) + public | sneaky_name_lengths_int_col_1234567890123456789_6402d2cd_225030 | index | postgres | sneaky_name_lengths_225030 +(1 row) SELECT "Constraint", "Definition" FROM table_checks WHERE relid='public.sneaky_name_lengths_225030'::regclass ORDER BY 1 DESC, 2 DESC; -ERROR: relation "public.sneaky_name_lengths_225030" does not exist + Constraint | Definition +--------------------------------------------------------------------- + checky_12345678901234567890123456789012345678901234567890 | CHECK (int_col_123456789012345678901234567890123456789012345678901234 > 100) +(1 row) + \c - - :master_host :master_port SET citus.shard_count TO 2; SET citus.shard_replication_factor TO 2; @@ -350,10 +343,11 @@ SELECT create_distributed_table('sneaky_name_lengths', 'col1', 'hash'); \c - - :public_worker_1_host :worker_1_port \di unique*225032 - List of relations - Schema | Name | Type | Owner | Table + List of relations + Schema | Name | Type | Owner | Table --------------------------------------------------------------------- -(0 rows) + public | unique_1234567890123456789012345678901234567890_a5986f27_225032 | index | postgres | sneaky_name_lengths_225032 +(1 row) \c - - :master_host :master_port SET citus.shard_count TO 2;