Re: ALTER TABLE name RENAME TO new_name; does notworkimmediately - Mailing list pgsql-bugs

From Tom Lane
Subject Re: ALTER TABLE name RENAME TO new_name; does notworkimmediately
Date
Msg-id 28268.1218394259@sss.pgh.pa.us
Whole thread Raw
In response to Re: ALTER TABLE name RENAME TO new_name; does notworkimmediately  (Gregory Stark <stark@enterprisedb.com>)
List pgsql-bugs
Gregory Stark <stark@enterprisedb.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 ----

pgsql-bugs by date:

Previous
From: Gregory Stark
Date:
Subject: Re: ALTER TABLE name RENAME TO new_name; does notworkimmediately
Next
From: Gregory Stark
Date:
Subject: Re: ALTER TABLE name RENAME TO new_name; does notworkimmediately