Coverage Report

Created: 2026-10-16 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/postgres/src/backend/optimizer/plan/analyzejoins.c
Line
Count
Source
1
/*-------------------------------------------------------------------------
2
 *
3
 * analyzejoins.c
4
 *    Routines for simplifying joins after initial query analysis
5
 *
6
 * While we do a great deal of join simplification in prep/prepjointree.c,
7
 * certain optimizations cannot be performed at that stage for lack of
8
 * detailed information about the query.  The routines here are invoked
9
 * after initsplan.c has done its work, and can do additional join removal
10
 * and simplification steps based on the information extracted.
11
 *
12
 * Although the decisions about what can be removed are made using the
13
 * planner's derived data structures, the removals themselves are implemented
14
 * by editing the query's jointree, which is a far simpler and more stable
15
 * representation.  We make no attempt to update the derived data structures
16
 * to match; instead, query_planner() throws them all away and recomputes them
17
 * whenever we report having removed something.
18
 *
19
 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
20
 * Portions Copyright (c) 1994, Regents of the University of California
21
 *
22
 *
23
 * IDENTIFICATION
24
 *    src/backend/optimizer/plan/analyzejoins.c
25
 *
26
 *-------------------------------------------------------------------------
27
 */
28
#include "postgres.h"
29
30
#include "catalog/pg_class.h"
31
#include "nodes/makefuncs.h"
32
#include "nodes/nodeFuncs.h"
33
#include "optimizer/optimizer.h"
34
#include "optimizer/pathnode.h"
35
#include "optimizer/paths.h"
36
#include "optimizer/planmain.h"
37
#include "optimizer/prep.h"
38
#include "optimizer/restrictinfo.h"
39
#include "parser/parse_agg.h"
40
#include "parser/parse_relation.h"
41
#include "rewrite/rewriteManip.h"
42
#include "utils/lsyscache.h"
43
44
/*
45
 * Utility structure.  A sorting procedure is needed to simplify the search
46
 * for SJE-candidate baserels, which must reference the same database relation
47
 * with the same reader permissions (checkAsUser value).  We require the
48
 * checkAsUser fields to match to ensure that merged RTEs carry the same
49
 * securityQuals; in future this rule might keep us out of trouble with other
50
 * role-based features, too.  Having collected all baserels from the jointree,
51
 * remove_self_joins_recurse sorts them according to their reloid and useroid
52
 * values, groups them in another pass and attempts to remove self-joins
53
 * within each group.  This preliminary sorting prevents quadratic behavior
54
 * in the case of numerous joins.
55
 */
56
typedef struct
57
{
58
  int     relid;
59
  Oid     reloid;
60
  Oid     useroid;
61
} SelfJoinCandidate;
62
63
bool    enable_self_join_elimination;
64
65
/* local functions */
66
static bool join_is_removable(PlannerInfo *root, SpecialJoinInfo *sjinfo);
67
static Node *remove_join_from_jointree(Node *jtnode, int ojrelid,
68
                     int *nremoved);
69
static void remove_rels_from_query_tree(PlannerInfo *root,
70
                    Relids removed_relids);
71
static bool reduce_semijoin_in_jointree(Node *jtnode, Relids syn_righthand);
72
static bool rel_supports_distinctness(PlannerInfo *root, RelOptInfo *rel);
73
static bool rel_is_distinct_for(PlannerInfo *root, RelOptInfo *rel,
74
                List *clause_list, List **extra_clauses);
75
static DistinctColInfo *distinct_col_search(int colno, List *distinct_cols);
76
static bool innerrel_is_unique_ext(PlannerInfo *root,
77
                   Relids joinrelids,
78
                   Relids outerrelids,
79
                   RelOptInfo *innerrel,
80
                   JoinType jointype,
81
                   List *restrictlist,
82
                   bool force_cache,
83
                   List **extra_clauses);
84
static bool is_innerrel_unique_for(PlannerInfo *root,
85
                   Relids joinrelids,
86
                   Relids outerrelids,
87
                   RelOptInfo *innerrel,
88
                   JoinType jointype,
89
                   List *restrictlist,
90
                   List **extra_clauses);
91
static Node *remove_rel_from_jointree(Node *jtnode, int relid,
92
                    Node **orphan_quals, int *nremoved);
93
static Node *merge_quals(Node *quals1, Node *quals2);
94
static void fixup_selfjoin_jointree(PlannerInfo *root, Node *jtnode, int relid,
95
                  Node **hoist_quals, bool *found_relid);
96
static List *fixup_selfjoin_quals(PlannerInfo *root, List *quals, int relid);
97
static Node *replace_selfjoin_qual(Node *qual);
98
static int  self_join_candidates_cmp(const void *a, const void *b);
99
100
101
/*
102
 * remove_useless_outer_joins
103
 *    Check for relations that don't actually need to be joined at all,
104
 *    and remove them from the query's jointree.
105
 *
106
 * Returns true if we removed anything.  In that case the caller must discard
107
 * everything it has derived from the jointree and compute it over again,
108
 * since we don't try to update any of that here.
109
 */
110
bool
111
remove_useless_outer_joins(PlannerInfo *root)
112
0
{
113
0
  Relids    removed_relids = NULL;
114
0
  ListCell   *lc;
115
116
  /*
117
   * We are only interested in relations that are left-joined to, so we can
118
   * scan the join_info_list to find them easily.
119
   */
120
0
  foreach(lc, root->join_info_list)
121
0
  {
122
0
    SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(lc);
123
0
    int     innerrelid;
124
0
    int     nremoved;
125
0
    RangeTblEntry *rte;
126
127
    /* Skip if not removable */
128
0
    if (!join_is_removable(root, sjinfo))
129
0
      continue;
130
131
    /*
132
     * join_is_removable insists that the join's syntactic righthand side
133
     * be a single baserel, so we can implement the removal by dropping
134
     * the JoinExpr and everything below its righthand side.
135
     */
136
0
    innerrelid = bms_singleton_member(sjinfo->syn_righthand);
137
138
    /* We verify that exactly one JoinExpr gets removed */
139
0
    nremoved = 0;
140
0
    root->parse->jointree = (FromExpr *)
141
0
      remove_join_from_jointree((Node *) root->parse->jointree,
142
0
                    sjinfo->ojrelid, &nremoved);
143
0
    if (nremoved != 1)
144
0
      elog(ERROR, "failed to find join %d in jointree", sjinfo->ojrelid);
145
146
    /* Track all the relids we've removed, for use below */
147
0
    removed_relids = bms_add_member(removed_relids, innerrelid);
148
0
    removed_relids = bms_add_member(removed_relids, sjinfo->ojrelid);
149
150
    /*
151
     * As in pull_up_simple_subquery, discard no-longer-needed subqueries.
152
     * This is not just an optimization, but is necessary to prevent
153
     * subsequent processing from descending into stale subtrees and
154
     * seeing inconsistent data.  For the same reason, discard any
155
     * tablesample and securityQuals subtrees of the removed rel.
156
     * (Although simple_rte_array[] will be rebuilt shortly, we can still
157
     * use it to find the RTE in the parse tree.)
158
     */
159
0
    rte = root->simple_rte_array[innerrelid];
160
0
    if (rte->rtekind == RTE_SUBQUERY)
161
0
      rte->subquery = NULL;
162
0
    rte->tablesample = NULL;
163
0
    rte->securityQuals = NIL;
164
165
    /*
166
     * It's okay to keep scanning join_info_list for more removable joins,
167
     * even though the data that join_is_removable consults is now
168
     * slightly out of date.  Removing a join can only delete attr_needed
169
     * bits and join clauses, and any attr_needed bit or join clause that
170
     * mentions the removed rel above its own join level would have
171
     * prevented that rel from being removable.  So what remains to be
172
     * examined is unchanged by what we just did.
173
     *
174
     * The converse doesn't hold: dropping a join can make some other join
175
     * removable that didn't look so before.  That's why our caller loops
176
     * until we report finding nothing more to remove.
177
     */
178
0
  }
179
180
0
  if (bms_is_empty(removed_relids))
181
0
    return false;
182
183
  /* Clean up the traces that the removed rels have left elsewhere */
184
0
  remove_rels_from_query_tree(root, removed_relids);
185
186
0
  return true;
187
0
}
188
189
/*
190
 * join_is_removable
191
 *    Check whether we need not perform this special join at all, because
192
 *    it will just duplicate its left input.
193
 *
194
 * This is true for a left join for which the join condition cannot match
195
 * more than one inner-side row.  (There are other possibly interesting
196
 * cases, but we don't have the infrastructure to prove them.)  We also
197
 * have to check that the inner side doesn't generate any variables needed
198
 * above the join.
199
 */
