From 68c85557334868abe269fce38c85489123028e5e Mon Sep 17 00:00:00 2001 From: Onur Tirtir Date: Tue, 25 Jan 2022 16:10:28 +0300 Subject: [PATCH] test --- .../distributed/deparser/ruleutils_14.c | 73 ++++++++++++++++++- .../planner/function_call_delegation.c | 2 +- .../planner/multi_router_planner.c | 6 +- .../distributed/planner/shard_pruning.c | 42 +++++------ src/include/distributed/shard_pruning.h | 4 +- 5 files changed, 92 insertions(+), 35 deletions(-) diff --git a/src/backend/distributed/deparser/ruleutils_14.c b/src/backend/distributed/deparser/ruleutils_14.c index bde8e1b23..57564dfaf 100644 --- a/src/backend/distributed/deparser/ruleutils_14.c +++ b/src/backend/distributed/deparser/ruleutils_14.c @@ -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 * diff --git a/src/backend/distributed/planner/function_call_delegation.c b/src/backend/distributed/planner/function_call_delegation.c index 2ae9fdde3..a40928f67 100644 --- a/src/backend/distributed/planner/function_call_delegation.c +++ b/src/backend/distributed/planner/function_call_delegation.c @@ -563,7 +563,7 @@ ShardPlacementForFunctionColocatedWithDistTable(DistObjectCacheEntry *procedure, { bool missingOk = false; partitionValue = - TransformPartitionRestrictionValue(partitionColumn, partitionValue, + TransformVarRestrictionValue(partitionColumn, partitionValue, missingOk); } diff --git a/src/backend/distributed/planner/multi_router_planner.c b/src/backend/distributed/planner/multi_router_planner.c index 60d3facc2..86f549273 100644 --- a/src/backend/distributed/planner/multi_router_planner.c +++ b/src/backend/distributed/planner/multi_router_planner.c @@ -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); } diff --git a/src/backend/distributed/planner/shard_pruning.c b/src/backend/distributed/planner/shard_pruning.c index 665c9a75b..517f89141 100644 --- a/src/backend/distributed/planner/shard_pruning.c +++ b/src/backend/distributed/planner/shard_pruning.c @@ -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)))); } diff --git a/src/include/distributed/shard_pruning.h b/src/include/distributed/shard_pruning.h index 04176314e..d631f5c29 100644 --- a/src/include/distributed/shard_pruning.h +++ b/src/include/distributed/shard_pruning.h @@ -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_ */