mirror of https://github.com/citusdata/citus.git
Clean up from code review
Only change to behavior is: - don't ignore array const's constcollid in SAORestrictions - don't end lines with commas in DebugLogPruningInstancepull/3486/head
parent
cdedb98c54
commit
7382c8be00
|
@ -7,8 +7,8 @@
|
|||
* need to be queried to find rows matching the expression in a query.
|
||||
*
|
||||
* In PruneShards we first make a compact representation of the given
|
||||
* query logical tree. This tree represent boolean operators and its
|
||||
* associated valid constrainst (expression nodes) and whether boolean
|
||||
* query logical tree. This tree represents boolean operators and its
|
||||
* associated valid constraints (expression nodes) and whether boolean
|
||||
* operator has associated unknown constraints. This allows essentially
|
||||
* unknown constraints to be replaced by a simple placeholder flag.
|
||||
*
|
||||
|
@ -17,7 +17,7 @@
|
|||
* 1. AND(hash_col IN (1,2), OR(X, X))
|
||||
* 2. AND(hash_col IN (1,2), OR(X))
|
||||
* 3. AND(hash_col IN (1,2), X)
|
||||
* Where X represents any (set of) unrecognized unprunable constraint(s).
|
||||
* Where X represents any set of unrecognized unprunable constraint(s).
|
||||
*
|
||||
* Above allows the following pruning machinery to understand that
|
||||
* the target shard is determined solely by constraint: hash_col IN (1,2).
|
||||
|
@ -38,7 +38,7 @@
|
|||
* expressions. While (P OR Q) AND (R OR S) is logically equivalent to (P AND
|
||||
* R) OR (P AND S) OR (Q AND R) OR (Q AND S), in our implementation it becomes
|
||||
* P OR Q OR R OR S. This is acceptable since this will always result in a
|
||||
* superset of shards. If this proves to be a issue in practice, a more
|
||||
* superset of shards. If this proves to be a issue in practice, a more
|
||||
* complete algorithm could be implemented.
|
||||
*
|
||||
* We then evaluate each non-partial pruning instance in the disjunction
|
||||
|
@ -93,6 +93,7 @@
|
|||
#include "utils/memutils.h"
|
||||
#include "utils/ruleutils.h"
|
||||
|
||||
|
||||
/*
|
||||
* Tree node for compact representation of the given query logical tree.
|
||||
* Represent a single boolean operator node and its associated
|
||||
|
@ -101,7 +102,7 @@
|
|||
typedef struct PruningTreeNode
|
||||
{
|
||||
/* Indicates is this AND/OR boolean operator */
|
||||
bool isAnd;
|
||||
BoolExprType boolop;
|
||||
|
||||
/* Does this boolean operator have unknown/unprunable constraint(s) */
|
||||
bool hasInvalidConstraints;
|
||||
|
@ -109,10 +110,7 @@ typedef struct PruningTreeNode
|
|||
/* List of recognized valid prunable constraints of this boolean opearator */
|
||||
List *validConstraints;
|
||||
|
||||
/*
|
||||
* Child boolean operators.
|
||||
* Parent is always different boolean operator from its children.
|
||||
*/
|
||||
/* Child boolean producing operators. Parents are always different from their children */
|
||||
List *childBooleanNodes;
|
||||
} PruningTreeNode;
|
||||
|
||||
|
@ -140,8 +138,8 @@ typedef struct PruningInstance
|
|||
bool evaluatesToFalse;
|
||||
|
||||
/*
|
||||
* Constraints on the partition column value. If multiple values are
|
||||
* found the more restrictive one should be stored here. Even in case of
|
||||
* 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.
|
||||
*/
|
||||
|
@ -168,15 +166,15 @@ typedef struct PruningInstance
|
|||
/*
|
||||
* 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 it being used for pruning.
|
||||
* 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.
|
||||
*/
|
||||
typedef struct PendingPruningInstance
|
||||
|
@ -274,32 +272,13 @@ static int LowerShardBoundary(Datum partitionColumnValue,
|
|||
ShardInterval **shardIntervalCache,
|
||||
int shardCount, FunctionCallInfo compareFunction,
|
||||
bool includeMax);
|
||||
static inline PruningTreeNode * CreatePruningNode(bool isAnd);
|
||||
static inline OpExpr * SAORestrictionArrayEqualityOp(
|
||||
ScalarArrayOpExpr *arrayOperatorExpression,
|
||||
Var *partitionColumn);
|
||||
static inline void DebugLogNode(char *fmt, Node *node, List *deparseCtx);
|
||||
static PruningTreeNode * CreatePruningNode(BoolExprType boolop);
|
||||
static OpExpr * SAORestrictionArrayEqualityOp(ScalarArrayOpExpr *arrayOperatorExpression,
|
||||
Var *partitionColumn);
|
||||
static void DebugLogNode(char *fmt, Node *node, List *deparseCtx);
|
||||
static void DebugLogPruningInstance(PruningInstance *pruning, List *deparseCtx);
|
||||
static int ConstraintCount(PruningTreeNode *node);
|
||||
|
||||
#define AndBooleanNode() (CreatePruningNode(true))
|
||||
#define OrBooleanNode() (CreatePruningNode(false))
|
||||
#define IsAndOp(node) ((node)->isAnd)
|
||||
#define IsOrOp(node) (!(node)->isAnd)
|
||||
#define ConstraintCount(node) \
|
||||
(list_length((node)->childBooleanNodes) + \
|
||||
list_length((node)->validConstraints) + \
|
||||
((node)->hasInvalidConstraints ? 1 : 0))
|
||||
|
||||
#define DebugLogPruningInstance(prune, deparseCtx) \
|
||||
DebugLogNode("constraint value: %s, ", \
|
||||
(Node *) (prune)->equalConsts, (deparseCtx)); \
|
||||
DebugLogNode("constraint (lt) value: %s, ", \
|
||||
(Node *) (prune)->lessConsts, (deparseCtx)); \
|
||||
DebugLogNode("constraint (lteq) value: %s, ", \
|
||||
(Node *) (prune)->lessEqualConsts, (deparseCtx)); \
|
||||
DebugLogNode("constraint (gt) value: %s, ", \
|
||||
(Node *) (prune)->greaterConsts, (deparseCtx)); \
|
||||
DebugLogNode("constraint (gteq) value: %s, ", \
|
||||
(Node *) (prune)->greaterEqualConsts, (deparseCtx));
|
||||
|
||||
/*
|
||||
* PruneShards returns all shards from a distributed table that cannot be
|
||||
|
@ -378,7 +357,7 @@ PruneShards(Oid relationId, Index rangeTableId, List *whereClauseList,
|
|||
"a partition column comparator")));
|
||||
}
|
||||
|
||||
PruningTreeNode *tree = AndBooleanNode();
|
||||
PruningTreeNode *tree = CreatePruningNode(AND_EXPR);
|
||||
|
||||
PruningTreeBuildContext treeBuildContext = { 0 };
|
||||
treeBuildContext.current = tree;
|
||||
|
@ -393,7 +372,7 @@ PruneShards(Oid relationId, Index rangeTableId, List *whereClauseList,
|
|||
/* Figure out what we can prune on */
|
||||
PrunableExpressions(tree, &context);
|
||||
|
||||
List *debugLoggedPruningInstances = NULL;
|
||||
List *debugLoggedPruningInstances = NIL;
|
||||
|
||||
/*
|
||||
* Prune using each of the PrunableInstances we found, and OR results
|
||||
|
@ -414,7 +393,7 @@ PruneShards(Oid relationId, Index rangeTableId, List *whereClauseList,
|
|||
|
||||
/*
|
||||
* If the current instance has no prunable expressions, we'll have to
|
||||
* return all shards. No point in continuing pruning in that case.
|
||||
* return all shards. No point in continuing pruning in that case.
|
||||
*/
|
||||
if (!prune->hasValidConstraint)
|
||||
{
|
||||
|
@ -485,7 +464,7 @@ PruneShards(Oid relationId, Index rangeTableId, List *whereClauseList,
|
|||
|
||||
if (IsLoggableLevel(DEBUG3))
|
||||
{
|
||||
if (foundRestriction && debugLoggedPruningInstances)
|
||||
if (foundRestriction && debugLoggedPruningInstances != NIL)
|
||||
{
|
||||
List *deparseCtx = deparse_context_for("unknown", relationId);
|
||||
foreach(pruneCell, debugLoggedPruningInstances)
|
||||
|
@ -524,7 +503,7 @@ PruneShards(Oid relationId, Index rangeTableId, List *whereClauseList,
|
|||
|
||||
|
||||
/*
|
||||
* Check whether node is a valid constraint for pruning
|
||||
* IsValidConditionNode checks whether node is a valid constraint for pruning.
|
||||
*/
|
||||
static bool
|
||||
IsValidConditionNode(Node *node, Var *partitionColumn)
|
||||
|
@ -550,12 +529,7 @@ IsValidConditionNode(Node *node, Var *partitionColumn)
|
|||
else if (IsA(node, ScalarArrayOpExpr))
|
||||
{
|
||||
ScalarArrayOpExpr *arrayOperatorExpression = (ScalarArrayOpExpr *) node;
|
||||
if (SAORestrictions(arrayOperatorExpression, partitionColumn, NULL))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return SAORestrictions(arrayOperatorExpression, partitionColumn, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -565,7 +539,7 @@ IsValidConditionNode(Node *node, Var *partitionColumn)
|
|||
|
||||
|
||||
/*
|
||||
* Build a logical tree of valid constraints and invalid constaints for pruning.
|
||||
* BuildPruningTree builds a logical tree of constraints for pruning.
|
||||
*/
|
||||
static bool
|
||||
BuildPruningTree(Node *node, PruningTreeBuildContext *context)
|
||||
|
@ -582,15 +556,14 @@ BuildPruningTree(Node *node, PruningTreeBuildContext *context)
|
|||
else if (IsA(node, BoolExpr))
|
||||
{
|
||||
BoolExpr *boolExpr = (BoolExpr *) node;
|
||||
bool isAnded = boolExpr->boolop == AND_EXPR;
|
||||
|
||||
if (boolExpr->boolop == NOT_EXPR)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (context->current->isAnd != isAnded)
|
||||
else if (context->current->boolop != boolExpr->boolop)
|
||||
{
|
||||
PruningTreeNode *child = CreatePruningNode(isAnded);
|
||||
PruningTreeNode *child = CreatePruningNode(boolExpr->boolop);
|
||||
|
||||
context->current->childBooleanNodes = lappend(
|
||||
context->current->childBooleanNodes, child);
|
||||
|
@ -624,14 +597,12 @@ BuildPruningTree(Node *node, PruningTreeBuildContext *context)
|
|||
|
||||
|
||||
/*
|
||||
* Simplifies the logical tree of valid and invalid constraints for pruning.
|
||||
* SimplifyPruningTree reduces logical tree of valid and invalid constraints for pruning.
|
||||
* The goal is to remove any node having just a single constraint associated with it.
|
||||
* This constraint is assigned to the parent logical node.
|
||||
* Removal of nodes is done by traversing from tree leafs upward.
|
||||
*
|
||||
* For example logical tree of
|
||||
* AND(hash_col = 1, OR(X)) gets simplified into AND(hash_col = 1, X)
|
||||
* Where X is any unknown condition.
|
||||
* For example 'AND(hash_col = 1, OR(X))' gets simplified to 'AND(hash_col = 1, X)',
|
||||
* where X is any unknown condition.
|
||||
*/
|
||||
static void
|
||||
SimplifyPruningTree(PruningTreeNode *node, PruningTreeNode *parent)
|
||||
|
@ -649,11 +620,11 @@ SimplifyPruningTree(PruningTreeNode *node, PruningTreeNode *parent)
|
|||
if (!parent)
|
||||
{
|
||||
/* Root is always ANDed expressions */
|
||||
Assert(IsAndOp(node));
|
||||
Assert(node->boolop == AND_EXPR);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Boolean operator with just a single (regocnized/unknown) constraints gets simplified */
|
||||
/* Boolean operator with single (recognized/unknown) constraint gets simplified */
|
||||
if (ConstraintCount(node) <= 1)
|
||||
{
|
||||
parent->validConstraints = list_concat(parent->validConstraints,
|
||||
|
@ -704,19 +675,19 @@ static void
|
|||
PrunableExpressions(PruningTreeNode *tree, ClauseWalkerContext *context)
|
||||
{
|
||||
/*
|
||||
* Build initial list of prunable expressions. As long as only,
|
||||
* Build initial list of prunable expressions. As long as only,
|
||||
* implicitly or explicitly, ANDed expressions are found, this perform a
|
||||
* depth-first search. When an ORed expression is found, the current
|
||||
* depth-first search. When an ORed expression is found, the current
|
||||
* PruningInstance is added to context->pruningInstances (once for each
|
||||
* ORed expression), then the tree-traversal is continued without
|
||||
* recursing. Once at the top-level again, we'll process all pending
|
||||
* recursing. Once at the top-level again, we'll process all pending
|
||||
* expressions - that allows us to find all ANDed expressions, before
|
||||
* recursing into an ORed expression.
|
||||
*/
|
||||
PrunableExpressionsWalker(tree, context);
|
||||
|
||||
/*
|
||||
* Process all pending instances. While processing, new ones might be
|
||||
* Process all pending instances. While processing, new ones might be
|
||||
* added to the list, so don't use foreach().
|
||||
*
|
||||
* Check the places in PruningInstanceWalker that push onto
|
||||
|
@ -756,15 +727,15 @@ PrunableExpressionsWalker(PruningTreeNode *node, ClauseWalkerContext *context)
|
|||
return;
|
||||
}
|
||||
|
||||
if (IsOrOp(node))
|
||||
if (node->boolop == OR_EXPR)
|
||||
{
|
||||
/*
|
||||
* "Queue" partial pruning instances. This is used to convert
|
||||
* "Queue" partial pruning instances. This is used to convert
|
||||
* expressions like (A AND (B OR C) AND D) into (A AND B AND D),
|
||||
* (A AND C AND D), with A, B, C, D being restrictions. When the
|
||||
* (A AND C AND D), with A, B, C, D being restrictions. When the
|
||||
* OR is encountered, a reference to the partially built
|
||||
* PruningInstance (containing A at this point), is added to
|
||||
* context->pendingInstances once for B and once for C. Once a
|
||||
* context->pendingInstances once for B and once for C. Once a
|
||||
* full tree-walk completed, PrunableExpressions() will complete
|
||||
* the pending instances, which'll now also know about restriction
|
||||
* D, by calling PrunableExpressionsWalker() once for B and once
|
||||
|
@ -773,7 +744,7 @@ PrunableExpressionsWalker(PruningTreeNode *node, ClauseWalkerContext *context)
|
|||
|
||||
if (node->hasInvalidConstraints)
|
||||
{
|
||||
PruningTreeNode *child = AndBooleanNode();
|
||||
PruningTreeNode *child = CreatePruningNode(AND_EXPR);
|
||||
child->hasInvalidConstraints = true;
|
||||
|
||||
AddNewConjuction(context, child);
|
||||
|
@ -783,7 +754,7 @@ PrunableExpressionsWalker(PruningTreeNode *node, ClauseWalkerContext *context)
|
|||
{
|
||||
Node *constraint = (Node *) lfirst(cell);
|
||||
|
||||
PruningTreeNode *child = AndBooleanNode();
|
||||
PruningTreeNode *child = CreatePruningNode(AND_EXPR);
|
||||
child->validConstraints = list_make1(constraint);
|
||||
|
||||
AddNewConjuction(context, child);
|
||||
|
@ -792,14 +763,14 @@ PrunableExpressionsWalker(PruningTreeNode *node, ClauseWalkerContext *context)
|
|||
foreach(cell, node->childBooleanNodes)
|
||||
{
|
||||
PruningTreeNode *child = (PruningTreeNode *) lfirst(cell);
|
||||
Assert(IsAndOp(child));
|
||||
Assert(child->boolop == AND_EXPR);
|
||||
AddNewConjuction(context, child);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Assert(IsAndOp(node));
|
||||
Assert(node->boolop == AND_EXPR);
|
||||
|
||||
foreach(cell, node->validConstraints)
|
||||
{
|
||||
|
@ -881,14 +852,14 @@ PrunableExpressionsWalker(PruningTreeNode *node, ClauseWalkerContext *context)
|
|||
foreach(cell, node->childBooleanNodes)
|
||||
{
|
||||
PruningTreeNode *child = (PruningTreeNode *) lfirst(cell);
|
||||
Assert(IsOrOp(child));
|
||||
Assert(child->boolop == OR_EXPR);
|
||||
PrunableExpressionsWalker(child, context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check whether expression is a valid comparison of a var to a constant.
|
||||
* VarConstOpExprClause check whether an expression is a valid comparison of a Var to a Const.
|
||||
* Also obtaining the var with constant when valid.
|
||||
*/
|
||||
static bool
|
||||
|
@ -946,21 +917,20 @@ AddSAOPartitionKeyRestrictionToInstance(ClauseWalkerContext *context,
|
|||
ScalarArrayOpExpr *arrayOperatorExpression)
|
||||
{
|
||||
List *restrictions = NULL;
|
||||
if (SAORestrictions(arrayOperatorExpression, context->partitionColumn, &restrictions))
|
||||
{
|
||||
PruningTreeNode *node = OrBooleanNode();
|
||||
node->validConstraints = restrictions;
|
||||
AddNewConjuction(context, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert(false);
|
||||
}
|
||||
bool validSAORestriction PG_USED_FOR_ASSERTS_ONLY =
|
||||
SAORestrictions(arrayOperatorExpression, context->partitionColumn, &restrictions);
|
||||
|
||||
Assert(validSAORestriction);
|
||||
|
||||
PruningTreeNode *node = CreatePruningNode(OR_EXPR);
|
||||
node->validConstraints = restrictions;
|
||||
AddNewConjuction(context, node);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check whether SAO constraint is valid. Also obtaining the built equality restrictions.
|
||||
* SAORestrictions checks whether an SAO constraint is valid.
|
||||
* Also obtains equality restrictions.
|
||||
*/
|
||||
static bool
|
||||
SAORestrictions(ScalarArrayOpExpr *arrayOperatorExpression, Var *partitionColumn,
|
||||
|
@ -977,11 +947,12 @@ SAORestrictions(ScalarArrayOpExpr *arrayOperatorExpression, Var *partitionColumn
|
|||
equal(strippedLeftOpExpression, partitionColumn) &&
|
||||
IsA(arrayArgument, Const))
|
||||
{
|
||||
Const *arrayConst = (Const *) arrayArgument;
|
||||
int16 typlen = 0;
|
||||
bool typbyval = false;
|
||||
char typalign = '\0';
|
||||
Datum arrayElement = 0;
|
||||
Datum inArray = ((Const *) arrayArgument)->constvalue;
|
||||
Datum inArray = arrayConst->constvalue;
|
||||
bool isNull = false;
|
||||
bool foundValid = false;
|
||||
|
||||
|
@ -991,7 +962,7 @@ SAORestrictions(ScalarArrayOpExpr *arrayOperatorExpression, Var *partitionColumn
|
|||
return false;
|
||||
}
|
||||
|
||||
ArrayType *array = DatumGetArrayTypeP(((Const *) arrayArgument)->constvalue);
|
||||
ArrayType *array = DatumGetArrayTypeP(arrayConst->constvalue);
|
||||
|
||||
/* get the necessary information from array type to iterate over it */
|
||||
Oid elementType = ARR_ELEMTYPE(array);
|
||||
|
@ -1018,8 +989,8 @@ SAORestrictions(ScalarArrayOpExpr *arrayOperatorExpression, Var *partitionColumn
|
|||
if (requestedRestrictions)
|
||||
{
|
||||
Const *constElement = makeConst(elementType, -1,
|
||||
DEFAULT_COLLATION_OID, typlen,
|
||||
arrayElement,
|
||||
arrayConst->constcollid,
|
||||
typlen, arrayElement,
|
||||
isNull, typbyval);
|
||||
|
||||
/* build partcol = arrayelem operator */
|
||||
|
@ -1058,7 +1029,7 @@ AddNewConjuction(ClauseWalkerContext *context, PruningTreeNode *node)
|
|||
|
||||
/*
|
||||
* Signal that this instance is not to be used for pruning on
|
||||
* its own. Once the pending instance is processed, it'll be
|
||||
* its own. Once the pending instance is processed, it'll be
|
||||
* used.
|
||||
*/
|
||||
instance->instance->isPartial = true;
|
||||
|
@ -1067,7 +1038,8 @@ AddNewConjuction(ClauseWalkerContext *context, PruningTreeNode *node)
|
|||
|
||||
|
||||
/*
|
||||
* Check whether operator clause is valid restriction for partition column.
|
||||
* IsValidPartitionKeyRestriction check whether an operator clause is
|
||||
* a valid restriction for comparing to a partition column.
|
||||
*/
|
||||
static bool
|
||||
IsValidPartitionKeyRestriction(OpExpr *opClause)
|
||||
|
@ -1216,11 +1188,12 @@ AddPartitionKeyRestrictionToInstance(ClauseWalkerContext *context, OpExpr *opCla
|
|||
|
||||
|
||||
/*
|
||||
* Sometimes PostgreSQL chooses to try to wrap our Var in a coercion rather
|
||||
* than the Const; to deal with this, we strip the coercions from both and
|
||||
* manually coerce the Const into the type of our partition column. It is
|
||||
* conceivable that in some instances, this may not be possible; in those cases
|
||||
* we will simply fail to prune partitions based on this clause.
|
||||
* TransformPartitionRestrictionValue works around how PostgreSQL sometimes
|
||||
* chooses to try to wrap our Var in a coercion rather than the Const.
|
||||
* To deal with this, we strip coercions from both and manually coerce
|
||||
* the Const into the type of our partition column.
|
||||
* It is conceivable that in some instances this may not be possible,
|
||||
* in those cases we will simply fail to prune partitions based on this clause.
|
||||
*/
|
||||
static Const *
|
||||
TransformPartitionRestrictionValue(Var *partitionColumn, Const *restrictionValue)
|
||||
|
@ -1255,7 +1228,7 @@ TransformPartitionRestrictionValue(Var *partitionColumn, Const *restrictionValue
|
|||
|
||||
|
||||
/*
|
||||
* Check whether operator clause is valid restriction for hashed column.
|
||||
* IsValidHashRestriction checks whether an operator clause is a valid restriction for hashed column.
|
||||
*/
|
||||
static bool
|
||||
IsValidHashRestriction(OpExpr *opClause)
|
||||
|
@ -1293,11 +1266,11 @@ AddHashRestrictionToInstance(ClauseWalkerContext *context, OpExpr *opClause,
|
|||
Assert(IsValidHashRestriction(opClause));
|
||||
|
||||
/*
|
||||
* Ladidadida, dirty hackety hack. We only add such
|
||||
* Ladidadida, dirty hackety hack. We only add such
|
||||
* constraints (in ShardIntervalOpExpressions()) to select a
|
||||
* shard based on its exact boundaries. For efficient binary
|
||||
* shard based on its exact boundaries. For efficient binary
|
||||
* search it's better to simply use one representative value
|
||||
* to look up the shard. In practice, this is sufficient for
|
||||
* to look up the shard. In practice, this is sufficient for
|
||||
* now.
|
||||
*/
|
||||
PruningInstance *prune = context->currentPruningInstance;
|
||||
|
@ -1394,7 +1367,7 @@ PruneOne(DistTableCacheEntry *cacheEntry, ClauseWalkerContext *context,
|
|||
/*
|
||||
* For an equal constraints, if there's no overlapping shards (always the
|
||||
* case for hash and range partitioning, sometimes for append), can
|
||||
* perform binary search for the right interval. That's usually the
|
||||
* perform binary search for the right interval. That's usually the
|
||||
* fastest, so try that first.
|
||||
*/
|
||||
if (prune->equalConsts &&
|
||||
|
@ -1414,7 +1387,7 @@ PruneOne(DistTableCacheEntry *cacheEntry, ClauseWalkerContext *context,
|
|||
|
||||
/*
|
||||
* If the hash value we're looking for is known, we can search for the
|
||||
* interval directly. That's fast and should only ever be the case for a
|
||||
* interval directly. That's fast and should only ever be the case for a
|
||||
* hash-partitioned table.
|
||||
*/
|
||||
if (prune->hashedEqualConsts)
|
||||
|
@ -1435,7 +1408,7 @@ PruneOne(DistTableCacheEntry *cacheEntry, ClauseWalkerContext *context,
|
|||
{
|
||||
/*
|
||||
* equalConst based pruning above yielded a different shard than
|
||||
* pruning based on pre-hashed equality. This is useful in case
|
||||
* pruning based on pre-hashed equality. This is useful in case
|
||||
* of INSERT ... SELECT, where both can occur together (one via
|
||||
* join/colocation, the other via a plain equality restriction).
|
||||
*/
|
||||
|
@ -1824,8 +1797,7 @@ ExhaustivePrune(DistTableCacheEntry *cacheEntry, ClauseWalkerContext *context,
|
|||
|
||||
|
||||
/*
|
||||
* ExhaustivePruneOne returns true if curInterval is pruned away, false
|
||||
* otherwise.
|
||||
* ExhaustivePruneOne returns whether curInterval is pruned away.
|
||||
*/
|
||||
static bool
|
||||
ExhaustivePruneOne(ShardInterval *curInterval,
|
||||
|
@ -1912,11 +1884,11 @@ ExhaustivePruneOne(ShardInterval *curInterval,
|
|||
/*
|
||||
* Helper for creating a node for pruning tree
|
||||
*/
|
||||
static inline PruningTreeNode *
|
||||
CreatePruningNode(bool isAnd)
|
||||
static PruningTreeNode *
|
||||
CreatePruningNode(BoolExprType boolop)
|
||||
{
|
||||
PruningTreeNode *node = palloc0(sizeof(PruningTreeNode));
|
||||
node->isAnd = isAnd;
|
||||
node->boolop = boolop;
|
||||
node->childBooleanNodes = NULL;
|
||||
node->validConstraints = NULL;
|
||||
node->hasInvalidConstraints = false;
|
||||
|
@ -1925,9 +1897,10 @@ CreatePruningNode(bool isAnd)
|
|||
|
||||
|
||||
/*
|
||||
* Create equality operator for a single element of scalar array constraint.
|
||||
* SAORestrictionArrayEqualityOp creates an equality operator
|
||||
* for a single element of a scalar array constraint.
|
||||
*/
|
||||
static inline OpExpr *
|
||||
static OpExpr *
|
||||
SAORestrictionArrayEqualityOp(ScalarArrayOpExpr *arrayOperatorExpression,
|
||||
Var *partitionColumn)
|
||||
{
|
||||
|
@ -1944,16 +1917,45 @@ SAORestrictionArrayEqualityOp(ScalarArrayOpExpr *arrayOperatorExpression,
|
|||
|
||||
|
||||
/*
|
||||
* Debug helper for logging expression nodes
|
||||
* DebugLogNode is a helper for logging expression nodes.
|
||||
*/
|
||||
static inline void
|
||||
static void
|
||||
DebugLogNode(char *fmt, Node *node, List *deparseCtx)
|
||||
{
|
||||
if (!node)
|
||||
if (node != NULL)
|
||||
{
|
||||
return;
|
||||
char *deparsed = deparse_expression(node, deparseCtx, false, false);
|
||||
ereport(DEBUG3, (errmsg(fmt, deparsed)));
|
||||
}
|
||||
|
||||
char *deparsed = deparse_expression(node, deparseCtx, false, false);
|
||||
ereport(DEBUG3, (errmsg(fmt, deparsed)));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* DebugLogPruningInstance is a helper for logging purning constraints.
|
||||
*/
|
||||
static void
|
||||
DebugLogPruningInstance(PruningInstance *pruning, List *deparseCtx)
|
||||
{
|
||||
DebugLogNode("constraint value: %s",
|
||||
(Node *) pruning->equalConsts, deparseCtx);
|
||||
DebugLogNode("constraint (lt) value: %s", \
|
||||
(Node *) pruning->lessConsts, deparseCtx);
|
||||
DebugLogNode("constraint (lteq) value: %s", \
|
||||
(Node *) pruning->lessEqualConsts, deparseCtx);
|
||||
DebugLogNode("constraint (gt) value: %s", \
|
||||
(Node *) pruning->greaterConsts, deparseCtx);
|
||||
DebugLogNode("constraint (gteq) value: %s",
|
||||
(Node *) pruning->greaterEqualConsts, deparseCtx);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ConstraintCount returns how many arguments this node is taking.
|
||||
*/
|
||||
static int
|
||||
ConstraintCount(PruningTreeNode *node)
|
||||
{
|
||||
return list_length(node->childBooleanNodes) +
|
||||
list_length(node->validConstraints) +
|
||||
(node->hasInvalidConstraints ? 1 : 0);
|
||||
}
|
||||
|
|
|
@ -219,14 +219,14 @@ SET client_min_messages TO DEBUG3;
|
|||
-- Check that we support runing for ANY/IN with literal.
|
||||
SELECT count(*) FROM lineitem_hash_part
|
||||
WHERE l_orderkey = ANY ('{1,2,3}');
|
||||
DEBUG: constraint value: '1'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '2'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '3'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '1'::bigint
|
||||
DEBUG: constraint value: '2'::bigint
|
||||
DEBUG: constraint value: '3'::bigint
|
||||
DEBUG: shard count: 3
|
||||
DEBUG: Router planner cannot handle multi-shard select queries
|
||||
DEBUG: constraint value: '1'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '2'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '3'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '1'::bigint
|
||||
DEBUG: constraint value: '2'::bigint
|
||||
DEBUG: constraint value: '3'::bigint
|
||||
DEBUG: shard count: 3
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
|
@ -238,14 +238,14 @@ DEBUG: assigned task to node localhost:xxxxx
|
|||
|
||||
SELECT count(*) FROM lineitem_hash_part
|
||||
WHERE l_orderkey IN (1,2,3);
|
||||
DEBUG: constraint value: '1'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '2'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '3'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '1'::bigint
|
||||
DEBUG: constraint value: '2'::bigint
|
||||
DEBUG: constraint value: '3'::bigint
|
||||
DEBUG: shard count: 3
|
||||
DEBUG: Router planner cannot handle multi-shard select queries
|
||||
DEBUG: constraint value: '1'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '2'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '3'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '1'::bigint
|
||||
DEBUG: constraint value: '2'::bigint
|
||||
DEBUG: constraint value: '3'::bigint
|
||||
DEBUG: shard count: 3
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
|
@ -356,8 +356,8 @@ DEBUG: assigned task to node localhost:xxxxx
|
|||
SELECT count(*) FROM lineitem
|
||||
WHERE l_orderkey >= 1 AND l_orderkey <= 3;
|
||||
DEBUG: Router planner does not support append-partitioned tables.
|
||||
DEBUG: constraint (lteq) value: '3'::bigint,
|
||||
DEBUG: constraint (gteq) value: '1'::bigint,
|
||||
DEBUG: constraint (lteq) value: '3'::bigint
|
||||
DEBUG: constraint (gteq) value: '1'::bigint
|
||||
DEBUG: shard count: 1
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
count
|
||||
|
@ -368,8 +368,8 @@ DEBUG: assigned task to node localhost:xxxxx
|
|||
SELECT count(*) FROM lineitem
|
||||
WHERE (l_orderkey >= 1 AND l_orderkey <= 3) AND (l_quantity > 11 AND l_quantity < 22);
|
||||
DEBUG: Router planner does not support append-partitioned tables.
|
||||
DEBUG: constraint (lteq) value: '3'::bigint,
|
||||
DEBUG: constraint (gteq) value: '1'::bigint,
|
||||
DEBUG: constraint (lteq) value: '3'::bigint
|
||||
DEBUG: constraint (gteq) value: '1'::bigint
|
||||
DEBUG: shard count: 1
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
count
|
||||
|
@ -381,9 +381,9 @@ DEBUG: assigned task to node localhost:xxxxx
|
|||
SELECT count(*) FROM lineitem
|
||||
WHERE l_orderkey = ANY ('{1,2,3}');
|
||||
DEBUG: Router planner does not support append-partitioned tables.
|
||||
DEBUG: constraint value: '1'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '2'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '3'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '1'::bigint
|
||||
DEBUG: constraint value: '2'::bigint
|
||||
DEBUG: constraint value: '3'::bigint
|
||||
DEBUG: shard count: 1
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
count
|
||||
|
@ -394,9 +394,9 @@ DEBUG: assigned task to node localhost:xxxxx
|
|||
SELECT count(*) FROM lineitem
|
||||
WHERE l_orderkey IN (1,2,3);
|
||||
DEBUG: Router planner does not support append-partitioned tables.
|
||||
DEBUG: constraint value: '1'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '2'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '3'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '1'::bigint
|
||||
DEBUG: constraint value: '2'::bigint
|
||||
DEBUG: constraint value: '3'::bigint
|
||||
DEBUG: shard count: 1
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
count
|
||||
|
@ -418,9 +418,9 @@ DEBUG: assigned task to node localhost:xxxxx
|
|||
|
||||
SELECT count(*) FROM lineitem_range
|
||||
WHERE l_orderkey = ANY ('{1,2,3}');
|
||||
DEBUG: constraint value: '1'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '2'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '3'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '1'::bigint
|
||||
DEBUG: constraint value: '2'::bigint
|
||||
DEBUG: constraint value: '3'::bigint
|
||||
DEBUG: shard count: 1
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
|
@ -431,9 +431,9 @@ DEBUG: Plan is router executable
|
|||
|
||||
SELECT count(*) FROM lineitem_range
|
||||
WHERE l_orderkey IN (1,2,3);
|
||||
DEBUG: constraint value: '1'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '2'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '3'::bigint COLLATE "default",
|
||||
DEBUG: constraint value: '1'::bigint
|
||||
DEBUG: constraint value: '2'::bigint
|
||||
DEBUG: constraint value: '3'::bigint
|
||||
DEBUG: shard count: 1
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
|
@ -526,7 +526,7 @@ DEBUG: assigned task to node localhost:xxxxx
|
|||
|
||||
SELECT count(*) FROM orders_hash_partitioned
|
||||
WHERE o_orderkey = (random() + 100) AND o_orderkey = 1;
|
||||
DEBUG: constraint value: 1,
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: shard count: 1
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
|
@ -575,9 +575,9 @@ SELECT count(*)
|
|||
WHERE orders1.o_orderkey = orders2.o_orderkey
|
||||
AND orders1.o_orderkey = 1
|
||||
AND orders2.o_orderkey is NULL;
|
||||
DEBUG: constraint value: 1,
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: shard count: 1
|
||||
DEBUG: constraint value: 1,
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: shard count: 1
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
|
@ -606,7 +606,7 @@ DEBUG: assigned task to node localhost:xxxxx
|
|||
-- Shards restricted correctly with prunable constraint
|
||||
SELECT count(*) FROM orders_hash_partitioned
|
||||
WHERE o_orderkey = 1;
|
||||
DEBUG: constraint value: 1,
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: shard count: 1
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
|
@ -619,7 +619,7 @@ DETAIL: distribution column value: 1
|
|||
-- Shards restricted correctly with prunable constraint ANDed with unprunable expression using OR
|
||||
SELECT count(*) FROM orders_hash_partitioned
|
||||
WHERE o_orderkey = 1 AND (o_custkey = 11 OR o_custkey = 22);
|
||||
DEBUG: constraint value: 1,
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: shard count: 1
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
|
@ -632,12 +632,12 @@ DETAIL: distribution column value: 1
|
|||
-- Shards restricted correctly with prunable constraints ORed
|
||||
SELECT count(*) FROM orders_hash_partitioned
|
||||
WHERE (o_orderkey = 1 OR o_orderkey = 2);
|
||||
DEBUG: constraint value: 1,
|
||||
DEBUG: constraint value: 2,
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: shard count: 2
|
||||
DEBUG: Router planner cannot handle multi-shard select queries
|
||||
DEBUG: constraint value: 1,
|
||||
DEBUG: constraint value: 2,
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: shard count: 2
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
|
@ -649,12 +649,12 @@ DEBUG: assigned task to node localhost:xxxxx
|
|||
-- Shards restricted correctly with prunable constraints ANDed with unprunable expression using OR
|
||||
SELECT count(*) FROM orders_hash_partitioned
|
||||
WHERE (o_orderkey = 1 OR o_orderkey = 2) AND (o_custkey = 11 OR o_custkey = 22);
|
||||
DEBUG: constraint value: 1,
|
||||
DEBUG: constraint value: 2,
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: shard count: 2
|
||||
DEBUG: Router planner cannot handle multi-shard select queries
|
||||
DEBUG: constraint value: 1,
|
||||
DEBUG: constraint value: 2,
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: shard count: 2
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
|
@ -666,16 +666,16 @@ DEBUG: assigned task to node localhost:xxxxx
|
|||
-- Shards restricted correctly with many different prunable constraints ORed
|
||||
SELECT count(*) FROM orders_hash_partitioned
|
||||
WHERE (o_orderkey = 1 AND o_custkey = 11) OR (o_orderkey = 1 AND o_custkey = 33) OR (o_orderkey = 2 AND o_custkey = 22) OR (o_orderkey = 2 AND o_custkey = 44);
|
||||
DEBUG: constraint value: 1,
|
||||
DEBUG: constraint value: 1,
|
||||
DEBUG: constraint value: 2,
|
||||
DEBUG: constraint value: 2,
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: shard count: 2
|
||||
DEBUG: Router planner cannot handle multi-shard select queries
|
||||
DEBUG: constraint value: 1,
|
||||
DEBUG: constraint value: 1,
|
||||
DEBUG: constraint value: 2,
|
||||
DEBUG: constraint value: 2,
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: shard count: 2
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
|
@ -687,12 +687,12 @@ DEBUG: assigned task to node localhost:xxxxx
|
|||
-- Shards restricted correctly with prunable SAO constraint ANDed with unprunable expression using OR
|
||||
SELECT count(*) FROM orders_hash_partitioned
|
||||
WHERE (o_orderkey IN (1,2)) AND (o_custkey = 11 OR o_custkey = 22 OR o_custkey = 33);
|
||||
DEBUG: constraint value: 1 COLLATE "default",
|
||||
DEBUG: constraint value: 2 COLLATE "default",
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: shard count: 2
|
||||
DEBUG: Router planner cannot handle multi-shard select queries
|
||||
DEBUG: constraint value: 1 COLLATE "default",
|
||||
DEBUG: constraint value: 2 COLLATE "default",
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: shard count: 2
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
|
@ -704,12 +704,12 @@ DEBUG: assigned task to node localhost:xxxxx
|
|||
-- Shards restricted correctly with prunable SAO constraint ANDed with multiple unprunable expressions
|
||||
SELECT count(*) FROM orders_hash_partitioned
|
||||
WHERE (o_orderkey IN (1,2)) AND (o_totalprice < 11 OR o_totalprice > 19) AND o_shippriority > 100 AND (o_custkey = 11 OR o_custkey = 22);
|
||||
DEBUG: constraint value: 1 COLLATE "default",
|
||||
DEBUG: constraint value: 2 COLLATE "default",
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: shard count: 2
|
||||
DEBUG: Router planner cannot handle multi-shard select queries
|
||||
DEBUG: constraint value: 1 COLLATE "default",
|
||||
DEBUG: constraint value: 2 COLLATE "default",
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: shard count: 2
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
|
@ -721,16 +721,16 @@ DEBUG: assigned task to node localhost:xxxxx
|
|||
-- Shards restricted correctly with prunable SAO constraints ORed
|
||||
SELECT count(*) FROM orders_hash_partitioned
|
||||
WHERE (o_orderkey IN (1,2) AND o_custkey = 11) OR (o_orderkey IN (2,3) AND o_custkey = 22);
|
||||
DEBUG: constraint value: 1 COLLATE "default",
|
||||
DEBUG: constraint value: 2 COLLATE "default",
|
||||
DEBUG: constraint value: 2 COLLATE "default",
|
||||
DEBUG: constraint value: 3 COLLATE "default",
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: constraint value: 3
|
||||
DEBUG: shard count: 3
|
||||
DEBUG: Router planner cannot handle multi-shard select queries
|
||||
DEBUG: constraint value: 1 COLLATE "default",
|
||||
DEBUG: constraint value: 2 COLLATE "default",
|
||||
DEBUG: constraint value: 2 COLLATE "default",
|
||||
DEBUG: constraint value: 3 COLLATE "default",
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: constraint value: 3
|
||||
DEBUG: shard count: 3
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
|
@ -760,14 +760,14 @@ DEBUG: assigned task to node localhost:xxxxx
|
|||
-- Shards restricted correctly with prunable constraint ORed
|
||||
SELECT count(*) FROM orders_hash_partitioned
|
||||
WHERE o_orderkey = 1 OR ((o_orderkey = 2 AND o_custkey = 22) OR (o_orderkey = 3 AND o_custkey = 33));
|
||||
DEBUG: constraint value: 1,
|
||||
DEBUG: constraint value: 2,
|
||||
DEBUG: constraint value: 3,
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: constraint value: 3
|
||||
DEBUG: shard count: 3
|
||||
DEBUG: Router planner cannot handle multi-shard select queries
|
||||
DEBUG: constraint value: 1,
|
||||
DEBUG: constraint value: 2,
|
||||
DEBUG: constraint value: 3,
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: constraint value: 3
|
||||
DEBUG: shard count: 3
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
|
@ -780,12 +780,12 @@ DEBUG: assigned task to node localhost:xxxxx
|
|||
-- Shards restricted correctly with prunable constraint ORed with falsy expression
|
||||
SELECT count(*) FROM orders_hash_partitioned
|
||||
WHERE o_orderkey = 1 OR (o_orderkey = 2 AND (o_custkey = 11 OR (o_orderkey = 3 AND o_custkey = 44)));
|
||||
DEBUG: constraint value: 1,
|
||||
DEBUG: constraint value: 2,
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: shard count: 2
|
||||
DEBUG: Router planner cannot handle multi-shard select queries
|
||||
DEBUG: constraint value: 1,
|
||||
DEBUG: constraint value: 2,
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: shard count: 2
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
|
@ -797,12 +797,12 @@ DEBUG: assigned task to node localhost:xxxxx
|
|||
-- Shards restricted correctly with prunable SAO constraint ORed with prunable nested EQ constraint
|
||||
SELECT count(*) FROM orders_hash_partitioned
|
||||
WHERE (o_orderkey IN (1,2)) AND (o_custkey = 11 OR o_custkey = 22 OR o_custkey = 33) AND o_totalprice <= 20;
|
||||
DEBUG: constraint value: 1 COLLATE "default",
|
||||
DEBUG: constraint value: 2 COLLATE "default",
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: shard count: 2
|
||||
DEBUG: Router planner cannot handle multi-shard select queries
|
||||
DEBUG: constraint value: 1 COLLATE "default",
|
||||
DEBUG: constraint value: 2 COLLATE "default",
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: shard count: 2
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
|
@ -814,12 +814,12 @@ DEBUG: assigned task to node localhost:xxxxx
|
|||
-- Shards restricted correctly with prunable SAO constraint ANDed with unprunable expressions
|
||||
SELECT count(*) FROM orders_hash_partitioned
|
||||
WHERE (o_orderkey IN (1,2)) AND (o_custkey = 11 OR o_custkey = 33) AND o_custkey = 22;
|
||||
DEBUG: constraint value: 1 COLLATE "default",
|
||||
DEBUG: constraint value: 2 COLLATE "default",
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: shard count: 2
|
||||
DEBUG: Router planner cannot handle multi-shard select queries
|
||||
DEBUG: constraint value: 1 COLLATE "default",
|
||||
DEBUG: constraint value: 2 COLLATE "default",
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: shard count: 2
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
|
@ -848,14 +848,14 @@ DEBUG: assigned task to node localhost:xxxxx
|
|||
-- Shards restricted correctly with prunable SAO constraint ORed with prunable nested EQ constraint
|
||||
SELECT count(*) FROM orders_hash_partitioned
|
||||
WHERE ((o_orderkey IN (1,2)) AND (o_custkey = 11 OR o_custkey = 22)) OR (o_orderkey = 3 AND o_custkey = 33);
|
||||
DEBUG: constraint value: 3,
|
||||
DEBUG: constraint value: 1 COLLATE "default",
|
||||
DEBUG: constraint value: 2 COLLATE "default",
|
||||
DEBUG: constraint value: 3
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: shard count: 3
|
||||
DEBUG: Router planner cannot handle multi-shard select queries
|
||||
DEBUG: constraint value: 3,
|
||||
DEBUG: constraint value: 1 COLLATE "default",
|
||||
DEBUG: constraint value: 2 COLLATE "default",
|
||||
DEBUG: constraint value: 3
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: shard count: 3
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
|
@ -885,7 +885,7 @@ DEBUG: assigned task to node localhost:xxxxx
|
|||
-- Single shard used when deeply nested prunable expression is restrictive with nested ANDs
|
||||
SELECT count(*) FROM orders_hash_partitioned
|
||||
WHERE o_orderkey = 1 OR (o_orderkey = 2 AND (o_orderkey = 3 OR (o_orderkey = 1 AND o_custkey = 11)));
|
||||
DEBUG: constraint value: 1,
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: shard count: 1
|
||||
DEBUG: Creating router plan
|
||||
DEBUG: Plan is router executable
|
||||
|
@ -910,14 +910,14 @@ DETAIL: distribution column value: 1
|
|||
-- Deeply nested prunable expression affects used shards
|
||||
SELECT count(*) FROM orders_hash_partitioned
|
||||
WHERE o_orderkey = 1 OR ((o_orderkey = 2 OR o_orderkey = 3) AND (o_custkey = 22 OR o_custkey = 33));
|
||||
DEBUG: constraint value: 1,
|
||||
DEBUG: constraint value: 2,
|
||||
DEBUG: constraint value: 3,
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: constraint value: 3
|
||||
DEBUG: shard count: 3
|
||||
DEBUG: Router planner cannot handle multi-shard select queries
|
||||
DEBUG: constraint value: 1,
|
||||
DEBUG: constraint value: 2,
|
||||
DEBUG: constraint value: 3,
|
||||
DEBUG: constraint value: 1
|
||||
DEBUG: constraint value: 2
|
||||
DEBUG: constraint value: 3
|
||||
DEBUG: shard count: 3
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
DEBUG: assigned task to node localhost:xxxxx
|
||||
|
|
Loading…
Reference in New Issue