200
static bool
201
join_is_removable(PlannerInfo *root, SpecialJoinInfo *sjinfo)
202
0
{
203
0
  int     innerrelid;
204
0
  RelOptInfo *innerrel;
205
0
  Relids    inputrelids;
206
0
  Relids    joinrelids;
207
0
  List     *clause_list = NIL;
208
0
  ListCell   *l;
209
0
  int     attroff;
210
211
  /*
212
   * Must be a left join to a single baserel, else we aren't going to be
213
   * able to do anything with it.
214
   */
215
0
  if (sjinfo->jointype != JOIN_LEFT)
216
0
    return false;
217
218
  /*
219
   * We test the syntactic righthand side, not min_righthand, because the
220
   * removal is done by deleting the whole righthand subtree of the join.
221
   * (min_righthand can be a singleton when syn_righthand is not, but in
222
   * such a case the attr_needed tests below would reject the join anyway.)
223
   */
224
0
  if (!bms_get_singleton_member(sjinfo->syn_righthand, &innerrelid))
225
0
    return false;
226
0
  Assert(bms_equal(sjinfo->min_righthand, sjinfo->syn_righthand));
227
228
  /*
229
   * Never try to eliminate a left join to the query result rel.  Although
230
   * the case is syntactically impossible in standard SQL, MERGE will build
231
   * a join tree that looks exactly like that.
232
   */
233
0
  if (innerrelid == root->parse->resultRelation)
234
0
    return false;
235
236
0
  innerrel = find_base_rel(root, innerrelid);
237
238
  /*
239
   * Before we go to the effort of checking whether any innerrel variables
240
   * are needed above the join, make a quick check to eliminate cases in
241
   * which we will surely be unable to prove uniqueness of the innerrel.
242
   */
243
0
  if (!rel_supports_distinctness(root, innerrel))
244
0
    return false;
245
246
  /* Compute the relid set for the join we are considering */
247
0
  inputrelids = bms_union(sjinfo->min_lefthand, sjinfo->min_righthand);
248
0
  Assert(sjinfo->ojrelid != 0);
249
0
  joinrelids = bms_copy(inputrelids);
250
0
  joinrelids = bms_add_member(joinrelids, sjinfo->ojrelid);
251
252
  /*
253
   * We can't remove the join if any inner-rel attributes are used above the
254
   * join.  Here, "above" the join includes pushed-down conditions, so we
255
   * should reject if attr_needed includes the OJ's own relid; therefore,
256
   * compare to inputrelids not joinrelids.
257
   *
258
   * As a micro-optimization, it seems better to start with max_attr and
259
   * count down rather than starting with min_attr and counting up, on the
260
   * theory that the system attributes are somewhat less likely to be wanted
261
   * and should be tested last.
262
   */
263
0
  for (attroff = innerrel->max_attr - innerrel->min_attr;
264
0
     attroff >= 0;
265
0
     attroff--)
266
0
  {
267
0
    if (!bms_is_subset(innerrel->attr_needed[attroff], inputrelids))
268
0
      return false;
269
0
  }
270
271
  /*
272
   * Similarly check that the inner rel isn't needed by any PlaceHolderVars
273
   * that will be used above the join.  The PHV case is a little bit more
274
   * complicated, because PHVs may have been assigned a ph_eval_at location
275
   * that includes the innerrel, yet their contained expression might not
276
   * actually reference the innerrel (it could be just a constant, for
277
   * instance).  If such a PHV is due to be evaluated above the join then it
278
   * needn't prevent join removal.
279
   */
280
0
  foreach(l, root->placeholder_list)
281
0
  {
282
0
    PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(l);
283
284
0
    if (bms_overlap(phinfo->ph_lateral, innerrel->relids))
285
0
      return false;   /* it references innerrel laterally */
286
0
    if (!bms_overlap(phinfo->ph_eval_at, innerrel->relids))
287
0
      continue;     /* it definitely doesn't reference innerrel */
288
0
    if (bms_is_subset(phinfo->ph_needed, inputrelids))
289
0
      continue;     /* PHV is not used above the join */
290
0
    if (!bms_is_member(sjinfo->ojrelid, phinfo->ph_eval_at))
291
0
      return false;   /* it has to be evaluated below the join */
292
293
    /*
294
     * We need to be sure there will still be a place to evaluate the PHV
295
     * if we remove the join, ie that ph_eval_at wouldn't become empty.
296
     */
297
0
    if (!bms_overlap(sjinfo->min_lefthand, phinfo->ph_eval_at))
298
0
      return false;   /* there isn't any other place to eval PHV */
299
    /* Check contained expression last, since this is a bit expensive */
300
0
    if (bms_overlap(pull_varnos(root, (Node *) phinfo->ph_var->phexpr),
301
0
            innerrel->relids))
302
0
      return false;   /* contained expression references innerrel */
303
0
  }
304
305
  /*
306
   * Search for mergejoinable clauses that constrain the inner rel against
307
   * either the outer rel or a pseudoconstant.  If an operator is
308
   * mergejoinable then it behaves like equality for some btree opclass, so
309
   * it's what we want.  The mergejoinability test also eliminates clauses
310
   * containing volatile functions, which we couldn't depend on.
311
   */
312
0
  foreach(l, innerrel->joininfo)
313
0
  {
314
0
    RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(l);
315
316
    /*
317
     * If the current join commutes with some other outer join(s) via
318
     * outer join identity 3, there will be multiple clones of its join
319
     * clauses in the joininfo list.  We want to consider only the
320
     * has_clone form of such clauses.  Processing more than one form
321
     * would be wasteful, and also some of the others would confuse the
322
     * RINFO_IS_PUSHED_DOWN test below.
323
     */
324
0
    if (restrictinfo->is_clone)
325
0
      continue;     /* ignore it */
326
327
    /*
328
     * If it's not a join clause for this outer join, we can't use it.
329
     * Note that if the clause is pushed-down, then it is logically from
330
     * above the outer join, even if it references no other rels (it might
331
     * be from WHERE, for example).
332
     */
333
0
    if (RINFO_IS_PUSHED_DOWN(restrictinfo, joinrelids))
334
0
      continue;     /* ignore; not useful here */
335
336
    /* Ignore if it's not a mergejoinable clause */
337
0
    if (!restrictinfo->can_join ||
338
0
      restrictinfo->mergeopfamilies == NIL)
339
0
      continue;     /* not mergejoinable */
340
341
    /*
342
     * Check if the clause has the form "outer op inner" or "inner op
343
     * outer", and if so mark which side is inner.
344
     */
345
0
    if (!clause_sides_match_join(restrictinfo, sjinfo->min_lefthand,
346
0
                   innerrel->relids))
347
0
      continue;     /* no good for these input relations */
348
349
    /* OK, add to list */
350
0
    clause_list = lappend(clause_list, restrictinfo);
351
0
  }
352
353
  /*
354
   * Now that we have the relevant equality join clauses, try to prove the
355
   * innerrel distinct.
356
   */
357
0
  if (rel_is_distinct_for(root, innerrel, clause_list, NULL))
358
0
    return true;
359
360
  /*
361
   * Some day it would be nice to check for other methods of establishing
362
   * distinctness.
363
   */
364
0
  return false;
365
0
}
366
367
/*
368
 * remove_join_from_jointree
369
 *    Delete the JoinExpr with the given RT index, along with everything
370
 *    below its righthand side, from the query's jointree.
371
 *
372
 * The JoinExpr is replaced by its lefthand input.  Its ON conditions can just
373
 * be dropped: since this is a left join, they could only have determined
374
 * which righthand rows join to a given lefthand row, and there are no
375
 * righthand rows anymore.
376
 *
377
 * *nremoved is incremented by the number of JoinExprs removed (there should
378
 * be exactly one, but the caller checks that).
379
 */
380
static Node *
381
remove_join_from_jointree(Node *jtnode, int ojrelid, int *nremoved)
382
0
{
383
0
  if (jtnode == NULL)
384
0
    return NULL;
385
0
  if (IsA(jtnode, RangeTblRef))
386
0
  {
387
    /* nothing to do here */
388
0
  }
389
0
  else if (IsA(jtnode, FromExpr))
390
0
  {
391
0
    FromExpr   *f = (FromExpr *) jtnode;
392
0
    ListCell   *l;
393
394
0
    foreach(l, f->fromlist)
395
0
      lfirst(l) = remove_join_from_jointree((Node *) lfirst(l),
396
0
                          ojrelid, nremoved);
397
0
  }
398
0
  else if (IsA(jtnode, JoinExpr))
399
0
  {
400
0
    JoinExpr   *j = (JoinExpr *) jtnode;
401
402
0
    if (j->rtindex == ojrelid)
403
0
    {
404
0
      (*nremoved)++;
405
0
      return j->larg;
406
0
    }
407
0
    j->larg = remove_join_from_jointree(j->larg, ojrelid, nremoved);
408
0
    j->rarg = remove_join_from_jointree(j->rarg, ojrelid, nremoved);
409
0
  }
410
0
  else
411
0
    elog(ERROR, "unrecognized jointree node type: %d",
412
0
       (int) nodeTag(jtnode));
413
414
0
  return jtnode;
415
0
}
416
417
/*
418
 * remove_rels_from_query_tree
419
 *    Delete all remaining references to the given relids from the query.
420
 *
421
 * Having removed some relations and outer joins from the jointree, we must
422
 * get rid of any references to them that are left behind elsewhere.  There
423
 * should be no ordinary Vars of a removed relation left, but OJ relids can
424
 * still appear in the nullingrels sets of surviving Vars and PlaceHolderVars,
425
 * and both regular and OJ relids can appear in the phrels sets of
426
 * PlaceHolderVars.  ChangeVarNodes knows how to strip a relid out of all of
427
 * those.
428
 */
429
static void
430
remove_rels_from_query_tree(PlannerInfo *root, Relids removed_relids)
431
0
{
432
0
  int     relid = -1;
433
434
0
  while ((relid = bms_next_member(removed_relids, relid)) >= 0)
435
0
  {
436
0
    ChangeVarNodes((Node *) root->parse, relid, INVALID_VAR, 0);
437
438
    /*
439
     * processed_tlist shares some but not all of its nodes with
440
     * parse->targetList, so it has to be processed separately.  (That's
441
     * harmless: ChangeVarNodes works in-place, and removing a relid that
442
     * isn't there is idempotent.)
443
     */
444
0
    ChangeVarNodes((Node *) root->processed_tlist, relid, INVALID_VAR, 0);
445
446
    /* There could be references in the append_rel_list, too */
447
0
    if (root->append_rel_list != NIL)
448
0
      ChangeVarNodes((Node *) root->append_rel_list, relid, INVALID_VAR, 0);
449
0
  }
450
0
}
451
452
/*
453
 * reduce_unique_semijoins
454
 *    Check for semijoins that can be simplified to plain inner joins
455
 *    because the inner relation is provably unique for the join clauses.
456
 *
457
 * Ideally this would happen during reduce_outer_joins, but we don't have
458
 * enough information at that point.
459
 *
460
 * Like the join removal cases, we do this on the query's jointree, so
461
 * returning true means the caller must recompute the derived data.
462
 */
463
bool
464
reduce_unique_semijoins(PlannerInfo *root)
465
0
{
466
0
  bool    changed = false;
467
0
  ListCell   *lc;
468
469
  /*
470
   * Scan the join_info_list to find semijoins.
471
   */
472
0
  foreach(lc, root->join_info_list)
473
0
  {
474
0
    SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(lc);
475
0
    int     innerrelid;
476
0
    RelOptInfo *innerrel;
477
0
    Relids    joinrelids;
478
0
    List     *restrictlist;
479
480
    /*
481
     * Must be a semijoin to a single baserel, else we aren't going to be
482
     * able to do anything with it.
483
     */
484
0
    if (sjinfo->jointype != JOIN_SEMI)
485
0
      continue;
486
487
    /*
488
     * We test the syntactic righthand side, since that's what identifies
489
     * the JoinExpr we'll modify.
490
     */
491
0
    if (!bms_get_singleton_member(sjinfo->syn_righthand, &innerrelid))
492
0
      continue;
493
0
    Assert(bms_equal(sjinfo->min_righthand, sjinfo->syn_righthand));
494
495
0
    innerrel = find_base_rel(root, innerrelid);
496
497
    /*
498
     * Before we trouble to run generate_join_implied_equalities, make a
499
     * quick check to eliminate cases in which we will surely be unable to
500
     * prove uniqueness of the innerrel.
501
     */
502
0
    if (!rel_supports_distinctness(root, innerrel))
503
0
      continue;
504
505
    /* Compute the relid set for the join we are considering */
506
0
    joinrelids = bms_union(sjinfo->min_lefthand, sjinfo->min_righthand);
507
0
    Assert(sjinfo->ojrelid == 0); /* SEMI joins don't have RT indexes */
508
509
    /*
510
     * Since we're only considering a single-rel RHS, any join clauses it
511
     * has must be clauses linking it to the semijoin's min_lefthand.  We
512
     * can also consider EC-derived join clauses.
513
     */
514
0
    restrictlist =
515
0
      list_concat(generate_join_implied_equalities(root,
516
0
                             joinrelids,
517
0
                             sjinfo->min_lefthand,
518
0
                             innerrel,
519
0
                             NULL),
520
0
            innerrel->joininfo);
521
522
    /* Test whether the innerrel is unique for those clauses. */
523
0
    if (!innerrel_is_unique(root,
524
0
                joinrelids, sjinfo->min_lefthand, innerrel,
525
0
                JOIN_SEMI, restrictlist, true))
526
0
      continue;
527
528
    /* OK, reduce the join to a plain inner join in the jointree. */
529
0
    if (!reduce_semijoin_in_jointree((Node *) root->parse->jointree,
530
0
                     sjinfo->syn_righthand))
531
0
      elog(ERROR, "failed to find semijoin in jointree");
532
0
    changed = true;
533
0
  }
534
535
0
  return changed;
536
0
}
537
538
/*
539
 * reduce_semijoin_in_jointree
540
 *    Find the JoinExpr for the semijoin with the given syntactic righthand
541
 *    side, and turn it into an inner join.
542
 *
543
 * Semijoins have no RT index of their own, so we have to identify the one
544
 * we want by the set of relids on its righthand side.
545
 */
