Fix index renaming when creating citus local tables

pull/4574/head
Ahmet Gedemenli 2021-01-25 21:25:31 +03:00
parent 7952100f49
commit e99f052904
3 changed files with 43 additions and 28 deletions

View File

@ -52,7 +52,7 @@ static char * GetRenameShardConstraintCommand(Oid relationId, char *constraintNa
static void RenameShardRelationIndexes(Oid shardRelationId, uint64 shardId); static void RenameShardRelationIndexes(Oid shardRelationId, uint64 shardId);
static void RenameShardRelationStatistics(Oid shardRelationId, uint64 shardId); static void RenameShardRelationStatistics(Oid shardRelationId, uint64 shardId);
static char * GetDropTriggerCommand(Oid relationId, char *triggerName); static char * GetDropTriggerCommand(Oid relationId, char *triggerName);
static char * GetRenameShardIndexCommand(char *indexName, uint64 shardId); static char * GetRenameShardIndexCommand(Oid indexOid, uint64 shardId);
static char * GetRenameShardStatsCommand(char *statSchema, char *statsName, static char * GetRenameShardStatsCommand(char *statSchema, char *statsName,
char *statsNameWithShardId); char *statsNameWithShardId);
static void RenameShardRelationNonTruncateTriggers(Oid shardRelationId, uint64 shardId); static void RenameShardRelationNonTruncateTriggers(Oid shardRelationId, uint64 shardId);
@ -60,7 +60,7 @@ static char * GetRenameShardTriggerCommand(Oid shardRelationId, char *triggerNam
uint64 shardId); uint64 shardId);
static void DropRelationTruncateTriggers(Oid relationId); static void DropRelationTruncateTriggers(Oid relationId);
static char * GetDropTriggerCommand(Oid relationId, char *triggerName); static char * GetDropTriggerCommand(Oid relationId, char *triggerName);
static List * GetExplicitIndexNameList(Oid relationId); static List * GetExplicitIndexOidList(Oid relationId);
static List * GetRenameStatsCommandList(List *statsOidList, uint64 shardId); static List * GetRenameStatsCommandList(List *statsOidList, uint64 shardId);
static void DropAndMoveDefaultSequenceOwnerships(Oid sourceRelationId, static void DropAndMoveDefaultSequenceOwnerships(Oid sourceRelationId,
Oid targetRelationId); Oid targetRelationId);
@ -539,18 +539,18 @@ GetRenameShardConstraintCommand(Oid relationId, char *constraintName, uint64 sha
* RenameShardRelationIndexes appends given shardId to the end of the names * RenameShardRelationIndexes appends given shardId to the end of the names
* of shard relation indexes except the ones that are already renamed via * of shard relation indexes except the ones that are already renamed via
* RenameShardRelationConstraints. This function utilizes * RenameShardRelationConstraints. This function utilizes
* GetExplicitIndexNameList to pick the indexes to be renamed, see more * GetExplicitIndexOidList to pick the indexes to be renamed, see more
* details in function's comment. * details in function's comment.
*/ */
static void static void
RenameShardRelationIndexes(Oid shardRelationId, uint64 shardId) RenameShardRelationIndexes(Oid shardRelationId, uint64 shardId)
{ {
List *indexNameList = GetExplicitIndexNameList(shardRelationId); List *indexOidList = GetExplicitIndexOidList(shardRelationId);
char *indexName = NULL; Oid indexOid = InvalidOid;
foreach_ptr(indexName, indexNameList) foreach_oid(indexOid, indexOidList)
{ {
const char *commandString = GetRenameShardIndexCommand(indexName, shardId); const char *commandString = GetRenameShardIndexCommand(indexOid, shardId);
ExecuteAndLogDDLCommand(commandString); ExecuteAndLogDDLCommand(commandString);
} }
} }
@ -561,13 +561,14 @@ RenameShardRelationIndexes(Oid shardRelationId, uint64 shardId)
* the index with indexName. * the index with indexName.
*/ */
static char * static char *
GetRenameShardIndexCommand(char *indexName, uint64 shardId) GetRenameShardIndexCommand(Oid indexOid, uint64 shardId)
{ {
char *indexName = get_rel_name(indexOid);
char *shardIndexName = pstrdup(indexName); char *shardIndexName = pstrdup(indexName);
AppendShardIdToName(&shardIndexName, shardId); AppendShardIdToName(&shardIndexName, shardId);
const char *quotedShardIndexName = quote_identifier(shardIndexName); const char *quotedShardIndexName = quote_identifier(shardIndexName);
const char *quotedIndexName = quote_identifier(indexName); const char *quotedIndexName = generate_qualified_relation_name(indexOid);
StringInfo renameCommand = makeStringInfo(); StringInfo renameCommand = makeStringInfo();
appendStringInfo(renameCommand, "ALTER INDEX %s RENAME TO %s;", appendStringInfo(renameCommand, "ALTER INDEX %s RENAME TO %s;",
@ -724,7 +725,7 @@ GetDropTriggerCommand(Oid relationId, char *triggerName)
/* /*
* GetExplicitIndexNameList returns a list of index names defined "explicitly" * GetExplicitIndexOidList returns a list of index oids defined "explicitly"
* on the relation with relationId by the "CREATE INDEX" commands. That means, * on the relation with relationId by the "CREATE INDEX" commands. That means,
* all the constraints defined on the relation except: * all the constraints defined on the relation except:
* - primary indexes, * - primary indexes,
@ -733,7 +734,7 @@ GetDropTriggerCommand(Oid relationId, char *triggerName)
* that are actually applied by the related constraints. * that are actually applied by the related constraints.
*/ */
static List * static List *
GetExplicitIndexNameList(Oid relationId) GetExplicitIndexOidList(Oid relationId)
{ {
int scanKeyCount = 1; int scanKeyCount = 1;
ScanKeyData scanKey[1]; ScanKeyData scanKey[1];
@ -750,7 +751,7 @@ GetExplicitIndexNameList(Oid relationId)
useIndex, NULL, scanKeyCount, useIndex, NULL, scanKeyCount,
scanKey); scanKey);
List *indexNameList = NIL; List *indexOidList = NIL;
HeapTuple heapTuple = systable_getnext(scanDescriptor); HeapTuple heapTuple = systable_getnext(scanDescriptor);
while (HeapTupleIsValid(heapTuple)) while (HeapTupleIsValid(heapTuple))
@ -767,9 +768,7 @@ GetExplicitIndexNameList(Oid relationId)
*/ */
if (!indexImpliedByConstraint) if (!indexImpliedByConstraint)
{ {
char *indexName = get_rel_name(indexId); indexOidList = lappend_oid(indexOidList, indexId);
indexNameList = lappend(indexNameList, pstrdup(indexName));
} }
heapTuple = systable_getnext(scanDescriptor); heapTuple = systable_getnext(scanDescriptor);
@ -781,7 +780,7 @@ GetExplicitIndexNameList(Oid relationId)
/* revert back to original search_path */ /* revert back to original search_path */
PopOverrideSearchPath(); PopOverrideSearchPath();
return indexNameList; return indexOidList;
} }

View File

@ -535,6 +535,18 @@ ORDER BY 1;
unique_a_b_1504027 | citus_local_table_1_1504027 | 1 2 unique_a_b_1504027 | citus_local_table_1_1504027 | 1 2
(2 rows) (2 rows)
-- test creating citus local table with an index from non-default schema
CREATE SCHEMA "test_\'index_schema";
CREATE TABLE "test_\'index_schema".testindex (a int, b int);
CREATE INDEX ind ON "test_\'index_schema".testindex (a);
ALTER TABLE "test_\'index_schema".testindex ADD CONSTRAINT fkey_to_dummy_ref FOREIGN KEY (a) REFERENCES dummy_reference_table(a);
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (1504040, E'test_\\''index_schema', 1504037, 'citus_local_tables_test_schema', E'ALTER TABLE "test_\\''index_schema".testindex ADD CONSTRAINT fkey_to_dummy_ref FOREIGN KEY (a) REFERENCES dummy_reference_table(a);')
SELECT COUNT(*)=2 FROM pg_indexes WHERE tablename LIKE 'testindex%' AND indexname LIKE 'ind%';
?column?
---------------------------------------------------------------------
t
(1 row)
-- execute truncate & drop commands for multiple relations to see that we don't break local execution -- execute truncate & drop commands for multiple relations to see that we don't break local execution
TRUNCATE citus_local_table_1, citus_local_table_2, distributed_table, local_table, reference_table, local_table_4; TRUNCATE citus_local_table_1, citus_local_table_2, distributed_table, local_table, reference_table, local_table_4;
NOTICE: executing the command locally: TRUNCATE TABLE citus_local_tables_test_schema.citus_local_table_1_xxxxx CASCADE NOTICE: executing the command locally: TRUNCATE TABLE citus_local_tables_test_schema.citus_local_table_1_xxxxx CASCADE
@ -741,15 +753,12 @@ CREATE STATISTICS stx1 ON a, b FROM test_citus_local_table_with_stats;
ALTER TABLE test_citus_local_table_with_stats ADD CONSTRAINT fkey_to_dummy_ref FOREIGN KEY (a) REFERENCES dummy_reference_table(a); ALTER TABLE test_citus_local_table_with_stats ADD CONSTRAINT fkey_to_dummy_ref FOREIGN KEY (a) REFERENCES dummy_reference_table(a);
NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (xxxxx, 'citus_local_tables_test_schema', xxxxx, 'citus_local_tables_test_schema', 'ALTER TABLE test_citus_local_table_with_stats ADD CONSTRAINT fkey_to_dummy_ref FOREIGN KEY (a) REFERENCES dummy_reference_table(a);') NOTICE: executing the command locally: SELECT worker_apply_inter_shard_ddl_command (xxxxx, 'citus_local_tables_test_schema', xxxxx, 'citus_local_tables_test_schema', 'ALTER TABLE test_citus_local_table_with_stats ADD CONSTRAINT fkey_to_dummy_ref FOREIGN KEY (a) REFERENCES dummy_reference_table(a);')
CREATE STATISTICS "CiTUS!LocalTables"."Bad\'StatName" ON a, b FROM test_citus_local_table_with_stats; CREATE STATISTICS "CiTUS!LocalTables"."Bad\'StatName" ON a, b FROM test_citus_local_table_with_stats;
NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1504043, 'citus_local_tables_test_schema', E'CREATE STATISTICS "CiTUS!LocalTables"."Bad\\''StatName" ON a, b FROM citus_local_tables_test_schema.test_citus_local_table_with_stats') NOTICE: executing the command locally: SELECT worker_apply_shard_ddl_command (1504044, 'citus_local_tables_test_schema', E'CREATE STATISTICS "CiTUS!LocalTables"."Bad\\''StatName" ON a, b FROM citus_local_tables_test_schema.test_citus_local_table_with_stats')
SELECT stxname FROM pg_statistic_ext ORDER BY stxname; SELECT COUNT(*)=4 FROM pg_statistic_ext WHERE stxname LIKE 'stx1%' or stxname LIKE 'Bad\\''StatName%' ;
stxname ?column?
--------------------------------------------------------------------- ---------------------------------------------------------------------
Bad\'StatName t
Bad\'StatName_1504043 (1 row)
stx1
stx1_1504043
(4 rows)
-- observe the debug messages telling that we switch to sequential -- observe the debug messages telling that we switch to sequential
-- execution when truncating a citus local table that is referenced -- execution when truncating a citus local table that is referenced
@ -766,5 +775,5 @@ NOTICE: executing the command locally: TRUNCATE TABLE citus_local_tables_test_s
RESET client_min_messages; RESET client_min_messages;
\set VERBOSITY terse \set VERBOSITY terse
-- cleanup at exit -- cleanup at exit
DROP SCHEMA citus_local_tables_test_schema, "CiTUS!LocalTables" CASCADE; DROP SCHEMA citus_local_tables_test_schema, "CiTUS!LocalTables", "test_\'index_schema" CASCADE;
NOTICE: drop cascades to 24 other objects NOTICE: drop cascades to 26 other objects

View File

@ -388,6 +388,13 @@ FROM pg_index
WHERE indrelid::regclass::text LIKE 'citus_local_table_1%' AND indexrelid::regclass::text LIKE 'unique_a_b%' WHERE indrelid::regclass::text LIKE 'citus_local_table_1%' AND indexrelid::regclass::text LIKE 'unique_a_b%'
ORDER BY 1; ORDER BY 1;
-- test creating citus local table with an index from non-default schema
CREATE SCHEMA "test_\'index_schema";
CREATE TABLE "test_\'index_schema".testindex (a int, b int);
CREATE INDEX ind ON "test_\'index_schema".testindex (a);
ALTER TABLE "test_\'index_schema".testindex ADD CONSTRAINT fkey_to_dummy_ref FOREIGN KEY (a) REFERENCES dummy_reference_table(a);
SELECT COUNT(*)=2 FROM pg_indexes WHERE tablename LIKE 'testindex%' AND indexname LIKE 'ind%';
-- execute truncate & drop commands for multiple relations to see that we don't break local execution -- execute truncate & drop commands for multiple relations to see that we don't break local execution
TRUNCATE citus_local_table_1, citus_local_table_2, distributed_table, local_table, reference_table, local_table_4; TRUNCATE citus_local_table_1, citus_local_table_2, distributed_table, local_table, reference_table, local_table_4;
@ -489,7 +496,7 @@ CREATE TABLE test_citus_local_table_with_stats(a int, b int);
CREATE STATISTICS stx1 ON a, b FROM test_citus_local_table_with_stats; CREATE STATISTICS stx1 ON a, b FROM test_citus_local_table_with_stats;
ALTER TABLE test_citus_local_table_with_stats ADD CONSTRAINT fkey_to_dummy_ref FOREIGN KEY (a) REFERENCES dummy_reference_table(a); ALTER TABLE test_citus_local_table_with_stats ADD CONSTRAINT fkey_to_dummy_ref FOREIGN KEY (a) REFERENCES dummy_reference_table(a);
CREATE STATISTICS "CiTUS!LocalTables"."Bad\'StatName" ON a, b FROM test_citus_local_table_with_stats; CREATE STATISTICS "CiTUS!LocalTables"."Bad\'StatName" ON a, b FROM test_citus_local_table_with_stats;
SELECT stxname FROM pg_statistic_ext ORDER BY stxname; SELECT COUNT(*)=4 FROM pg_statistic_ext WHERE stxname LIKE 'stx1%' or stxname LIKE 'Bad\\''StatName%' ;
-- observe the debug messages telling that we switch to sequential -- observe the debug messages telling that we switch to sequential
-- execution when truncating a citus local table that is referenced -- execution when truncating a citus local table that is referenced
@ -503,4 +510,4 @@ RESET client_min_messages;
\set VERBOSITY terse \set VERBOSITY terse
-- cleanup at exit -- cleanup at exit
DROP SCHEMA citus_local_tables_test_schema, "CiTUS!LocalTables" CASCADE; DROP SCHEMA citus_local_tables_test_schema, "CiTUS!LocalTables", "test_\'index_schema" CASCADE;