mirror of https://github.com/citusdata/citus.git
test
parent
577224cf23
commit
68c8555733
|
@ -5083,6 +5083,10 @@ get_rule_expr_paren(Node *node, deparse_context *context,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#include "distributed/shard_pruning.h"
|
||||||
|
static void
|
||||||
|
TransformBinaryOpExprConst(OpExpr *opexpr);
|
||||||
|
|
||||||
/* ----------
|
/* ----------
|
||||||
* get_rule_expr - Parse back an expression
|
* get_rule_expr - Parse back an expression
|
||||||
*
|
*
|
||||||
|
@ -5228,9 +5232,11 @@ get_rule_expr(Node *node, deparse_context *context,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_OpExpr:
|
case T_OpExpr:
|
||||||
|
{
|
||||||
|
TransformBinaryOpExprConst((OpExpr *) node);
|
||||||
get_oper_expr((OpExpr *) node, context);
|
get_oper_expr((OpExpr *) node, context);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case T_DistinctExpr:
|
case T_DistinctExpr:
|
||||||
{
|
{
|
||||||
DistinctExpr *expr = (DistinctExpr *) node;
|
DistinctExpr *expr = (DistinctExpr *) node;
|
||||||
|
@ -6309,6 +6315,67 @@ get_rule_expr(Node *node, deparse_context *context,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* transform CoerceViaIO -> Const
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
TransformBinaryOpExprConst(OpExpr *opexpr)
|
||||||
|
{
|
||||||
|
RelabelType *relabelPtr = NULL;
|
||||||
|
Var *var = NULL;
|
||||||
|
|
||||||
|
if (list_length(opexpr->args) != 2)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node *arg1 = linitial(opexpr->args);
|
||||||
|
Node *arg2 = lsecond(opexpr->args);
|
||||||
|
if (IsA(arg1, RelabelType) && IsA(arg2, Var))
|
||||||
|
{
|
||||||
|
relabelPtr = (RelabelType *) arg1;
|
||||||
|
var = (Var *) arg2;
|
||||||
|
}
|
||||||
|
else if (IsA(arg1, Var) && IsA(arg2, RelabelType))
|
||||||
|
{
|
||||||
|
var = (Var *) arg1;
|
||||||
|
relabelPtr = (RelabelType *) arg2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* not a "Var OP RelabelType" or "RelabelType OR Var" */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: Probably need to consider multiple casts too ?
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!IsA(relabelPtr->arg, CoerceViaIO))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsA(((CoerceViaIO *) relabelPtr->arg)->arg, Const))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return NULL if TransformVarRestrictionValue fails to transform
|
||||||
|
* and issue DEBUG1
|
||||||
|
*/
|
||||||
|
bool missingOk = true;
|
||||||
|
Const *transformedValue =
|
||||||
|
TransformVarRestrictionValue(var, ((Const *)((CoerceViaIO *) relabelPtr->arg)->arg), missingOk);
|
||||||
|
if (transformedValue)
|
||||||
|
{
|
||||||
|
relabelPtr->arg = ((Expr *) transformedValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get_rule_expr_toplevel - Parse back a toplevel expression
|
* get_rule_expr_toplevel - Parse back a toplevel expression
|
||||||
*
|
*
|
||||||
|
|
|
@ -563,7 +563,7 @@ ShardPlacementForFunctionColocatedWithDistTable(DistObjectCacheEntry *procedure,
|
||||||
{
|
{
|
||||||
bool missingOk = false;
|
bool missingOk = false;
|
||||||
partitionValue =
|
partitionValue =
|
||||||
TransformPartitionRestrictionValue(partitionColumn, partitionValue,
|
TransformVarRestrictionValue(partitionColumn, partitionValue,
|
||||||
missingOk);
|
missingOk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2632,7 +2632,7 @@ TargetShardIntervalForFastPathQuery(Query *query, bool *isMultiShardQuery,
|
||||||
{
|
{
|
||||||
bool missingOk = false;
|
bool missingOk = false;
|
||||||
inputDistributionKeyValue =
|
inputDistributionKeyValue =
|
||||||
TransformPartitionRestrictionValue(distributionKey,
|
TransformVarRestrictionValue(distributionKey,
|
||||||
inputDistributionKeyValue, missingOk);
|
inputDistributionKeyValue, missingOk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2966,7 +2966,7 @@ BuildRoutesForInsert(Query *query, DeferredErrorMessage **planningError)
|
||||||
* FuncExpr coercions for casts created with CREATE CAST ... WITH
|
* FuncExpr coercions for casts created with CREATE CAST ... WITH
|
||||||
* FUNCTION .. AS IMPLICIT. To support this first we strip them here.
|
* FUNCTION .. AS IMPLICIT. To support this first we strip them here.
|
||||||
* Then we do the coercion manually below using
|
* Then we do the coercion manually below using
|
||||||
* TransformPartitionRestrictionValue, if the types are not the same.
|
* TransformVarRestrictionValue, if the types are not the same.
|
||||||
*
|
*
|
||||||
* NOTE: eval_const_expressions below would do some of these removals
|
* NOTE: eval_const_expressions below would do some of these removals
|
||||||
* too, but it's unclear if it would do all of them. It is possible
|
* too, but it's unclear if it would do all of them. It is possible
|
||||||
|
@ -3012,7 +3012,7 @@ BuildRoutesForInsert(Query *query, DeferredErrorMessage **planningError)
|
||||||
{
|
{
|
||||||
bool missingOk = false;
|
bool missingOk = false;
|
||||||
partitionValueConst =
|
partitionValueConst =
|
||||||
TransformPartitionRestrictionValue(partitionColumn,
|
TransformVarRestrictionValue(partitionColumn,
|
||||||
partitionValueConst,
|
partitionValueConst,
|
||||||
missingOk);
|
missingOk);
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,7 +257,7 @@ static bool SAORestrictions(ScalarArrayOpExpr *arrayOperatorExpression,
|
||||||
Var *partitionColumn,
|
Var *partitionColumn,
|
||||||
List **requestedRestrictions);
|
List **requestedRestrictions);
|
||||||
static void ErrorTypesDontMatch(Oid firstType, Oid firstCollId, Oid secondType,
|
static void ErrorTypesDontMatch(Oid firstType, Oid firstCollId, Oid secondType,
|
||||||
Oid secondCollId);
|
Oid secondCollId, int elevel);
|
||||||
static bool IsValidHashRestriction(OpExpr *opClause);
|
static bool IsValidHashRestriction(OpExpr *opClause);
|
||||||
static void AddHashRestrictionToInstance(ClauseWalkerContext *context, OpExpr *opClause,
|
static void AddHashRestrictionToInstance(ClauseWalkerContext *context, OpExpr *opClause,
|
||||||
Var *varClause, Const *constantClause);
|
Var *varClause, Const *constantClause);
|
||||||
|
@ -1106,7 +1106,7 @@ AddPartitionKeyRestrictionToInstance(ClauseWalkerContext *context, OpExpr *opCla
|
||||||
if (constantClause->consttype != partitionColumn->vartype)
|
if (constantClause->consttype != partitionColumn->vartype)
|
||||||
{
|
{
|
||||||
/* we want our restriction value in terms of the type of the partition column */
|
/* we want our restriction value in terms of the type of the partition column */
|
||||||
constantClause = TransformPartitionRestrictionValue(partitionColumn,
|
constantClause = TransformVarRestrictionValue(partitionColumn,
|
||||||
constantClause, true);
|
constantClause, true);
|
||||||
if (constantClause == NULL)
|
if (constantClause == NULL)
|
||||||
{
|
{
|
||||||
|
@ -1212,33 +1212,27 @@ AddPartitionKeyRestrictionToInstance(ClauseWalkerContext *context, OpExpr *opCla
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TransformPartitionRestrictionValue works around how PostgreSQL sometimes
|
* TransformVarRestrictionValue works around how PostgreSQL sometimes
|
||||||
* chooses to try to wrap our Var in a coercion rather than the Const.
|
* 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
|
* To deal with this, we strip coercions from both and manually coerce
|
||||||
* the Const into the type of our partition column.
|
* 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.
|
|
||||||
*/
|
*/
|
||||||
Const *
|
Const *
|
||||||
TransformPartitionRestrictionValue(Var *partitionColumn, Const *restrictionValue,
|
TransformVarRestrictionValue(Var *var, Const *restrictionValue, bool missingOk)
|
||||||
bool missingOk)
|
|
||||||
{
|
{
|
||||||
Node *transformedValue = coerce_to_target_type(NULL, (Node *) restrictionValue,
|
Node *transformedValue = coerce_to_target_type(NULL, (Node *) restrictionValue,
|
||||||
restrictionValue->consttype,
|
restrictionValue->consttype,
|
||||||
partitionColumn->vartype,
|
var->vartype,
|
||||||
partitionColumn->vartypmod,
|
var->vartypmod,
|
||||||
COERCION_ASSIGNMENT,
|
COERCION_ASSIGNMENT,
|
||||||
COERCE_IMPLICIT_CAST, -1);
|
COERCE_IMPLICIT_CAST, -1);
|
||||||
|
|
||||||
/* if NULL, no implicit coercion is possible between the types */
|
/* if NULL, no implicit coercion is possible between the types */
|
||||||
if (transformedValue == NULL)
|
if (transformedValue == NULL)
|
||||||
{
|
{
|
||||||
if (!missingOk)
|
int elevel = missingOk ? DEBUG1 : ERROR;
|
||||||
{
|
ErrorTypesDontMatch(var->vartype, var->varcollid, restrictionValue->consttype,
|
||||||
ErrorTypesDontMatch(partitionColumn->vartype, partitionColumn->varcollid,
|
restrictionValue->constcollid, elevel);
|
||||||
restrictionValue->consttype,
|
|
||||||
restrictionValue->constcollid);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1252,12 +1246,9 @@ TransformPartitionRestrictionValue(Var *partitionColumn, Const *restrictionValue
|
||||||
/* if still not a constant, no immutable coercion matched */
|
/* if still not a constant, no immutable coercion matched */
|
||||||
if (!IsA(transformedValue, Const))
|
if (!IsA(transformedValue, Const))
|
||||||
{
|
{
|
||||||
if (!missingOk)
|
int elevel = missingOk ? DEBUG1 : ERROR;
|
||||||
{
|
ErrorTypesDontMatch(var->vartype, var->varcollid, restrictionValue->consttype,
|
||||||
ErrorTypesDontMatch(partitionColumn->vartype, partitionColumn->varcollid,
|
restrictionValue->constcollid, elevel);
|
||||||
restrictionValue->consttype,
|
|
||||||
restrictionValue->constcollid);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1270,7 +1261,8 @@ TransformPartitionRestrictionValue(Var *partitionColumn, Const *restrictionValue
|
||||||
* ErrorTypesDontMatch throws an error explicitly printing the type names.
|
* ErrorTypesDontMatch throws an error explicitly printing the type names.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
ErrorTypesDontMatch(Oid firstType, Oid firstCollId, Oid secondType, Oid secondCollId)
|
ErrorTypesDontMatch(Oid firstType, Oid firstCollId, Oid secondType, Oid secondCollId,
|
||||||
|
int elevel)
|
||||||
{
|
{
|
||||||
Datum firstTypename =
|
Datum firstTypename =
|
||||||
DirectFunctionCall1Coll(regtypeout, firstCollId, ObjectIdGetDatum(firstType));
|
DirectFunctionCall1Coll(regtypeout, firstCollId, ObjectIdGetDatum(firstType));
|
||||||
|
@ -1278,7 +1270,7 @@ ErrorTypesDontMatch(Oid firstType, Oid firstCollId, Oid secondType, Oid secondCo
|
||||||
Datum secondTypename =
|
Datum secondTypename =
|
||||||
DirectFunctionCall1Coll(regtypeout, secondCollId, ObjectIdGetDatum(secondType));
|
DirectFunctionCall1Coll(regtypeout, secondCollId, ObjectIdGetDatum(secondType));
|
||||||
|
|
||||||
ereport(ERROR, (errmsg("Cannot coerce %s to %s",
|
ereport(elevel, (errmsg("Cannot coerce %s to %s",
|
||||||
DatumGetCString(secondTypename),
|
DatumGetCString(secondTypename),
|
||||||
DatumGetCString(firstTypename))));
|
DatumGetCString(firstTypename))));
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,7 @@ extern List * PruneShards(Oid relationId, Index rangeTableId, List *whereClauseL
|
||||||
Const **partitionValueConst);
|
Const **partitionValueConst);
|
||||||
extern bool ContainsFalseClause(List *whereClauseList);
|
extern bool ContainsFalseClause(List *whereClauseList);
|
||||||
extern List * get_all_actual_clauses(List *restrictinfo_list);
|
extern List * get_all_actual_clauses(List *restrictinfo_list);
|
||||||
extern Const * TransformPartitionRestrictionValue(Var *partitionColumn,
|
extern Const * TransformVarRestrictionValue(Var *var, Const *restrictionValue, bool missingOk);
|
||||||
Const *restrictionValue,
|
|
||||||
bool missingOk);
|
|
||||||
bool VarConstOpExprClause(OpExpr *opClause, Var **varClause, Const **constantClause);
|
bool VarConstOpExprClause(OpExpr *opClause, Var **varClause, Const **constantClause);
|
||||||
|
|
||||||
#endif /* SHARD_PRUNING_H_ */
|
#endif /* SHARD_PRUNING_H_ */
|
||||||
|
|
Loading…
Reference in New Issue