* Generate implied qual * Input: * root - planner information * old_rinfo - old clause to infer from * old_expr - the expression to be replaced * new_expr - new expression replacing it */
| 119 | * new_expr - new expression replacing it |
| 120 | */ |
| 121 | static void |
| 122 | gen_implied_qual(PlannerInfo *root, |
| 123 | RestrictInfo *old_rinfo, |
| 124 | Node *old_expr, |
| 125 | Node *new_expr) |
| 126 | { |
| 127 | Node *new_clause; |
| 128 | ReplaceExpressionMutatorReplacement ctx; |
| 129 | Relids new_qualscope; |
| 130 | ListCell *lc; |
| 131 | RestrictInfo *new_rinfo; |
| 132 | |
| 133 | /* Expression types must match */ |
| 134 | Assert(exprType(old_expr) == exprType(new_expr) |
| 135 | && exprTypmod(old_expr) == exprTypmod(new_expr)); |
| 136 | |
| 137 | /* |
| 138 | * Clone the clause, replacing first node with the second. |
| 139 | */ |
| 140 | ctx.replaceThis = old_expr; |
| 141 | ctx.withThis = new_expr; |
| 142 | ctx.numReplacementsDone = 0; |
| 143 | new_clause = (Node *) replace_expression_mutator((Node *) old_rinfo->clause, &ctx); |
| 144 | |
| 145 | if (ctx.numReplacementsDone == 0) |
| 146 | return; |
| 147 | |
| 148 | new_qualscope = pull_varnos(root, new_clause); |
| 149 | if (new_qualscope == NULL) |
| 150 | return; |
| 151 | |
| 152 | if (subexpression_match((Expr *) new_expr, old_rinfo->clause)) |
| 153 | return; |
| 154 | |
| 155 | /* |
| 156 | * Have we seen this clause before? This is needed to avoid infinite |
| 157 | * recursion. |
| 158 | */ |
| 159 | foreach(lc, root->non_eq_clauses) |
| 160 | { |
| 161 | RestrictInfo *r = (RestrictInfo *) lfirst(lc); |
| 162 | |
| 163 | if (equal(r->clause, new_clause)) |
| 164 | return; |
| 165 | } |
| 166 | |
| 167 | /* |
| 168 | * Ok, we're good to go. Construct a new RestrictInfo, and pass it to |
| 169 | * distribute_to_rels(). This is a cut-down version of |
| 170 | * distribute_qual_to_rels(): We know the qual is not useful for the |
| 171 | * equivalence class machinery, because it's derived from a clause that |
| 172 | * wasn't either. |
| 173 | */ |
| 174 | new_rinfo = make_restrictinfo(root, |
| 175 | (Expr *) new_clause, |
| 176 | old_rinfo->is_pushed_down, |
| 177 | old_rinfo->outerjoin_delayed, |
| 178 | old_rinfo->pseudoconstant, |
no test coverage detected