Re: ALTER TABLE name RENAME TO new_name; does notworkimmediately

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Gregory Stark <stark(at)enterprisedb(dot)com>
Cc: "Alvaro Herrera" <alvherre(at)commandprompt(dot)com>, megous(at)gmail(dot)com, pgsql-bugs(at)postgresql(dot)org
Subject: Re: ALTER TABLE name RENAME TO new_name; does notworkimmediately
Date: 2008-08-10 18:50:59
Message-ID: 28268.1218394259@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Gregory Stark <stark(at)enterprisedb(dot)com> writes:
> Uhm. Is it possible we're mistakenly doing a HOT update because we're lying
> about what indexes exist?

Yup, exactly. Here's my proposed fix...

regards, tom lane

Index: src/backend/catalog/index.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/catalog/index.c,v
retrieving revision 1.300
diff -c -r1.300 index.c
*** src/backend/catalog/index.c 19 Jun 2008 00:46:04 -0000 1.300
--- src/backend/catalog/index.c 10 Aug 2008 18:49:08 -0000
***************
*** 2380,2388 ****
* problem.
*/
is_pg_class = (RelationGetRelid(rel) == RelationRelationId);
! doneIndexes = NIL;

/* Reindex all the indexes. */
foreach(indexId, indexIds)
{
Oid indexOid = lfirst_oid(indexId);
--- 2380,2392 ----
* problem.
*/
is_pg_class = (RelationGetRelid(rel) == RelationRelationId);
!
! /* Ensure rd_indexattr is valid; see comments for RelationSetIndexList */
! if (is_pg_class)
! (void) RelationGetIndexAttrBitmap(rel);

/* Reindex all the indexes. */
+ doneIndexes = NIL;
foreach(indexId, indexIds)
{
Oid indexOid = lfirst_oid(indexId);
Index: src/backend/utils/cache/relcache.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v
retrieving revision 1.272
diff -c -r1.272 relcache.c
*** src/backend/utils/cache/relcache.c 12 May 2008 00:00:52 -0000 1.272
--- src/backend/utils/cache/relcache.c 10 Aug 2008 18:49:08 -0000
***************
*** 2986,2991 ****
--- 2986,2998 ----
* messages. In practice it is only used on pg_class (see REINDEX).
*
* It is up to the caller to make sure the given list is correctly ordered.
+ *
+ * We deliberately do not change rd_indexattr here: even when operating
+ * with a temporary partial index list, HOT-update decisions must be made
+ * correctly with respect to the full index set. It is up to the caller
+ * to ensure that a correct rd_indexattr set has been cached before first
+ * calling RelationSetIndexList; else a subsequent inquiry might cause a
+ * wrong rd_indexattr set to get computed and cached.
*/
void
RelationSetIndexList(Relation relation, List *indexIds, Oid oidIndex)
***************
*** 3004,3010 ****
relation->rd_indexvalid = 2; /* mark list as forced */
/* must flag that we have a forced index list */
need_eoxact_work = true;
- /* we deliberately do not change rd_indexattr */
}

/*
--- 3011,3016 ----

In response to

Browse pgsql-bugs by date

  From Date Subject
Next Message Gregory Stark 2008-08-10 18:56:32 Re: ALTER TABLE name RENAME TO new_name; does notworkimmediately
Previous Message Gregory Stark 2008-08-10 18:37:19 Re: ALTER TABLE name RENAME TO new_name; does notworkimmediately