Improve CONCURRENTLY-related error messages

Thought this looked slightly nicer than the default behavior.

Changed preventTransaction to concurrent to be clearer that this code
path presently affects CONCURRENTLY code only.
pull/1287/head
Jason Petersen 2017-03-30 01:13:39 -06:00
parent dd9365433e
commit cf775c4773
No known key found for this signature in database
GPG Key ID: 9F1D3510D110ABA9
3 changed files with 42 additions and 27 deletions

View File

@ -684,7 +684,7 @@ PlanIndexStmt(IndexStmt *createIndexStatement, const char *createIndexCommand)
{ {
DDLJob *ddlJob = palloc0(sizeof(DDLJob)); DDLJob *ddlJob = palloc0(sizeof(DDLJob));
ddlJob->targetRelationId = relationId; ddlJob->targetRelationId = relationId;
ddlJob->preventTransaction = createIndexStatement->concurrent; ddlJob->concurrent = createIndexStatement->concurrent;
ddlJob->commandString = createIndexCommand; ddlJob->commandString = createIndexCommand;
ddlJob->taskList = IndexTaskList(relationId, createIndexStatement); ddlJob->taskList = IndexTaskList(relationId, createIndexStatement);
@ -778,7 +778,7 @@ PlanDropIndexStmt(DropStmt *dropIndexStatement, const char *dropIndexCommand)
ErrorIfUnsupportedDropIndexStmt(dropIndexStatement); ErrorIfUnsupportedDropIndexStmt(dropIndexStatement);
ddlJob->targetRelationId = distributedRelationId; ddlJob->targetRelationId = distributedRelationId;
ddlJob->preventTransaction = dropIndexStatement->concurrent; ddlJob->concurrent = dropIndexStatement->concurrent;
ddlJob->commandString = dropIndexCommand; ddlJob->commandString = dropIndexCommand;
ddlJob->taskList = DropIndexTaskList(distributedRelationId, distributedIndexId, ddlJob->taskList = DropIndexTaskList(distributedRelationId, distributedIndexId,
dropIndexStatement); dropIndexStatement);
@ -873,7 +873,7 @@ PlanAlterTableStmt(AlterTableStmt *alterTableStatement, const char *alterTableCo
ddlJob = palloc0(sizeof(DDLJob)); ddlJob = palloc0(sizeof(DDLJob));
ddlJob->targetRelationId = leftRelationId; ddlJob->targetRelationId = leftRelationId;
ddlJob->preventTransaction = false; ddlJob->concurrent = false;
ddlJob->commandString = alterTableCommand; ddlJob->commandString = alterTableCommand;
if (rightRelationId) if (rightRelationId)
@ -1987,24 +1987,7 @@ ExecuteDistributedDDLJob(DDLJob *ddlJob)
EnsureCoordinator(); EnsureCoordinator();
if (ddlJob->preventTransaction) if (!ddlJob->concurrent)
{
/* save old commit protocol to restore at xact end */
Assert(SavedMultiShardCommitProtocol == COMMIT_PROTOCOL_BARE);
SavedMultiShardCommitProtocol = MultiShardCommitProtocol;
MultiShardCommitProtocol = COMMIT_PROTOCOL_BARE;
if (shouldSyncMetadata)
{
List *commandList = list_make2(DISABLE_DDL_PROPAGATION,
(char *) ddlJob->commandString);
SendBareCommandListToWorkers(WORKERS_WITH_METADATA, commandList);
}
ExecuteSequentialTasksWithoutResults(ddlJob->taskList);
}
else
{ {
ShowNoticeIfNotUsing2PC(); ShowNoticeIfNotUsing2PC();
@ -2016,6 +1999,36 @@ ExecuteDistributedDDLJob(DDLJob *ddlJob)
ExecuteModifyTasksWithoutResults(ddlJob->taskList); ExecuteModifyTasksWithoutResults(ddlJob->taskList);
} }
else
{
/* save old commit protocol to restore at xact end */
Assert(SavedMultiShardCommitProtocol == COMMIT_PROTOCOL_BARE);
SavedMultiShardCommitProtocol = MultiShardCommitProtocol;
MultiShardCommitProtocol = COMMIT_PROTOCOL_BARE;
PG_TRY();
{
if (shouldSyncMetadata)
{
List *commandList = list_make2(DISABLE_DDL_PROPAGATION,
(char *) ddlJob->commandString);
SendBareCommandListToWorkers(WORKERS_WITH_METADATA, commandList);
}
ExecuteSequentialTasksWithoutResults(ddlJob->taskList);
}
PG_CATCH();
{
ereport(ERROR,
(errmsg("CONCURRENTLY-enabled index command failed"),
errdetail("CONCURRENTLY-enabled index commands can fail partially, "
"leaving behind an INVALID index."),
errhint("Use DROP INDEX IF EXISTS to remove the invalid index, then "
"retry the original command.")));
}
PG_END_TRY();
}
} }
@ -2701,7 +2714,7 @@ PlanGrantStmt(GrantStmt *grantStmt)
ddlJob = palloc0(sizeof(DDLJob)); ddlJob = palloc0(sizeof(DDLJob));
ddlJob->targetRelationId = relOid; ddlJob->targetRelationId = relOid;
ddlJob->preventTransaction = false; ddlJob->concurrent = false;
ddlJob->commandString = pstrdup(ddlString.data); ddlJob->commandString = pstrdup(ddlString.data);
ddlJob->taskList = DDLTaskList(relOid, ddlString.data); ddlJob->taskList = DDLTaskList(relOid, ddlString.data);

View File

@ -23,7 +23,7 @@ extern bool EnableDDLPropagation;
typedef struct DDLJob typedef struct DDLJob
{ {
Oid targetRelationId; /* oid of the target distributed relation */ Oid targetRelationId; /* oid of the target distributed relation */
bool preventTransaction; /* prevent use of worker transactions? */ bool concurrent; /* related to a CONCURRENTLY index command? */
const char *commandString; /* initial (coordinator) DDL command string */ const char *commandString; /* initial (coordinator) DDL command string */
List *taskList; /* worker DDL tasks to execute */ List *taskList; /* worker DDL tasks to execute */
} DDLJob; } DDLJob;

View File

@ -250,8 +250,9 @@ CREATE INDEX CONCURRENTLY ith_b_idx_102089 ON index_test_hash_102089(b);
\c - - - :master_port \c - - - :master_port
-- should fail because worker index already exists -- should fail because worker index already exists
CREATE INDEX CONCURRENTLY ith_b_idx ON index_test_hash(b); CREATE INDEX CONCURRENTLY ith_b_idx ON index_test_hash(b);
ERROR: relation "ith_b_idx_102089" already exists ERROR: CONCURRENTLY-enabled index command failed
CONTEXT: while executing command on localhost:57637 DETAIL: CONCURRENTLY-enabled index commands can fail partially, leaving behind an INVALID index.
HINT: Use DROP INDEX IF EXISTS to remove the invalid index, then retry the original command.
-- the failure results in an INVALID index -- the failure results in an INVALID index
SELECT indisvalid AS "Index Valid?" FROM pg_index WHERE indexrelid='ith_b_idx'::regclass; SELECT indisvalid AS "Index Valid?" FROM pg_index WHERE indexrelid='ith_b_idx'::regclass;
Index Valid? Index Valid?
@ -273,8 +274,9 @@ SELECT indisvalid AS "Index Valid?" FROM pg_index WHERE indexrelid='ith_b_idx'::
DROP INDEX CONCURRENTLY ith_b_idx_102089; DROP INDEX CONCURRENTLY ith_b_idx_102089;
\c - - - :master_port \c - - - :master_port
DROP INDEX CONCURRENTLY ith_b_idx; DROP INDEX CONCURRENTLY ith_b_idx;
ERROR: index "ith_b_idx_102089" does not exist ERROR: CONCURRENTLY-enabled index command failed
CONTEXT: while executing command on localhost:57637 DETAIL: CONCURRENTLY-enabled index commands can fail partially, leaving behind an INVALID index.
HINT: Use DROP INDEX IF EXISTS to remove the invalid index, then retry the original command.
-- the failure results in an INVALID index -- the failure results in an INVALID index
SELECT indisvalid AS "Index Valid?" FROM pg_index WHERE indexrelid='ith_b_idx'::regclass; SELECT indisvalid AS "Index Valid?" FROM pg_index WHERE indexrelid='ith_b_idx'::regclass;
Index Valid? Index Valid?