Thread
Commits
-
Clean up planner confusion between ncolumns and nkeycolumns.
- 364857f73898 11.3 landed
- 75c46149fc22 12.0 landed
-
Fix indexable-row-comparison logic to account for covering indexes.
- eb68d71f99e9 11.2 landed
- 6bdc3005b54f 12.0 landed
-
indxpath.c's references to IndexOptInfo.ncolumns are all wrong, no?
Tom Lane <tgl@sss.pgh.pa.us> — 2019-02-11T01:18:48Z
Apparently, whoever went through indxpath.c to substitute nkeycolumns for ncolumns was not paying attention. As far as I can tell, the *only* place in there where it's correct to reference ncolumns is in check_index_only, where we determine which columns can be extracted from an index-only scan. A lot of the other places are obviously wrong, eg in relation_has_unique_index_for: for (c = 0; c < ind->ncolumns; c++) ... if (!list_member_oid(rinfo->mergeopfamilies, ind->opfamily[c])) Even if it were plausible that an INCLUDE column is something to consider when deciding whether the index enforces uniqueness, this code accesses beyond the documented end of the opfamily[] array :-( The fact that the regression tests haven't caught this doesn't give me a warm feeling about how thoroughly the included-columns logic has been tested. It's really easy to make it fall over, for instance regression=# explain select * from tenk1 where (thousand, tenthous) < (10,100); QUERY PLAN -------------------------------------------------------------------------------- ----- Bitmap Heap Scan on tenk1 (cost=5.11..233.86 rows=107 width=244) Recheck Cond: (ROW(thousand, tenthous) < ROW(10, 100)) -> Bitmap Index Scan on tenk1_thous_tenthous (cost=0.00..5.09 rows=107 widt h=0) Index Cond: (ROW(thousand, tenthous) < ROW(10, 100)) (4 rows) regression=# drop index tenk1_thous_tenthous; DROP INDEX regression=# create index on tenk1(thousand) include (tenthous); CREATE INDEX regression=# explain select * from tenk1 where (thousand, tenthous) < (10,100); ERROR: operator 97 is not a member of opfamily 2139062142 I've got mixed feelings about whether to try to fix this before tomorrow's wraps. The attached patch seems correct and passes check-world, but there's sure not a lot of margin for error now. Thoughts? regards, tom lane -
Re: indxpath.c's references to IndexOptInfo.ncolumns are all wrong, no?
Peter Geoghegan <pg@bowt.ie> — 2019-02-11T01:35:04Z
On Sun, Feb 10, 2019 at 5:18 PM Tom Lane <tgl@sss.pgh.pa.us> wrote: > Apparently, whoever went through indxpath.c to substitute nkeycolumns > for ncolumns was not paying attention. As far as I can tell, the > *only* place in there where it's correct to reference ncolumns is in > check_index_only, where we determine which columns can be extracted from > an index-only scan. Ugh. Yeah, it's rather inconsistent. > I've got mixed feelings about whether to try to fix this before > tomorrow's wraps. The attached patch seems correct and passes > check-world, but there's sure not a lot of margin for error now. > Thoughts? I think that it should be fixed in the next point release if at all possible. The bug is a simple omission. I have a hard time imagining how your patch could possibly destabilize things, since nkeycolumns is already used in numerous other places in indxpath.c. -- Peter Geoghegan
-
Re: indxpath.c's references to IndexOptInfo.ncolumns are all wrong, no?
Tom Lane <tgl@sss.pgh.pa.us> — 2019-02-11T02:10:14Z
Peter Geoghegan <pg@bowt.ie> writes: > On Sun, Feb 10, 2019 at 5:18 PM Tom Lane <tgl@sss.pgh.pa.us> wrote: >> Apparently, whoever went through indxpath.c to substitute nkeycolumns >> for ncolumns was not paying attention. As far as I can tell, the >> *only* place in there where it's correct to reference ncolumns is in >> check_index_only, where we determine which columns can be extracted from >> an index-only scan. > Ugh. Yeah, it's rather inconsistent. Looking closer, it seems like most of these are accidentally protected by the fact that match_clause_to_index stops at nkeycolumns, so that the indexclauses lists for later columns can never become nonempty; they're merely wasting cycles by iterating over later columns, rather than doing anything seriously wrong. It would be possible to get match_pathkeys_to_index to trigger the assertion in match_clause_to_ordering_op if GIST supported included columns, but it doesn't. And I think relation_has_unique_index_for can be fooled into reporting that an index doesn't prove uniqueness, when it does. But the only one of these that's really got obviously bad consequences is the one in expand_indexqual_rowcompare, which triggers the failure I showed before. It's also the most obviously wrong code: /* * The Var side can match any column of the index. */ for (i = 0; i < index->nkeycolumns; i++) { if (...) break; } if (i >= index->ncolumns) break; /* no match found */ Even without understanding the bigger picture, any C programmer ought to find that loop logic pretty fishy. (I'm a bit surprised Coverity hasn't whined about it.) Maybe the right compromise is to fix expand_indexqual_rowcompare now and leave the rest for post-wrap. regards, tom lane