546
static bool
547
reduce_semijoin_in_jointree(Node *jtnode, Relids syn_righthand)
548
0
{
549
0
  if (jtnode == NULL)
550
0
    return false;
551
0
  if (IsA(jtnode, RangeTblRef))
552
0
  {
553
    /* nothing to do here */
554
0
  }
555
0
  else if (IsA(jtnode, FromExpr))
556
0
  {
557
0
    FromExpr   *f = (FromExpr *) jtnode;
558
0
    ListCell   *l;
559
560
0
    foreach(l, f->fromlist)
561
0
    {
562
0
      if (reduce_semijoin_in_jointree((Node *) lfirst(l), syn_righthand))
563
0
        return true;
564
0
    }
565
0
  }
566
0
  else if (IsA(jtnode, JoinExpr))
567
0
  {
568
0
    JoinExpr   *j = (JoinExpr *) jtnode;
569
570
0
    if (j->jointype == JOIN_SEMI &&
571
0
      bms_equal(get_relids_in_jointree(j->rarg, true, false),
572
0
            syn_righthand))
573
0
    {
574
0
      j->jointype = JOIN_INNER;
575
0
      return true;
576
0
    }
577
0
    if (reduce_semijoin_in_jointree(j->larg, syn_righthand))
578
0
      return true;
579
0
    if (reduce_semijoin_in_jointree(j->rarg, syn_righthand))
580
0
      return true;
581
0
  }
582
0
  else
583
0
    elog(ERROR, "unrecognized jointree node type: %d",
584
0
       (int) nodeTag(jtnode));
585
586
0
  return false;
587
0
}
588
589
590
/*
591
 * rel_supports_distinctness
592
 *    Could the relation possibly be proven distinct on some set of columns?
593
 *
594
 * This is effectively a pre-checking function for rel_is_distinct_for().
595
 * It must return true if rel_is_distinct_for() could possibly return true
596
 * with this rel, but it should not expend a lot of cycles.  The idea is
597
 * that callers can avoid doing possibly-expensive processing to compute
598
 * rel_is_distinct_for()'s argument lists if the call could not possibly
599
 * succeed.
600
 */
601
static bool
602
rel_supports_distinctness(PlannerInfo *root, RelOptInfo *rel)
603
0
{
604
  /* We only know about baserels ... */
605
0
  if (rel->reloptkind != RELOPT_BASEREL)
606
0
    return false;
607
0
  if (rel->rtekind == RTE_RELATION)
608
0
  {
609
    /*
610
     * For a plain relation, we only know how to prove uniqueness by
611
     * reference to unique indexes.  Make sure there's at least one
612
     * suitable unique index.  It must be immediately enforced, and not a
613
     * partial index. (Keep these conditions in sync with
614
     * relation_has_unique_index_for!)
615
     */
616
0
    ListCell   *lc;
617
618
0
    foreach(lc, rel->indexlist)
619
0
    {
620
0
      IndexOptInfo *ind = (IndexOptInfo *) lfirst(lc);
621
622
0
      if (ind->unique && ind->immediate && ind->indpred == NIL)
623
0
        return true;
624
0
    }
625
0
  }
626
0
  else if (rel->rtekind == RTE_SUBQUERY)
627
0
  {
628
0
    Query    *subquery = root->simple_rte_array[rel->relid]->subquery;
629
630
    /* Check if the subquery has any qualities that support distinctness */
631
0
    if (query_supports_distinctness(subquery))
632
0
      return true;
633
0
  }
634
  /* We have no proof rules for any other rtekinds. */
635
0
  return false;
636
0
}
637
638
/*
639
 * rel_is_distinct_for
640
 *    Does the relation return only distinct rows according to clause_list?
641
 *
642
 * clause_list is a list of join restriction clauses involving this rel and
643
 * some other one.  Return true if no two rows emitted by this rel could
644
 * possibly join to the same row of the other rel.
645
 *
646
 * The caller must have already determined that each condition is a
647
 * mergejoinable equality with an expression in this relation on one side, and
648
 * an expression not involving this relation on the other.  The transient
649
 * outer_is_left flag is used to identify which side references this relation:
650
 * left side if outer_is_left is false, right side if it is true.
651
 *
652
 * Note that the passed-in clause_list may be destructively modified!  This
653
 * is OK for current uses, because the clause_list is built by the caller for
654
 * the sole purpose of passing to this function.
655
 *
656
 * (*extra_clauses) to be set to the right sides of baserestrictinfo clauses,
657
 * looking like "x = const" if distinctness is derived from such clauses, not
658
 * joininfo clauses.  Pass NULL to the extra_clauses if this value is not
659
 * needed.
660
 */
661
static bool
662
rel_is_distinct_for(PlannerInfo *root, RelOptInfo *rel, List *clause_list,
663
          List **extra_clauses)
664
0
{
665
  /*
666
   * We could skip a couple of tests here if we assume all callers checked
667
   * rel_supports_distinctness first, but it doesn't seem worth taking any
668
   * risk for.
669
   */
670
0
  if (rel->reloptkind != RELOPT_BASEREL)
671
0
    return false;
672
0
  if (rel->rtekind == RTE_RELATION)
673
0
  {
674
    /*
675
     * Examine the indexes to see if we have a matching unique index.
676
     * relation_has_unique_index_for automatically adds any usable
677
     * restriction clauses for the rel, so we needn't do that here.
678
     */
679
0
    if (relation_has_unique_index_for(root, rel, clause_list, extra_clauses))
680
0
      return true;
681
0
  }
682
0
  else if (rel->rtekind == RTE_SUBQUERY)
683
0
  {
684
0
    Index   relid = rel->relid;
685
0
    Query    *subquery = root->simple_rte_array[relid]->subquery;
686
0
    List     *distinct_cols = NIL;
687
0
    ListCell   *l;
688
689
    /*
690
     * Build the argument list for query_is_distinct_for: a list of
691
     * DistinctColInfo entries, each holding an output column number that
692
     * the query needs to be distinct over, the equality operator that the
693
     * column needs to be distinct according to, and that operator's input
694
     * collation.  The collation matters because the subquery's own
695
     * DISTINCT / GROUP BY / set-op proves uniqueness under its own
696
     * collation, which need not agree with the operator's.
697
     *
698
     * (XXX we are not considering restriction clauses attached to the
699
     * subquery; is that worth doing?)
700
     */
701
0
    foreach(l, clause_list)
702
0
    {
703
0
      RestrictInfo *rinfo = lfirst_node(RestrictInfo, l);
704
0
      OpExpr     *opexpr;
705
0
      Var      *var;
706
0
      DistinctColInfo *dcinfo;
707
708
      /*
709
       * The caller's mergejoinability test should have selected only
710
       * OpExprs.  The operator might be a cross-type operator and thus
711
       * not exactly the same operator the subquery would consider;
712
       * that's all right since query_is_distinct_for can resolve such
713
       * cases.
714
       */
715
0
      opexpr = castNode(OpExpr, rinfo->clause);
716
717
      /* caller identified the inner side for us */
718
0
      if (rinfo->outer_is_left)
719
0
        var = (Var *) get_rightop(rinfo->clause);
720
0
      else
721
0
        var = (Var *) get_leftop(rinfo->clause);
722
723
      /*
724
       * We may ignore any RelabelType node above the operand.  (There
725
       * won't be more than one, since eval_const_expressions() has been
726
       * applied already.)
727
       */
728
0
      if (var && IsA(var, RelabelType))
729
0
        var = (Var *) ((RelabelType *) var)->arg;
730
731
      /*
732
       * If inner side isn't a Var referencing a subquery output column,
733
       * this clause doesn't help us.
734
       */
735
0
      if (!var || !IsA(var, Var) ||
736
0
        var->varno != relid || var->varlevelsup != 0)
737
0
        continue;
738
739
0
      dcinfo = palloc_object(DistinctColInfo);
740
0
      dcinfo->colno = var->varattno;
741
0
      dcinfo->opid = opexpr->opno;
742
0
      dcinfo->collid = opexpr->inputcollid;
743
0
      distinct_cols = lappend(distinct_cols, dcinfo);
744
0
    }
745
746
0
    if (query_is_distinct_for(subquery, distinct_cols))
747
0
      return true;
748
0
  }
749
0
  return false;
750
0
}
751
752
753
/*
754
 * query_supports_distinctness - could the query possibly be proven distinct
755
 *    on some set of output columns?
756
 *
757
 * This is effectively a pre-checking function for query_is_distinct_for().
758
 * It must return true if query_is_distinct_for() could possibly return true
759
 * with this query, but it should not expend a lot of cycles.  The idea is
760
 * that callers can avoid doing possibly-expensive processing to compute
761
 * query_is_distinct_for()'s argument lists if the call could not possibly
762
 * succeed.
763
 */
764
bool
765
query_supports_distinctness(Query *query)
766
0
{
767
  /* SRFs break distinctness except with plain DISTINCT, see below */
768
0
  if (query->hasTargetSRFs &&
769
0
    (query->distinctClause == NIL || query->hasDistinctOn))
770
0
    return false;
771
772
  /* check for features we can prove distinctness with */
773
0
  if (query->distinctClause != NIL ||
774
0
    query->groupClause != NIL ||
775
0
    query->groupingSets != NIL ||
776
0
    query->hasAggs ||
777
0
    query->havingQual ||
778
0
    query->setOperations)
779
0
    return true;
780
781
0
  return false;
782
0
}
783
784
/*
785
 * query_is_distinct_for - does query never return duplicates of the
786
 *    specified columns?
787
 *
788
 * query is a not-yet-planned subquery (in current usage, it's always from
789
 * a subquery RTE, which the planner avoids scribbling on).
790
 *
791
 * distinct_cols is a list of DistinctColInfo, one per requested output column.
792
 * Each entry names the subquery output column number we want distinct, the
793
 * upper-level equality operator we'll compare values with, and that operator's
794
 * input collation.  We are interested in whether rows consisting of just these
795
 * columns are certain to be distinct.
796
 *
797
 * "Distinctness" is defined according to whether the corresponding upper-level
798
 * equality operators would think the values are distinct.  (Note: each opid
799
 * could be a cross-type operator, and thus not exactly the equality operator
800
 * that the subquery would use itself.  We use equality_ops_are_compatible() to
801
 * check compatibility.  That looks at opfamily membership for index AMs that
802
 * have declared that they support consistent equality semantics within an
803
 * opfamily, and so should give trustworthy answers for all operators that we
804
 * might need to deal with here.)
805
 *
806
 * The collid must also agree on equality with the collation the subquery's own
807
 * DISTINCT/GROUP BY/set-op uses to deduplicate the column, else the subquery's
808
 * distinctness does not carry over to the caller's equality semantics.  Two
809
 * collations agree on equality if they match or if both are deterministic (in
810
 * which case both reduce equality to byte-equality; see CREATE COLLATION).
811
 */
