Look at hash joinable operator instead of type-equality while deciding on xl_dbt3_expt
authorPavan Deolasee <[email protected]>
Thu, 20 Aug 2015 05:13:37 +0000 (10:43 +0530)
committerPavan Deolasee <[email protected]>
Thu, 20 Aug 2015 05:13:37 +0000 (10:43 +0530)
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

src/backend/optimizer/util/pathnode.c

index 1ceca4160b4e398576ea2064f897f6a0bce19a24..131f60a69ae255b1ca741f76fd8ee61910bde8d7 100644 (file)
@@ -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;