|
10 | 10 | *
|
11 | 11 | *
|
12 | 12 | * IDENTIFICATION
|
13 |
| - * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.186 2005/04/2502:14:47 tgl Exp $ |
| 13 | + * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.187 2005/04/2503: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 thatqpquals must contain scan_clauses |
| 772 | + * the qpqual. The upshot is thatqpqual 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 perhapsweneed 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 ifwecan 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);
|
|