812
bool
813
query_is_distinct_for(Query *query, List *distinct_cols)
814
0
{
815
0
  ListCell   *l;
816
0
  DistinctColInfo *dcinfo;
817
818
  /*
819
   * DISTINCT (including DISTINCT ON) guarantees uniqueness if all the
820
   * columns in the DISTINCT clause appear in colnos and operator semantics
821
   * match.  With plain DISTINCT this is true even if there are SRFs in the
822
   * tlist, since they are all DISTINCT columns and hence get expanded
823
   * before the Unique step.  But with DISTINCT ON, the planner may postpone
824
   * SRFs that are not DISTINCT ON or ORDER BY columns until after the
825
   * Unique step, which can produce duplicates of the DISTINCT ON columns;
826
   * so we can't rely on DISTINCT ON if there are any tlist SRFs.
827
   */
828
0
  if (query->distinctClause &&
829
0
    !(query->hasTargetSRFs && query->hasDistinctOn))
830
0
  {
831
0
    foreach(l, query->distinctClause)
832
0
    {
833
0
      SortGroupClause *sgc = (SortGroupClause *) lfirst(l);
834
0
      TargetEntry *tle = get_sortgroupclause_tle(sgc,
835
0
                             query->targetList);
836
837
0
      dcinfo = distinct_col_search(tle->resno, distinct_cols);
838
0
      if (dcinfo == NULL ||
839
0
        !equality_ops_are_compatible(dcinfo->opid, sgc->eqop) ||
840
0
        !collations_agree_on_equality(dcinfo->collid,
841
0
                        exprCollation((Node *) tle->expr)))
842
0
        break;     /* exit early if no match */
843
0
    }
844
0
    if (l == NULL)     /* had matches for all? */
845
0
      return true;
846
0
  }
847
848
  /*
849
   * Otherwise, a set-returning function in the query's targetlist can
850
   * result in returning duplicate rows, despite any grouping that might
851
   * occur before tlist evaluation.  (If all tlist SRFs are within GROUP BY
852
   * columns, it would be safe because they'd be expanded before grouping.
853
   * But it doesn't currently seem worth the effort to check for that.)
854
   */
855
0
  if (query->hasTargetSRFs)
856
0
    return false;
857
858
  /*
859
   * Similarly, GROUP BY without GROUPING SETS guarantees uniqueness if all
860
   * the grouped columns appear in colnos and operator semantics match.
861
   */
862
0
  if (query->groupClause && !query->groupingSets)
863
0
  {
864
0
    foreach(l, query->groupClause)
865
0
    {
866
0
      SortGroupClause *sgc = (SortGroupClause *) lfirst(l);
867
0
      TargetEntry *tle = get_sortgroupclause_tle(sgc,
868
0
                             query->targetList);
869
870
0
      dcinfo = distinct_col_search(tle->resno, distinct_cols);
871
0
      if (dcinfo == NULL ||
872
0
        !equality_ops_are_compatible(dcinfo->opid, sgc->eqop) ||
873
0
        !collations_agree_on_equality(dcinfo->collid,
874
0
                        exprCollation((Node *) tle->expr)))
875
0
        break;     /* exit early if no match */
876
0
    }
877
0
    if (l == NULL)     /* had matches for all? */
878
0
      return true;
879
0
  }
880
0
  else if (query->groupingSets)
881
0
  {
882
0
    List     *gsets;
883
884
    /*
885
     * If we have grouping sets with expressions, we probably don't have
886
     * uniqueness and analysis would be hard. Punt.
887
     */
888
0
    if (query->groupClause)
889
0
      return false;
890
891
    /*
892
     * If we have no groupClause (therefore no grouping expressions), we
893
     * might have one or many empty grouping sets.  If there's just one,
894
     * or if the DISTINCT clause is used on the GROUP BY, then we're
895
     * returning only one row and are certainly unique.  But otherwise, we
896
     * know we're certainly not unique.
897
     */
898
0
    if (query->groupDistinct)
899
0
      return true;
900
901
0
    gsets = expand_grouping_sets(query->groupingSets, false, -1);
902
903
0
    return (list_length(gsets) == 1);
904
0
  }
905
0
  else
906
0
  {
907
    /*
908
     * If we have no GROUP BY, but do have aggregates or HAVING, then the
909
     * result is at most one row so it's surely unique, for any operators.
910
     */
911
0
    if (query->hasAggs || query->havingQual)
912
0
      return true;
913
0
  }
914
915
  /*
916
   * UNION, INTERSECT, EXCEPT guarantee uniqueness of the whole output row,
917
   * except with ALL.
918
   */
919
0
  if (query->setOperations)
920
0
  {
921
0
    SetOperationStmt *topop = castNode(SetOperationStmt, query->setOperations);
922
923
0
    Assert(topop->op != SETOP_NONE);
924
925
0
    if (!topop->all)
926
0
    {
927
0
      ListCell   *lg;
928
929
      /* We're good if all the nonjunk output columns are in colnos */
930
0
      lg = list_head(topop->groupClauses);
931
0
      foreach(l, query->targetList)
932
0
      {
933
0
        TargetEntry *tle = (TargetEntry *) lfirst(l);
934
0
        SortGroupClause *sgc;
935
936
0
        if (tle->resjunk)
937
0
          continue; /* ignore resjunk columns */
938
939
        /* non-resjunk columns should have grouping clauses */
940
0
        Assert(lg != NULL);
941
0
        sgc = (SortGroupClause *) lfirst(lg);
942
0
        lg = lnext(topop->groupClauses, lg);
943
944
0
        dcinfo = distinct_col_search(tle->resno, distinct_cols);
945
0
        if (dcinfo == NULL ||
946
0
          !equality_ops_are_compatible(dcinfo->opid, sgc->eqop) ||
947
0
          !collations_agree_on_equality(dcinfo->collid,
948
0
                          exprCollation((Node *) tle->expr)))
949
0
          break;   /* exit early if no match */
950
0
      }
951
0
      if (l == NULL)   /* had matches for all? */
952
0
        return true;
953
0
    }
954
0
  }
955
956
  /*
957
   * XXX Are there any other cases in which we can easily see the result
958
   * must be distinct?
959
   *
960
   * If you do add more smarts to this function, be sure to update
961
   * query_supports_distinctness() to match.
962
   */
963
964
0
  return false;
965
0
}
966
967
/*
968
 * distinct_col_search - subroutine for query_is_distinct_for
969
 *
970
 * If colno matches the colno field of an entry in distinct_cols, return a
971
 * pointer to that entry; else return NULL.  (Ordinarily distinct_cols would
972
 * not contain duplicate colnos, but if it does, we arbitrarily select the
973
 * first match.)
974
 */
975
static DistinctColInfo *
976
distinct_col_search(int colno, List *distinct_cols)
977
0
{
978
0
  foreach_ptr(DistinctColInfo, dcinfo, distinct_cols)
979
0
  {
980
0
    if (dcinfo->colno == colno)
981
0
      return dcinfo;
982
0
  }
983
984
0
  return NULL;
985
0
}
986
987
988
/*
989
 * innerrel_is_unique
990
 *    Check if the innerrel provably contains at most one tuple matching any
991
 *    tuple from the outerrel, based on join clauses in the 'restrictlist'.
992
 *
993
 * We need an actual RelOptInfo for the innerrel, but it's sufficient to
994
 * identify the outerrel by its Relids.  This asymmetry supports use of this
995
 * function before joinrels have been built.  (The caller is expected to
996
 * also supply the joinrelids, just to save recalculating that.)
997
 *
998
 * The proof must be made based only on clauses that will be "joinquals"
999
 * rather than "otherquals" at execution.  For an inner join there's no
1000
 * difference; but if the join is outer, we must ignore pushed-down quals,
1001
 * as those will become "otherquals".  Note that this means the answer might
1002
 * vary depending on whether IS_OUTER_JOIN(jointype); since we cache the
1003
 * answer without regard to that, callers must take care not to call this
1004
 * with jointypes that would be classified differently by IS_OUTER_JOIN().
1005
 *
1006
 * The actual proof is undertaken by is_innerrel_unique_for(); this function
1007
 * is a frontend that is mainly concerned with caching the answers.
1008
 * In particular, the force_cache argument allows overriding the internal
1009
 * heuristic about whether to cache negative answers; it should be "true"
1010
 * if making an inquiry that is not part of the normal bottom-up join search
1011
 * sequence.
1012
 */
1013
bool
1014
innerrel_is_unique(PlannerInfo *root,
1015
           Relids joinrelids,
1016
           Relids outerrelids,
1017
           RelOptInfo *innerrel,
1018
           JoinType jointype,
1019
           List *restrictlist,
1020
           bool force_cache)
1021
0
{
1022
0
  return innerrel_is_unique_ext(root, joinrelids, outerrelids, innerrel,
1023
0
                  jointype, restrictlist, force_cache, NULL);
1024
0
}
1025
1026
/*
1027
 * innerrel_is_unique_ext
1028
 *    Do the same as innerrel_is_unique(), but also set to (*extra_clauses)
1029
 *    additional clauses from a baserestrictinfo list used to prove the
1030
 *    uniqueness.
1031
 *
1032
 * A non-NULL extra_clauses indicates that we're checking for self-join and
1033
 * correspondingly dealing with filtered clauses.
1034
 */
1035
static bool
1036
innerrel_is_unique_ext(PlannerInfo *root,
1037
             Relids joinrelids,
1038
             Relids outerrelids,
1039
             RelOptInfo *innerrel,
1040
             JoinType jointype,
1041
             List *restrictlist,
1042
             bool force_cache,
1043
             List **extra_clauses)
1044
0
{
1045
0
  MemoryContext old_context;
1046
0
  ListCell   *lc;
1047
0
  UniqueRelInfo *uniqueRelInfo;
1048
0
  List     *outer_exprs = NIL;
1049
0
  bool    self_join = (extra_clauses != NULL);
1050
1051
  /* Certainly can't prove uniqueness when there are no joinclauses */
1052
0
  if (restrictlist == NIL)
1053
0
    return false;
1054
1055
  /*
1056
   * Make a quick check to eliminate cases in which we will surely be unable
1057
   * to prove uniqueness of the innerrel.
1058
   */
1059
0
  if (!rel_supports_distinctness(root, innerrel))
1060
0
    return false;
1061
1062
  /*
1063
   * Query the cache to see if we've managed to prove that innerrel is
1064
   * unique for any subset of this outerrel.  For non-self-join search, we
1065
   * don't need an exact match, as extra outerrels can't make the innerrel
1066
   * any less unique (or more formally, the restrictlist for a join to a
1067
   * superset outerrel must be a superset of the conditions we successfully
1068
   * used before). For self-join search, we require an exact match of
1069
   * outerrels because we need extra clauses to be valid for our case. Also,
1070
   * for self-join checking we've filtered the clauses list.  Thus, we can
1071
   * match only the result cached for a self-join search for another
1072
   * self-join check.
1073
   */
1074
0
  foreach(lc, innerrel->unique_for_rels)
1075
0
  {
1076
0
    uniqueRelInfo = (UniqueRelInfo *) lfirst(lc);
1077
1078
0
    if ((!self_join && bms_is_subset(uniqueRelInfo->outerrelids, outerrelids)) ||
1079
0
      (self_join && bms_equal(uniqueRelInfo->outerrelids, outerrelids) &&
1080
0
       uniqueRelInfo->self_join))
1081
0
    {
1082
0
      if (extra_clauses)
1083
0
        *extra_clauses = uniqueRelInfo->extra_clauses;
1084
0
      return true;   /* Success! */
1085
0
    }
1086
0
  }
1087
1088
  /*
1089
   * Conversely, we may have already determined that this outerrel, or some
1090
   * superset thereof, cannot prove this innerrel to be unique.
1091
   */
1092
0
  foreach(lc, innerrel->non_unique_for_rels)
1093
0
  {
1094
0
    Relids    unique_for_rels = (Relids) lfirst(lc);
1095
1096
0
    if (bms_is_subset(outerrelids, unique_for_rels))
1097
0
      return false;
1098
0
  }
1099
1100
  /* No cached information, so try to make the proof. */
1101
0
  if (is_innerrel_unique_for(root, joinrelids, outerrelids, innerrel,
1102
0
                 jointype, restrictlist,
1103
0
                 self_join ? &outer_exprs : NULL))
1104
0
  {
1105
    /*
1106
     * Cache the positive result for future probes, being sure to keep it
1107
     * in the planner_cxt even if we are working in GEQO.
1108
     *
1109
     * Note: one might consider trying to isolate the minimal subset of
1110
     * the outerrels that proved the innerrel unique.  But it's not worth
1111
     * the trouble, because the planner builds up joinrels incrementally
1112
     * and so we'll see the minimally sufficient outerrels before any
1113
     * supersets of them anyway.
1114
     */
1115
0
    old_context = MemoryContextSwitchTo(root->planner_cxt);
1116
0
    uniqueRelInfo = makeNode(UniqueRelInfo);
1117
0
    uniqueRelInfo->outerrelids = bms_copy(outerrelids);
1118
0
    uniqueRelInfo->self_join = self_join;
1119
0
    uniqueRelInfo->extra_clauses = outer_exprs;
1120
0
    innerrel->unique_for_rels = lappend(innerrel->unique_for_rels,
1121
0
                      uniqueRelInfo);
1122
0
    MemoryContextSwitchTo(old_context);
1123
1124
0
    if (extra_clauses)
1125
0
      *extra_clauses = outer_exprs;
1126
0
    return true;     /* Success! */
1127
0
  }
1128
0
  else
1129
0
  {
1130
    /*
1131
     * None of the join conditions for outerrel proved innerrel unique, so
1132
     * we can safely reject this outerrel or any subset of it in future
1133
     * checks.
1134
     *
1135
     * However, in normal planning mode, caching this knowledge is totally
1136
     * pointless; it won't be queried again, because we build up joinrels
1137
     * from smaller to larger.  It's only useful when using GEQO or
1138
     * another planner extension that attempts planning multiple times.
1139
     *
1140
     * Also, allow callers to override that heuristic and force caching;
1141
     * that's useful for reduce_unique_semijoins, which calls here before
1142
     * the normal join search starts.
1143
     */
1144
0
    if (force_cache || root->assumeReplanning)
1145
0
    {
1146
0
      old_context = MemoryContextSwitchTo(root->planner_cxt);
1147
0
      innerrel->non_unique_for_rels =
1148
0
        lappend(innerrel->non_unique_for_rels,
1149
0
            bms_copy(outerrelids));
1150
0
      MemoryContextSwitchTo(old_context);
1151
0
    }
1152
1153
0
    return false;
1154
0
  }
1155
0
}
1156
1157
/*
1158
 * is_innerrel_unique_for
1159
 *    Check if the innerrel provably contains at most one tuple matching any
1160
 *    tuple from the outerrel, based on join clauses in the 'restrictlist'.
1161
 */
