|
10 | 10 | *
|
11 | 11 | *
|
12 | 12 | * 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 $ |
14 | 14 | *
|
15 | 15 | *-------------------------------------------------------------------------
|
16 | 16 | */
|
@@ -720,6 +720,7 @@ create_indexscan_plan(Query *root,
|
720 | 720 | List *nonlossy_indexquals;
|
721 | 721 | List *indexstrategy;
|
722 | 722 | List *indexsubtype;
|
| 723 | + ListCell *l; |
723 | 724 | IndexScan *scan_plan;
|
724 | 725 |
|
725 | 726 | /* it should be a base rel... */
|
@@ -768,13 +769,31 @@ create_indexscan_plan(Query *root,
|
768 | 769 | * checked (either by the index itself, or by nodeIndexscan.c), but if
|
769 | 770 | * there are any "special" operators involved then they must be included
|
770 | 771 | * 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 |
772 | 773 | * 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. |
773 | 784 | */
|
774 |
| - qpqual = list_difference_ptr(scan_clauses, nonlossy_indexquals); |
| 785 | + qpqual = NIL; |
| 786 | + foreach(l, scan_clauses) |
| 787 | + { |
| 788 | + RestrictInfo *rinfo = (RestrictInfo *) lfirst(l); |
775 | 789 |
|
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 | + } |
778 | 797 |
|
779 | 798 | /* Sort clauses into best execution order */
|
780 | 799 | qpqual = order_qual_clauses(root, qpqual);
|
@@ -813,6 +832,7 @@ create_bitmap_scan_plan(Query *root,
|
813 | 832 | List *bitmapqualorig;
|
814 | 833 | List *indexquals;
|
815 | 834 | List *qpqual;
|
| 835 | + ListCell *l; |
816 | 836 | BitmapHeapScan *scan_plan;
|
817 | 837 |
|
818 | 838 | /* it should be a base rel... */
|
@@ -848,13 +868,23 @@ create_bitmap_scan_plan(Query *root,
|
848 | 868 | * must be added to qpqual. The upshot is that qpquals must contain
|
849 | 869 | * scan_clauses minus whatever appears in indexquals.
|
850 | 870 | *
|
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. |
856 | 876 | */
|
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 | + } |
858 | 888 |
|
859 | 889 | /* Sort clauses into best execution order */
|
860 | 890 | qpqual = order_qual_clauses(root, qpqual);
|
|
0 commit comments