summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavan Deolasee2015-08-20 05:13:37 +0000
committerPavan Deolasee2015-08-20 05:13:37 +0000
commit7652a30acd108f13a0f00364be79f9a047310358 (patch)
tree31f5dfb377bd01d5e12d30b503af3a4a59f8ec73
parent146684f451d5e58590d89950391e5c25dfe292c5 (diff)
Look at hash joinable operator instead of type-equality while deciding onxl_dbt3_expt
restriction for remote subplan This should help multiple cases such as a simple SELECT query on a INT2 or INT8 distribution column and an integer constant or a join between two tables on columns of mixed types such as INT2/INT4/INT8 or FLOAT4/FLOAT8
-rw-r--r--src/backend/optimizer/util/pathnode.c44
1 files changed, 36 insertions, 8 deletions
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index 1ceca4160b..131f60a69a 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -738,6 +738,36 @@ restrict_distribution(PlannerInfo *root, RestrictInfo *ri,
if (ri->orclause)
return;
+ /*
+ * Check if the operator is hash joinable. Currently we only support hash
+ * joinable operator for arriving at restricted nodes. This allows us
+ * correctly deduce clauses which include a mix of int2/int4/int8 or
+ * float4/float8 or clauses which have same type arguments and have a hash
+ * joinable operator.
+ *
+ * Note: This stuff is mostly copied from check_hashjoinable
+ */
+ {
+ Expr *clause = ri->clause;
+ Oid opno;
+ Node *leftarg;
+
+ if (ri->pseudoconstant)
+ return;
+ if (!is_opclause(clause))
+ return;
+ if (list_length(((OpExpr *) clause)->args) != 2)
+ return;
+
+ opno = ((OpExpr *) clause)->opno;
+ leftarg = linitial(((OpExpr *) clause)->args);
+
+ if (!op_hashjoinable(opno, exprType(leftarg)) ||
+ contain_volatile_functions((Node *) clause))
+ return;
+ }
+
+
keytype = exprType(distribution->distributionExpr);
if (ri->left_ec)
{
@@ -752,8 +782,7 @@ restrict_distribution(PlannerInfo *root, RestrictInfo *ri,
{
Expr *cexpr = (Expr *) eval_const_expressions(root,
(Node *) em->em_expr);
- if (IsA(cexpr, Const) &&
- ((Const *) cexpr)->consttype == keytype)
+ if (IsA(cexpr, Const))
constExpr = (Const *) cexpr;
}
}
@@ -771,8 +800,7 @@ restrict_distribution(PlannerInfo *root, RestrictInfo *ri,
{
Expr *cexpr = (Expr *) eval_const_expressions(root,
(Node *) em->em_expr);
- if (IsA(cexpr, Const) &&
- ((Const *) cexpr)->consttype == keytype)
+ if (IsA(cexpr, Const))
constExpr = (Const *) cexpr;
}
}
@@ -794,8 +822,7 @@ restrict_distribution(PlannerInfo *root, RestrictInfo *ri,
{
found_key = true;
other = (Expr *) eval_const_expressions(root, (Node *) other);
- if (IsA(other, Const) &&
- ((Const *) other)->consttype == keytype)
+ if (IsA(other, Const))
constExpr = (Const *) other;
}
}
@@ -1128,8 +1155,6 @@ set_joinpath_distribution(PlannerInfo *root, JoinPath *pathnode)
* Make sure distribution functions are the same, for now they depend
* on data type
*/
- if (exprType((Node *) innerd->distributionExpr) != exprType((Node *) outerd->distributionExpr))
- goto not_allowed_join;
/*
* Planner already did necessary work and if there is a join
@@ -1161,6 +1186,9 @@ set_joinpath_distribution(PlannerInfo *root, JoinPath *pathnode)
if (ri->orclause)
continue;
+ if (!OidIsValid(ri->hashjoinoperator))
+ continue;
+
found_outer = false;
found_inner = false;