1162
static bool
1163
is_innerrel_unique_for(PlannerInfo *root,
1164
             Relids joinrelids,
1165
             Relids outerrelids,
1166
             RelOptInfo *innerrel,
1167
             JoinType jointype,
1168
             List *restrictlist,
1169
             List **extra_clauses)
1170
0
{
1171
0
  List     *clause_list = NIL;
1172
0
  ListCell   *lc;
1173
1174
  /*
1175
   * Search for mergejoinable clauses that constrain the inner rel against
1176
   * the outer rel.  If an operator is mergejoinable then it behaves like
1177
   * equality for some btree opclass, so it's what we want.  The
1178
   * mergejoinability test also eliminates clauses containing volatile
1179
   * functions, which we couldn't depend on.
1180
   */
1181
0
  foreach(lc, restrictlist)
1182
0
  {
1183
0
    RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(lc);
1184
1185
    /*
1186
     * As noted above, if it's a pushed-down clause and we're at an outer
1187
     * join, we can't use it.
1188
     */
1189
0
    if (IS_OUTER_JOIN(jointype) &&
1190
0
      RINFO_IS_PUSHED_DOWN(restrictinfo, joinrelids))
1191
0
      continue;
1192
1193
    /* Ignore if it's not a mergejoinable clause */
1194
0
    if (!restrictinfo->can_join ||
1195
0
      restrictinfo->mergeopfamilies == NIL)
1196
0
      continue;     /* not mergejoinable */
1197
1198
    /*
1199
     * Check if the clause has the form "outer op inner" or "inner op
1200
     * outer", and if so mark which side is inner.
1201
     */
1202
0
    if (!clause_sides_match_join(restrictinfo, outerrelids,
1203
0
                   innerrel->relids))
1204
0
      continue;     /* no good for these input relations */
1205
1206
    /* OK, add to the list */
1207
0
    clause_list = lappend(clause_list, restrictinfo);
1208
0
  }
1209
1210
  /* Let rel_is_distinct_for() do the hard work */
1211
0
  return rel_is_distinct_for(root, innerrel, clause_list, extra_clauses);
1212
0
}
1213
1214
/*
1215
 * Remove the toRemove relation after we have proven that it participates only
1216
 * in an unneeded unique self-join with toKeep.
1217
 *
1218
 * The removal is done by deleting the relation's RangeTblRef from the
1219
 * jointree and then pointing everything that referenced it at the relation we
1220
 * are keeping.  All the conditions that were attached to the removed relation
1221
 * thereby become conditions on the remaining one, which is what we want:
1222
 * we've proven that the two relations select the same rows.  Note that
1223
 * this change requires us to hoist those conditions up to someplace
1224
 * syntactically enclosing toKeep.
1225
 *
1226
 * kmark and rmark are the PlanRowMarks (if any) for the kept and removed
1227
 * relations.  We could re-locate those, but the caller already found them.
1228
 */
1229
static void
1230
remove_self_join_rel(PlannerInfo *root,
1231
           RelOptInfo *toKeep, RelOptInfo *toRemove,
1232
           PlanRowMark *kmark, PlanRowMark *rmark)
1233
0
{
1234
0
  Node     *orphan_quals = NULL;
1235
0
  int     nremoved = 0;
1236
0
  Node     *hoist_quals = NULL;
1237
0
  bool    found_relid = false;
1238
1239
0
  Assert(toKeep->relid > 0);
1240
0
  Assert(toRemove->relid > 0);
1241
1242
  /* We verify that exactly one reference gets removed from the jointree */
1243
0
  root->parse->jointree = (FromExpr *)
1244
0
    remove_rel_from_jointree((Node *) root->parse->jointree,
1245
0
                 toRemove->relid,
1246
0
                 &orphan_quals, &nremoved);
1247
0
  if (nremoved != 1)
1248
0
    elog(ERROR, "failed to find relation %d in jointree", toRemove->relid);
1249
  /* The topmost FromExpr can't have gone away, so nothing can be orphaned */
1250
0
  Assert(root->parse->jointree != NULL);
1251
0
  Assert(orphan_quals == NULL);
1252
1253
  /*
1254
   * Replace all references to the removed relation.  Note that this must
1255
   * happen after the jointree surgery, else we'd not be able to tell the
1256
   * two relations' RangeTblRefs apart.
1257
   */
1258
0
  ChangeVarNodes((Node *) root->parse, toRemove->relid, toKeep->relid, 0);
1259
1260
  /*
1261
   * processed_tlist shares some but not all of its nodes with
1262
   * parse->targetList, so it has to be processed separately.  (That's
1263
   * harmless: ChangeVarNodes works in-place, and the second visit to a
1264
   * shared node finds nothing to change.)
1265
   */
1266
0
  ChangeVarNodes((Node *) root->processed_tlist, toRemove->relid,
1267
0
           toKeep->relid, 0);
1268
1269
  /* There could be references in the append_rel_list, too */
1270
0
  if (root->append_rel_list != NIL)
1271
0
    ChangeVarNodes((Node *) root->append_rel_list, toRemove->relid,
1272
0
             toKeep->relid, 0);
1273
1274
  /*
1275
   * As in remove_useless_outer_joins, discard the securityQuals of the
1276
   * removed rel, so that later passes don't visit them.  We know the kept
1277
   * rel has the same quals.  (tablesample is already known NULL.)
1278
   */
1279
0
  root->simple_rte_array[toRemove->relid]->securityQuals = NIL;
1280
1281
  /* Clean up the quals that the substitution has messed with */
1282
0
  fixup_selfjoin_jointree(root, (Node *) root->parse->jointree,
1283
0
              toKeep->relid,
1284
0
              &hoist_quals, &found_relid);
1285
  /* We shouldn't have any leftover quals, and we must have found toKeep */
1286
0
  Assert(hoist_quals == NULL);
1287
0
  Assert(found_relid);
1288
1289
  /*
1290
   * If the removed relation has a row mark, transfer it to the remaining
1291
   * one.
1292
   *
1293
   * If both rels have row marks, just keep the one corresponding to the
1294
   * remaining relation because we verified earlier that they have the same
1295
   * strength.
1296
   */
1297
0
  if (rmark)
1298
0
  {
1299
0
    if (kmark)
1300
0
    {
1301
0
      Assert(kmark->markType == rmark->markType);
1302
1303
0
      root->rowMarks = list_delete_ptr(root->rowMarks, rmark);
1304
0
    }
1305
0
    else
1306
0
    {
1307
      /* Shouldn't have inheritance children yet. */
1308
0
      Assert(rmark->rti == rmark->prti);
1309
1310
0
      rmark->rti = rmark->prti = toKeep->relid;
1311
0
    }
1312
0
  }
1313
0
}
1314
1315
/*
1316
 * remove_rel_from_jointree
1317
 *    Delete the RangeTblRef for the given relation from the query's
1318
 *    jointree.
1319
 *
1320
 * This is used for self-join elimination, where the removed relation's
1321
 * qual conditions must all be preserved (they will be transposed onto the
1322
 * remaining relation afterwards).  Hence, if dropping the RangeTblRef leaves
1323
 * a JoinExpr or FromExpr with nothing under it, we can't simply drop that
1324
 * node; we hand its quals back to the caller in *orphan_quals, to be merged
1325
 * into the nearest enclosing node that still has some content.  That's a
1326
 * valid transformation only for inner joins, but a jointree node can't become
1327
 * empty at an outer join here: remove_self_joins_one_group() insists that the
1328
 * two relations be on the same side of every outer join, so the relation we
1329
 * are keeping would have to be in the emptied subtree too.
1330
 *
1331
 * *nremoved is incremented by the number of RangeTblRefs removed (there
1332
 * should be exactly one, but the caller checks that).
1333
 */
1334
static Node *
1335
remove_rel_from_jointree(Node *jtnode, int relid,
1336
             Node **orphan_quals, int *nremoved)
