Skip to content

Commit 609813b

Browse files
committed
fix function get_pathman_relation_info(), refactoring for function validate_range_constraint()
1 parent b86a0e6 commit 609813b

File tree

2 files changed

+89
-44
lines changed

2 files changed

+89
-44
lines changed

src/init.c

Lines changed: 83 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ static bool validate_range_constraint(const Expr *expr,
8080
const AttrNumber part_attno,
8181
Datum *lower, Datum *upper,
8282
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);
8389

8490
static bool validate_hash_constraint(const Expr *expr,
8591
const PartRelationInfo *prel,
@@ -920,6 +926,65 @@ cmp_range_entries(const void *p1, const void *p2, void *arg)
920926
return cmp_bounds(flinfo, &v1->min, &v2->min);
921927
}
922928

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+
923988
/*
924989
* Validates range constraint. It MUST have one of the following formats:
925990
*
@@ -936,66 +1001,41 @@ validate_range_constraint(const Expr *expr,
9361001
Datum *lower, Datum *upper,
9371002
bool *lower_null, bool *upper_null)
9381003
{
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;
9691005

9701006
if (!expr)
9711007
return false;
1008+
1009+
/* Set default values */
9721010
*lower_null = *upper_null = true;
1011+
1012+
/* Find type cache entry for partitioned column's type */
9731013
tce = lookup_type_cache(prel->atttype, TYPECACHE_BTREE_OPFAMILY);
9741014

975-
/* It could be either AND operator on top or just an OpExpr */
1015+
/* Is it an AND clause? */
9761016
if (and_clause((Node *) expr))
9771017
{
978-
const BoolExpr *boolexpr = (const BoolExpr *) expr;
979-
ListCell *lc;
1018+
const BoolExpr *boolexpr = (const BoolExpr *) expr;
1019+
ListCell *lc;
9801020

1021+
/* Walk through boolexpr's args */
9811022
foreach (lc, boolexpr->args)
9821023
{
983-
Node *arg = lfirst(lc);
1024+
const OpExpr *opexpr = (const OpExpr *) lfirst(lc);
9841025

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))
9861029
return false;
987-
988-
validate_range_expr(arg, part_attno);
9891030
}
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 */
9951033
return true;
9961034
}
9971035

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);
9991039
}
10001040

10011041
/*

src/relation_info.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,13 @@ get_pathman_relation_info(Oid relid)
296296
/* TODO: possible refactoring, pass found 'prel' instead of searching */
297297
prel = refresh_pathman_relation_info(relid, part_type, attname, false);
298298
}
299+
299300
/* Else clear remaining cache entry */
300-
else remove_pathman_relation_info(relid);
301+
else
302+
{
303+
remove_pathman_relation_info(relid);
304+
prel = NULL; /* don't forget to reset 'prel' */
305+
}
301306
}
302307

303308
elog(DEBUG2,

0 commit comments

Comments
 (0)