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

Commit 1fcd4b7

Browse files
committed
While determining the filter clauses for an index scan (either plain
or bitmap), use pred_test to be a little smarter about cases where a filter clause is logically unnecessary. This may be overkill for the plain indexscan case, but it's definitely useful for OR'd bitmap scans.
1 parent 79a1b00 commit 1fcd4b7

File tree

2 files changed

+51
-15
lines changed

2 files changed

+51
-15
lines changed

src/backend/optimizer/path/indxpath.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.178 2005/04/25 01:30:13 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.179 2005/04/25 03:58:29 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -500,8 +500,14 @@ choose_bitmap_and(Query *root, RelOptInfo *rel, List *paths)
500500
* And we consider an index redundant if all its index conditions were
501501
* already used by earlier indexes. (We could use pred_test() to have
502502
* a more intelligent, but much more expensive, check --- but in most
503-
* cases simple equality should suffice, since after all the index
504-
* conditions are all coming from the same query clauses.)
503+
* cases simple pointer equality should suffice, since after all the
504+
* index conditions are all coming from the same RestrictInfo lists.)
505+
*
506+
* XXX is there any risk of throwing away a useful partial index here
507+
* because we don't explicitly look at indpred? At least in simple
508+
* cases, the partial index will sort before competing non-partial
509+
* indexes and so it makes the right choice, but perhaps we need to
510+
* work harder.
505511
*/
506512

507513
/* Convert list to array so we can apply qsort */
@@ -530,7 +536,7 @@ choose_bitmap_and(Query *root, RelOptInfo *rel, List *paths)
530536
if (IsA(newpath, IndexPath))
531537
{
532538
newqual = ((IndexPath *) newpath)->indexclauses;
533-
if (list_difference(newqual, qualsofar) == NIL)
539+
if (list_difference_ptr(newqual, qualsofar) == NIL)
534540
continue; /* redundant */
535541
}
536542

src/backend/optimizer/plan/createplan.c

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.186 2005/04/25 02:14:47 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.187 2005/04/25 03:58:30 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -720,6 +720,7 @@ create_indexscan_plan(Query *root,
720720
List *nonlossy_indexquals;
721721
List *indexstrategy;
722722
List *indexsubtype;
723+
ListCell *l;
723724
IndexScan *scan_plan;
724725

725726
/* it should be a base rel... */
@@ -768,13 +769,31 @@ create_indexscan_plan(Query *root,
768769
* checked (either by the index itself, or by nodeIndexscan.c), but if
769770
* there are any "special" operators involved then they must be included
770771
* in qpqual. Also, any lossy index operators must be rechecked in
771-
* the qpqual. The upshot is that qpquals must contain scan_clauses
772+
* the qpqual. The upshot is that qpqual must contain scan_clauses
772773
* minus whatever appears in nonlossy_indexquals.
774+
*
775+
* In normal cases simple pointer equality checks will be enough to
776+
* spot duplicate RestrictInfos, so we try that first. In some situations
777+
* (particularly with OR'd index conditions) we may have scan_clauses
778+
* that are not equal to, but are logically implied by, the index quals;
779+
* so we also try a pred_test() check to see if we can discard quals
780+
* that way.
781+
*
782+
* While at it, we strip off the RestrictInfos to produce a list of
783+
* plain expressions.
773784
*/
774-
qpqual = list_difference_ptr(scan_clauses, nonlossy_indexquals);
785+
qpqual = NIL;
786+
foreach(l, scan_clauses)
787+
{
788+
RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
775789

776-
/* Reduce RestrictInfo list to bare expressions */
777-
qpqual = get_actual_clauses(qpqual);
790+
Assert(IsA(rinfo, RestrictInfo));
791+
if (list_member_ptr(nonlossy_indexquals, rinfo))
792+
continue;
793+
if (pred_test(list_make1(rinfo->clause), nonlossy_indexquals))
794+
continue;
795+
qpqual = lappend(qpqual, rinfo->clause);
796+
}
778797

779798
/* Sort clauses into best execution order */
780799
qpqual = order_qual_clauses(root, qpqual);
@@ -813,6 +832,7 @@ create_bitmap_scan_plan(Query *root,
813832
List *bitmapqualorig;
814833
List *indexquals;
815834
List *qpqual;
835+
ListCell *l;
816836
BitmapHeapScan *scan_plan;
817837

818838
/* it should be a base rel... */
@@ -848,13 +868,23 @@ create_bitmap_scan_plan(Query *root,
848868
* must be added to qpqual. The upshot is that qpquals must contain
849869
* scan_clauses minus whatever appears in indexquals.
850870
*
851-
* NOTE: when there are OR clauses in indexquals, the simple equality
852-
* check used by list_difference will only detect matches in case of
853-
* chance equality of the OR subclause ordering. This is probably all
854-
* right for now because that order will match what's in scan_clauses
855-
* ... but perhaps we need more smarts here.
871+
* In normal cases simple equal() checks will be enough to spot duplicate
872+
* clauses, so we try that first. In some situations (particularly with
873+
* OR'd index conditions) we may have scan_clauses that are not equal to,
874+
* but are logically implied by, the index quals; so we also try a
875+
* pred_test() check to see if we can discard quals that way.
856876
*/
857-
qpqual = list_difference(scan_clauses, indexquals);
877+
qpqual = NIL;
878+
foreach(l, scan_clauses)
879+
{
880+
Node *clause = (Node *) lfirst(l);
881+
882+
if (list_member(indexquals, clause))
883+
continue;
884+
if (pred_test(list_make1(clause), indexquals))
885+
continue;
886+
qpqual = lappend(qpqual, clause);
887+
}
858888

859889
/* Sort clauses into best execution order */
860890
qpqual = order_qual_clauses(root, qpqual);

0 commit comments

Comments
 (0)