From 5b8e442953da0bf4950b86c7cb4a6117842aedf7 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 20 Apr 2011 17:43:34 -0400 Subject: [PATCH] Make plan_cluster_use_sort cope with no IndexOptInfo for the target index. 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 | 29 +++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 58a5bf8ece..4b0b633c03 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -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 -- 2.40.0