fix/transform-restrict-val
Onur Tirtir 2022-01-25 16:10:28 +03:00
parent 577224cf23
commit 68c8555733
5 changed files with 92 additions and 35 deletions

View File

@ -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
*

View File

@ -563,7 +563,7 @@ ShardPlacementForFunctionColocatedWithDistTable(DistObjectCacheEntry *procedure,
{
bool missingOk = false;
partitionValue =
TransformPartitionRestrictionValue(partitionColumn, partitionValue,
TransformVarRestrictionValue(partitionColumn, partitionValue,
missingOk);
}

View File

@ -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);
}

View File

@ -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))));
}

View File

@ -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_ */