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

Commit 75c4614

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 8c67d29 commit 75c4614

File tree

2 files changed

+18
-12
lines changed

2 files changed

+18
-12
lines changed

src/backend/optimizer/path/indxpath.c

+12-11
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel)
253253
IndexOptInfo *index = (IndexOptInfo *) lfirst(lc);
254254

255255
/* Protect limited-size array in IndexClauseSets */
256-
Assert(index->ncolumns <= INDEX_MAX_KEYS);
256+
Assert(index->nkeycolumns <= INDEX_MAX_KEYS);
257257

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

626-
for (indexcol = 0; indexcol < index->ncolumns; indexcol++)
626+
for (indexcol = 0; indexcol < index->nkeycolumns; indexcol++)
627627
{
628628
ListCell *lc;
629629

@@ -920,7 +920,7 @@ build_index_paths(PlannerInfo *root, RelOptInfo *rel,
920920
index_clauses = NIL;
921921
found_lower_saop_clause = false;
922922
outer_relids = bms_copy(rel->lateral_relids);
923-
for (indexcol = 0; indexcol < index->ncolumns; indexcol++)
923+
for (indexcol = 0; indexcol < index->nkeycolumns; indexcol++)
924924
{
925925
ListCell *lc;
926926

@@ -3237,11 +3237,12 @@ match_pathkeys_to_index(IndexOptInfo *index, List *pathkeys,
32373237
/*
32383238
* We allow any column of the index to match each pathkey; they
32393239
* don't have to match left-to-right as you might expect. This is
3240-
* correct for GiST, which is the sole existing AM supporting
3241-
* amcanorderbyop. We might need different logic in future for
3242-
* other implementations.
3240+
* correct for GiST, and it doesn't matter for SP-GiST because
3241+
* that doesn't handle multiple columns anyway, and no other
3242+
* existing AMs support amcanorderbyop. We might need different
3243+
* logic in future for other implementations.
32433244
*/
3244-
for (indexcol = 0; indexcol < index->ncolumns; indexcol++)
3245+
for (indexcol = 0; indexcol < index->nkeycolumns; indexcol++)
32453246
{
32463247
Expr *expr;
32473248

@@ -3672,7 +3673,7 @@ relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel,
36723673
* Try to find each index column in the lists of conditions. This is
36733674
* O(N^2) or worse, but we expect all the lists to be short.
36743675
*/
3675-
for (c = 0; c < ind->ncolumns; c++)
3676+
for (c = 0; c < ind->nkeycolumns; c++)
36763677
{
36773678
bool matched = false;
36783679
ListCell *lc;
@@ -3747,8 +3748,8 @@ relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel,
37473748
break; /* no match; this index doesn't help us */
37483749
}
37493750

3750-
/* Matched all columns of this index? */
3751-
if (c == ind->ncolumns)
3751+
/* Matched all key columns of this index? */
3752+
if (c == ind->nkeycolumns)
37523753
return true;
37533754
}
37543755

src/backend/utils/adt/selfuncs.c

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

@@ -7242,7 +7247,7 @@ btcostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
72427247
if (index->reverse_sort[0])
72437248
varCorrelation = -varCorrelation;
72447249

7245-
if (index->ncolumns > 1)
7250+
if (index->nkeycolumns > 1)
72467251
costs.indexCorrelation = varCorrelation * 0.75;
72477252
else
72487253
costs.indexCorrelation = varCorrelation;

0 commit comments

Comments
 (0)