Make plan_cluster_use_sort cope with no IndexOptInfo for the target index.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 20 Apr 2011 21:43:34 +0000 (17:43 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 20 Apr 2011 21:44:17 +0000 (17:44 -0400)
The original coding assumed that such a case represents caller error, but
actually get_relation_info will omit generating an IndexOptInfo for any
index it thinks is unsafe to use.  Therefore, handle this case by returning
"true" to indicate that a seqscan-and-sort is the preferred way to
implement the CLUSTER operation.  New bug in 9.1, no backpatch needed.
Per bug #5985 from Daniel Grace.

src/backend/optimizer/plan/planner.c

index 58a5bf8eceb464e01fcca3a2711e2d12f5528132..4b0b633c03b14253f386fbb6b1cafbdd319725d9 100644 (file)
@@ -3093,15 +3093,6 @@ plan_cluster_use_sort(Oid tableOid, Oid indexOid)
        /* Build RelOptInfo */
        rel = build_simple_rel(root, 1, RELOPT_BASEREL);
 
-       /*
-        * Rather than doing all the pushups that would be needed to use
-        * set_baserel_size_estimates, just do a quick hack for rows and width.
-        */
-       rel->rows = rel->tuples;
-       rel->width = get_relation_data_width(tableOid, NULL);
-
-       root->total_table_pages = rel->pages;
-
        /* Locate IndexOptInfo for the target index */
        indexInfo = NULL;
        foreach(lc, rel->indexlist)
@@ -3110,9 +3101,25 @@ plan_cluster_use_sort(Oid tableOid, Oid indexOid)
                if (indexInfo->indexoid == indexOid)
                        break;
        }
+
+       /*
+        * It's possible that get_relation_info did not generate an IndexOptInfo
+        * for the desired index; this could happen if it's not yet reached its
+        * indcheckxmin usability horizon, or if it's a system index and we're
+        * ignoring system indexes.  In such cases we should tell CLUSTER to not
+        * trust the index contents but use seqscan-and-sort.
+        */
        if (lc == NULL)                         /* not in the list? */
-               elog(ERROR, "index %u does not belong to table %u",
-                        indexOid, tableOid);
+               return true;                    /* use sort */
+
+       /*
+        * Rather than doing all the pushups that would be needed to use
+        * set_baserel_size_estimates, just do a quick hack for rows and width.
+        */
+       rel->rows = rel->tuples;
+       rel->width = get_relation_data_width(tableOid, NULL);
+
+       root->total_table_pages = rel->pages;
 
        /*
         * Determine eval cost of the index expressions, if any.  We need to