* reconsider_outer_join_clauses for a single LEFT/RIGHT JOIN clause * * Returns true if we were able to propagate a constant through the clause. */
| 2077 | * Returns true if we were able to propagate a constant through the clause. |
| 2078 | */ |
| 2079 | static bool |
| 2080 | reconsider_outer_join_clause(PlannerInfo *root, RestrictInfo *rinfo, |
| 2081 | bool outer_on_left) |
| 2082 | { |
| 2083 | Expr *outervar, |
| 2084 | *innervar; |
| 2085 | Oid opno, |
| 2086 | collation, |
| 2087 | left_type, |
| 2088 | right_type, |
| 2089 | inner_datatype; |
| 2090 | Relids inner_relids, |
| 2091 | inner_nullable_relids; |
| 2092 | ListCell *lc1; |
| 2093 | |
| 2094 | Assert(is_opclause(rinfo->clause)); |
| 2095 | opno = ((OpExpr *) rinfo->clause)->opno; |
| 2096 | collation = ((OpExpr *) rinfo->clause)->inputcollid; |
| 2097 | |
| 2098 | /* If clause is outerjoin_delayed, operator must be strict */ |
| 2099 | if (rinfo->outerjoin_delayed && !op_strict(opno)) |
| 2100 | return false; |
| 2101 | |
| 2102 | /* Extract needed info from the clause */ |
| 2103 | op_input_types(opno, &left_type, &right_type); |
| 2104 | if (outer_on_left) |
| 2105 | { |
| 2106 | outervar = (Expr *) get_leftop(rinfo->clause); |
| 2107 | innervar = (Expr *) get_rightop(rinfo->clause); |
| 2108 | inner_datatype = right_type; |
| 2109 | inner_relids = rinfo->right_relids; |
| 2110 | } |
| 2111 | else |
| 2112 | { |
| 2113 | outervar = (Expr *) get_rightop(rinfo->clause); |
| 2114 | innervar = (Expr *) get_leftop(rinfo->clause); |
| 2115 | inner_datatype = left_type; |
| 2116 | inner_relids = rinfo->left_relids; |
| 2117 | } |
| 2118 | inner_nullable_relids = bms_intersect(inner_relids, |
| 2119 | rinfo->nullable_relids); |
| 2120 | |
| 2121 | /* Scan EquivalenceClasses for a match to outervar */ |
| 2122 | foreach(lc1, root->eq_classes) |
| 2123 | { |
| 2124 | EquivalenceClass *cur_ec = (EquivalenceClass *) lfirst(lc1); |
| 2125 | bool match; |
| 2126 | ListCell *lc2; |
| 2127 | |
| 2128 | /* Ignore EC unless it contains pseudoconstants */ |
| 2129 | if (!cur_ec->ec_has_const) |
| 2130 | continue; |
| 2131 | /* Never match to a volatile EC */ |
| 2132 | if (cur_ec->ec_has_volatile) |
| 2133 | continue; |
| 2134 | /* It has to match the outer-join clause as to semantics, too */ |
| 2135 | if (collation != cur_ec->ec_collation) |
| 2136 | continue; |
no test coverage detected