@@ -80,6 +80,12 @@ static bool validate_range_constraint(const Expr *expr,
80
80
const AttrNumber part_attno ,
81
81
Datum * lower , Datum * upper ,
82
82
bool * lower_null , bool * upper_null );
83
+ static bool validate_range_opexpr (const Expr * expr ,
84
+ const PartRelationInfo * prel ,
85
+ const TypeCacheEntry * tce ,
86
+ const AttrNumber part_attno ,
87
+ Datum * lower , Datum * upper ,
88
+ bool * lower_null , bool * upper_null );
83
89
84
90
static bool validate_hash_constraint (const Expr * expr ,
85
91
const PartRelationInfo * prel ,
@@ -920,6 +926,65 @@ cmp_range_entries(const void *p1, const void *p2, void *arg)
920
926
return cmp_bounds (flinfo , & v1 -> min , & v2 -> min );
921
927
}
922
928
929
+ /* Validates a single expression of kind VAR >= CONST or VAR < CONST */
930
+ static bool
931
+ validate_range_opexpr (const Expr * expr ,
932
+ const PartRelationInfo * prel ,
933
+ const TypeCacheEntry * tce ,
934
+ const AttrNumber part_attno ,
935
+ Datum * lower , Datum * upper ,
936
+ bool * lower_null , bool * upper_null )
937
+ {
938
+ const OpExpr * opexpr ;
939
+ Datum val ;
940
+
941
+ if (!expr )
942
+ return false;
943
+
944
+ /* Fail fast if it's not an OpExpr node */
945
+ if (!IsA (expr , OpExpr ))
946
+ return false;
947
+
948
+ /* Perform cast */
949
+ opexpr = (const OpExpr * ) expr ;
950
+
951
+ /* Try reading Const value */
952
+ if (!read_opexpr_const (opexpr , prel , part_attno , & val ))
953
+ return false;
954
+
955
+ /* Examine the strategy (expect '>=' OR '<') */
956
+ switch (get_op_opfamily_strategy (opexpr -> opno , tce -> btree_opf ))
957
+ {
958
+ case BTGreaterEqualStrategyNumber :
959
+ {
960
+ /* Bound already exists */
961
+ if (* lower_null == false)
962
+ return false;
963
+
964
+ * lower_null = false;
965
+ * lower = val ;
966
+
967
+ return true;
968
+ }
969
+
970
+ case BTLessStrategyNumber :
971
+ {
972
+ /* Bound already exists */
973
+ if (* upper_null == false)
974
+ return false;
975
+
976
+ * upper_null = false;
977
+ * upper = val ;
978
+
979
+ return true;
980
+ }
981
+
982
+ default :
983
+ return false;
984
+ }
985
+ }
986
+
987
+
923
988
/*
924
989
* Validates range constraint. It MUST have one of the following formats:
925
990
*
@@ -936,66 +1001,41 @@ validate_range_constraint(const Expr *expr,
936
1001
Datum * lower , Datum * upper ,
937
1002
bool * lower_null , bool * upper_null )
938
1003
{
939
- const TypeCacheEntry * tce ;
940
- const OpExpr * opexpr ;
941
- int strategy ;
942
-
943
- /* Validates a single expression of kind VAR >= CONST or VAR < CONST */
944
- #define validate_range_expr (expr , part_attno ) \
945
- { \
946
- Datum val; \
947
- opexpr = (OpExpr *) (expr); \
948
- strategy = get_op_opfamily_strategy(opexpr->opno, tce->btree_opf); \
949
- \
950
- /* Get const value */ \
951
- if (!read_opexpr_const (opexpr , prel , part_attno , & val )) \
952
- return false; \
953
- \
954
- /* Set min or max depending on operator */ \
955
- switch (strategy ) \
956
- { \
957
- case BTGreaterEqualStrategyNumber : \
958
- * lower_null = false; \
959
- * lower = val ; \
960
- break ; \
961
- case BTLessStrategyNumber : \
962
- * upper_null = false; \
963
- * upper = val ; \
964
- break ; \
965
- default : \
966
- return false; \
967
- } \
968
- }
1004
+ const TypeCacheEntry * tce ;
969
1005
970
1006
if (!expr )
971
1007
return false;
1008
+
1009
+ /* Set default values */
972
1010
* lower_null = * upper_null = true;
1011
+
1012
+ /* Find type cache entry for partitioned column's type */
973
1013
tce = lookup_type_cache (prel -> atttype , TYPECACHE_BTREE_OPFAMILY );
974
1014
975
- /* It could be either AND operator on top or just an OpExpr */
1015
+ /* Is it an AND clause? */
976
1016
if (and_clause ((Node * ) expr ))
977
1017
{
978
- const BoolExpr * boolexpr = (const BoolExpr * ) expr ;
979
- ListCell * lc ;
1018
+ const BoolExpr * boolexpr = (const BoolExpr * ) expr ;
1019
+ ListCell * lc ;
980
1020
1021
+ /* Walk through boolexpr's args */
981
1022
foreach (lc , boolexpr -> args )
982
1023
{
983
- Node * arg = lfirst (lc );
1024
+ const OpExpr * opexpr = ( const OpExpr * ) lfirst (lc );
984
1025
985
- if (!IsA (arg , OpExpr ))
1026
+ /* Exit immediately if something is wrong */
1027
+ if (!validate_range_opexpr ((const Expr * ) opexpr , prel , tce , part_attno ,
1028
+ lower , upper , lower_null , upper_null ))
986
1029
return false;
987
-
988
- validate_range_expr (arg , part_attno );
989
1030
}
990
- return true;
991
- }
992
- else if (IsA (expr , OpExpr ))
993
- {
994
- validate_range_expr (expr , part_attno );
1031
+
1032
+ /* Everything seems to be fine */
995
1033
return true;
996
1034
}
997
1035
998
- return false;
1036
+ /* It might be just an OpExpr clause */
1037
+ else return validate_range_opexpr (expr , prel , tce , part_attno ,
1038
+ lower , upper , lower_null , upper_null );
999
1039
}
1000
1040
1001
1041
/*
0 commit comments