1337
0
{
1338
0
  if (jtnode == NULL)
1339
0
    return NULL;
1340
0
  if (IsA(jtnode, RangeTblRef))
1341
0
  {
1342
0
    RangeTblRef *rtr = (RangeTblRef *) jtnode;
1343
1344
0
    if (rtr->rtindex == relid)
1345
0
    {
1346
0
      (*nremoved)++;
1347
0
      return NULL;
1348
0
    }
1349
0
  }
1350
0
  else if (IsA(jtnode, FromExpr))
1351
0
  {
1352
0
    FromExpr   *f = (FromExpr *) jtnode;
1353
0
    List     *newfromlist = NIL;
1354
0
    Node     *sub_orphans = NULL;
1355
0
    ListCell   *l;
1356
1357
0
    foreach(l, f->fromlist)
1358
0
    {
1359
0
      Node     *newchild;
1360
1361
0
      newchild = remove_rel_from_jointree((Node *) lfirst(l), relid,
1362
0
                        &sub_orphans, nremoved);
1363
0
      if (newchild != NULL)
1364
0
        newfromlist = lappend(newfromlist, newchild);
1365
0
    }
1366
0
    f->fromlist = newfromlist;
1367
0
    f->quals = merge_quals(sub_orphans, f->quals);
1368
0
    if (newfromlist == NIL)
1369
0
    {
1370
      /* Nothing left here, so pass our quals up to the parent */
1371
0
      *orphan_quals = merge_quals(f->quals, *orphan_quals);
1372
0
      return NULL;
1373
0
    }
1374
0
  }
1375
0
  else if (IsA(jtnode, JoinExpr))
1376
0
  {
1377
0
    JoinExpr   *j = (JoinExpr *) jtnode;
1378
0
    Node     *sub_orphans = NULL;
1379
1380
0
    j->larg = remove_rel_from_jointree(j->larg, relid,
1381
0
                       &sub_orphans, nremoved);
1382
0
    j->rarg = remove_rel_from_jointree(j->rarg, relid,
1383
0
                       &sub_orphans, nremoved);
1384
0
    if (j->larg == NULL || j->rarg == NULL)
1385
0
    {
1386
0
      Node     *surviving = (j->larg != NULL) ? j->larg : j->rarg;
1387
0
      Node     *quals = merge_quals(sub_orphans, j->quals);
1388
1389
      /* As explained above, this can only happen for an inner join */
1390
0
      Assert(j->jointype == JOIN_INNER);
1391
      /* We can't have removed both children */
1392
0
      Assert(surviving != NULL);
1393
1394
      /*
1395
       * Replace the join by a FromExpr, so that the surviving side's
1396
       * rows are still filtered by the join's conditions.
1397
       */
1398
0
      return (Node *) makeFromExpr(list_make1(surviving), quals);
1399
0
    }
1400
    /* A subtree that survives never hands any quals back to us */
1401
0
    Assert(sub_orphans == NULL);
1402
0
  }
1403
0
  else
1404
0
    elog(ERROR, "unrecognized jointree node type: %d",
1405
0
       (int) nodeTag(jtnode));
1406
1407
0
  return jtnode;
1408
0
}
1409
1410
/*
1411
 * merge_quals
1412
 *    Combine two jointree qual conditions.
1413
 *
1414
 * quals1 should be the quals from the lower of the two jointree levels,
1415
 * so that those quals get applied first.
1416
 *
1417
 * Jointree quals have been through preprocess_expression() by now, so each
1418
 * one is either NULL or an implicitly-ANDed List.
1419
 */
1420
static Node *
1421
merge_quals(Node *quals1, Node *quals2)
1422
0
{
1423
0
  if (quals1 == NULL)
1424
0
    return quals2;
1425
0
  if (quals2 == NULL)
1426
0
    return quals1;
1427
0
  return (Node *) list_concat(castNode(List, quals1),
1428
0
                castNode(List, quals2));
1429
0
}
1430
1431
/*
1432
 * fixup_selfjoin_jointree
1433
 *    Clean up the query's jointree quals after self-join elimination has
1434
 *    merged one relation into another.  (relid is the kept relation.)
1435
 *
1436
 * See fixup_selfjoin_quals() for what needs fixing locally to each qual list.
1437
 * In addition, we need to check quals to see if they refer to relid, and if
1438
 * so make sure they get hoisted to someplace syntactically above relid.
1439
 * Do that using a "hoist_quals" in/out parameter similar to "orphan_quals"
1440
 * in remove_rel_from_jointree.  (We can't readily merge these concerns into
1441
 * a single pass, since remove_rel_from_jointree must run before we relabel
1442
 * the removed rel's Vars.)  In addition, *found_relid is set true if
1443
 * the subtree rooted at jtnode is found to contain relid's RangeTblRef,
1444
 * so that we can tell when to stop hoisting quals.
1445
 * If a qual gets hoisted up, we apply fixup_selfjoin_quals() to it only
1446
 * after it reaches its final level.  This rule improves the odds of
1447
 * detecting duplicate quals.
1448
 */
1449
static void
1450
fixup_selfjoin_jointree(PlannerInfo *root, Node *jtnode, int relid,
1451
            Node **hoist_quals, bool *found_relid)
1452
0
{
1453
0
  if (jtnode == NULL)
1454
0
    return;
1455
0
  if (IsA(jtnode, RangeTblRef))
1456
0
  {
1457
0
    RangeTblRef *rtr = (RangeTblRef *) jtnode;
1458
1459
0
    if (rtr->rtindex == relid)
1460
0
    {
1461
0
      Assert(!*found_relid);
1462
0
      *found_relid = true;
1463
0
    }
1464
0
  }
1465
0
  else if (IsA(jtnode, FromExpr))
1466
0
  {
1467
0
    FromExpr   *f = (FromExpr *) jtnode;
1468
0
    Node     *sub_hoist_quals = NULL;
1469
0
    bool    sub_found_relid = false;
1470
0
    ListCell   *l;
1471
1472
0
    foreach(l, f->fromlist)
1473
0
      fixup_selfjoin_jointree(root, (Node *) lfirst(l), relid,
1474
0
                  &sub_hoist_quals, &sub_found_relid);
1475
0
    if (sub_found_relid)
1476
0
    {
1477
      /* This FromExpr covers relid, so OK to stop hoisting quals here */
1478
0
      f->quals = merge_quals(sub_hoist_quals, f->quals);
1479
0
      Assert(!*found_relid);
1480
0
      *found_relid = true;
1481
0
    }
1482
0
    else
1483
0
    {
1484
      /* We might need to hoist some of our own quals too */
1485
0
      List     *hoistable = NIL;
1486
0
      List     *keepable = NIL;
1487
1488
0
      foreach_ptr(Node, qual, castNode(List, f->quals))
1489
0
      {
1490
0
        if (bms_is_member(relid, pull_varnos(root, qual)))
1491
0
          hoistable = lappend(hoistable, qual);
1492
0
        else
1493
0
          keepable = lappend(keepable, qual);
1494
0
      }
1495
0
      f->quals = (Node *) keepable;
1496
0
      sub_hoist_quals = merge_quals(sub_hoist_quals, (Node *) hoistable);
1497
0
      *hoist_quals = merge_quals(sub_hoist_quals, *hoist_quals);
1498
0
    }
1499
0
    f->quals = (Node *) fixup_selfjoin_quals(root,
1500
0
                         castNode(List, f->quals),
1501
0
                         relid);
1502
0
  }
1503
0
  else if (IsA(jtnode, JoinExpr))
1504
0
  {
1505
0
    JoinExpr   *j = (JoinExpr *) jtnode;
1506
0
    Node     *sub_hoist_quals = NULL;
1507
0
    bool    sub_found_relid = false;
1508
1509
0
    fixup_selfjoin_jointree(root, j->larg, relid,
1510
0
                &sub_hoist_quals, &sub_found_relid);
1511
0
    fixup_selfjoin_jointree(root, j->rarg, relid,
1512
0
                &sub_hoist_quals, &sub_found_relid);
1513
0
    if (sub_found_relid)
1514
0
    {
1515
      /* This JoinExpr covers relid, so OK to stop hoisting quals here */
1516
0
      j->quals = merge_quals(sub_hoist_quals, j->quals);
1517
0
      Assert(!*found_relid);
1518
0
      *found_relid = true;
1519
0
    }
1520
0
    else
1521
0
    {
1522
      /* We might need to hoist some of our own quals too */
1523
0
      List     *hoistable = NIL;
1524
0
      List     *keepable = NIL;
1525
1526
0
      foreach_ptr(Node, qual, castNode(List, j->quals))
1527
0
      {
1528
0
        if (bms_is_member(relid, pull_varnos(root, qual)))
1529
0
          hoistable = lappend(hoistable, qual);
1530
0
        else
1531
0
          keepable = lappend(keepable, qual);
1532
0
      }
1533
0
      j->quals = (Node *) keepable;
1534
0
      sub_hoist_quals = merge_quals(sub_hoist_quals, (Node *) hoistable);
1535
      /* We should never need to hoist quals above an outer join */
1536
0
      Assert(sub_hoist_quals == NULL || j->jointype == JOIN_INNER);
1537
0
      *hoist_quals = merge_quals(sub_hoist_quals, *hoist_quals);
1538
0
    }
1539
0
    j->quals = (Node *) fixup_selfjoin_quals(root,
1540
0
                         castNode(List, j->quals),
1541
0
                         relid);
1542
0
  }
1543
0
  else
1544
0
    elog(ERROR, "unrecognized jointree node type: %d",
1545
0
       (int) nodeTag(jtnode));
1546
0
}
1547
1548
/*
1549
 * fixup_selfjoin_quals
1550
 *    Clean up one qual list after self-join elimination.
1551
 *
1552
 * Two things need fixing here.  First, a join clause such as "t1.a = t2.a"
1553
 * has turned into "t1.a = t1.a".  For a strict mergejoinable operator that
1554
 * means "t1.a IS NOT NULL", and we should make the substitution, for two
1555
 * reasons:
1556
 * 1. It will typically result in better selectivity estimates.
1557
 * 2. EquivalenceClass processing is likely to make the substitution
1558
 *    if we don't.  While not directly harmful, we'd then fail to
1559
 *    recognize it as a duplicate of a user-written "t1.a IS NOT NULL"
1560
 *    clause, again leading to bad selectivity estimates.
1561
 * Second, conditions that were written against the two relations separately
1562
 * may now be identical, and we don't want to apply the same condition twice
1563
 * (much less double-count its selectivity).
1564
 *
1565
 * We only touch the top-level conjuncts of the list.  There, turning a NULL
1566
 * result into FALSE makes no difference, whereas below a NOT it would,
1567
 * invalidating the IS NOT NULL substitution.  EquivalenceClass processing
1568
 * will not be applied to sub-clauses, and cleaning up duplicates in them
1569
 * seems like more trouble than it's worth.  Also, we only consider clauses
1570
 * that mention the relation we merged into, so that we don't change the
1571
 * treatment of anything we didn't touch.
1572
 *
1573
 * Since this is not a correctness issue but just an optimization opportunity,
1574
 * we likewise don't worry about recognizing duplicates that appear in
1575
 * different qual lists.
1576
 */
1577
static List *
1578
fixup_selfjoin_quals(PlannerInfo *root, List *quals, int relid)
1579
0
{
1580
0
  List     *result = NIL;
1581
0
  ListCell   *l;
1582
1583
0
  foreach(l, quals)
1584
0
  {
1585
0
    Node     *qual = (Node *) lfirst(l);
1586
1587
0
    if (bms_is_member(relid, pull_varnos(root, qual)))
1588
0
    {
1589
0
      qual = replace_selfjoin_qual(qual);
1590
      /* Drop it if the substitution has made it a duplicate */
1591
0
      if (list_member(result, qual))
1592
0
        continue;
1593
0
    }
1594
0
    result = lappend(result, qual);
1595
0
  }
1596
1597
0
  return result;
1598
0
}
1599
1600
/*
1601
 * replace_selfjoin_qual
1602
 *    Replace one "X = X" qual by "X IS NOT NULL", if it is one.
1603
 */
