8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.127 2008/04/13 19:18:14 tgl Exp $
11
+ * $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.128 2008/04/13 20:51:20 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -576,8 +576,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
576
576
ExecIndexBuildScanKeys ((PlanState * ) indexstate ,
577
577
indexstate -> iss_RelationDesc ,
578
578
node -> indexqual ,
579
- node -> indexstrategy ,
580
- node -> indexsubtype ,
581
579
& indexstate -> iss_ScanKeys ,
582
580
& indexstate -> iss_NumScanKeys ,
583
581
& indexstate -> iss_RuntimeKeys ,
@@ -655,12 +653,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
655
653
* planstate: executor state node we are working for
656
654
* index: the index we are building scan keys for
657
655
* quals: indexquals expressions
658
- * strategies: associated operator strategy numbers
659
- * subtypes: associated operator subtype OIDs
660
- *
661
- * (Any elements of the strategies and subtypes lists that correspond to
662
- * RowCompareExpr quals are not used here; instead we look up the info
663
- * afresh.)
664
656
*
665
657
* Output params are:
666
658
*
@@ -675,15 +667,12 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
675
667
* ScalarArrayOpExpr quals are not supported.
676
668
*/
677
669
void
678
- ExecIndexBuildScanKeys (PlanState * planstate , Relation index ,
679
- List * quals , List * strategies , List * subtypes ,
670
+ ExecIndexBuildScanKeys (PlanState * planstate , Relation index , List * quals ,
680
671
ScanKey * scanKeys , int * numScanKeys ,
681
672
IndexRuntimeKeyInfo * * runtimeKeys , int * numRuntimeKeys ,
682
673
IndexArrayKeyInfo * * arrayKeys , int * numArrayKeys )
683
674
{
684
675
ListCell * qual_cell ;
685
- ListCell * strategy_cell ;
686
- ListCell * subtype_cell ;
687
676
ScanKey scan_keys ;
688
677
IndexRuntimeKeyInfo * runtime_keys ;
689
678
IndexArrayKeyInfo * array_keys ;
@@ -725,40 +714,31 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
725
714
extra_scan_keys = n_scan_keys ;
726
715
727
716
/*
728
- * for each opclause in the given qual, convert each qual's opclause into
717
+ * for each opclause in the given qual, convert the opclause into
729
718
* a single scan key
730
719
*/
731
- qual_cell = list_head (quals );
732
- strategy_cell = list_head (strategies );
733
- subtype_cell = list_head (subtypes );
734
-
735
- for (j = 0 ; j < n_scan_keys ; j ++ )
720
+ j = 0 ;
721
+ foreach (qual_cell , quals )
736
722
{
737
- ScanKey this_scan_key = & scan_keys [j ];
738
- Expr * clause ; /* one clause of index qual */
723
+ Expr * clause = (Expr * ) lfirst (qual_cell );
724
+ ScanKey this_scan_key = & scan_keys [j ++ ];
725
+ Oid opno ; /* operator's OID */
739
726
RegProcedure opfuncid ; /* operator proc id used in scan */
740
- StrategyNumber strategy ; /* op's strategy number */
741
- Oid subtype ; /* op's strategy subtype */
727
+ Oid opfamily ; /* opfamily of index column */
728
+ int op_strategy ; /* operator's strategy number */
729
+ Oid op_lefttype ; /* operator's declared input types */
730
+ Oid op_righttype ;
742
731
Expr * leftop ; /* expr on lhs of operator */
743
732
Expr * rightop ; /* expr on rhs ... */
744
733
AttrNumber varattno ; /* att number used in scan */
745
734
746
- /*
747
- * extract clause information from the qualification
748
- */
749
- clause = (Expr * ) lfirst (qual_cell );
750
- qual_cell = lnext (qual_cell );
751
- strategy = lfirst_int (strategy_cell );
752
- strategy_cell = lnext (strategy_cell );
753
- subtype = lfirst_oid (subtype_cell );
754
- subtype_cell = lnext (subtype_cell );
755
-
756
735
if (IsA (clause , OpExpr ))
757
736
{
758
737
/* indexkey op const or indexkey op expression */
759
738
int flags = 0 ;
760
739
Datum scanvalue ;
761
740
741
+ opno = ((OpExpr * ) clause )-> opno ;
762
742
opfuncid = ((OpExpr * ) clause )-> opfuncid ;
763
743
764
744
/*
@@ -776,6 +756,19 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
776
756
elog (ERROR , "indexqual doesn't have key on left side" );
777
757
778
758
varattno = ((Var * ) leftop )-> varattno ;
759
+ if (varattno < 1 || varattno > index -> rd_index -> indnatts )
760
+ elog (ERROR , "bogus index qualification" );
761
+
762
+ /*
763
+ * We have to look up the operator's strategy number. This
764
+ * provides a cross-check that the operator does match the index.
765
+ */
766
+ opfamily = index -> rd_opfamily [varattno - 1 ];
767
+
768
+ get_op_opfamily_properties (opno , opfamily ,
769
+ & op_strategy ,
770
+ & op_lefttype ,
771
+ & op_righttype );
779
772
780
773
/*
781
774
* rightop is the constant or variable comparison value
@@ -810,8 +803,8 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
810
803
ScanKeyEntryInitialize (this_scan_key ,
811
804
flags ,
812
805
varattno , /* attribute number to scan */
813
- strategy , /* op's strategy */
814
- subtype , /* strategy subtype */
806
+ op_strategy , /* op's strategy */
807
+ op_righttype , /* strategy subtype */
815
808
opfuncid , /* reg proc to use */
816
809
scanvalue ); /* constant */
817
810
}
@@ -830,12 +823,6 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
830
823
ScanKey this_sub_key = & scan_keys [extra_scan_keys ];
831
824
int flags = SK_ROW_MEMBER ;
832
825
Datum scanvalue ;
833
- Oid opno ;
834
- Oid opfamily ;
835
- int op_strategy ;
836
- Oid op_lefttype ;
837
- Oid op_righttype ;
838
- bool op_recheck ;
839
826
840
827
/*
841
828
* leftop should be the index key Var, possibly relabeled
@@ -897,8 +884,7 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
897
884
get_op_opfamily_properties (opno , opfamily ,
898
885
& op_strategy ,
899
886
& op_lefttype ,
900
- & op_righttype ,
901
- & op_recheck );
887
+ & op_righttype );
902
888
903
889
if (op_strategy != rc -> rctype )
904
890
elog (ERROR , "RowCompare index qualification contains wrong operator" );
@@ -941,6 +927,7 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
941
927
ScalarArrayOpExpr * saop = (ScalarArrayOpExpr * ) clause ;
942
928
943
929
Assert (saop -> useOr );
930
+ opno = saop -> opno ;
944
931
opfuncid = saop -> opfuncid ;
945
932
946
933
/*
@@ -958,6 +945,19 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
958
945
elog (ERROR , "indexqual doesn't have key on left side" );
959
946
960
947
varattno = ((Var * ) leftop )-> varattno ;
948
+ if (varattno < 1 || varattno > index -> rd_index -> indnatts )
949
+ elog (ERROR , "bogus index qualification" );
950
+
951
+ /*
952
+ * We have to look up the operator's strategy number. This
953
+ * provides a cross-check that the operator does match the index.
954
+ */
955
+ opfamily = index -> rd_opfamily [varattno - 1 ];
956
+
957
+ get_op_opfamily_properties (opno , opfamily ,
958
+ & op_strategy ,
959
+ & op_lefttype ,
960
+ & op_righttype );
961
961
962
962
/*
963
963
* rightop is the constant or variable array value
@@ -981,8 +981,8 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
981
981
ScanKeyEntryInitialize (this_scan_key ,
982
982
0 , /* flags */
983
983
varattno , /* attribute number to scan */
984
- strategy , /* op's strategy */
985
- subtype , /* strategy subtype */
984
+ op_strategy , /* op's strategy */
985
+ op_righttype , /* strategy subtype */
986
986
opfuncid , /* reg proc to use */
987
987
(Datum ) 0 ); /* constant */
988
988
}
@@ -1013,8 +1013,8 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
1013
1013
ScanKeyEntryInitialize (this_scan_key ,
1014
1014
SK_ISNULL | SK_SEARCHNULL ,
1015
1015
varattno , /* attribute number to scan */
1016
- strategy , /* op's strategy */
1017
- subtype , /* strategy subtype */
1016
+ InvalidStrategy , /* no strategy */
1017
+ InvalidOid , /* no strategy subtype */
1018
1018
InvalidOid , /* no reg proc for this */
1019
1019
(Datum ) 0 ); /* constant */
1020
1020
}
0 commit comments