@@ -75,8 +75,8 @@ static int cmp_range_entries(const void *p1, const void *p2, void *arg);
75
75
76
76
static bool validate_range_constraint (const Expr * expr ,
77
77
const PartRelationInfo * prel ,
78
- Datum * min ,
79
- Datum * max );
78
+ Datum * lower , Datum * upper ,
79
+ bool * lower_null , bool * upper_null );
80
80
81
81
static bool validate_hash_constraint (const Expr * expr ,
82
82
const PartRelationInfo * prel ,
@@ -375,14 +375,18 @@ fill_prel_with_partitions(const Oid *partitions,
375
375
376
376
case PT_RANGE :
377
377
{
378
- Datum range_min ,range_max ;
378
+ Datum lower ,upper ;
379
+ bool lower_null ,upper_null ;
379
380
380
381
if (validate_range_constraint (con_expr ,prel ,
381
- & range_min ,& range_max ))
382
+ & lower ,& upper ,
383
+ & lower_null ,& upper_null ))
382
384
{
383
- prel -> ranges [i ].child_oid = partitions [i ];
384
- prel -> ranges [i ].min = range_min ;
385
- prel -> ranges [i ].max = range_max ;
385
+ prel -> ranges [i ].child_oid = partitions [i ];
386
+ prel -> ranges [i ].min = lower ;
387
+ prel -> ranges [i ].max = upper ;
388
+ prel -> ranges [i ].infinite_min = lower_null ;
389
+ prel -> ranges [i ].infinite_max = upper_null ;
386
390
}
387
391
else
388
392
{
@@ -864,61 +868,91 @@ cmp_range_entries(const void *p1, const void *p2, void *arg)
864
868
865
869
Oid cmp_proc_oid = * (Oid * )arg ;
866
870
871
+ /* If range is half open */
872
+ if (v1 -> infinite_min )
873
+ if (v2 -> infinite_min )
874
+ return Int32GetDatum (0 );
875
+ return Int32GetDatum (-1 );
876
+
877
+ /* Else if range is closed */
867
878
return OidFunctionCall2 (cmp_proc_oid ,v1 -> min ,v2 -> min );
868
879
}
869
880
870
881
/*
871
- * Validates range constraint. It MUST havethis exact format :
882
+ * Validates range constraint. It MUST haveone of the following formats :
872
883
*
873
884
*VARIABLE >= CONST AND VARIABLE < CONST
885
+ *VARIABLE >= CONST
886
+ *VARIABLE < CONST
874
887
*
875
- * Writes 'min ' & 'max ' values on success.
888
+ * Writes 'lower ' & 'upper' and 'lower_null' & 'upper_null ' values on success.
876
889
*/
877
890
static bool
878
891
validate_range_constraint (const Expr * expr ,
879
892
const PartRelationInfo * prel ,
880
- Datum * min ,
881
- Datum * max )
893
+ Datum * lower , Datum * upper ,
894
+ bool * lower_null , bool * upper_null )
882
895
{
883
896
const TypeCacheEntry * tce ;
884
- const BoolExpr * boolexpr = (const BoolExpr * )expr ;
885
897
const OpExpr * opexpr ;
886
898
int strategy ;
887
899
888
- if (!expr )
889
- return false;
900
+ /* Validates a single expression of kind VAR >= CONST or VAR < CONST */
901
+ #define validate_range_expr (expr )\
902
+ {\
903
+ Datum val;\
904
+ opexpr = (OpExpr *) (expr);\
905
+ strategy = get_op_opfamily_strategy(opexpr->opno, tce->btree_opf);\
906
+ \
907
+ /* Get const value */ \
908
+ if (!read_opexpr_const (opexpr ,prel ,& val ))\
909
+ return false;\
910
+ \
911
+ /* Set min or max depending on operator */ \
912
+ switch (strategy )\
913
+ {\
914
+ case BTGreaterEqualStrategyNumber :\
915
+ * lower_null = false;\
916
+ * lower = val ;\
917
+ break ;\
918
+ case BTLessStrategyNumber :\
919
+ * upper_null = false;\
920
+ * upper = val ;\
921
+ break ;\
922
+ default :\
923
+ return false;\
924
+ }\
925
+ }
890
926
891
- /* it should be an AND operator on top */
892
- if (!and_clause ((Node * )expr ))
927
+ if (!expr )
893
928
return false;
894
-
929
+ * lower_null = * upper_null = false;
895
930
tce = lookup_type_cache (prel -> atttype ,TYPECACHE_BTREE_OPFAMILY );
896
931
897
- /* check that left operand is >= operator */
898
- opexpr = (OpExpr * )linitial (boolexpr -> args );
899
- strategy = get_op_opfamily_strategy (opexpr -> opno ,tce -> btree_opf );
900
-
901
- if (strategy == BTGreaterEqualStrategyNumber )
932
+ /* It could be either AND operator on top or just an OpExpr */
933
+ if (and_clause ((Node * )expr ))
902
934
{
903
- if (!read_opexpr_const (opexpr ,prel ,min ))
904
- return false;
905
- }
906
- else
907
- return false;
935
+ const BoolExpr * boolexpr = (const BoolExpr * )expr ;
936
+ ListCell * lc ;
937
+
938
+ foreach (lc ,boolexpr -> args )
939
+ {
940
+ Node * arg = lfirst (lc );
908
941
909
- /* check that right operand is < operator */
910
- opexpr = (OpExpr * )lsecond (boolexpr -> args );
911
- strategy = get_op_opfamily_strategy (opexpr -> opno ,tce -> btree_opf );
942
+ if (!IsA (arg ,OpExpr ))
943
+ return false;
912
944
913
- if (strategy == BTLessStrategyNumber )
945
+ validate_range_expr (arg );
946
+ }
947
+ return true;
948
+ }
949
+ else if (IsA (expr ,OpExpr ))
914
950
{
915
- if (! read_opexpr_const ( opexpr , prel , max ))
916
- return false ;
951
+ validate_range_expr ( expr );
952
+ return true ;
917
953
}
918
- else
919
- return false;
920
954
921
- return true ;
955
+ return false ;
922
956
}
923
957
924
958
/*