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

Commit 364857f

Browse files
committed
Clean up planner confusion between ncolumns and nkeycolumns.
We're only going to consider key columns when creating indexquals, so there is no point in having the outer loops in indxpath.c iterate further than nkeycolumns. Doing so in match_pathkeys_to_index() is actually wrong, and would have caused crashes by now, except that we have no index AMs supporting both amcanorderbyop and amcaninclude. It's also wrong in relation_has_unique_index_for(). The effect there is to fail to prove uniqueness even when the index does prove it, if there are extra columns. Also future-proof examine_variable() for the day when extra columns can be expressions, and fix what's either a thinko or just an oversight in btcostestimate(): we should consider the number of key columns, not the total, when deciding whether to derate correlation. None of these things seemed important enough to risk changing in a just-before-wrap patch, but since we're past the release wrap window, time to fix 'em. Discussion: https://postgr.es/m/25526.1549847928@sss.pgh.pa.us
1 parent c2e0954 commit 364857f

File tree

2 files changed

+18
-12
lines changed

2 files changed

+18
-12
lines changed

src/backend/optimizer/path/indxpath.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel)
252252
IndexOptInfo *index = (IndexOptInfo *) lfirst(lc);
253253

254254
/* Protect limited-size array in IndexClauseSets */
255-
Assert(index->ncolumns <= INDEX_MAX_KEYS);
255+
Assert(index->nkeycolumns <= INDEX_MAX_KEYS);
256256

257257
/*
258258
* Ignore partial indexes that do not match the query.
@@ -467,7 +467,7 @@ consider_index_join_clauses(PlannerInfo *root, RelOptInfo *rel,
467467
* relation itself is also included in the relids set. considered_relids
468468
* lists all relids sets we've already tried.
469469
*/
470-
for (indexcol = 0; indexcol < index->ncolumns; indexcol++)
470+
for (indexcol = 0; indexcol < index->nkeycolumns; indexcol++)
471471
{
472472
/* Consider each applicable simple join clause */
473473
considered_clauses += list_length(jclauseset->indexclauses[indexcol]);
@@ -621,7 +621,7 @@ get_join_index_paths(PlannerInfo *root, RelOptInfo *rel,
621621
/* Identify indexclauses usable with this relids set */
622622
MemSet(&clauseset, 0, sizeof(clauseset));
623623

624-
for (indexcol = 0; indexcol < index->ncolumns; indexcol++)
624+
for (indexcol = 0; indexcol < index->nkeycolumns; indexcol++)
625625
{
626626
ListCell *lc;
627627

@@ -921,7 +921,7 @@ build_index_paths(PlannerInfo *root, RelOptInfo *rel,
921921
clause_columns = NIL;
922922
found_lower_saop_clause = false;
923923
outer_relids = bms_copy(rel->lateral_relids);
924-
for (indexcol = 0; indexcol < index->ncolumns; indexcol++)
924+
for (indexcol = 0; indexcol < index->nkeycolumns; indexcol++)
925925
{
926926
ListCell *lc;
927927

@@ -2649,11 +2649,12 @@ match_pathkeys_to_index(IndexOptInfo *index, List *pathkeys,
26492649
/*
26502650
* We allow any column of the index to match each pathkey; they
26512651
* don't have to match left-to-right as you might expect. This is
2652-
* correct for GiST, which is the sole existing AM supporting
2653-
* amcanorderbyop. We might need different logic in future for
2654-
* other implementations.
2652+
* correct for GiST, and it doesn't matter for SP-GiST because
2653+
* that doesn't handle multiple columns anyway, and no other
2654+
* existing AMs support amcanorderbyop. We might need different
2655+
* logic in future for other implementations.
26552656
*/
2656-
for (indexcol = 0; indexcol < index->ncolumns; indexcol++)
2657+
for (indexcol = 0; indexcol < index->nkeycolumns; indexcol++)
26572658
{
26582659
Expr *expr;
26592660

@@ -3084,7 +3085,7 @@ relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel,
30843085
* Try to find each index column in the lists of conditions. This is
30853086
* O(N^2) or worse, but we expect all the lists to be short.
30863087
*/
3087-
for (c = 0; c < ind->ncolumns; c++)
3088+
for (c = 0; c < ind->nkeycolumns; c++)
30883089
{
30893090
bool matched = false;
30903091
ListCell *lc;
@@ -3159,8 +3160,8 @@ relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel,
31593160
break; /* no match; this index doesn't help us */
31603161
}
31613162

3162-
/* Matched all columns of this index? */
3163-
if (c == ind->ncolumns)
3163+
/* Matched all key columns of this index? */
3164+
if (c == ind->nkeycolumns)
31643165
return true;
31653166
}
31663167

src/backend/utils/adt/selfuncs.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4868,6 +4868,10 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid,
48684868
* it to expressional index columns, in hopes of finding some
48694869
* statistics.
48704870
*
4871+
* Note that we consider all index columns including INCLUDE columns,
4872+
* since there could be stats for such columns. But the test for
4873+
* uniqueness needs to be warier.
4874+
*
48714875
* XXX it's conceivable that there are multiple matches with different
48724876
* index opfamilies; if so, we need to pick one that matches the
48734877
* operator we are estimating for. FIXME later.
@@ -4903,6 +4907,7 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid,
49034907
*/
49044908
if (index->unique &&
49054909
index->nkeycolumns == 1 &&
4910+
pos == 0 &&
49064911
(index->indpred == NIL || index->predOK))
49074912
vardata->isunique = true;
49084913

@@ -7213,7 +7218,7 @@ btcostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
72137218
if (index->reverse_sort[0])
72147219
varCorrelation = -varCorrelation;
72157220

7216-
if (index->ncolumns > 1)
7221+
if (index->nkeycolumns > 1)
72177222
costs.indexCorrelation = varCorrelation * 0.75;
72187223
else
72197224
costs.indexCorrelation = varCorrelation;

0 commit comments

Comments
 (0)