Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit eca1388

Browse files
committed
Fix corner-case bug introduced with HOT: if REINDEX TABLE pg_class (or a
REINDEX DATABASE including same) is done before a session has done any other update on pg_class, the pg_class relcache entry was left with an incorrect setting of rd_indexattr, because the indexed-attributes set would be first demanded at a time when we'd forced a partial list of indexes into the pg_class entry, and it would remain cached after that. This could result in incorrect decisions about HOT-update safety later in the same session. In practice, since only pg_class_relname_nsp_index would be missed out, only ALTER TABLE RENAME and ALTER TABLE SET SCHEMA could trigger a problem. Per report and test case from Ondrej Jirman.
1 parent 30fd8ec commit eca1388

File tree

2 files changed

+14
-4
lines changed

2 files changed

+14
-4
lines changed

src/backend/catalog/index.c

+6-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.300 2008/06/19 00:46:04 alvherre Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.301 2008/08/10 19:02:33 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -2380,9 +2380,13 @@ reindex_relation(Oid relid, bool toast_too)
23802380
* problem.
23812381
*/
23822382
is_pg_class = (RelationGetRelid(rel) == RelationRelationId);
2383-
doneIndexes = NIL;
2383+
2384+
/* Ensure rd_indexattr is valid; see comments for RelationSetIndexList */
2385+
if (is_pg_class)
2386+
(void) RelationGetIndexAttrBitmap(rel);
23842387

23852388
/* Reindex all the indexes. */
2389+
doneIndexes = NIL;
23862390
foreach(indexId, indexIds)
23872391
{
23882392
Oid indexOid = lfirst_oid(indexId);

src/backend/utils/cache/relcache.c

+8-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.272 2008/05/12 00:00:52 alvherre Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.273 2008/08/10 19:02:33 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -2986,6 +2986,13 @@ insert_ordered_oid(List *list, Oid datum)
29862986
* messages. In practice it is only used on pg_class (see REINDEX).
29872987
*
29882988
* It is up to the caller to make sure the given list is correctly ordered.
2989+
*
2990+
* We deliberately do not change rd_indexattr here: even when operating
2991+
* with a temporary partial index list, HOT-update decisions must be made
2992+
* correctly with respect to the full index set. It is up to the caller
2993+
* to ensure that a correct rd_indexattr set has been cached before first
2994+
* calling RelationSetIndexList; else a subsequent inquiry might cause a
2995+
* wrong rd_indexattr set to get computed and cached.
29892996
*/
29902997
void
29912998
RelationSetIndexList(Relation relation, List *indexIds, Oid oidIndex)
@@ -3004,7 +3011,6 @@ RelationSetIndexList(Relation relation, List *indexIds, Oid oidIndex)
30043011
relation->rd_indexvalid = 2; /* mark list as forced */
30053012
/* must flag that we have a forced index list */
30063013
need_eoxact_work = true;
3007-
/* we deliberately do not change rd_indexattr */
30083014
}
30093015

30103016
/*

0 commit comments

Comments
 (0)