Commit a1b7e70c authored by Tom Lane's avatar Tom Lane

Fix code that checks to see if an index can be considered to match the query's

requested sort order.  It was assuming that build_index_pathkeys always
generates a pathkey per index column, which was not true if implied equality
deduction had determined that two index columns were effectively equated to
each other.  Simplest fix seems to be to install an option that causes
build_index_pathkeys to support this behavior as well as the original one.
Per report from Brian Hirt.
parent 4400ca2b
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.198 2006/01/26 02:35:49 tgl Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.199 2006/01/29 17:27:42 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -343,7 +343,8 @@ find_usable_indexes(PlannerInfo *root, RelOptInfo *rel, ...@@ -343,7 +343,8 @@ find_usable_indexes(PlannerInfo *root, RelOptInfo *rel,
if (istoplevel && index_is_ordered && !isjoininner) if (istoplevel && index_is_ordered && !isjoininner)
{ {
index_pathkeys = build_index_pathkeys(root, index, index_pathkeys = build_index_pathkeys(root, index,
ForwardScanDirection); ForwardScanDirection,
true);
useful_pathkeys = truncate_useless_pathkeys(root, rel, useful_pathkeys = truncate_useless_pathkeys(root, rel,
index_pathkeys); index_pathkeys);
} }
...@@ -1705,7 +1706,7 @@ match_index_to_query_keys(PlannerInfo *root, ...@@ -1705,7 +1706,7 @@ match_index_to_query_keys(PlannerInfo *root,
ListCell *r; ListCell *r;
/* Get the pathkeys that exactly describe the index */ /* Get the pathkeys that exactly describe the index */
index_pathkeys = build_index_pathkeys(root, index, indexscandir); index_pathkeys = build_index_pathkeys(root, index, indexscandir, false);
/* /*
* Can we match to the query's requested pathkeys? The inner loop skips * Can we match to the query's requested pathkeys? The inner loop skips
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.74 2005/11/22 18:17:12 momjian Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.75 2006/01/29 17:27:42 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -909,13 +909,20 @@ get_cheapest_fractional_path_for_pathkeys(List *paths, ...@@ -909,13 +909,20 @@ get_cheapest_fractional_path_for_pathkeys(List *paths,
* If 'scandir' is BackwardScanDirection, attempt to build pathkeys * If 'scandir' is BackwardScanDirection, attempt to build pathkeys
* representing a backwards scan of the index. Return NIL if can't do it. * representing a backwards scan of the index. Return NIL if can't do it.
* *
* If 'canonical' is TRUE, we remove duplicate pathkeys (which can occur
* if two index columns are equijoined, eg WHERE x = 1 AND y = 1). This
* is required if the result is to be compared directly to a canonical query
* pathkeys list. However, some callers want a list with exactly one entry
* per index column, and they must pass FALSE.
*
* We generate the full pathkeys list whether or not all are useful for the * We generate the full pathkeys list whether or not all are useful for the
* current query. Caller should do truncate_useless_pathkeys(). * current query. Caller should do truncate_useless_pathkeys().
*/ */
List * List *
build_index_pathkeys(PlannerInfo *root, build_index_pathkeys(PlannerInfo *root,
IndexOptInfo *index, IndexOptInfo *index,
ScanDirection scandir) ScanDirection scandir,
bool canonical)
{ {
List *retval = NIL; List *retval = NIL;
int *indexkeys = index->indexkeys; int *indexkeys = index->indexkeys;
...@@ -956,11 +963,11 @@ build_index_pathkeys(PlannerInfo *root, ...@@ -956,11 +963,11 @@ build_index_pathkeys(PlannerInfo *root,
item = makePathKeyItem(indexkey, sortop, true); item = makePathKeyItem(indexkey, sortop, true);
cpathkey = make_canonical_pathkey(root, item); cpathkey = make_canonical_pathkey(root, item);
/* /* Eliminate redundant ordering info if requested */
* Eliminate redundant ordering info; could happen if query is such if (canonical)
* that index keys are equijoined... retval = list_append_unique_ptr(retval, cpathkey);
*/ else
retval = list_append_unique_ptr(retval, cpathkey); retval = lappend(retval, cpathkey);
indexkeys++; indexkeys++;
ordering++; ordering++;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/optimizer/paths.h,v 1.90 2005/12/20 02:30:36 tgl Exp $ * $PostgreSQL: pgsql/src/include/optimizer/paths.h,v 1.91 2006/01/29 17:27:42 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -114,7 +114,7 @@ extern Path *get_cheapest_fractional_path_for_pathkeys(List *paths, ...@@ -114,7 +114,7 @@ extern Path *get_cheapest_fractional_path_for_pathkeys(List *paths,
List *pathkeys, List *pathkeys,
double fraction); double fraction);
extern List *build_index_pathkeys(PlannerInfo *root, IndexOptInfo *index, extern List *build_index_pathkeys(PlannerInfo *root, IndexOptInfo *index,
ScanDirection scandir); ScanDirection scandir, bool canonical);
extern List *convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel, extern List *convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel,
List *subquery_pathkeys); List *subquery_pathkeys);
extern List *build_join_pathkeys(PlannerInfo *root, extern List *build_join_pathkeys(PlannerInfo *root,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment