mirror of
https://github.com/postgres/postgres.git
synced 2025-10-25 13:17:41 +03:00
Make ALTER TABLE revalidate uniqueness and exclusion constraints.
Failure to do so can lead to constraint violations. This was broken by
commit 1ddc2703a9 on 2010-02-07, so
back-patch to 9.0.
Noah Misch. Regression test by me.
This commit is contained in:
@@ -565,7 +565,7 @@ rebuild_relation(Relation OldHeap, Oid indexOid,
|
||||
* rebuild the target's indexes and throw away the transient table.
|
||||
*/
|
||||
finish_heap_swap(tableOid, OIDNewHeap, is_system_catalog,
|
||||
swap_toast_by_content, frozenXid);
|
||||
swap_toast_by_content, false, frozenXid);
|
||||
}
|
||||
|
||||
|
||||
@@ -1362,10 +1362,12 @@ void
|
||||
finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
|
||||
bool is_system_catalog,
|
||||
bool swap_toast_by_content,
|
||||
bool check_constraints,
|
||||
TransactionId frozenXid)
|
||||
{
|
||||
ObjectAddress object;
|
||||
Oid mapped_tables[4];
|
||||
int reindex_flags;
|
||||
int i;
|
||||
|
||||
/* Zero out possible results from swapped_relation_files */
|
||||
@@ -1395,7 +1397,10 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
|
||||
* so no chance to reclaim disk space before commit. We do not need a
|
||||
* final CommandCounterIncrement() because reindex_relation does it.
|
||||
*/
|
||||
reindex_relation(OIDOldHeap, false, true);
|
||||
reindex_flags = REINDEX_SUPPRESS_INDEX_USE;
|
||||
if (check_constraints)
|
||||
reindex_flags |= REINDEX_CHECK_CONSTRAINTS;
|
||||
reindex_relation(OIDOldHeap, false, reindex_flags);
|
||||
|
||||
/* Destroy new heap with old filenode */
|
||||
object.classId = RelationRelationId;
|
||||
|
||||
@@ -1629,7 +1629,7 @@ ReindexTable(RangeVar *relation)
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
if (!reindex_relation(heapOid, true, false))
|
||||
if (!reindex_relation(heapOid, true, 0))
|
||||
ereport(NOTICE,
|
||||
(errmsg("table \"%s\" has no indexes",
|
||||
relation->relname)));
|
||||
@@ -1742,7 +1742,7 @@ ReindexDatabase(const char *databaseName, bool do_system, bool do_user)
|
||||
StartTransactionCommand();
|
||||
/* functions in indexes may want a snapshot set */
|
||||
PushActiveSnapshot(GetTransactionSnapshot());
|
||||
if (reindex_relation(relid, true, false))
|
||||
if (reindex_relation(relid, true, 0))
|
||||
ereport(NOTICE,
|
||||
(errmsg("table \"%s.%s\" was reindexed",
|
||||
get_namespace_name(get_rel_namespace(relid)),
|
||||
|
||||
@@ -1076,7 +1076,7 @@ ExecuteTruncate(TruncateStmt *stmt)
|
||||
/*
|
||||
* Reconstruct the indexes to match, and we're done.
|
||||
*/
|
||||
reindex_relation(heap_relid, true, false);
|
||||
reindex_relation(heap_relid, true, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3236,13 +3236,14 @@ ATRewriteTables(List **wqueue, LOCKMODE lockmode)
|
||||
|
||||
/*
|
||||
* Swap the physical files of the old and new heaps, then rebuild
|
||||
* indexes and discard the new heap. We can use RecentXmin for
|
||||
* indexes and discard the old heap. We can use RecentXmin for
|
||||
* the table's new relfrozenxid because we rewrote all the tuples
|
||||
* in ATRewriteTable, so no older Xid remains in the table. Also,
|
||||
* we never try to swap toast tables by content, since we have no
|
||||
* interest in letting this code work on system catalogs.
|
||||
*/
|
||||
finish_heap_swap(tab->relid, OIDNewHeap, false, false, RecentXmin);
|
||||
finish_heap_swap(tab->relid, OIDNewHeap,
|
||||
false, false, true, RecentXmin);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user