equivclass.patch
text/x-patch
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/optimizer/path/equivclass.c | 29 | 2 |
diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c
index 6f1abbe47d..12a1d390b7 100644
--- a/src/backend/optimizer/path/equivclass.c
+++ b/src/backend/optimizer/path/equivclass.c
@@ -1623,8 +1623,21 @@ generate_join_implied_equalities_normal(PlannerInfo *root,
EquivalenceMember *best_inner_em = NULL;
Oid best_eq_op = InvalidOid;
int best_score = -1;
+ int max_score = 3;
RestrictInfo *rinfo;
+ /* The case of possible self-join */
+ if (bms_num_members(outer_relids) == 1 &&
+ bms_num_members(inner_relids) == 1)
+ {
+ int orel = bms_next_member(outer_relids, -1);
+ int irel = bms_next_member(inner_relids, -1);
+
+ if (root->simple_rte_array[irel]->relid ==
+ root->simple_rte_array[orel]->relid)
+ max_score = 4;
+ }
+
foreach(lc1, outer_members)
{
EquivalenceMember *outer_em = (EquivalenceMember *) lfirst(lc1);
@@ -1653,17 +1666,31 @@ generate_join_implied_equalities_normal(PlannerInfo *root,
if (op_hashjoinable(eq_op,
exprType((Node *) outer_em->em_expr)))
score++;
+ if (score == 3 && score < max_score)
+ {
+ /* Look for self-join clause */
+ Var *outer_var = (Var *) (IsA(outer_em->em_expr, Var) ?
+ outer_em->em_expr :
+ ((RelabelType *) outer_em->em_expr)->arg);
+ Var *inner_var = (Var *) (IsA(inner_em->em_expr, Var) ?
+ inner_em->em_expr :
+ ((RelabelType *) inner_em->em_expr)->arg);
+
+ if (outer_var->varattno == inner_var->varattno)
+ score++;
+ }
+
if (score > best_score)
{
best_outer_em = outer_em;
best_inner_em = inner_em;
best_eq_op = eq_op;
best_score = score;
- if (best_score == 3)
+ if (best_score == max_score)
break; /* no need to look further */
}
}
- if (best_score == 3)
+ if (best_score == max_score)
break; /* no need to look further */
}
if (best_score < 0)