Refactor ExhaustivePruneOne into ExhaustivePruneOneWithMinMax

pull/4753/head
Onur Tirtir 2021-02-27 00:30:39 +03:00
parent feee25dfbd
commit a114bf141e
2 changed files with 78 additions and 67 deletions

View File

@ -128,56 +128,6 @@ typedef struct PruningTreeBuildContext
PruningTreeNode *current; PruningTreeNode *current;
} PruningTreeBuildContext; } PruningTreeBuildContext;
/*
* A pruning instance is a set of ANDed constraints on a partition key.
*/
typedef struct PruningInstance
{
/* Does this instance contain any prunable expressions? */
bool hasValidConstraint;
/*
* This constraint never evaluates to true, i.e. pruning does not have to
* be performed.
*/
bool evaluatesToFalse;
/*
* Constraints on the partition column value. If multiple values are
* found the more restrictive one should be stored here. Even for
* a hash-partitioned table, actual column-values are stored here, *not*
* hashed values.
*/
Const *lessConsts;
Const *lessEqualConsts;
Const *equalConsts;
Const *greaterEqualConsts;
Const *greaterConsts;
/*
* Constraint using a pre-hashed column value. The constant will store the
* hashed value, not the original value of the restriction.
*/
Const *hashedEqualConsts;
/*
* Has this PruningInstance been added to
* ClauseWalkerContext->pruningInstances? This is not done immediately,
* but the first time a constraint (independent of us being able to handle
* that constraint) is found.
*/
bool addedToPruningInstances;
/*
* When OR clauses are found, the non-ORed part (think of a < 3 AND (a > 5
* OR a > 7)) of the expression is stored in one PruningInstance which is
* then copied for the ORed expressions. The original is marked as
* isPartial, to avoid being used for pruning.
*/
bool isPartial;
} PruningInstance;
/* /*
* Partial instances that need to be finished building. This is used to * Partial instances that need to be finished building. This is used to
* collect all ANDed restrictions, before looking into ORed expressions. * collect all ANDed restrictions, before looking into ORed expressions.
@ -1863,7 +1813,6 @@ ExhaustivePruneOne(ShardInterval *curInterval,
{ {
FunctionCallInfo compareFunctionCall = (FunctionCallInfo) & FunctionCallInfo compareFunctionCall = (FunctionCallInfo) &
context->compareIntervalFunctionCall; context->compareIntervalFunctionCall;
Datum compareWith = 0;
/* NULL boundaries can't be compared to */ /* NULL boundaries can't be compared to */
if (!curInterval->minValueExists || !curInterval->maxValueExists) if (!curInterval->minValueExists || !curInterval->maxValueExists)
@ -1871,30 +1820,43 @@ ExhaustivePruneOne(ShardInterval *curInterval,
return false; return false;
} }
return ExhaustivePruneOneWithMinMax(prune, compareFunctionCall,
curInterval->minValue,
curInterval->maxValue);
}
/*
* ExhaustivePruneOneWithMinMax returns true if given "prune" object prunes
* the interval with given min and max values.
*/
bool
ExhaustivePruneOneWithMinMax(PruningInstance *prune,
FunctionCallInfo compareFunctionCall,
Datum minimumValue, Datum maximumValue)
{
if (prune->equalConsts) if (prune->equalConsts)
{ {
compareWith = prune->equalConsts->constvalue; Datum compareWith = prune->equalConsts->constvalue;
if (PerformValueCompare(compareFunctionCall, if (PerformValueCompare(compareFunctionCall,
compareWith, compareWith,
curInterval->minValue) < 0) minimumValue) < 0)
{ {
return true; return true;
} }
if (PerformValueCompare(compareFunctionCall, if (PerformValueCompare(compareFunctionCall,
compareWith, compareWith,
curInterval->maxValue) > 0) maximumValue) > 0)
{ {
return true; return true;
} }
} }
if (prune->greaterEqualConsts) if (prune->greaterEqualConsts)
{ {
compareWith = prune->greaterEqualConsts->constvalue; Datum compareWith = prune->greaterEqualConsts->constvalue;
if (PerformValueCompare(compareFunctionCall, if (PerformValueCompare(compareFunctionCall,
curInterval->maxValue, maximumValue,
compareWith) < 0) compareWith) < 0)
{ {
return true; return true;
@ -1902,10 +1864,9 @@ ExhaustivePruneOne(ShardInterval *curInterval,
} }
if (prune->greaterConsts) if (prune->greaterConsts)
{ {
compareWith = prune->greaterConsts->constvalue; Datum compareWith = prune->greaterConsts->constvalue;
if (PerformValueCompare(compareFunctionCall, if (PerformValueCompare(compareFunctionCall,
curInterval->maxValue, maximumValue,
compareWith) <= 0) compareWith) <= 0)
{ {
return true; return true;
@ -1913,10 +1874,9 @@ ExhaustivePruneOne(ShardInterval *curInterval,
} }
if (prune->lessEqualConsts) if (prune->lessEqualConsts)
{ {
compareWith = prune->lessEqualConsts->constvalue; Datum compareWith = prune->lessEqualConsts->constvalue;
if (PerformValueCompare(compareFunctionCall, if (PerformValueCompare(compareFunctionCall,
curInterval->minValue, minimumValue,
compareWith) > 0) compareWith) > 0)
{ {
return true; return true;
@ -1924,10 +1884,9 @@ ExhaustivePruneOne(ShardInterval *curInterval,
} }
if (prune->lessConsts) if (prune->lessConsts)
{ {
compareWith = prune->lessConsts->constvalue; Datum compareWith = prune->lessConsts->constvalue;
if (PerformValueCompare(compareFunctionCall, if (PerformValueCompare(compareFunctionCall,
curInterval->minValue, minimumValue,
compareWith) >= 0) compareWith) >= 0)
{ {
return true; return true;

View File

@ -16,6 +16,55 @@
#define INVALID_SHARD_INDEX -1 #define INVALID_SHARD_INDEX -1
/*
* A pruning instance is a set of ANDed constraints on a partition key.
*/
typedef struct PruningInstance
{
/* Does this instance contain any prunable expressions? */
bool hasValidConstraint;
/*
* This constraint never evaluates to true, i.e. pruning does not have to
* be performed.
*/
bool evaluatesToFalse;
/*
* Constraints on the partition column value. If multiple values are
* found the more restrictive one should be stored here. Even for
* a hash-partitioned table, actual column-values are stored here, *not*
* hashed values.
*/
Const *lessConsts;
Const *lessEqualConsts;
Const *equalConsts;
Const *greaterEqualConsts;
Const *greaterConsts;
/*
* Constraint using a pre-hashed column value. The constant will store the
* hashed value, not the original value of the restriction.
*/
Const *hashedEqualConsts;
/*
* Has this PruningInstance been added to
* ClauseWalkerContext->pruningInstances? This is not done immediately,
* but the first time a constraint (independent of us being able to handle
* that constraint) is found.
*/
bool addedToPruningInstances;
/*
* When OR clauses are found, the non-ORed part (think of a < 3 AND (a > 5
* OR a > 7)) of the expression is stored in one PruningInstance which is
* then copied for the ORed expressions. The original is marked as
* isPartial, to avoid being used for pruning.
*/
bool isPartial;
} PruningInstance;
/* Function declarations for shard pruning */ /* Function declarations for shard pruning */
extern List * PruneShards(Oid relationId, Index rangeTableId, List *whereClauseList, extern List * PruneShards(Oid relationId, Index rangeTableId, List *whereClauseList,
Const **partitionValueConst); Const **partitionValueConst);
@ -25,5 +74,8 @@ extern Const * TransformPartitionRestrictionValue(Var *partitionColumn,
Const *restrictionValue, Const *restrictionValue,
bool missingOk); bool missingOk);
bool VarConstOpExprClause(OpExpr *opClause, Var **varClause, Const **constantClause); bool VarConstOpExprClause(OpExpr *opClause, Var **varClause, Const **constantClause);
extern bool ExhaustivePruneOneWithMinMax(PruningInstance *prune,
FunctionCallInfo compareFunctionCall,
Datum minimumValue, Datum maximumValue);
#endif /* SHARD_PRUNING_H_ */ #endif /* SHARD_PRUNING_H_ */