1604
static Node *
1605
replace_selfjoin_qual(Node *qual)
1606
0
{
1607
0
  OpExpr     *opexpr;
1608
0
  Node     *leftop;
1609
0
  Node     *rightop;
1610
0
  NullTest   *ntest;
1611
1612
  /* See if it looks like "X op X" */
1613
0
  if (!is_opclause(qual))
1614
0
    return qual;
1615
0
  opexpr = (OpExpr *) qual;
1616
0
  if (list_length(opexpr->args) != 2)
1617
0
    return qual;
1618
0
  leftop = get_leftop((Expr *) opexpr);
1619
0
  rightop = get_rightop((Expr *) opexpr);
1620
0
  if (!equal(leftop, rightop))
1621
0
    return qual;
1622
1623
  /*
1624
   * The operator must be strict and behave like btree equality, else we
1625
   * can't conclude that it yields true for any non-null input.  And the
1626
   * input had better not be volatile, else the two evaluations might not
1627
   * agree.  If either condition doesn't hold, the clause is not a candidate
1628
   * to be an equivalence, so we needn't worry about it getting replaced by
1629
   * equivclass.c.
1630
   */
1631
0
  set_opfuncid(opexpr);
1632
0
  if (!func_strict(opexpr->opfuncid))
1633
0
    return qual;
1634
0
  if (!op_mergejoinable(opexpr->opno, exprType(leftop)))
1635
0
    return qual;
1636
0
  if (contain_volatile_functions(leftop))
1637
0
    return qual;
1638
1639
  /* OK, replace it */
1640
0
  ntest = makeNode(NullTest);
1641
0
  ntest->arg = (Expr *) leftop;
1642
0
  ntest->nulltesttype = IS_NOT_NULL;
1643
0
  ntest->argisrow = false;  /* correct even if composite arg */
1644
0
  ntest->location = -1;
1645
0
  return (Node *) ntest;
1646
0
}
1647
1648
/*
1649
 * split_selfjoin_quals
1650
 *    Processes 'joinquals' by building two lists: one containing the quals
1651
 *    where the columns/exprs are on either side of the join match and
1652
 *    another one containing the remaining quals.
1653
 *
1654
 * 'joinquals' must only contain quals for a RTE_RELATION being joined to
1655
 * itself.
1656
 */
1657
static void
1658
split_selfjoin_quals(PlannerInfo *root, List *joinquals, List **selfjoinquals,
1659
           List **otherjoinquals, int from, int to)
1660
0
{
1661
0
  List     *sjoinquals = NIL;
1662
0
  List     *ojoinquals = NIL;
1663
1664
0
  foreach_node(RestrictInfo, rinfo, joinquals)
1665
0
  {
1666
0
    OpExpr     *expr;
1667
0
    Node     *leftexpr;
1668
0
    Node     *rightexpr;
1669
1670
    /*
1671
     * Since the given joinquals all came from
1672
     * generate_join_implied_equalities, they ought to look like equality
1673
     * operators on single-relation expressions.  But let's check that.
1674
     * Anything that doesn't look like that can be dumped into ojoinquals.
1675
     */
1676
0
    if (!rinfo->mergeopfamilies ||
1677
0
      bms_num_members(rinfo->clause_relids) != 2 ||
1678
0
      bms_membership(rinfo->left_relids) != BMS_SINGLETON ||
1679
0
      bms_membership(rinfo->right_relids) != BMS_SINGLETON)
1680
0
    {
1681
0
      ojoinquals = lappend(ojoinquals, rinfo);
1682
0
      continue;
1683
0
    }
1684
1685
0
    expr = (OpExpr *) rinfo->clause;
1686
1687
0
    if (!IsA(expr, OpExpr) || list_length(expr->args) != 2)
1688
0
    {
1689
0
      ojoinquals = lappend(ojoinquals, rinfo);
1690
0
      continue;
1691
0
    }
1692
1693
0
    leftexpr = get_leftop(rinfo->clause);
1694
0
    rightexpr = copyObject(get_rightop(rinfo->clause));
1695
1696
0
    if (leftexpr && IsA(leftexpr, RelabelType))
1697
0
      leftexpr = (Node *) ((RelabelType *) leftexpr)->arg;
1698
0
    if (rightexpr && IsA(rightexpr, RelabelType))
1699
0
      rightexpr = (Node *) ((RelabelType *) rightexpr)->arg;
1700
1701
    /*
1702
     * Quite an expensive operation, narrowing the use case. For example,
1703
     * when we have cast of the same var to different (but compatible)
1704
     * types.
1705
     */
1706
0
    ChangeVarNodes(rightexpr,
1707
0
             bms_singleton_member(rinfo->right_relids),
1708
0
             bms_singleton_member(rinfo->left_relids), 0);
1709
1710
0
    if (equal(leftexpr, rightexpr))
1711
0
      sjoinquals = lappend(sjoinquals, rinfo);
1712
0
    else
1713
0
      ojoinquals = lappend(ojoinquals, rinfo);
1714
0
  }
1715
1716
0
  *selfjoinquals = sjoinquals;
1717
0
  *otherjoinquals = ojoinquals;
1718
0
}
1719
1720
/*
1721
 * Check that each base restriction used to prove uniqueness of relid has
1722
 * a matching restriction in outer->baserestrictinfo, after replacing
1723
 * relid with outer->relid.
1724
 *
1725
 * Require equal() clauses, including the operator and input collation.
1726
 * Formerly this tried to match commuted forms of clauses, but that added
1727
 * a great deal of extra complication without much extra value.
1728
 */
1729
static bool
1730
match_unique_clauses(PlannerInfo *root, RelOptInfo *outer, List *uclauses,
1731
           Index relid)
1732
0
{
1733
0
  Assert(outer->relid > 0 && relid > 0);
1734
1735
0
  foreach_node(RestrictInfo, rinfo, uclauses)
1736
0
  {
1737
0
    Expr     *clause;
1738
0
    bool    matched = false;
1739
1740
    /* Convert the clause from uclauses to use outer's Vars */
1741
0
    clause = (Expr *) copyObject(rinfo->clause);
1742
0
    ChangeVarNodes((Node *) clause, relid, outer->relid, 0);
1743
1744
    /* Look for a matching restriction on the outer relation */
1745
0
    foreach_node(RestrictInfo, orinfo, outer->baserestrictinfo)
1746
0
    {
1747
0
      if (equal(clause, orinfo->clause))
1748
0
      {
1749
0
        matched = true;
1750
0
        break;
1751
0
      }
1752
0
    }
1753
1754
0
    if (!matched)
1755
0
      return false;
1756
0
  }
1757
1758
0
  return true;
1759
0
}
1760
1761
/*
1762
 * Find and remove unique self-joins in a group of base relations that have
1763
 * the same Oid.
1764
 *
1765
 * Return true if we removed any joins.
1766
 *
1767
 * After a removal, we continue searching for more removals, even though the
1768
 * tests will be using derived data that is now partially stale.  That is safe
1769
 * because we are trying to prove that a candidate pair of relations must
1770
 * match the same row, and the stale data can only omit quals, never invent
1771
 * them.  The removed relation's quals are moved onto the kept relation in
1772
 * the jointree but not into its baserestrictinfo, and no other derived data
1773
 * changes.  A proof made from a subset of the applicable quals remains valid
1774
 * when the rest are added, since extra quals can only remove rows from the
1775
 * join.  So a pass may miss a removal that a later pass will find, but it
1776
 * cannot make one that isn't justified.
1777
 */
1778
static bool
1779
remove_self_joins_one_group(PlannerInfo *root, Relids relids)
1780
0
{
1781
0
  bool    removed = false;
1782
0
  int     k;        /* Index of kept relation */
1783
0
  int     r = -1;     /* Index of removed relation */
1784
1785
0
  while ((r = bms_next_member(relids, r)) > 0)
1786
0
  {
1787
0
    RelOptInfo *rrel = root->simple_rel_array[r];
1788
1789
    /* k iterates over the relids after r */
1790
0
    k = r;
1791
0
    while ((k = bms_next_member(relids, k)) > 0)
1792
0
    {
1793
0
      Relids    joinrelids = NULL;
1794
0
      RelOptInfo *krel = root->simple_rel_array[k];
1795
0
      List     *restrictlist;
1796
0
      List     *selfjoinquals;
1797
0
      List     *otherjoinquals;
1798
0
      ListCell   *lc;
1799
0
      bool    jinfo_check = true;
1800
0
      PlanRowMark *kmark = NULL;
1801
0
      PlanRowMark *rmark = NULL;
1802
0
      List     *uclauses = NIL;
1803
1804
      /* A sanity check: the relations have the same Oid. */
1805
0
      Assert(root->simple_rte_array[k]->relid ==
1806
0
           root->simple_rte_array[r]->relid);
1807
1808
      /*
1809
       * It is impossible to eliminate the join of two relations if they
1810
       * are not on the same side of every outer join.  Otherwise, the
1811
       * planner can't find any variants of the correct query plan.
1812
       */
1813
0
      foreach(lc, root->join_info_list)
1814
0
      {
1815
0
        SpecialJoinInfo *info = (SpecialJoinInfo *) lfirst(lc);
1816
1817
0
        if ((bms_is_member(k, info->syn_lefthand) ^
1818
0
           bms_is_member(r, info->syn_lefthand)) ||
1819
0
          (bms_is_member(k, info->syn_righthand) ^
1820
0
           bms_is_member(r, info->syn_righthand)))
1821
0
        {
1822
0
          jinfo_check = false;
1823
0
          break;
1824
0
        }
1825
0
      }
1826
0
      if (!jinfo_check)
1827
0
        continue;
1828
1829
      /*
1830
       * Check Row Marks equivalence. We can't remove the join if the
1831
       * relations have row marks of different strength (e.g., one is
1832
       * locked FOR UPDATE, and another just has ROW_MARK_REFERENCE for
1833
       * EvalPlanQual rechecking).
1834
       */
1835
0
      foreach(lc, root->rowMarks)
1836
0
      {
1837
0
        PlanRowMark *rowMark = (PlanRowMark *) lfirst(lc);
1838
1839
0
        if (rowMark->rti == r)
1840
0
        {
1841
0
          Assert(rmark == NULL);
1842
0
          rmark = rowMark;
1843
0
        }
1844
0
        else if (rowMark->rti == k)
1845
0
        {
1846
0
          Assert(kmark == NULL);
1847
0
          kmark = rowMark;
1848
0
        }
1849
1850
0
        if (kmark && rmark)
1851
0
          break;
1852
0
      }
1853
0
      if (kmark && rmark && kmark->markType != rmark->markType)
1854
0
        continue;
1855
1856
      /*
1857
       * We only deal with base rels here, so their relids bitset
1858
       * contains only one member -- their relid.
1859
       */
1860
0
      joinrelids = bms_add_member(joinrelids, r);
1861
0
      joinrelids = bms_add_member(joinrelids, k);
1862
1863
      /*
1864
       * PHVs should not impose any constraints on removing self-joins.
1865
       */
1866
1867
      /*
1868
       * At this stage, joininfo lists of inner and outer can contain
1869
       * only clauses required for a superior outer join that can't
1870
       * influence this optimization. So, we can avoid to call the
1871
       * build_joinrel_restrictlist() routine.
1872
       */
1873
0
      restrictlist = generate_join_implied_equalities(root, joinrelids,
1874
0
                              rrel->relids,
1875
0
                              krel, NULL);
1876
0
      if (restrictlist == NIL)
1877
0
        continue;
1878
1879
      /*
1880
       * Process restrictlist to separate the self-join quals from the
1881
       * other quals. e.g., "x = x" goes to selfjoinquals and "a = b" to
1882
       * otherjoinquals.
1883
       */
1884
0
      split_selfjoin_quals(root, restrictlist, &selfjoinquals,
1885
0
                 &otherjoinquals, rrel->relid, krel->relid);
1886
1887
0
      Assert(list_length(restrictlist) ==
1888
0
           (list_length(selfjoinquals) + list_length(otherjoinquals)));
1889
1890
      /*
1891
       * To enable SJE for the only degenerate case without any self
1892
       * join clauses at all, add baserestrictinfo to this list. The
1893
       * degenerate case works only if both sides have the same clause.
1894
       * So doesn't matter which side to add.
1895
       */
1896
0
      selfjoinquals = list_concat(selfjoinquals, krel->baserestrictinfo);
1897
1898
      /*
1899
       * Determine if the rrel can duplicate outer rows. We must bypass
1900
       * the unique rel cache here since we're possibly using a subset
1901
       * of join quals. We can use 'force_cache' == true when all join
1902
       * quals are self-join quals.  Otherwise, we could end up putting
1903
       * false negatives in the cache.
1904
       */
1905
0
      if (!innerrel_is_unique_ext(root, joinrelids, rrel->relids,
1906
0
                    krel, JOIN_INNER, selfjoinquals,
1907
0
                    list_length(otherjoinquals) == 0,
1908
0
                    &uclauses))
1909
0
        continue;
1910
1911
      /*
1912
       * 'uclauses' is the copy of outer->baserestrictinfo that are
1913
       * associated with an index.  We proved by matching selfjoinquals
1914
       * to a unique index that the outer relation has at most one
1915
       * matching row for each inner row.  Sometimes that is not enough.
1916
       * e.g. "WHERE s1.b = s2.b AND s1.a = 1 AND s2.a = 2" when the
1917
       * unique index is (a,b).  Having non-empty uclauses, we must
1918
       * validate that the inner baserestrictinfo contains the same
1919
       * expressions, or we won't match the same row on each side of the
1920
       * join.
1921
       */
1922
0
      if (!match_unique_clauses(root, rrel, uclauses, krel->relid))
1923
0
        continue;
1924
1925
      /* OK, remove rrel from the query */
1926
0
      remove_self_join_rel(root, krel, rrel, kmark, rmark);
1927
0
      removed = true;
1928
1929
      /*
1930
       * Since relation r is now gone, we mustn't keep looking for
1931
       * matches to it.  But we can keep scanning later relids members
1932
       * for additional join pairs.
1933
       */
1934
0
      break;
1935
0
    }
1936
0
  }
1937
1938
0
  return removed;
1939
0
}
1940
1941
/*
1942
 * Gather indexes of base relations from the joinlist and try to eliminate
1943
 * self-joins.
1944
 *
1945
 * Return true if we removed any joins.
1946
 */
