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
|
||||
*
|
||||
|
@ -5228,9 +5232,11 @@ get_rule_expr(Node *node, deparse_context *context,
|
|||
break;
|
||||
|
||||
case T_OpExpr:
|
||||
get_oper_expr((OpExpr *) node, context);
|
||||
break;
|
||||
|
||||
{
|
||||
TransformBinaryOpExprConst((OpExpr *) node);
|
||||
get_oper_expr((OpExpr *) node, context);
|
||||
break;
|
||||
}
|
||||
case T_DistinctExpr:
|
||||
{
|
||||
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
|
||||
*
|
||||
|
|
|
@ -563,7 +563,7 @@ ShardPlacementForFunctionColocatedWithDistTable(DistObjectCacheEntry *procedure,
|
|||
{
|
||||
bool missingOk = false;
|
||||
partitionValue =
|
||||
TransformPartitionRestrictionValue(partitionColumn, partitionValue,
|
||||
TransformVarRestrictionValue(partitionColumn, partitionValue,
|
||||
missingOk);
|
||||
}
|
||||
|
||||
|
|
|
@ -2632,7 +2632,7 @@ TargetShardIntervalForFastPathQuery(Query *query, bool *isMultiShardQuery,
|
|||
{
|
||||
bool missingOk = false;
|
||||
inputDistributionKeyValue =
|
||||
TransformPartitionRestrictionValue(distributionKey,
|
||||
TransformVarRestrictionValue(distributionKey,
|
||||
inputDistributionKeyValue, missingOk);
|
||||
}
|
||||
|
||||
|
@ -2966,7 +2966,7 @@ BuildRoutesForInsert(Query *query, DeferredErrorMessage **planningError)
|
|||
* FuncExpr coercions for casts created with CREATE CAST ... WITH
|
||||
* FUNCTION .. AS IMPLICIT. To support this first we strip them here.
|
||||
* 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
|
||||
* 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;
|
||||
partitionValueConst =
|
||||
TransformPartitionRestrictionValue(partitionColumn,
|
||||
TransformVarRestrictionValue(partitionColumn,
|
||||
partitionValueConst,
|
||||
missingOk);
|
||||
}
|
||||
|
|
|
@ -257,7 +257,7 @@ static bool SAORestrictions(ScalarArrayOpExpr *arrayOperatorExpression,
|
|||
Var *partitionColumn,
|
||||
List **requestedRestrictions);
|
||||
static void ErrorTypesDontMatch(Oid firstType, Oid firstCollId, Oid secondType,
|
||||
Oid secondCollId);
|
||||
Oid secondCollId, int elevel);
|
||||
static bool IsValidHashRestriction(OpExpr *opClause);
|
||||
static void AddHashRestrictionToInstance(ClauseWalkerContext *context, OpExpr *opClause,
|
||||
Var *varClause, Const *constantClause);
|
||||
|
@ -1106,7 +1106,7 @@ AddPartitionKeyRestrictionToInstance(ClauseWalkerContext *context, OpExpr *opCla
|
|||
if (constantClause->consttype != partitionColumn->vartype)
|
||||
{
|
||||
/* we want our restriction value in terms of the type of the partition column */
|
||||
constantClause = TransformPartitionRestrictionValue(partitionColumn,
|
||||
constantClause = TransformVarRestrictionValue(partitionColumn,
|
||||
constantClause, true);
|
||||
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.
|
||||
* 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.
|
||||
*/
|
||||
Const *
|
||||
TransformPartitionRestrictionValue(Var *partitionColumn, Const *restrictionValue,
|
||||
bool missingOk)
|
||||
TransformVarRestrictionValue(Var *var, Const *restrictionValue, bool missingOk)
|
||||
{
|
||||
Node *transformedValue = coerce_to_target_type(NULL, (Node *) restrictionValue,
|
||||
restrictionValue->consttype,
|
||||
partitionColumn->vartype,
|
||||
partitionColumn->vartypmod,
|
||||
var->vartype,
|
||||
var->vartypmod,
|
||||
COERCION_ASSIGNMENT,
|
||||
COERCE_IMPLICIT_CAST, -1);
|
||||
|
||||
/* if NULL, no implicit coercion is possible between the types */
|
||||
if (transformedValue == NULL)
|
||||
{
|
||||
if (!missingOk)
|
||||
{
|
||||
ErrorTypesDontMatch(partitionColumn->vartype, partitionColumn->varcollid,
|
||||
restrictionValue->consttype,
|
||||
restrictionValue->constcollid);
|
||||
}
|
||||
int elevel = missingOk ? DEBUG1 : ERROR;
|
||||
ErrorTypesDontMatch(var->vartype, var->varcollid, restrictionValue->consttype,
|
||||
restrictionValue->constcollid, elevel);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1252,12 +1246,9 @@ TransformPartitionRestrictionValue(Var *partitionColumn, Const *restrictionValue
|
|||
/* if still not a constant, no immutable coercion matched */
|
||||
if (!IsA(transformedValue, Const))
|
||||
{
|
||||
if (!missingOk)
|
||||
{
|
||||
ErrorTypesDontMatch(partitionColumn->vartype, partitionColumn->varcollid,
|
||||
restrictionValue->consttype,
|
||||
restrictionValue->constcollid);
|
||||
}
|
||||
int elevel = missingOk ? DEBUG1 : ERROR;
|
||||
ErrorTypesDontMatch(var->vartype, var->varcollid, restrictionValue->consttype,
|
||||
restrictionValue->constcollid, elevel);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1270,7 +1261,8 @@ TransformPartitionRestrictionValue(Var *partitionColumn, Const *restrictionValue
|
|||
* ErrorTypesDontMatch throws an error explicitly printing the type names.
|
||||
*/
|
||||
static void
|
||||
ErrorTypesDontMatch(Oid firstType, Oid firstCollId, Oid secondType, Oid secondCollId)
|
||||
ErrorTypesDontMatch(Oid firstType, Oid firstCollId, Oid secondType, Oid secondCollId,
|
||||
int elevel)
|
||||
{
|
||||
Datum firstTypename =
|
||||
DirectFunctionCall1Coll(regtypeout, firstCollId, ObjectIdGetDatum(firstType));
|
||||
|
@ -1278,9 +1270,9 @@ ErrorTypesDontMatch(Oid firstType, Oid firstCollId, Oid secondType, Oid secondCo
|
|||
Datum secondTypename =
|
||||
DirectFunctionCall1Coll(regtypeout, secondCollId, ObjectIdGetDatum(secondType));
|
||||
|
||||
ereport(ERROR, (errmsg("Cannot coerce %s to %s",
|
||||
DatumGetCString(secondTypename),
|
||||
DatumGetCString(firstTypename))));
|
||||
ereport(elevel, (errmsg("Cannot coerce %s to %s",
|
||||
DatumGetCString(secondTypename),
|
||||
DatumGetCString(firstTypename))));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,9 +21,7 @@ extern List * PruneShards(Oid relationId, Index rangeTableId, List *whereClauseL
|
|||
Const **partitionValueConst);
|
||||
extern bool ContainsFalseClause(List *whereClauseList);
|
||||
extern List * get_all_actual_clauses(List *restrictinfo_list);
|
||||
extern Const * TransformPartitionRestrictionValue(Var *partitionColumn,
|
||||
Const *restrictionValue,
|
||||
bool missingOk);
|
||||
extern Const * TransformVarRestrictionValue(Var *var, Const *restrictionValue, bool missingOk);
|
||||
bool VarConstOpExprClause(OpExpr *opClause, Var **varClause, Const **constantClause);
|
||||
|
||||
#endif /* SHARD_PRUNING_H_ */
|
||||
|
|
Loading…
Reference in New Issue