@@ -239,6 +239,8 @@ my_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEntry *rte)
239239RangeTblEntry * * new_rte_array ;
240240int len = irange_list_length (ranges );
241241
242+ elog (NOTICE ,"%d" ,len );
243+
242244/* Expand simple_rel_array and simple_rte_array */
243245ereport (LOG , (errmsg ("Expanding simple_rel_array" )));
244246
@@ -556,8 +558,6 @@ handle_binary_opexpr(const PartRelationInfo *prel, WrapperNode *result,
556558RangeRelation * rangerel ;
557559Datum value ;
558560int i ,
559- startidx ,
560- endidx ,
561561int_value ,
562562strategy ;
563563FmgrInfo * cmp_func ;
@@ -589,87 +589,128 @@ handle_binary_opexpr(const PartRelationInfo *prel, WrapperNode *result,
589589if (rangerel != NULL )
590590{
591591RangeEntry * re ;
592- // List *children = NIL;
593- bool found = false;
594- startidx = 0 ;
595- int counter = 0 ;
592+ bool found = false,
593+ lossy = false;
594+ int counter = 0 ,
595+ startidx = 0 ,
596+ cmp_min ,
597+ cmp_max ,
598+ endidx = rangerel -> nranges - 1 ;
596599RangeEntry * ranges = dsm_array_get_pointer (& rangerel -> ranges );
597600
598- // int res = (int) FunctionCall2(cmp_func, rangerel->ranges[0].min, value);
599-
600- endidx = rangerel -> nranges - 1 ;
601-
602601/* check boundaries */
603602if (rangerel -> nranges == 0 )
604603{
605- result -> rangeset = list_make1_irange (make_irange (startidx ,endidx , true));
606- return ;
607- }
608- else if ((check_gt (cmp_func ,ranges [0 ].min ,value )&& (strategy == BTGreaterStrategyNumber || strategy == BTGreaterEqualStrategyNumber ))||
609- (check_lt (cmp_func ,ranges [rangerel -> nranges - 1 ].max ,value )&& (strategy == BTLessStrategyNumber || strategy == BTLessEqualStrategyNumber )))
610- {
611- result -> rangeset = list_make1_irange (make_irange (startidx ,endidx , true));
604+ result -> rangeset = NIL ;
612605return ;
613606}
614- else if (check_gt (cmp_func ,ranges [0 ].min ,value )||
615- check_lt (cmp_func ,ranges [rangerel -> nranges - 1 ].max ,value ))
607+ else
616608{
617- result -> rangeset = list_make1_irange (make_irange (startidx ,endidx , true));
618- return ;
609+ /* Corner cases */
610+ cmp_min = FunctionCall2 (cmp_func ,value ,ranges [0 ].min ),
611+ cmp_max = FunctionCall2 (cmp_func ,value ,ranges [rangerel -> nranges - 1 ].max );
612+
613+ if ((cmp_min < 0 && strategy == BTLessEqualStrategyNumber )||
614+ (cmp_min <=0 && strategy == BTLessStrategyNumber ))
615+ {
616+ result -> rangeset = NIL ;
617+ return ;
618+ }
619+
620+ if (cmp_max >=0 && (strategy == BTGreaterEqualStrategyNumber ||
621+ strategy == BTGreaterStrategyNumber ))
622+ {
623+ result -> rangeset = NIL ;
624+ return ;
625+ }
626+
627+ if ((cmp_min < 0 && strategy == BTGreaterStrategyNumber )||
628+ (cmp_min <=0 && strategy == BTGreaterEqualStrategyNumber ))
629+ {
630+ result -> rangeset = list_make1_irange (make_irange (startidx ,endidx , true));
631+ return ;
632+ }
633+
634+ if (cmp_max >=0 && (strategy == BTLessEqualStrategyNumber ||
635+ strategy == BTLessStrategyNumber ))
636+ {
637+ result -> rangeset = list_make1_irange (make_irange (startidx ,endidx , true));
638+ return ;
639+ }
619640}
620641
621642/* binary search */
622643while (true)
623644{
624645i = startidx + (endidx - startidx ) /2 ;
625- if (i >=0 && i < rangerel -> nranges )
646+ Assert (i >=0 && i < rangerel -> nranges );
647+ re = & ranges [i ];
648+ cmp_min = FunctionCall2 (cmp_func ,value ,re -> min );
649+ cmp_max = FunctionCall2 (cmp_func ,value ,re -> max );
650+ if (cmp_min < 0 || (cmp_min == 0 && strategy == BTLessStrategyNumber ))
626651{
627- re = & ranges [i ];
628- if (check_le (cmp_func ,re -> min ,value )&& check_le (cmp_func ,value ,re -> max ))
629- {
630- found = true;
631- break ;
632- }
633- else if (check_lt (cmp_func ,value ,re -> min ))
634- endidx = i - 1 ;
635- else if (check_gt (cmp_func ,value ,re -> max ))
636- startidx = i + 1 ;
652+ endidx = i - 1 ;
653+ }
654+ else if (cmp_max > 0 || (cmp_max >=0 && strategy != BTLessStrategyNumber ))
655+ {
656+ startidx = i + 1 ;
637657}
638658else
659+ {
660+ if (strategy == BTGreaterEqualStrategyNumber && cmp_min == 0 )
661+ lossy = false;
662+ else if (strategy == BTLessStrategyNumber && cmp_max == 0 )
663+ lossy = false;
664+ else
665+ lossy = true;
666+ found = true;
639667break ;
668+ }
640669/* for debug's sake */
641670Assert (++ counter < 100 );
642671}
643672
673+ Assert (found );
674+
644675/* filter partitions */
645- if ( found )
676+ switch ( strategy )
646677{
647- switch (strategy )
648- {
649- case BTLessStrategyNumber :
650- startidx = 0 ;
651- endidx = check_eq (cmp_func ,re -> min ,value ) ?i - 1 :i ;
652- break ;
653- case BTLessEqualStrategyNumber :
654- startidx = 0 ;
655- endidx = i ;
656- break ;
657- case BTEqualStrategyNumber :
658- // return list_make1_int(re->child_oid);
659- // return list_make1_int(make_range(prel->oid, prel->oid));
678+ case BTLessStrategyNumber :
679+ case BTLessEqualStrategyNumber :
680+ if (lossy )
681+ {
660682result -> rangeset = list_make1_irange (make_irange (i ,i , true));
661- return ;
662- case BTGreaterEqualStrategyNumber :
663- startidx = i ;
664- endidx = rangerel -> nranges - 1 ;
665- break ;
666- case BTGreaterStrategyNumber :
667- startidx = check_eq (cmp_func ,re -> max ,value ) ?i + 1 :i ;
668- endidx = rangerel -> nranges - 1 ;
669- }
670- result -> rangeset = list_make1_irange (make_irange (startidx ,endidx , true));
671- return ;
683+ if (i > 0 )
684+ result -> rangeset = lcons_irange (
685+ make_irange (0 ,i - 1 , false),result -> rangeset );
686+ }
687+ else
688+ {
689+ result -> rangeset = list_make1_irange (
690+ make_irange (0 ,i , false));
691+ }
692+ return ;
693+ case BTEqualStrategyNumber :
694+ result -> rangeset = list_make1_irange (make_irange (i ,i , true));
695+ return ;
696+ case BTGreaterEqualStrategyNumber :
697+ case BTGreaterStrategyNumber :
698+ if (lossy )
699+ {
700+ result -> rangeset = list_make1_irange (make_irange (i ,i , true));
701+ if (i < prel -> children_count - 1 )
702+ result -> rangeset = lappend_irange (result -> rangeset ,
703+ make_irange (i + 1 ,prel -> children_count - 1 , false));
704+ }
705+ else
706+ {
707+ result -> rangeset = list_make1_irange (
708+ make_irange (i ,prel -> children_count - 1 , false));
709+ }
710+ return ;
672711}
712+ result -> rangeset = list_make1_irange (make_irange (startidx ,endidx , true));
713+ return ;
673714}
674715}
675716