1947
static bool
1948
remove_self_joins_recurse(PlannerInfo *root, List *joinlist)
1949
0
{
1950
0
  bool    removed = false;
1951
0
  ListCell   *jl;
1952
0
  Relids    relids = NULL;
1953
0
  SelfJoinCandidate *candidates;
1954
0
  int     i;
1955
0
  int     j;
1956
0
  int     numRels;
1957
1958
  /* Collect indexes of possibly-mergeable relations from the joinlist */
1959
0
  foreach(jl, joinlist)
1960
0
  {
1961
0
    Node     *jlnode = (Node *) lfirst(jl);
1962
1963
0
    if (IsA(jlnode, RangeTblRef))
1964
0
    {
1965
0
      int     varno = ((RangeTblRef *) jlnode)->rtindex;
1966
0
      RangeTblEntry *rte = root->simple_rte_array[varno];
1967
1968
      /*
1969
       * To be considered for self-join removal, the RTE must:
1970
       *
1971
       * 1. Be an ordinary relation.  (Someday we might support SJE on
1972
       * partitioned tables, but not yet.)
1973
       *
1974
       * 2. Not have inh set, ie it has no inheritance children (or the
1975
       * user wrote ONLY to ignore them).  Under traditional inheritance
1976
       * a unique index on a parent table does not establish uniqueness
1977
       * across its children.  This rule also keeps us from trying to
1978
       * merge an inheritance scan with an ONLY scan, which would be
1979
       * wrong.  (preprocess_relation_rtes already cleared the inh flag
1980
       * for tables known not to have inheritance children.)
1981
       *
1982
       * 3. Not have a TABLESAMPLE clause.  Removing a relation with a
1983
       * TABLESAMPLE clause would change the semantics of the query,
1984
       * even if we merged it with another RTE with an identical
1985
       * TABLESAMPLE clause.  (Two such RTEs should represent
1986
       * independent samplings of the base table.)
1987
       *
1988
       * 4. Not be the query's result relation or MERGE target.  Merging
1989
       * would cause misbehavior during EPQ.
1990
       */
1991
0
      if (rte->rtekind == RTE_RELATION &&
1992
0
        rte->relkind == RELKIND_RELATION &&
1993
0
        !rte->inh &&
1994
0
        rte->tablesample == NULL &&
1995
0
        varno != root->parse->resultRelation &&
1996
0
        varno != root->parse->mergeTargetRelation)
1997
0
      {
1998
0
        Assert(!bms_is_member(varno, relids));
1999
0
        relids = bms_add_member(relids, varno);
2000
0
      }
2001
0
    }
2002
0
    else if (IsA(jlnode, List))
2003
0
    {
2004
      /* Recursively perform SJE within the sub-joinlist */
2005
0
      removed |= remove_self_joins_recurse(root, (List *) jlnode);
2006
0
    }
2007
0
    else
2008
0
      elog(ERROR, "unrecognized joinlist node type: %d",
2009
0
         (int) nodeTag(jlnode));
2010
0
  }
2011
2012
0
  numRels = bms_num_members(relids);
2013
2014
  /* No work if not at least two relations at this level */
2015
0
  if (numRels < 2)
2016
0
    return removed;     /* ... but don't fail to report sub-removals */
2017
2018
  /*
2019
   * In order to find relations with the same reloid/useroid we first build
2020
   * an array of candidates and then sort it by those oids.
2021
   */
2022
0
  candidates = palloc_array(SelfJoinCandidate, numRels);
2023
0
  i = -1;
2024
0
  j = 0;
2025
0
  while ((i = bms_next_member(relids, i)) >= 0)
2026
0
  {
2027
0
    RangeTblEntry *rte = root->simple_rte_array[i];
2028
2029
0
    candidates[j].relid = i;
2030
0
    candidates[j].reloid = rte->relid;
2031
0
    if (rte->perminfoindex != 0)
2032
0
    {
2033
0
      RTEPermissionInfo *perminfo;
2034
2035
0
      perminfo = getRTEPermissionInfo(root->parse->rteperminfos, rte);
2036
0
      candidates[j].useroid = perminfo->checkAsUser;
2037
0
    }
2038
0
    else
2039
0
      candidates[j].useroid = InvalidOid;
2040
0
    j++;
2041
0
  }
2042
2043
0
  qsort(candidates, numRels, sizeof(SelfJoinCandidate),
2044
0
      self_join_candidates_cmp);
2045
2046
  /*
2047
   * Iteratively form a group of relation indexes with the same oids and
2048
   * launch the routine that detects self-joins in this group.
2049
   *
2050
   * We remove considered relations from relids as we scan, so that that set
2051
   * should be empty at the end.
2052
   */
2053
0
  i = 0;
2054
0
  for (j = 1; j <= numRels; j++)
2055
0
  {
2056
0
    if (j == numRels ||
2057
0
      candidates[j].reloid != candidates[i].reloid ||
2058
0
      candidates[j].useroid != candidates[i].useroid)
2059
0
    {
2060
0
      if (j - i >= 2)
2061
0
      {
2062
        /* Create a group of relation indexes with the same oids */
2063
0
        Relids    group = NULL;
2064
2065
0
        while (i < j)
2066
0
        {
2067
0
          group = bms_add_member(group, candidates[i].relid);
2068
0
          i++;
2069
0
        }
2070
0
        relids = bms_del_members(relids, group);
2071
2072
        /* Try to remove self-joins from the group */
2073
0
        removed |= remove_self_joins_one_group(root, group);
2074
0
        bms_free(group);
2075
0
      }
2076
0
      else
2077
0
      {
2078
        /* Nothing to do with this group, just drop it from the set */
2079
0
        while (i < j)
2080
0
        {
2081
0
          relids = bms_del_member(relids, candidates[i].relid);
2082
0
          i++;
2083
0
        }
2084
0
      }
2085
0
    }
2086
0
  }
2087
2088
0
  Assert(bms_is_empty(relids));
2089
2090
0
  return removed;
2091
0
}
2092
2093
/*
2094
 * Compare self-join candidates by their reloid and then useroid.
2095
 */
2096
static int
2097
self_join_candidates_cmp(const void *a, const void *b)
2098
0
{
2099
0
  const SelfJoinCandidate *ca = (const SelfJoinCandidate *) a;
2100
0
  const SelfJoinCandidate *cb = (const SelfJoinCandidate *) b;
2101
2102
0
  if (ca->reloid != cb->reloid)
2103
0
    return (ca->reloid < cb->reloid ? -1 : 1);
2104
0
  else if (ca->useroid != cb->useroid)
2105
0
    return (ca->useroid < cb->useroid ? -1 : 1);
2106
0
  else
2107
0
    return 0;
2108
0
}
2109
2110
/*
2111
 * Find and remove useless self joins.
2112
 *
2113
 * Search for joins where a relation is joined to itself. If the join clause
2114
 * for each tuple from one side of the join is proven to match the same
2115
 * physical row (or nothing) on the other side, that self-join can be
2116
 * eliminated from the query.  Suitable join clauses are assumed to be in the
2117
 * form of X = X, and can be replaced with NOT NULL clauses.
2118
 *
2119
 * For the sake of simplicity, we don't apply this optimization to special
2120
 * joins. Here is a list of what we could do in some particular cases:
2121
 * 'a a1 semi join a a2': is reduced to inner by reduce_unique_semijoins,
2122
 * and then removed normally.
2123
 * 'a a1 anti join a a2': could simplify to a scan with 'outer quals AND
2124
 * (IS NULL on join columns OR NOT inner quals)'.
2125
 * 'a a1 left join a a2': could simplify to a scan like inner but without
2126
 * NOT NULL conditions on join columns.
2127
 * 'a a1 left join (a a2 join b)': can't simplify this, because join to b
2128
 * can both remove rows and introduce duplicates.
2129
 *
2130
 * To search for removable joins, we order all the relations on their Oid,
2131
 * go over each set with the same Oid, and consider each pair of relations
2132
 * in this set.
2133
 *
2134
 * To remove the join, we delete one of the participating relations from the
2135
 * query's jointree and rewrite all references to it to point to the remaining
2136
 * relation.  We also have to modify their row marks.
2137
 *
2138
 * 'joinlist' is the top-level joinlist of the query; we use it to identify
2139
 * groups of relations that could be joined to each other.
2140
 *
2141
 * We return true if we removed any self-joins.  If so, the caller must
2142
 * recompute everything that was derived from the jointree, and should then
2143
 * try join simplifications again since we might have exposed opportunities
2144
 * for additional simplifications.
2145
 */
2146
bool
2147
remove_useless_self_joins(PlannerInfo *root, List *joinlist)
2148
0
{
2149
  /* Skip if SJE is disabled, or if the joinlist has less than 2 members. */
2150
0
  if (!enable_self_join_elimination || joinlist == NIL ||
2151
0
    (list_length(joinlist) == 1 && !IsA(linitial(joinlist), List)))
2152
0
    return false;
2153
2154
  /* Try to merge pairs of self-joined relations. */
2155
0
  return remove_self_joins_recurse(root, joinlist);
2156
0
}