Coverage Report

Created: 2026-09-28 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/postgres/src/backend/optimizer/plan/initsplan.c
Line
Count
Source
1
/*-------------------------------------------------------------------------
2
 *
3
 * initsplan.c
4
 *    Target list, group by, qualification, joininfo initialization routines
5
 *
6
 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7
 * Portions Copyright (c) 1994, Regents of the University of California
8
 *
9
 *
10
 * IDENTIFICATION
11
 *    src/backend/optimizer/plan/initsplan.c
12
 *
13
 *-------------------------------------------------------------------------
14
 */
15
#include "postgres.h"
16
17
#include "access/nbtree.h"
18
#include "access/sysattr.h"
19
#include "catalog/pg_constraint.h"
20
#include "catalog/pg_type.h"
21
#include "nodes/makefuncs.h"
22
#include "nodes/nodeFuncs.h"
23
#include "optimizer/clauses.h"
24
#include "optimizer/cost.h"
25
#include "optimizer/inherit.h"
26
#include "optimizer/joininfo.h"
27
#include "optimizer/optimizer.h"
28
#include "optimizer/pathnode.h"
29
#include "optimizer/paths.h"
30
#include "optimizer/placeholder.h"
31
#include "optimizer/planmain.h"
32
#include "optimizer/restrictinfo.h"
33
#include "parser/analyze.h"
34
#include "rewrite/rewriteManip.h"
35
#include "utils/lsyscache.h"
36
#include "utils/rel.h"
37
#include "utils/typcache.h"
38
39
/* These parameters are set by GUC */
40
int     from_collapse_limit;
41
int     join_collapse_limit;
42
43
44
/*
45
 * deconstruct_jointree requires multiple passes over the join tree, because we
46
 * need to finish computing JoinDomains before we start distributing quals.
47
 * As long as we have to do that, other information such as the relevant
48
 * qualscopes might as well be computed in the first pass too.
49
 *
50
 * deconstruct_recurse recursively examines the join tree and builds a List
51
 * (in depth-first traversal order) of JoinTreeItem structs, which are then
52
 * processed iteratively by deconstruct_distribute.  If there are outer
53
 * joins, non-degenerate outer join clauses are processed in a third pass
54
 * deconstruct_distribute_oj_quals.
55
 *
56
 * The JoinTreeItem structs themselves can be freed at the end of
57
 * deconstruct_jointree, but do not modify or free their substructure,
58
 * as the relid sets may also be pointed to by RestrictInfo and
59
 * SpecialJoinInfo nodes.
60
 */
61
typedef struct JoinTreeItem
62
{
63
  /* Fields filled during deconstruct_recurse: */
64
  Node     *jtnode;     /* jointree node to examine */
65
  JoinDomain *jdomain;    /* join domain for its ON/WHERE clauses */
66
  struct JoinTreeItem *jti_parent;  /* JoinTreeItem for this node's
67
                     * parent, or NULL if it's the top */
68
  Relids    qualscope;    /* base+OJ Relids syntactically included in
69
                 * this jointree node */
70
  Relids    inner_join_rels;  /* base+OJ Relids syntactically included
71
                   * in inner joins appearing at or below
72
                   * this jointree node */
73
  Relids    left_rels;    /* if join node, Relids of the left side */
74
  Relids    right_rels;   /* if join node, Relids of the right side */
75
  Relids    nonnullable_rels; /* if outer join, Relids of the
76
                   * non-nullable side */
77
  /* Fields filled during deconstruct_distribute: */
78
  SpecialJoinInfo *sjinfo;  /* if outer join, its SpecialJoinInfo */
79
  List     *oj_joinclauses; /* outer join quals not yet distributed */
80
  List     *lateral_clauses;  /* quals postponed from children due to
81
                   * lateral references */
82
} JoinTreeItem;
83
84
/*
85
 * Compatibility info for one GROUP BY item, precomputed for use by
86
 * remove_useless_groupby_columns() when matching unique-index columns against
87
 * GROUP BY items.
88
 */
89
typedef struct GroupByColInfo
90
{
91
  AttrNumber  attno;      /* var->varattno */
92
  List     *eq_opfamilies;  /* mergejoin opfamilies of sgc->eqop */
93
  Oid     coll;     /* var->varcollid */
94
} GroupByColInfo;
95
96
97
static bool is_partial_agg_memory_risky(PlannerInfo *root);
98
static void create_agg_clause_infos(PlannerInfo *root);
99
static void create_grouping_expr_infos(PlannerInfo *root);
100
static EquivalenceClass *get_eclass_for_sortgroupclause(PlannerInfo *root,
101
                            SortGroupClause *sgc,
102
                            Expr *expr);
103
static void extract_lateral_references(PlannerInfo *root, RelOptInfo *brel,
104
                     Index rtindex);
105
static List *deconstruct_recurse(PlannerInfo *root, Node *jtnode,
106
                 JoinDomain *parent_domain,
107
                 JoinTreeItem *parent_jtitem,
108
                 List **item_list);
109
static void deconstruct_distribute(PlannerInfo *root, JoinTreeItem *jtitem);
110
static void process_security_barrier_quals(PlannerInfo *root,
111
                       int rti, JoinTreeItem *jtitem);
112
static void mark_rels_nulled_by_join(PlannerInfo *root, Index ojrelid,
113
                   Relids lower_rels);
114
static SpecialJoinInfo *make_outerjoininfo(PlannerInfo *root,
115
                       Relids left_rels, Relids right_rels,
116
                       Relids inner_join_rels,
117
                       JoinType jointype, Index ojrelid,
118
                       List *clause);
119
static void compute_semijoin_info(PlannerInfo *root, SpecialJoinInfo *sjinfo,
120
                  List *clause);
121
static void deconstruct_distribute_oj_quals(PlannerInfo *root,
122
                      List *jtitems,
123
                      JoinTreeItem *jtitem);
124
static void distribute_quals_to_rels(PlannerInfo *root, List *clauses,
125
                   JoinTreeItem *jtitem,
126
                   SpecialJoinInfo *sjinfo,
127
                   Index security_level,
128
                   Relids qualscope,
129
                   Relids ojscope,
130
                   Relids outerjoin_nonnullable,
131
                   Relids incompatible_relids,
132
                   bool allow_equivalence,
133
                   bool has_clone,
134
                   bool is_clone,
135
                   List **postponed_oj_qual_list);
136
static void distribute_qual_to_rels(PlannerInfo *root, Node *clause,
137
                  JoinTreeItem *jtitem,
138
                  SpecialJoinInfo *sjinfo,
139
                  Index security_level,
140
                  Relids qualscope,
141
                  Relids ojscope,
142
                  Relids outerjoin_nonnullable,
143
                  Relids incompatible_relids,
144
                  bool allow_equivalence,
145
                  bool has_clone,
146
                  bool is_clone,
147
                  List **postponed_oj_qual_list);
148
static Relids get_join_domain_min_rels(PlannerInfo *root, Relids domain_relids);
149
static void check_mergejoinable(RestrictInfo *restrictinfo);
150
static void check_hashjoinable(RestrictInfo *restrictinfo);
151
static void check_memoizable(RestrictInfo *restrictinfo);
152
153
154
/*****************************************************************************
155
 *
156
 *   JOIN TREES
157
 *
158
 *****************************************************************************/
159
160
/*
161
 * add_base_rels_to_query
162
 *
163
 *    Scan the query's jointree and create baserel RelOptInfos for all
164
 *    the base relations (e.g., table, subquery, and function RTEs)
165
 *    appearing in the jointree.
166
 *
167
 * The initial invocation must pass root->parse->jointree as the value of
168
 * jtnode.  Internally, the function recurses through the jointree.
169
 *
170
 * At the end of this process, there should be one baserel RelOptInfo for
171
 * every non-join RTE that is used in the query.  Some of the baserels
172
 * may be appendrel parents, which will require additional "otherrel"
173
 * RelOptInfos for their member rels, but those are added later.
174
 */
175
void
176
add_base_rels_to_query(PlannerInfo *root, Node *jtnode)
177
0
{
178
0
  if (jtnode == NULL)
179
0
    return;
180
0
  if (IsA(jtnode, RangeTblRef))
181
0
  {
182
0
    int     varno = ((RangeTblRef *) jtnode)->rtindex;
183
184
0
    (void) build_simple_rel(root, varno, NULL);
185
0
  }
186
0
  else if (IsA(jtnode, FromExpr))
187
0
  {
188
0
    FromExpr   *f = (FromExpr *) jtnode;
189
0
    ListCell   *l;
190
191
0
    foreach(l, f->fromlist)
192
0
      add_base_rels_to_query(root, lfirst(l));
193
0
  }
194
0
  else if (IsA(jtnode, JoinExpr))
195
0
  {
196
0
    JoinExpr   *j = (JoinExpr *) jtnode;
197
198
0
    add_base_rels_to_query(root, j->larg);
199
0
    add_base_rels_to_query(root, j->rarg);
200
0
  }
201
0
  else
202
0
    elog(ERROR, "unrecognized node type: %d",
203
0
       (int) nodeTag(jtnode));
204
0
}
205
206
/*
207
 * add_other_rels_to_query
208
 *    create "otherrel" RelOptInfos for the children of appendrel baserels
209
 *
210
 * At the end of this process, there should be RelOptInfos for all relations
211
 * that will be scanned by the query.
212
 */
213
void
214
add_other_rels_to_query(PlannerInfo *root)
215
0
{
216
0
  int     rti;
217
218
0
  for (rti = 1; rti < root->simple_rel_array_size; rti++)
219
0
  {
220
0
    RelOptInfo *rel = root->simple_rel_array[rti];
221
0
    RangeTblEntry *rte = root->simple_rte_array[rti];
222
223
    /* there may be empty slots corresponding to non-baserel RTEs */
224
0
    if (rel == NULL)
225
0
      continue;
226
227
    /* Ignore any "otherrels" that were already added. */
228
0
    if (rel->reloptkind != RELOPT_BASEREL)
229
0
      continue;
230
231
    /* If it's marked as inheritable, look for children. */
232
0
    if (rte->inh)
233
0
      expand_inherited_rtentry(root, rel, rte, rti);
234
0
  }
235
0
}
236
237
238
/*****************************************************************************
239
 *
240
 *   TARGET LISTS
241
 *
242
 *****************************************************************************/
243
244
/*
245
 * build_base_rel_tlists
246
 *    Add targetlist entries for each var needed in the query's final tlist
247
 *    (and HAVING clause, if any) to the appropriate base relations.
248
 *
249
 * We mark such vars as needed by "relation 0" to ensure that they will
250
 * propagate up through all join plan steps.
251
 */
252
void
253
build_base_rel_tlists(PlannerInfo *root, List *final_tlist)
254
0
{
255
0
  List     *tlist_vars = pull_var_clause((Node *) final_tlist,
256
0
                       PVC_RECURSE_AGGREGATES |
257
0
                       PVC_RECURSE_WINDOWFUNCS |
258
0
                       PVC_INCLUDE_PLACEHOLDERS);
259
260
0
  if (tlist_vars != NIL)
261
0
  {
262
0
    add_vars_to_targetlist(root, tlist_vars, bms_make_singleton(0));
263
0
    list_free(tlist_vars);
264
0
  }
265
266
  /*
267
   * If there's a HAVING clause, we'll need the Vars it uses, too.  Note
268
   * that HAVING can contain Aggrefs but not WindowFuncs.
269
   */
270
0
  if (root->parse->havingQual)
271
0
  {
272
0
    List     *having_vars = pull_var_clause(root->parse->havingQual,
273
0
                          PVC_RECURSE_AGGREGATES |
274
0
                          PVC_INCLUDE_PLACEHOLDERS);
275
276
0
    if (having_vars != NIL)
277
0
    {
278
0
      add_vars_to_targetlist(root, having_vars,
279
0
                   bms_make_singleton(0));
280
0
      list_free(having_vars);
281
0
    }
282
0
  }
283
0
}
284
285
/*
286
 * add_vars_to_targetlist
287
 *    For each variable appearing in the list, add it to the owning
288
 *    relation's targetlist if not already present, and mark the variable
289
 *    as being needed for the indicated join (or for final output if
290
 *    where_needed includes "relation 0").
291
 *
292
 *    The list may also contain PlaceHolderVars.  These don't necessarily
293
 *    have a single owning relation; we keep their attr_needed info in
294
 *    root->placeholder_list instead.  Find or create the associated
295
 *    PlaceHolderInfo entry, and update its ph_needed.
296
 */
297
void
298
add_vars_to_targetlist(PlannerInfo *root, List *vars,
299
             Relids where_needed)
300
0
{
301
0
  ListCell   *temp;
302
303
0
  Assert(!bms_is_empty(where_needed));
304
305
0
  foreach(temp, vars)
306
0
  {
307
0
    Node     *node = (Node *) lfirst(temp);
308
309
0
    if (IsA(node, Var))
310
0
    {
311
0
      Var      *var = (Var *) node;
312
0
      RelOptInfo *rel = find_base_rel(root, var->varno);
313
0
      int     attno = var->varattno;
314
315
0
      if (bms_is_subset(where_needed, rel->relids))
316
0
        continue;
317
0
      Assert(attno >= rel->min_attr && attno <= rel->max_attr);
318
0
      attno -= rel->min_attr;
319
0
      if (rel->attr_needed[attno] == NULL)
320
0
      {
321
        /*
322
         * Variable not yet requested, so add to rel's targetlist.
323
         *
324
         * The value available at the rel's scan level has not been
325
         * nulled by any outer join, so drop its varnullingrels.
326
         * (We'll put those back as we climb up the join tree.)
327
         */
328
0
        var = copyObject(var);
329
0
        var->varnullingrels = NULL;
330
0
        rel->reltarget->exprs = lappend(rel->reltarget->exprs, var);
331
        /* reltarget cost and width will be computed later */
332
0
      }
333
0
      rel->attr_needed[attno] = bms_add_members(rel->attr_needed[attno],
334
0
                            where_needed);
335
0
    }
336
0
    else if (IsA(node, PlaceHolderVar))
337
0
    {
338
0
      PlaceHolderVar *phv = (PlaceHolderVar *) node;
339
0
      PlaceHolderInfo *phinfo = find_placeholder_info(root, phv);
340
341
0
      phinfo->ph_needed = bms_add_members(phinfo->ph_needed,
342
0
                        where_needed);
343
0
    }
344
0
    else
345
0
      elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
346
0
  }
347
0
}
348
349
/*****************************************************************************
350
 *
351
 *    GROUP BY
352
 *
353
 *****************************************************************************/
354
355
/*
356
 * remove_useless_groupby_columns
357
 *    Remove any columns in the GROUP BY clause that are redundant due to
358
 *    being functionally dependent on other GROUP BY columns.
359
 *
360
 * Since some other DBMSes do not allow references to ungrouped columns, it's
361
 * not unusual to find all columns listed in GROUP BY even though listing the
362
 * primary-key columns, or columns of a unique constraint would be sufficient.
363
 * Deleting such excess columns avoids redundant sorting or hashing work, so
364
 * it's worth doing.
365
 *
366
 * Relcache invalidations will ensure that cached plans become invalidated
367
 * when the underlying supporting indexes are dropped or if a column's NOT
368
 * NULL attribute is removed.
369
 */
370
void
371
remove_useless_groupby_columns(PlannerInfo *root)
372
0
{
373
0
  Query    *parse = root->parse;
374
0
  Bitmapset **groupbyattnos;
375
0
  List    **groupbycols;
376
0
  Bitmapset **surplusvars;
377
0
  bool    tryremove = false;
378
0
  ListCell   *lc;
379
0
  int     relid;
380
381
  /* No chance to do anything if there are less than two GROUP BY items */
382
0
  if (list_length(root->processed_groupClause) < 2)
383
0
    return;
384
385
  /* Don't fiddle with the GROUP BY clause if the query has grouping sets */
386
0
  if (parse->groupingSets)
387
0
    return;
388
389
  /*
390
   * Scan the GROUP BY clause to find GROUP BY items that are simple Vars.
391
   * Fill groupbyattnos[k] with a bitmapset of the column attnos of RTE k
392
   * that are GROUP BY items, and groupbycols[k] with a parallel list of
393
   * GroupByColInfo records.  We need the latter so that, when checking a
394
   * unique index against this rel's GROUP BY items, we can verify that the
395
   * index's notion of equality agrees with at least one GROUP BY item per
396
   * index column.
397
   */
398
0
  groupbyattnos = palloc0_array(Bitmapset *, list_length(parse->rtable) + 1);
399
0
  groupbycols = palloc0_array(List *, list_length(parse->rtable) + 1);
400
0
  foreach(lc, root->processed_groupClause)
401
0
  {
402
0
    SortGroupClause *sgc = lfirst_node(SortGroupClause, lc);
403
0
    TargetEntry *tle = get_sortgroupclause_tle(sgc, parse->targetList);
404
0
    Var      *var = (Var *) tle->expr;
405
0
    GroupByColInfo *info;
406
407
    /*
408
     * Ignore non-Vars and Vars from other query levels.
409
     *
410
     * XXX in principle, stable expressions containing Vars could also be
411
     * removed, if all the Vars are functionally dependent on other GROUP
412
     * BY items.  But it's not clear that such cases occur often enough to
413
     * be worth troubling over.
414
     */
415
0
    if (!IsA(var, Var) ||
416
0
      var->varlevelsup > 0)
417
0
      continue;
418
419
    /* OK, remember we have this Var */
420
0
    relid = var->varno;
421
0
    Assert(relid <= list_length(parse->rtable));
422
423
    /*
424
     * If this isn't the first column for this relation then we now have
425
     * multiple columns.  That means there might be some that can be
426
     * removed.
427
     */
428
0
    tryremove |= !bms_is_empty(groupbyattnos[relid]);
429
0
    groupbyattnos[relid] = bms_add_member(groupbyattnos[relid],
430
0
                        var->varattno - FirstLowInvalidHeapAttributeNumber);
431
432
0
    info = palloc_object(GroupByColInfo);
433
0
    info->attno = var->varattno;
434
0
    info->eq_opfamilies = get_mergejoin_opfamilies(sgc->eqop);
435
0
    info->coll = var->varcollid;
436
0
    groupbycols[relid] = lappend(groupbycols[relid], info);
437
0
  }
438
439
  /*
440
   * No Vars or didn't find multiple Vars for any relation in the GROUP BY?
441
   * If so, nothing can be removed, so don't waste more effort trying.
442
   */
443
0
  if (!tryremove)
444
0
    return;
445
446
  /*
447
   * Consider each relation and see if it is possible to remove some of its
448
   * Vars from GROUP BY.  For simplicity and speed, we do the actual removal
449
   * in a separate pass.  Here, we just fill surplusvars[k] with a bitmapset
450
   * of the column attnos of RTE k that are removable GROUP BY items.
451
   */
452
0
  surplusvars = NULL;     /* don't allocate array unless required */
453
0
  relid = 0;
454
0
  foreach(lc, parse->rtable)
455
0
  {
456
0
    RangeTblEntry *rte = lfirst_node(RangeTblEntry, lc);
457
0
    RelOptInfo *rel;
458
0
    Bitmapset  *relattnos;
459
0
    Bitmapset  *best_keycolumns = NULL;
460
0
    int32   best_nkeycolumns = PG_INT32_MAX;
461
462
0
    relid++;
463
464
    /* Only plain relations could have primary-key constraints */
465
0
    if (rte->rtekind != RTE_RELATION)
466
0
      continue;
467
468
    /*
469
     * We must skip inheritance parent tables as some of the child rels
470
     * may cause duplicate rows.  This cannot happen with partitioned
471
     * tables, however.
472
     */
473
0
    if (rte->inh && rte->relkind != RELKIND_PARTITIONED_TABLE)
474
0
      continue;
475
476
    /* Nothing to do unless this rel has multiple Vars in GROUP BY */
477
0
    relattnos = groupbyattnos[relid];
478
0
    if (bms_membership(relattnos) != BMS_MULTIPLE)
479
0
      continue;
480
481
0
    rel = root->simple_rel_array[relid];
482
483
    /*
484
     * Now check each index for this relation to see if there are any with
485
     * columns which are a proper subset of the grouping columns for this
486
     * relation.
487
     */
488
0
    foreach_node(IndexOptInfo, index, rel->indexlist)
489
0
    {
490
0
      Bitmapset  *ind_attnos;
491
0
      bool    index_check_ok;
492
493
      /*
494
       * Skip any non-unique and deferrable indexes.  Predicate indexes
495
       * have not been checked yet, so we must skip those too as the
496
       * predOK check that's done later might fail.
497
       */
498
0
      if (!index->unique || !index->immediate || index->indpred != NIL)
499
0
        continue;
500
501
      /* For simplicity, we currently don't support expression indexes */
502
0
      if (index->indexprs != NIL)
503
0
        continue;
504
505
0
      ind_attnos = NULL;
506
0
      index_check_ok = true;
507
0
      for (int i = 0; i < index->nkeycolumns; i++)
508
0
      {
509
0
        AttrNumber  indkey_attno = index->indexkeys[i];
510
0
        Oid     indkey_opfamily = index->opfamily[i];
511
0
        Oid     indkey_coll = index->indexcollations[i];
512
0
        ListCell   *lc2;
513
514
        /*
515
         * We must insist that the index columns are all defined NOT
516
         * NULL otherwise duplicate NULLs could exist.  However, we
517
         * can relax this check when the index is defined with NULLS
518
         * NOT DISTINCT as there can only be 1 NULL row, therefore
519
         * functional dependency on the unique columns is maintained,
520
         * despite the NULL.
521
         */
522
0
        if (!index->nullsnotdistinct &&
523
0
          !bms_is_member(indkey_attno, rel->notnullattnums))
524
0
        {
525
0
          index_check_ok = false;
526
0
          break;
527
0
        }
528
529
        /*
530
         * The index proves uniqueness only under its own opfamily and
531
         * collation.  Require some GROUP BY item on this column to
532
         * use a compatible eqop and collation, the same check
533
         * relation_has_unique_index_for() applies to join clauses.
534
         */
535
0
        foreach(lc2, groupbycols[relid])
536
0
        {
537
0
          GroupByColInfo *info = (GroupByColInfo *) lfirst(lc2);
538
539
0
          if (info->attno != indkey_attno)
540
0
            continue;
541
0
          if (list_member_oid(info->eq_opfamilies, indkey_opfamily) &&
542
0
            collations_agree_on_equality(indkey_coll, info->coll))
543
0
            break;
544
0
        }
545
0
        if (lc2 == NULL)
546
0
        {
547
0
          index_check_ok = false;
548
0
          break;
549
0
        }
550
551
0
        ind_attnos =
552
0
          bms_add_member(ind_attnos,
553
0
                   indkey_attno -
554
0
                   FirstLowInvalidHeapAttributeNumber);
555
0
      }
556
557
0
      if (!index_check_ok)
558
0
        continue;
559
560
      /*
561
       * Skip any indexes where the indexed columns aren't a proper
562
       * subset of the GROUP BY.
563
       */
564
0
      if (bms_subset_compare(ind_attnos, relattnos) != BMS_SUBSET1)
565
0
        continue;
566
567
      /*
568
       * Record the attribute numbers from the index with the fewest
569
       * columns.  This allows the largest number of columns to be
570
       * removed from the GROUP BY clause.  In the future, we may wish
571
       * to consider using the narrowest set of columns and looking at
572
       * pg_statistic.stawidth as it might be better to use an index
573
       * with, say two INT4s, rather than, say, one long varlena column.
574
       */
575
0
      if (index->nkeycolumns < best_nkeycolumns)
576
0
      {
577
0
        best_keycolumns = ind_attnos;
578
0
        best_nkeycolumns = index->nkeycolumns;
579
0
      }
580
0
    }
581
582
    /* Did we find a suitable index? */
583
0
    if (!bms_is_empty(best_keycolumns))
584
0
    {
585
      /*
586
       * To easily remember whether we've found anything to do, we don't
587
       * allocate the surplusvars[] array until we find something.
588
       */
589
0
      if (surplusvars == NULL)
590
0
        surplusvars = palloc0_array(Bitmapset *, list_length(parse->rtable) + 1);
591
592
      /* Remember the attnos of the removable columns */
593
0
      surplusvars[relid] = bms_difference(relattnos, best_keycolumns);
594
0
    }
595
0
  }
596
597
  /*
598
   * If we found any surplus Vars, build a new GROUP BY clause without them.
599
   * (Note: this may leave some TLEs with unreferenced ressortgroupref
600
   * markings, but that's harmless.)
601
   */
602
0
  if (surplusvars != NULL)
603
0
  {
604
0
    List     *new_groupby = NIL;
605
606
0
    foreach(lc, root->processed_groupClause)
607
0
    {
608
0
      SortGroupClause *sgc = lfirst_node(SortGroupClause, lc);
609
0
      TargetEntry *tle = get_sortgroupclause_tle(sgc, parse->targetList);
610
0
      Var      *var = (Var *) tle->expr;
611
612
      /*
613
       * New list must include non-Vars, outer Vars, and anything not
614
       * marked as surplus.
615
       */
616
0
      if (!IsA(var, Var) ||
617
0
        var->varlevelsup > 0 ||
618
0
        !bms_is_member(var->varattno - FirstLowInvalidHeapAttributeNumber,
619
0
                 surplusvars[var->varno]))
620
0
        new_groupby = lappend(new_groupby, sgc);
621
0
    }
622
623
0
    root->processed_groupClause = new_groupby;
624
0
  }
625
0
}
626
627
/*
628
 * setup_eager_aggregation
629
 *    Check if eager aggregation is applicable, and if so collect suitable
630
 *    aggregate expressions and grouping expressions in the query.
631
 */
632
void
633
setup_eager_aggregation(PlannerInfo *root)
634
0
{
635
  /*
636
   * Don't apply eager aggregation if disabled by user.
637
   */
638
0
  if (!enable_eager_aggregate)
639
0
    return;
640
641
  /*
642
   * Don't apply eager aggregation if there are no available GROUP BY
643
   * clauses.
644
   */
645
0
  if (!root->processed_groupClause)
646
0
    return;
647
648
  /*
649
   * For now we don't try to support grouping sets.
650
   */
651
0
  if (root->parse->groupingSets)
652
0
    return;
653
654
  /*
655
   * For now we don't try to support DISTINCT or ORDER BY aggregates.
656
   */
657
0
  if (root->numOrderedAggs > 0)
658
0
    return;
659
660
  /*
661
   * If there are any aggregates that do not support partial mode, or any
662
   * partial aggregates that are non-serializable, do not apply eager
663
   * aggregation.
664
   */
665
0
  if (root->hasNonPartialAggs || root->hasNonSerialAggs)
666
0
    return;
667
668
  /*
669
   * We don't try to apply eager aggregation if there are set-returning
670
   * functions in targetlist.
671
   */
672
0
  if (root->parse->hasTargetSRFs)
673
0
    return;
674
675
  /*
676
   * Eager aggregation only makes sense if there are multiple base rels in
677
   * the query.
678
   */
679
0
  if (bms_membership(root->all_baserels) != BMS_MULTIPLE)
680
0
    return;
681
682
  /*
683
   * Don't apply eager aggregation if any aggregate poses a risk of
684
   * excessive memory usage during partial aggregation.
685
   */
686
0
  if (is_partial_agg_memory_risky(root))
687
0
    return;
688
689
  /*
690
   * Collect aggregate expressions and plain Vars that appear in the
691
   * targetlist and havingQual.
692
   */
693
0
  create_agg_clause_infos(root);
694
695
  /*
696
   * If there are no suitable aggregate expressions, we cannot apply eager
697
   * aggregation.
698
   */
699
0
  if (root->agg_clause_list == NIL)
700
0
    return;
701
702
  /*
703
   * Collect grouping expressions that appear in grouping clauses.
704
   */
705
0
  create_grouping_expr_infos(root);
706
0
}
707
708
/*
709
 * is_partial_agg_memory_risky
710
 *    Check if any aggregate poses a risk of excessive memory usage during
711
 *    partial aggregation.
712
 *
713
 * We check if any aggregate has a negative aggtransspace value, which
714
 * indicates that its transition state data can grow unboundedly in size.
715
 * Applying eager aggregation in such cases risks high memory usage since
716
 * partial aggregation results might be stored in join hash tables or
717
 * materialized nodes.
718
 */
719
static bool
720
is_partial_agg_memory_risky(PlannerInfo *root)
721
0
{
722
0
  ListCell   *lc;
723
724
0
  foreach(lc, root->aggtransinfos)
725
0
  {
726
0
    AggTransInfo *transinfo = lfirst_node(AggTransInfo, lc);
727
728
0
    if (transinfo->aggtransspace < 0)
729
0
      return true;
730
0
  }
731
732
0
  return false;
733
0
}
734
735
/*
736
 * create_agg_clause_infos
737
 *    Search the targetlist and havingQual for Aggrefs and plain Vars, and
738
 *    create an AggClauseInfo for each Aggref node.
739
 */
740
static void
741
create_agg_clause_infos(PlannerInfo *root)
742
0
{
743
0
  List     *tlist_exprs;
744
0
  List     *agg_clause_list = NIL;
745
0
  List     *tlist_vars = NIL;
746
0
  Relids    aggregate_relids = NULL;
747
0
  bool    eager_agg_applicable = true;
748
0
  ListCell   *lc;
749
750
0
  Assert(root->agg_clause_list == NIL);
751
0
  Assert(root->tlist_vars == NIL);
752
753
0
  tlist_exprs = pull_var_clause((Node *) root->processed_tlist,
754
0
                  PVC_INCLUDE_AGGREGATES |
755
0
                  PVC_RECURSE_WINDOWFUNCS |
756
0
                  PVC_RECURSE_PLACEHOLDERS);
757
758
  /*
759
   * Aggregates within the HAVING clause need to be processed in the same
760
   * way as those in the targetlist.  Note that HAVING can contain Aggrefs
761
   * but not WindowFuncs.
762
   */
763
0
  if (root->parse->havingQual != NULL)
764
0
  {
765
0
    List     *having_exprs;
766
767
0
    having_exprs = pull_var_clause((Node *) root->parse->havingQual,
768
0
                     PVC_INCLUDE_AGGREGATES |
769
0
                     PVC_RECURSE_PLACEHOLDERS);
770
0
    if (having_exprs != NIL)
771
0
    {
772
0
      tlist_exprs = list_concat(tlist_exprs, having_exprs);
773
0
      list_free(having_exprs);
774
0
    }
775
0
  }
776
777
0
  foreach(lc, tlist_exprs)
778
0
  {
779
0
    Expr     *expr = (Expr *) lfirst(lc);
780
0
    Aggref     *aggref;
781
0
    Relids    agg_eval_at;
782
0
    AggClauseInfo *ac_info;
783
784
    /* For now we don't try to support GROUPING() expressions */
785
0
    if (IsA(expr, GroupingFunc))
786
0
    {
787
0
      eager_agg_applicable = false;
788
0
      break;
789
0
    }
790
791
    /* Collect plain Vars for future reference */
792
0
    if (IsA(expr, Var))
793
0
    {
794
0
      tlist_vars = list_append_unique(tlist_vars, expr);
795
0
      continue;
796
0
    }
797
798
0
    aggref = castNode(Aggref, expr);
799
800
0
    Assert(aggref->aggorder == NIL);
801
0
    Assert(aggref->aggdistinct == NIL);
802
803
    /*
804
     * We cannot push down aggregates that contain volatile functions.
805
     * Doing so would change the number of times the function is
806
     * evaluated.
807
     */
808
0
    if (contain_volatile_functions((Node *) aggref))
809
0
    {
810
0
      eager_agg_applicable = false;
811
0
      break;
812
0
    }
813
814
    /*
815
     * If there are any securityQuals, do not try to apply eager
816
     * aggregation if any non-leakproof aggregate functions are present.
817
     * This is overly strict, but for now...
818
     */
819
0
    if (root->qual_security_level > 0 &&
820
0
      !get_func_leakproof(aggref->aggfnoid))
821
0
    {
822
0
      eager_agg_applicable = false;
823
0
      break;
824
0
    }
825
826
0
    agg_eval_at = pull_varnos(root, (Node *) aggref);
827
828
    /*
829
     * If all base relations in the query are referenced by aggregate
830
     * functions, then eager aggregation is not applicable.
831
     */
832
0
    aggregate_relids = bms_add_members(aggregate_relids, agg_eval_at);
833
0
    if (bms_is_subset(root->all_baserels, aggregate_relids))
834
0
    {
835
0
      eager_agg_applicable = false;
836
0
      break;
837
0
    }
838
839
    /* OK, create the AggClauseInfo node */
840
0
    ac_info = makeNode(AggClauseInfo);
841
0
    ac_info->aggref = aggref;
842
0
    ac_info->agg_eval_at = agg_eval_at;
843
844
    /* ... and add it to the list */
845
0
    agg_clause_list = list_append_unique(agg_clause_list, ac_info);
846
0
  }
847
848
0
  list_free(tlist_exprs);
849
850
0
  if (eager_agg_applicable)
851
0
  {
852
0
    root->agg_clause_list = agg_clause_list;
853
0
    root->tlist_vars = tlist_vars;
854
0
  }
855
0
  else
856
0
  {
857
0
    list_free_deep(agg_clause_list);
858
0
    list_free(tlist_vars);
859
0
  }
860
0
}
861
862
/*
863
 * create_grouping_expr_infos
864
 *    Create a GroupingExprInfo for each expression usable as grouping key.
865
 *
866
 * If any grouping expression is not suitable, we will just return with
867
 * root->group_expr_list being NIL.
868
 */
869
static void
870
create_grouping_expr_infos(PlannerInfo *root)
871
0
{
872
0
  List     *exprs = NIL;
873
0
  List     *sortgrouprefs = NIL;
874
0
  List     *ecs = NIL;
875
0
  ListCell   *lc,
876
0
         *lc1,
877
0
         *lc2,
878
0
         *lc3;
879
880
0
  Assert(root->group_expr_list == NIL);
881
882
0
  foreach(lc, root->processed_groupClause)
883
0
  {
884
0
    SortGroupClause *sgc = lfirst_node(SortGroupClause, lc);
885
0
    TargetEntry *tle = get_sortgroupclause_tle(sgc, root->processed_tlist);
886
0
    TypeCacheEntry *tce;
887
0
    Oid     equalimageproc;
888
889
0
    Assert(tle->ressortgroupref > 0);
890
891
    /*
892
     * For now we only support plain Vars as grouping expressions.
893
     */
894
0
    if (!IsA(tle->expr, Var))
895
0
      return;
896
897
    /*
898
     * Eager aggregation is only possible if equality implies image
899
     * equality for each grouping key.  Otherwise, placing keys with
900
     * different byte images into the same group may result in the loss of
901
     * information that could be necessary to evaluate upper qual clauses.
902
     *
903
     * For instance, the NUMERIC data type is not supported, as values
904
     * that are considered equal by the equality operator (e.g., 0 and
905
     * 0.0) can have different scales.
906
     */
907
0
    tce = lookup_type_cache(exprType((Node *) tle->expr),
908
0
                TYPECACHE_BTREE_OPFAMILY);
909
0
    if (!OidIsValid(tce->btree_opf) ||
910
0
      !OidIsValid(tce->btree_opintype))
911
0
      return;
912
913
0
    equalimageproc = get_opfamily_proc(tce->btree_opf,
914
0
                       tce->btree_opintype,
915
0
                       tce->btree_opintype,
916
0
                       BTEQUALIMAGE_PROC);
917
918
    /*
919
     * If there is no BTEQUALIMAGE_PROC, eager aggregation is assumed to
920
     * be unsafe.  Otherwise, we call the procedure to check.  We must be
921
     * careful to pass the expression's actual collation, rather than the
922
     * data type's default collation, to ensure that non-deterministic
923
     * collations are correctly handled.
924
     */
925
0
    if (!OidIsValid(equalimageproc) ||
926
0
      !DatumGetBool(OidFunctionCall1Coll(equalimageproc,
927
0
                         exprCollation((Node *) tle->expr),
928
0
                         ObjectIdGetDatum(tce->btree_opintype))))
929
0
      return;
930
931
0
    exprs = lappend(exprs, tle->expr);
932
0
    sortgrouprefs = lappend_int(sortgrouprefs, tle->ressortgroupref);
933
0
    ecs = lappend(ecs, get_eclass_for_sortgroupclause(root, sgc, tle->expr));
934
0
  }
935
936
  /*
937
   * Construct a GroupingExprInfo for each expression.
938
   */
939
0
  forthree(lc1, exprs, lc2, sortgrouprefs, lc3, ecs)
940
0
  {
941
0
    Expr     *expr = (Expr *) lfirst(lc1);
942
0
    int     sortgroupref = lfirst_int(lc2);
943
0
    EquivalenceClass *ec = (EquivalenceClass *) lfirst(lc3);
944
0
    GroupingExprInfo *ge_info;
945
946
0
    ge_info = makeNode(GroupingExprInfo);
947
0
    ge_info->expr = (Expr *) copyObject(expr);
948
0
    ge_info->sortgroupref = sortgroupref;
949
0
    ge_info->ec = ec;
950
951
0
    root->group_expr_list = lappend(root->group_expr_list, ge_info);
952
0
  }
953
0
}
954
955
/*
956
 * get_eclass_for_sortgroupclause
957
 *    Given a group clause and an expression, find an existing equivalence
958
 *    class that the expression is a member of; return NULL if none.
959
 */
960
static EquivalenceClass *
961
get_eclass_for_sortgroupclause(PlannerInfo *root, SortGroupClause *sgc,
962
                 Expr *expr)
963
0
{
964
0
  Oid     opfamily,
965
0
        opcintype,
966
0
        collation;
967
0
  CompareType cmptype;
968
0
  Oid     equality_op;
969
0
  List     *opfamilies;
970
971
  /* Punt if the group clause is not sortable */
972
0
  if (!OidIsValid(sgc->sortop))
973
0
    return NULL;
974
975
  /* Find the operator in pg_amop --- failure shouldn't happen */
976
0
  if (!get_ordering_op_properties(sgc->sortop,
977
0
                  &opfamily, &opcintype, &cmptype))
978
0
    elog(ERROR, "operator %u is not a valid ordering operator",
979
0
       sgc->sortop);
980
981
  /* Because SortGroupClause doesn't carry collation, consult the expr */
982
0
  collation = exprCollation((Node *) expr);
983
984
  /*
985
   * EquivalenceClasses need to contain opfamily lists based on the family
986
   * membership of mergejoinable equality operators, which could belong to
987
   * more than one opfamily.  So we have to look up the opfamily's equality
988
   * operator and get its membership.
989
   */
990
0
  equality_op = get_opfamily_member_for_cmptype(opfamily,
991
0
                          opcintype,
992
0
                          opcintype,
993
0
                          COMPARE_EQ);
994
0
  if (!OidIsValid(equality_op))  /* shouldn't happen */
995
0
    elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
996
0
       COMPARE_EQ, opcintype, opcintype, opfamily);
997
0
  opfamilies = get_mergejoin_opfamilies(equality_op);
998
0
  if (!opfamilies)     /* certainly should find some */
999
0
    elog(ERROR, "could not find opfamilies for equality operator %u",
1000
0
       equality_op);
1001
1002
  /* Now find a matching EquivalenceClass */
1003
0
  return get_eclass_for_sort_expr(root, expr, opfamilies, opcintype,
1004
0
                  collation, sgc->tleSortGroupRef,
1005
0
                  NULL, false);
1006
0
}
1007
1008
/*****************************************************************************
1009
 *
1010
 *    LATERAL REFERENCES
1011
 *
1012
 *****************************************************************************/
1013
1014
/*
1015
 * find_lateral_references
1016
 *    For each LATERAL subquery, extract all its references to Vars and
1017
 *    PlaceHolderVars of the current query level, and make sure those values
1018
 *    will be available for evaluation of the subquery.
1019
 *
1020
 * While later planning steps ensure that the Var/PHV source rels are on the
1021
 * outside of nestloops relative to the LATERAL subquery, we also need to
1022
 * ensure that the Vars/PHVs propagate up to the nestloop join level; this
1023
 * means setting suitable where_needed values for them.
1024
 *
1025
 * Note that this only deals with lateral references in unflattened LATERAL
1026
 * subqueries.  When we flatten a LATERAL subquery, its lateral references
1027
 * become plain Vars in the parent query, but they may have to be wrapped in
1028
 * PlaceHolderVars if they need to be forced NULL by outer joins that don't
1029
 * also null the LATERAL subquery.  That's all handled elsewhere.
1030
 *
1031
 * This has to run before deconstruct_jointree, since it might result in
1032
 * creation of PlaceHolderInfos.
1033
 */
1034
void
1035
find_lateral_references(PlannerInfo *root)
1036
0
{
1037
0
  Index   rti;
1038
1039
  /* We need do nothing if the query contains no LATERAL RTEs */
1040
0
  if (!root->hasLateralRTEs)
1041
0
    return;
1042
1043
  /*
1044
   * Examine all baserels (the rel array has been set up by now).
1045
   */
1046
0
  for (rti = 1; rti < root->simple_rel_array_size; rti++)
1047
0
  {
1048
0
    RelOptInfo *brel = root->simple_rel_array[rti];
1049
1050
    /* there may be empty slots corresponding to non-baserel RTEs */
1051
0
    if (brel == NULL)
1052
0
      continue;
1053
1054
0
    Assert(brel->relid == rti); /* sanity check on array */
1055
1056
    /*
1057
     * This bit is less obvious than it might look.  We ignore appendrel
1058
     * otherrels and consider only their parent baserels.  In a case where
1059
     * a LATERAL-containing UNION ALL subquery was pulled up, it is the
1060
     * otherrel that is actually going to be in the plan.  However, we
1061
     * want to mark all its lateral references as needed by the parent,
1062
     * because it is the parent's relid that will be used for join
1063
     * planning purposes.  And the parent's RTE will contain all the
1064
     * lateral references we need to know, since the pulled-up member is
1065
     * nothing but a copy of parts of the original RTE's subquery.  We
1066
     * could visit the parent's children instead and transform their
1067
     * references back to the parent's relid, but it would be much more
1068
     * complicated for no real gain.  (Important here is that the child
1069
     * members have not yet received any processing beyond being pulled
1070
     * up.)  Similarly, in appendrels created by inheritance expansion,
1071
     * it's sufficient to look at the parent relation.
1072
     */
1073
1074
    /* ignore RTEs that are "other rels" */
1075
0
    if (brel->reloptkind != RELOPT_BASEREL)
1076
0
      continue;
1077
1078
0
    extract_lateral_references(root, brel, rti);
1079
0
  }
1080
0
}
1081
1082
static void
1083
extract_lateral_references(PlannerInfo *root, RelOptInfo *brel, Index rtindex)
1084
0
{
1085
0
  RangeTblEntry *rte = root->simple_rte_array[rtindex];
1086
0
  List     *vars;
1087
0
  List     *newvars;
1088
0
  Relids    where_needed;
1089
0
  ListCell   *lc;
1090
1091
  /* No cross-references are possible if it's not LATERAL */
1092
0
  if (!rte->lateral)
1093
0
    return;
1094
1095
  /* Fetch the appropriate variables */
1096
0
  if (rte->rtekind == RTE_RELATION)
1097
0
    vars = pull_vars_of_level((Node *) rte->tablesample, 0);
1098
0
  else if (rte->rtekind == RTE_SUBQUERY)
1099
0
    vars = pull_vars_of_level((Node *) rte->subquery, 1);
1100
0
  else if (rte->rtekind == RTE_FUNCTION)
1101
0
    vars = pull_vars_of_level((Node *) rte->functions, 0);
1102
0
  else if (rte->rtekind == RTE_TABLEFUNC)
1103
0
    vars = pull_vars_of_level((Node *) rte->tablefunc, 0);
1104
0
  else if (rte->rtekind == RTE_VALUES)
1105
0
    vars = pull_vars_of_level((Node *) rte->values_lists, 0);
1106
0
  else
1107
0
  {
1108
0
    Assert(false);
1109
0
    return;         /* keep compiler quiet */
1110
0
  }
1111
1112
0
  if (vars == NIL)
1113
0
    return;         /* nothing to do */
1114
1115
  /* Copy each Var (or PlaceHolderVar) and adjust it to match our level */
1116
0
  newvars = NIL;
1117
0
  foreach(lc, vars)
1118
0
  {
1119
0
    Node     *node = (Node *) lfirst(lc);
1120
1121
0
    node = copyObject(node);
1122
0
    if (IsA(node, Var))
1123
0
    {
1124
0
      Var      *var = (Var *) node;
1125
1126
      /* Adjustment is easy since it's just one node */
1127
0
      var->varlevelsup = 0;
1128
0
    }
1129
0
    else if (IsA(node, PlaceHolderVar))
1130
0
    {
1131
0
      PlaceHolderVar *phv = (PlaceHolderVar *) node;
1132
0
      int     levelsup = phv->phlevelsup;
1133
1134
      /*
1135
       * Have to work harder to adjust the contained expression too.
1136
       * (Its expression has already been preprocessed by
1137
       * subquery_planner(), so we must not do that again here.)
1138
       */
1139
0
      if (levelsup != 0)
1140
0
        IncrementVarSublevelsUp(node, -levelsup, 0);
1141
0
    }
1142
0
    else
1143
0
      Assert(false);
1144
0
    newvars = lappend(newvars, node);
1145
0
  }
1146
1147
0
  list_free(vars);
1148
1149
  /*
1150
   * We mark the Vars as being "needed" at the LATERAL RTE.  This is a bit
1151
   * of a cheat: a more formal approach would be to mark each one as needed
1152
   * at the join of the LATERAL RTE with its source RTE.  But it will work,
1153
   * and it's much less tedious than computing a separate where_needed for
1154
   * each Var.
1155
   */
1156
0
  where_needed = bms_make_singleton(rtindex);
1157
1158
  /*
1159
   * Push Vars into their source relations' targetlists, and PHVs into
1160
   * root->placeholder_list.
1161
   */
1162
0
  add_vars_to_targetlist(root, newvars, where_needed);
1163
1164
  /* Remember the lateral references for create_lateral_join_info */
1165
0
  brel->lateral_vars = newvars;
1166
0
}
1167
1168
/*
1169
 * create_lateral_join_info
1170
 *    Fill in the per-base-relation direct_lateral_relids, lateral_relids
1171
 *    and lateral_referencers sets.
1172
 */
1173
void
1174
create_lateral_join_info(PlannerInfo *root)
1175
0
{
1176
0
  bool    found_laterals = false;
1177
0
  Index   rti;
1178
0
  ListCell   *lc;
1179
1180
  /* We need do nothing if the query contains no LATERAL RTEs */
1181
0
  if (!root->hasLateralRTEs)
1182
0
    return;
1183
1184
  /* We'll need to have the ph_eval_at values for PlaceHolderVars */
1185
0
  Assert(root->placeholdersFrozen);
1186
1187
  /*
1188
   * Examine all baserels (the rel array has been set up by now).
1189
   */
1190
0
  for (rti = 1; rti < root->simple_rel_array_size; rti++)
1191
0
  {
1192
0
    RelOptInfo *brel = root->simple_rel_array[rti];
1193
0
    Relids    lateral_relids;
1194
1195
    /* there may be empty slots corresponding to non-baserel RTEs */
1196
0
    if (brel == NULL)
1197
0
      continue;
1198
1199
0
    Assert(brel->relid == rti); /* sanity check on array */
1200
1201
    /* ignore RTEs that are "other rels" */
1202
0
    if (brel->reloptkind != RELOPT_BASEREL)
1203
0
      continue;
1204
1205
0
    lateral_relids = NULL;
1206
1207
    /* consider each laterally-referenced Var or PHV */
1208
0
    foreach(lc, brel->lateral_vars)
1209
0
    {
1210
0
      Node     *node = (Node *) lfirst(lc);
1211
1212
0
      if (IsA(node, Var))
1213
0
      {
1214
0
        Var      *var = (Var *) node;
1215
1216
0
        found_laterals = true;
1217
0
        lateral_relids = bms_add_member(lateral_relids,
1218
0
                        var->varno);
1219
0
      }
1220
0
      else if (IsA(node, PlaceHolderVar))
1221
0
      {
1222
0
        PlaceHolderVar *phv = (PlaceHolderVar *) node;
1223
0
        PlaceHolderInfo *phinfo = find_placeholder_info(root, phv);
1224
1225
0
        found_laterals = true;
1226
0
        lateral_relids = bms_add_members(lateral_relids,
1227
0
                         phinfo->ph_eval_at);
1228
0
      }
1229
0
      else
1230
0
        Assert(false);
1231
0
    }
1232
1233
    /* We now have all the simple lateral refs from this rel */
1234
0
    brel->direct_lateral_relids = lateral_relids;
1235
0
    brel->lateral_relids = bms_copy(lateral_relids);
1236
0
  }
1237
1238
  /*
1239
   * Now check for lateral references within PlaceHolderVars, and mark their
1240
   * eval_at rels as having lateral references to the source rels.
1241
   *
1242
   * For a PHV that is due to be evaluated at a baserel, mark its source(s)
1243
   * as direct lateral dependencies of the baserel (adding onto the ones
1244
   * recorded above).  If it's due to be evaluated at a join, mark its
1245
   * source(s) as indirect lateral dependencies of each baserel in the join,
1246
   * ie put them into lateral_relids but not direct_lateral_relids.  This is
1247
   * appropriate because we can't put any such baserel on the outside of a
1248
   * join to one of the PHV's lateral dependencies, but on the other hand we
1249
   * also can't yet join it directly to the dependency.
1250
   */
1251
0
  foreach(lc, root->placeholder_list)
1252
0
  {
1253
0
    PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(lc);
1254
0
    Relids    eval_at = phinfo->ph_eval_at;
1255
0
    Relids    lateral_refs;
1256
0
    int     varno;
1257
1258
0
    if (phinfo->ph_lateral == NULL)
1259
0
      continue;     /* PHV is uninteresting if no lateral refs */
1260
1261
0
    found_laterals = true;
1262
1263
    /*
1264
     * Include only baserels not outer joins in the evaluation sites'
1265
     * lateral relids.  This avoids problems when outer join order gets
1266
     * rearranged, and it should still ensure that the lateral values are
1267
     * available when needed.
1268
     */
1269
0
    lateral_refs = bms_intersect(phinfo->ph_lateral, root->all_baserels);
1270
0
    Assert(!bms_is_empty(lateral_refs));
1271
1272
0
    if (bms_get_singleton_member(eval_at, &varno))
1273
0
    {
1274
      /* Evaluation site is a baserel */
1275
0
      RelOptInfo *brel = find_base_rel(root, varno);
1276
1277
0
      brel->direct_lateral_relids =
1278
0
        bms_add_members(brel->direct_lateral_relids,
1279
0
                lateral_refs);
1280
0
      brel->lateral_relids =
1281
0
        bms_add_members(brel->lateral_relids,
1282
0
                lateral_refs);
1283
0
    }
1284
0
    else
1285
0
    {
1286
      /* Evaluation site is a join */
1287
0
      varno = -1;
1288
0
      while ((varno = bms_next_member(eval_at, varno)) >= 0)
1289
0
      {
1290
0
        RelOptInfo *brel = find_base_rel_ignore_join(root, varno);
1291
1292
0
        if (brel == NULL)
1293
0
          continue; /* ignore outer joins in eval_at */
1294
0
        brel->lateral_relids = bms_add_members(brel->lateral_relids,
1295
0
                             lateral_refs);
1296
0
      }
1297
0
    }
1298
0
  }
1299
1300
  /*
1301
   * If we found no actual lateral references, we're done; but reset the
1302
   * hasLateralRTEs flag to avoid useless work later.
1303
   */
1304
0
  if (!found_laterals)
1305
0
  {
1306
0
    root->hasLateralRTEs = false;
1307
0
    return;
1308
0
  }
1309
1310
  /*
1311
   * Calculate the transitive closure of the lateral_relids sets, so that
1312
   * they describe both direct and indirect lateral references.  If relation
1313
   * X references Y laterally, and Y references Z laterally, then we will
1314
   * have to scan X on the inside of a nestloop with Z, so for all intents
1315
   * and purposes X is laterally dependent on Z too.
1316
   *
1317
   * This code is essentially Warshall's algorithm for transitive closure.
1318
   * The outer loop considers each baserel, and propagates its lateral
1319
   * dependencies to those baserels that have a lateral dependency on it.
1320
   */
1321
0
  for (rti = 1; rti < root->simple_rel_array_size; rti++)
1322
0
  {
1323
0
    RelOptInfo *brel = root->simple_rel_array[rti];
1324
0
    Relids    outer_lateral_relids;
1325
0
    Index   rti2;
1326
1327
0
    if (brel == NULL || brel->reloptkind != RELOPT_BASEREL)
1328
0
      continue;
1329
1330
    /* need not consider baserel further if it has no lateral refs */
1331
0
    outer_lateral_relids = brel->lateral_relids;
1332
0
    if (outer_lateral_relids == NULL)
1333
0
      continue;
1334
1335
    /* else scan all baserels */
1336
0
    for (rti2 = 1; rti2 < root->simple_rel_array_size; rti2++)
1337
0
    {
1338
0
      RelOptInfo *brel2 = root->simple_rel_array[rti2];
1339
1340
0
      if (brel2 == NULL || brel2->reloptkind != RELOPT_BASEREL)
1341
0
        continue;
1342
1343
      /* if brel2 has lateral ref to brel, propagate brel's refs */
1344
0
      if (bms_is_member(rti, brel2->lateral_relids))
1345
0
        brel2->lateral_relids = bms_add_members(brel2->lateral_relids,
1346
0
                            outer_lateral_relids);
1347
0
    }
1348
0
  }
1349
1350
  /*
1351
   * Now that we've identified all lateral references, mark each baserel
1352
   * with the set of relids of rels that reference it laterally (possibly
1353
   * indirectly) --- that is, the inverse mapping of lateral_relids.
1354
   */
1355
0
  for (rti = 1; rti < root->simple_rel_array_size; rti++)
1356
0
  {
1357
0
    RelOptInfo *brel = root->simple_rel_array[rti];
1358
0
    Relids    lateral_relids;
1359
0
    int     rti2;
1360
1361
0
    if (brel == NULL || brel->reloptkind != RELOPT_BASEREL)
1362
0
      continue;
1363
1364
    /* Nothing to do at rels with no lateral refs */
1365
0
    lateral_relids = brel->lateral_relids;
1366
0
    if (bms_is_empty(lateral_relids))
1367
0
      continue;
1368
1369
    /* No rel should have a lateral dependency on itself */
1370
0
    Assert(!bms_is_member(rti, lateral_relids));
1371
1372
    /* Mark this rel's referencees */
1373
0
    rti2 = -1;
1374
0
    while ((rti2 = bms_next_member(lateral_relids, rti2)) >= 0)
1375
0
    {
1376
0
      RelOptInfo *brel2 = root->simple_rel_array[rti2];
1377
1378
0
      if (brel2 == NULL)
1379
0
        continue;   /* must be an OJ */
1380
1381
0
      Assert(brel2->reloptkind == RELOPT_BASEREL);
1382
0
      brel2->lateral_referencers =
1383
0
        bms_add_member(brel2->lateral_referencers, rti);
1384
0
    }
1385
0
  }
1386
0
}
1387
1388
1389
/*****************************************************************************
1390
 *
1391
 *    JOIN TREE PROCESSING
1392
 *
1393
 *****************************************************************************/
1394
1395
/*
1396
 * deconstruct_jointree
1397
 *    Recursively scan the query's join tree for WHERE and JOIN/ON qual
1398
 *    clauses, and add these to the appropriate restrictinfo and joininfo
1399
 *    lists belonging to base RelOptInfos.  Also, add SpecialJoinInfo nodes
1400
 *    to root->join_info_list for any outer joins appearing in the query tree.
1401
 *    Return a "joinlist" data structure showing the join order decisions
1402
 *    that need to be made by make_one_rel().
1403
 *
1404
 * The "joinlist" result is a list of items that are either RangeTblRef
1405
 * jointree nodes or sub-joinlists.  All the items at the same level of
1406
 * joinlist must be joined in an order to be determined by make_one_rel()
1407
 * (note that legal orders may be constrained by SpecialJoinInfo nodes).
1408
 * A sub-joinlist represents a subproblem to be planned separately. Currently
1409
 * sub-joinlists arise only from FULL OUTER JOIN or when collapsing of
1410
 * subproblems is stopped by join_collapse_limit or from_collapse_limit.
1411
 */
1412
List *
1413
deconstruct_jointree(PlannerInfo *root)
1414
0
{
1415
0
  List     *result;
1416
0
  JoinDomain *top_jdomain;
1417
0
  List     *item_list = NIL;
1418
0
  ListCell   *lc;
1419
1420
  /*
1421
   * After this point, no more PlaceHolderInfos may be made, because
1422
   * make_outerjoininfo requires all active placeholders to be present in
1423
   * root->placeholder_list while we crawl up the join tree.
1424
   */
1425
0
  root->placeholdersFrozen = true;
1426
1427
  /* Fetch the already-created top-level join domain for the query */
1428
0
  top_jdomain = linitial_node(JoinDomain, root->join_domains);
1429
0
  top_jdomain->jd_relids = NULL; /* filled during deconstruct_recurse */
1430
1431
  /* Start recursion at top of jointree */
1432
0
  Assert(root->parse->jointree != NULL &&
1433
0
       IsA(root->parse->jointree, FromExpr));
1434
1435
  /* These are filled as we scan the jointree */
1436
0
  root->all_baserels = NULL;
1437
0
  root->outer_join_rels = NULL;
1438
1439
  /* Perform the initial scan of the jointree */
1440
0
  result = deconstruct_recurse(root, (Node *) root->parse->jointree,
1441
0
                 top_jdomain, NULL,
1442
0
                 &item_list);
1443
1444
  /* Now we can form the value of all_query_rels, too */
1445
0
  root->all_query_rels = bms_union(root->all_baserels, root->outer_join_rels);
1446
1447
  /* ... which should match what we computed for the top join domain */
1448
0
  Assert(bms_equal(root->all_query_rels, top_jdomain->jd_relids));
1449
1450
  /* Now scan all the jointree nodes again, and distribute quals */
1451
0
  foreach(lc, item_list)
1452
0
  {
1453
0
    JoinTreeItem *jtitem = (JoinTreeItem *) lfirst(lc);
1454
1455
0
    deconstruct_distribute(root, jtitem);
1456
0
  }
1457
1458
  /*
1459
   * If there were any special joins then we may have some postponed LEFT
1460
   * JOIN clauses to deal with.
1461
   */
1462
0
  if (root->join_info_list)
1463
0
  {
1464
0
    foreach(lc, item_list)
1465
0
    {
1466
0
      JoinTreeItem *jtitem = (JoinTreeItem *) lfirst(lc);
1467
1468
0
      if (jtitem->oj_joinclauses != NIL)
1469
0
        deconstruct_distribute_oj_quals(root, item_list, jtitem);
1470
0
    }
1471
0
  }
1472
1473
  /* Don't need the JoinTreeItems any more */
1474
0
  list_free_deep(item_list);
1475
1476
0
  return result;
1477
0
}
1478
1479
/*
1480
 * deconstruct_recurse
1481
 *    One recursion level of deconstruct_jointree's initial jointree scan.
1482
 *
1483
 * jtnode is the jointree node to examine, and parent_domain is the
1484
 * enclosing join domain.  (We must add all base+OJ relids appearing
1485
 * here or below to parent_domain.)  parent_jtitem is the JoinTreeItem
1486
 * for the parent jointree node, or NULL at the top of the recursion.
1487
 *
1488
 * item_list is an in/out parameter: we add a JoinTreeItem struct to
1489
 * that list for each jointree node, in depth-first traversal order.
1490
 * (Hence, after each call, the last list item corresponds to its jtnode.)
1491
 *
1492
 * Return value is the appropriate joinlist for this jointree node.
1493
 */
1494
static List *
1495
deconstruct_recurse(PlannerInfo *root, Node *jtnode,
1496
          JoinDomain *parent_domain,
1497
          JoinTreeItem *parent_jtitem,
1498
          List **item_list)
1499
0
{
1500
0
  List     *joinlist;
1501
0
  JoinTreeItem *jtitem;
1502
1503
0
  Assert(jtnode != NULL);
1504
1505
  /* Make the new JoinTreeItem, but don't add it to item_list yet */
1506
0
  jtitem = palloc0_object(JoinTreeItem);
1507
0
  jtitem->jtnode = jtnode;
1508
0
  jtitem->jti_parent = parent_jtitem;
1509
1510
0
  if (IsA(jtnode, RangeTblRef))
1511
0
  {
1512
0
    int     varno = ((RangeTblRef *) jtnode)->rtindex;
1513
1514
    /* Fill all_baserels as we encounter baserel jointree nodes */
1515
0
    root->all_baserels = bms_add_member(root->all_baserels, varno);
1516
    /* This node belongs to parent_domain */
1517
0
    jtitem->jdomain = parent_domain;
1518
0
    parent_domain->jd_relids = bms_add_member(parent_domain->jd_relids,
1519
0
                          varno);
1520
    /* qualscope is just the one RTE */
1521
0
    jtitem->qualscope = bms_make_singleton(varno);
1522
    /* A single baserel does not create an inner join */
1523
0
    jtitem->inner_join_rels = NULL;
1524
0
    joinlist = list_make1(jtnode);
1525
0
  }
1526
0
  else if (IsA(jtnode, FromExpr))
1527
0
  {
1528
0
    FromExpr   *f = (FromExpr *) jtnode;
1529
0
    int     remaining;
1530
0
    ListCell   *l;
1531
1532
    /* This node belongs to parent_domain, as do its children */
1533
0
    jtitem->jdomain = parent_domain;
1534
1535
    /*
1536
     * Recurse to handle child nodes, and compute output joinlist.  We
1537
     * collapse subproblems into a single joinlist whenever the resulting
1538
     * joinlist wouldn't exceed from_collapse_limit members.  Also, always
1539
     * collapse one-element subproblems, since that won't lengthen the
1540
     * joinlist anyway.
1541
     */
1542
0
    jtitem->qualscope = NULL;
1543
0
    jtitem->inner_join_rels = NULL;
1544
0
    joinlist = NIL;
1545
0
    remaining = list_length(f->fromlist);
1546
0
    foreach(l, f->fromlist)
1547
0
    {
1548
0
      JoinTreeItem *sub_item;
1549
0
      List     *sub_joinlist;
1550
0
      int     sub_members;
1551
1552
0
      sub_joinlist = deconstruct_recurse(root, lfirst(l),
1553
0
                         parent_domain,
1554
0
                         jtitem,
1555
0
                         item_list);
1556
0
      sub_item = (JoinTreeItem *) llast(*item_list);
1557
0
      jtitem->qualscope = bms_add_members(jtitem->qualscope,
1558
0
                        sub_item->qualscope);
1559
0
      jtitem->inner_join_rels = sub_item->inner_join_rels;
1560
0
      sub_members = list_length(sub_joinlist);
1561
0
      remaining--;
1562
0
      if (sub_members <= 1 ||
1563
0
        list_length(joinlist) + sub_members + remaining <= from_collapse_limit)
1564
0
        joinlist = list_concat(joinlist, sub_joinlist);
1565
0
      else
1566
0
        joinlist = lappend(joinlist, sub_joinlist);
1567
0
    }
1568
1569
    /*
1570
     * A FROM with more than one list element is an inner join subsuming
1571
     * all below it, so we should report inner_join_rels = qualscope. If
1572
     * there was exactly one element, we should (and already did) report
1573
     * whatever its inner_join_rels were.  If there were no elements (is
1574
     * that still possible?) the initialization before the loop fixed it.
1575
     */
1576
0
    if (list_length(f->fromlist) > 1)
1577
0
      jtitem->inner_join_rels = jtitem->qualscope;
1578
0
  }
1579
0
  else if (IsA(jtnode, JoinExpr))
1580
0
  {
1581
0
    JoinExpr   *j = (JoinExpr *) jtnode;
1582
0
    JoinDomain *child_domain,
1583
0
           *fj_domain;
1584
0
    JoinTreeItem *left_item,
1585
0
           *right_item;
1586
0
    List     *leftjoinlist,
1587
0
           *rightjoinlist;
1588
1589
0
    switch (j->jointype)
1590
0
    {
1591
0
      case JOIN_INNER:
1592
        /* This node belongs to parent_domain, as do its children */
1593
0
        jtitem->jdomain = parent_domain;
1594
        /* Recurse */
1595
0
        leftjoinlist = deconstruct_recurse(root, j->larg,
1596
0
                           parent_domain,
1597
0
                           jtitem,
1598
0
                           item_list);
1599
0
        left_item = (JoinTreeItem *) llast(*item_list);
1600
0
        rightjoinlist = deconstruct_recurse(root, j->rarg,
1601
0
                          parent_domain,
1602
0
                          jtitem,
1603
0
                          item_list);
1604
0
        right_item = (JoinTreeItem *) llast(*item_list);
1605
        /* Compute qualscope etc */
1606
0
        jtitem->qualscope = bms_union(left_item->qualscope,
1607
0
                        right_item->qualscope);
1608
0
        jtitem->inner_join_rels = jtitem->qualscope;
1609
0
        jtitem->left_rels = left_item->qualscope;
1610
0
        jtitem->right_rels = right_item->qualscope;
1611
        /* Inner join adds no restrictions for quals */
1612
0
        jtitem->nonnullable_rels = NULL;
1613
0
        break;
1614
0
      case JOIN_LEFT:
1615
0
      case JOIN_ANTI:
1616
        /* Make new join domain for my quals and the RHS */
1617
0
        child_domain = makeNode(JoinDomain);
1618
0
        child_domain->jd_relids = NULL; /* filled by recursion */
1619
0
        root->join_domains = lappend(root->join_domains, child_domain);
1620
0
        jtitem->jdomain = child_domain;
1621
        /* Recurse */
1622
0
        leftjoinlist = deconstruct_recurse(root, j->larg,
1623
0
                           parent_domain,
1624
0
                           jtitem,
1625
0
                           item_list);
1626
0
        left_item = (JoinTreeItem *) llast(*item_list);
1627
0
        rightjoinlist = deconstruct_recurse(root, j->rarg,
1628
0
                          child_domain,
1629
0
                          jtitem,
1630
0
                          item_list);
1631
0
        right_item = (JoinTreeItem *) llast(*item_list);
1632
        /* Compute join domain contents, qualscope etc */
1633
0
        parent_domain->jd_relids =
1634
0
          bms_add_members(parent_domain->jd_relids,
1635
0
                  child_domain->jd_relids);
1636
0
        jtitem->qualscope = bms_union(left_item->qualscope,
1637
0
                        right_item->qualscope);
1638
        /* caution: ANTI join derived from SEMI will lack rtindex */
1639
0
        if (j->rtindex != 0)
1640
0
        {
1641
0
          parent_domain->jd_relids =
1642
0
            bms_add_member(parent_domain->jd_relids,
1643
0
                     j->rtindex);
1644
0
          jtitem->qualscope = bms_add_member(jtitem->qualscope,
1645
0
                             j->rtindex);
1646
0
          root->outer_join_rels = bms_add_member(root->outer_join_rels,
1647
0
                               j->rtindex);
1648
0
          mark_rels_nulled_by_join(root, j->rtindex,
1649
0
                       right_item->qualscope);
1650
0
        }
1651
0
        jtitem->inner_join_rels = bms_union(left_item->inner_join_rels,
1652
0
                          right_item->inner_join_rels);
1653
0
        jtitem->left_rels = left_item->qualscope;
1654
0
        jtitem->right_rels = right_item->qualscope;
1655
0
        jtitem->nonnullable_rels = left_item->qualscope;
1656
0
        break;
1657
0
      case JOIN_SEMI:
1658
        /* This node belongs to parent_domain, as do its children */
1659
0
        jtitem->jdomain = parent_domain;
1660
        /* Recurse */
1661
0
        leftjoinlist = deconstruct_recurse(root, j->larg,
1662
0
                           parent_domain,
1663
0
                           jtitem,
1664
0
                           item_list);
1665
0
        left_item = (JoinTreeItem *) llast(*item_list);
1666
0
        rightjoinlist = deconstruct_recurse(root, j->rarg,
1667
0
                          parent_domain,
1668
0
                          jtitem,
1669
0
                          item_list);
1670
0
        right_item = (JoinTreeItem *) llast(*item_list);
1671
        /* Compute qualscope etc */
1672
0
        jtitem->qualscope = bms_union(left_item->qualscope,
1673
0
                        right_item->qualscope);
1674
        /* SEMI join never has rtindex, so don't add to anything */
1675
0
        Assert(j->rtindex == 0);
1676
0
        jtitem->inner_join_rels = bms_union(left_item->inner_join_rels,
1677
0
                          right_item->inner_join_rels);
1678
0
        jtitem->left_rels = left_item->qualscope;
1679
0
        jtitem->right_rels = right_item->qualscope;
1680
        /* Semi join adds no restrictions for quals */
1681
0
        jtitem->nonnullable_rels = NULL;
1682
0
        break;
1683
0
      case JOIN_FULL:
1684
        /* The FULL JOIN's quals need their very own domain */
1685
0
        fj_domain = makeNode(JoinDomain);
1686
0
        root->join_domains = lappend(root->join_domains, fj_domain);
1687
0
        jtitem->jdomain = fj_domain;
1688
        /* Recurse, giving each side its own join domain */
1689
0
        child_domain = makeNode(JoinDomain);
1690
0
        child_domain->jd_relids = NULL; /* filled by recursion */
1691
0
        root->join_domains = lappend(root->join_domains, child_domain);
1692
0
        leftjoinlist = deconstruct_recurse(root, j->larg,
1693
0
                           child_domain,
1694
0
                           jtitem,
1695
0
                           item_list);
1696
0
        left_item = (JoinTreeItem *) llast(*item_list);
1697
0
        fj_domain->jd_relids = bms_copy(child_domain->jd_relids);
1698
0
        child_domain = makeNode(JoinDomain);
1699
0
        child_domain->jd_relids = NULL; /* filled by recursion */
1700
0
        root->join_domains = lappend(root->join_domains, child_domain);
1701
0
        rightjoinlist = deconstruct_recurse(root, j->rarg,
1702
0
                          child_domain,
1703
0
                          jtitem,
1704
0
                          item_list);
1705
0
        right_item = (JoinTreeItem *) llast(*item_list);
1706
        /* Compute qualscope etc */
1707
0
        fj_domain->jd_relids = bms_add_members(fj_domain->jd_relids,
1708
0
                             child_domain->jd_relids);
1709
0
        parent_domain->jd_relids = bms_add_members(parent_domain->jd_relids,
1710
0
                               fj_domain->jd_relids);
1711
0
        jtitem->qualscope = bms_union(left_item->qualscope,
1712
0
                        right_item->qualscope);
1713
0
        Assert(j->rtindex != 0);
1714
0
        parent_domain->jd_relids = bms_add_member(parent_domain->jd_relids,
1715
0
                              j->rtindex);
1716
0
        jtitem->qualscope = bms_add_member(jtitem->qualscope,
1717
0
                           j->rtindex);
1718
0
        root->outer_join_rels = bms_add_member(root->outer_join_rels,
1719
0
                             j->rtindex);
1720
0
        mark_rels_nulled_by_join(root, j->rtindex,
1721
0
                     left_item->qualscope);
1722
0
        mark_rels_nulled_by_join(root, j->rtindex,
1723
0
                     right_item->qualscope);
1724
0
        jtitem->inner_join_rels = bms_union(left_item->inner_join_rels,
1725
0
                          right_item->inner_join_rels);
1726
0
        jtitem->left_rels = left_item->qualscope;
1727
0
        jtitem->right_rels = right_item->qualscope;
1728
        /* each side is both outer and inner */
1729
0
        jtitem->nonnullable_rels = jtitem->qualscope;
1730
0
        break;
1731
0
      default:
1732
        /* JOIN_RIGHT was eliminated during reduce_outer_joins() */
1733
0
        elog(ERROR, "unrecognized join type: %d",
1734
0
           (int) j->jointype);
1735
0
        leftjoinlist = rightjoinlist = NIL; /* keep compiler quiet */
1736
0
        break;
1737
0
    }
1738
1739
    /*
1740
     * Compute the output joinlist.  We fold subproblems together except
1741
     * at a FULL JOIN or where join_collapse_limit would be exceeded.
1742
     */
1743
0
    if (j->jointype == JOIN_FULL)
1744
0
    {
1745
      /* force the join order exactly at this node */
1746
0
      joinlist = list_make1(list_make2(leftjoinlist, rightjoinlist));
1747
0
    }
1748
0
    else if (list_length(leftjoinlist) + list_length(rightjoinlist) <=
1749
0
         join_collapse_limit)
1750
0
    {
1751
      /* OK to combine subproblems */
1752
0
      joinlist = list_concat(leftjoinlist, rightjoinlist);
1753
0
    }
1754
0
    else
1755
0
    {
1756
      /* can't combine, but needn't force join order above here */
1757
0
      Node     *leftpart,
1758
0
             *rightpart;
1759
1760
      /* avoid creating useless 1-element sublists */
1761
0
      if (list_length(leftjoinlist) == 1)
1762
0
        leftpart = (Node *) linitial(leftjoinlist);
1763
0
      else
1764
0
        leftpart = (Node *) leftjoinlist;
1765
0
      if (list_length(rightjoinlist) == 1)
1766
0
        rightpart = (Node *) linitial(rightjoinlist);
1767
0
      else
1768
0
        rightpart = (Node *) rightjoinlist;
1769
0
      joinlist = list_make2(leftpart, rightpart);
1770
0
    }
1771
0
  }
1772
0
  else
1773
0
  {
1774
0
    elog(ERROR, "unrecognized node type: %d",
1775
0
       (int) nodeTag(jtnode));
1776
0
    joinlist = NIL;     /* keep compiler quiet */
1777
0
  }
1778
1779
  /* Finally, we can add the new JoinTreeItem to item_list */
1780
0
  *item_list = lappend(*item_list, jtitem);
1781
1782
0
  return joinlist;
1783
0
}
1784
1785
/*
1786
 * deconstruct_distribute
1787
 *    Process one jointree node in phase 2 of deconstruct_jointree processing.
1788
 *
1789
 * Distribute quals of the node to appropriate restriction and join lists.
1790
 * In addition, entries will be added to root->join_info_list for outer joins.
1791
 */
1792
static void
1793
deconstruct_distribute(PlannerInfo *root, JoinTreeItem *jtitem)
1794
0
{
1795
0
  Node     *jtnode = jtitem->jtnode;
1796
1797
0
  if (IsA(jtnode, RangeTblRef))
1798
0
  {
1799
0
    int     varno = ((RangeTblRef *) jtnode)->rtindex;
1800
1801
    /* Deal with any securityQuals attached to the RTE */
1802
0
    if (root->qual_security_level > 0)
1803
0
      process_security_barrier_quals(root,
1804
0
                       varno,
1805
0
                       jtitem);
1806
0
  }
1807
0
  else if (IsA(jtnode, FromExpr))
1808
0
  {
1809
0
    FromExpr   *f = (FromExpr *) jtnode;
1810
1811
    /*
1812
     * Process any lateral-referencing quals that were postponed to this
1813
     * level by children.
1814
     */
1815
0
    distribute_quals_to_rels(root, jtitem->lateral_clauses,
1816
0
                 jtitem,
1817
0
                 NULL,
1818
0
                 root->qual_security_level,
1819
0
                 jtitem->qualscope,
1820
0
                 NULL, NULL, NULL,
1821
0
                 true, false, false,
1822
0
                 NULL);
1823
1824
    /*
1825
     * Now process the top-level quals.
1826
     */
1827
0
    distribute_quals_to_rels(root, (List *) f->quals,
1828
0
                 jtitem,
1829
0
                 NULL,
1830
0
                 root->qual_security_level,
1831
0
                 jtitem->qualscope,
1832
0
                 NULL, NULL, NULL,
1833
0
                 true, false, false,
1834
0
                 NULL);
1835
0
  }
1836
0
  else if (IsA(jtnode, JoinExpr))
1837
0
  {
1838
0
    JoinExpr   *j = (JoinExpr *) jtnode;
1839
0
    Relids    ojscope;
1840
0
    List     *my_quals;
1841
0
    SpecialJoinInfo *sjinfo;
1842
0
    List    **postponed_oj_qual_list;
1843
1844
    /*
1845
     * Include lateral-referencing quals postponed from children in
1846
     * my_quals, so that they'll be handled properly in
1847
     * make_outerjoininfo.  (This is destructive to
1848
     * jtitem->lateral_clauses, but we won't use that again.)
1849
     */
1850
0
    my_quals = list_concat(jtitem->lateral_clauses,
1851
0
                 (List *) j->quals);
1852
1853
    /*
1854
     * For an OJ, form the SpecialJoinInfo now, so that we can pass it to
1855
     * distribute_qual_to_rels.  We must compute its ojscope too.
1856
     *
1857
     * Semijoins are a bit of a hybrid: we build a SpecialJoinInfo, but we
1858
     * want ojscope = NULL for distribute_qual_to_rels.
1859
     */
1860
0
    if (j->jointype != JOIN_INNER)
1861
0
    {
1862
0
      sjinfo = make_outerjoininfo(root,
1863
0
                    jtitem->left_rels,
1864
0
                    jtitem->right_rels,
1865
0
                    jtitem->inner_join_rels,
1866
0
                    j->jointype,
1867
0
                    j->rtindex,
1868
0
                    my_quals);
1869
0
      jtitem->sjinfo = sjinfo;
1870
0
      if (j->jointype == JOIN_SEMI)
1871
0
        ojscope = NULL;
1872
0
      else
1873
0
        ojscope = bms_union(sjinfo->min_lefthand,
1874
0
                  sjinfo->min_righthand);
1875
0
    }
1876
0
    else
1877
0
    {
1878
0
      sjinfo = NULL;
1879
0
      ojscope = NULL;
1880
0
    }
1881
1882
    /*
1883
     * If it's a left join with a join clause that is strict for the LHS,
1884
     * then we need to postpone handling of any non-degenerate join
1885
     * clauses, in case the join is able to commute with another left join
1886
     * per identity 3.  (Degenerate clauses need not be postponed, since
1887
     * they will drop down below this join anyway.)
1888
     */
1889
0
    if (j->jointype == JOIN_LEFT && sjinfo->lhs_strict)
1890
0
    {
1891
0
      postponed_oj_qual_list = &jtitem->oj_joinclauses;
1892
1893
      /*
1894
       * Add back any commutable lower OJ relids that were removed from
1895
       * min_lefthand or min_righthand, else the ojscope cross-check in
1896
       * distribute_qual_to_rels will complain.  Since we are postponing
1897
       * processing of non-degenerate clauses, this addition doesn't
1898
       * affect anything except that cross-check.  Real clause
1899
       * positioning decisions will be made later, when we revisit the
1900
       * postponed clauses.
1901
       */
1902
0
      ojscope = bms_add_members(ojscope, sjinfo->commute_below_l);
1903
0
      ojscope = bms_add_members(ojscope, sjinfo->commute_below_r);
1904
0
    }
1905
0
    else
1906
0
      postponed_oj_qual_list = NULL;
1907
1908
    /* Process the JOIN's qual clauses */
1909
0
    distribute_quals_to_rels(root, my_quals,
1910
0
                 jtitem,
1911
0
                 sjinfo,
1912
0
                 root->qual_security_level,
1913
0
                 jtitem->qualscope,
1914
0
                 ojscope, jtitem->nonnullable_rels,
1915
0
                 NULL, /* incompatible_relids */
1916
0
                 true, /* allow_equivalence */
1917
0
                 false, false,  /* not clones */
1918
0
                 postponed_oj_qual_list);
1919
1920
    /* And add the SpecialJoinInfo to join_info_list */
1921
0
    if (sjinfo)
1922
0
      root->join_info_list = lappend(root->join_info_list, sjinfo);
1923
0
  }
1924
0
  else
1925
0
  {
1926
0
    elog(ERROR, "unrecognized node type: %d",
1927
0
       (int) nodeTag(jtnode));
1928
0
  }
1929
0
}
1930
1931
/*
1932
 * process_security_barrier_quals
1933
 *    Transfer security-barrier quals into relation's baserestrictinfo list.
1934
 *
1935
 * The rewriter put any relevant security-barrier conditions into the RTE's
1936
 * securityQuals field, but it's now time to copy them into the rel's
1937
 * baserestrictinfo.
1938
 *
1939
 * In inheritance cases, we only consider quals attached to the parent rel
1940
 * here; they will be valid for all children too, so it's okay to consider
1941
 * them for purposes like equivalence class creation.  Quals attached to
1942
 * individual child rels will be dealt with during path creation.
1943
 */
1944
static void
1945
process_security_barrier_quals(PlannerInfo *root,
1946
                 int rti, JoinTreeItem *jtitem)
1947
0
{
1948
0
  RangeTblEntry *rte = root->simple_rte_array[rti];
1949
0
  Index   security_level = 0;
1950
0
  ListCell   *lc;
1951
1952
  /*
1953
   * Each element of the securityQuals list has been preprocessed into an
1954
   * implicitly-ANDed list of clauses.  All the clauses in a given sublist
1955
   * should get the same security level, but successive sublists get higher
1956
   * levels.
1957
   */
1958
0
  foreach(lc, rte->securityQuals)
1959
0
  {
1960
0
    List     *qualset = (List *) lfirst(lc);
1961
1962
    /*
1963
     * We cheat to the extent of passing ojscope = qualscope rather than
1964
     * its more logical value of NULL.  The only effect this has is to
1965
     * force a Var-free qual to be evaluated at the rel rather than being
1966
     * pushed up to top of tree, which we don't want.
1967
     */
1968
0
    distribute_quals_to_rels(root, qualset,
1969
0
                 jtitem,
1970
0
                 NULL,
1971
0
                 security_level,
1972
0
                 jtitem->qualscope,
1973
0
                 jtitem->qualscope,
1974
0
                 NULL,
1975
0
                 NULL,
1976
0
                 true,
1977
0
                 false, false,  /* not clones */
1978
0
                 NULL);
1979
0
    security_level++;
1980
0
  }
1981
1982
  /* Assert that qual_security_level is higher than anything we just used */
1983
0
  Assert(security_level <= root->qual_security_level);
1984
0
}
1985
1986
/*
1987
 * mark_rels_nulled_by_join
1988
 *    Fill RelOptInfo.nulling_relids of baserels nulled by this outer join
1989
 *
1990
 * Inputs:
1991
 *  ojrelid: RT index of the join RTE (must not be 0)
1992
 *  lower_rels: the base+OJ Relids syntactically below nullable side of join
1993
 */
1994
static void
1995
mark_rels_nulled_by_join(PlannerInfo *root, Index ojrelid,
1996
             Relids lower_rels)
1997
0
{
1998
0
  int     relid = -1;
1999
2000
0
  while ((relid = bms_next_member(lower_rels, relid)) > 0)
2001
0
  {
2002
0
    RelOptInfo *rel = root->simple_rel_array[relid];
2003
2004
    /* ignore the RTE_GROUP RTE */
2005
0
    if (relid == root->group_rtindex)
2006
0
      continue;
2007
2008
0
    if (rel == NULL)   /* must be an outer join */
2009
0
    {
2010
0
      Assert(bms_is_member(relid, root->outer_join_rels));
2011
0
      continue;
2012
0
    }
2013
0
    rel->nulling_relids = bms_add_member(rel->nulling_relids, ojrelid);
2014
0
  }
2015
0
}
2016
2017
/*
2018
 * make_outerjoininfo
2019
 *    Build a SpecialJoinInfo for the current outer join
2020
 *
2021
 * Inputs:
2022
 *  left_rels: the base+OJ Relids syntactically on outer side of join
2023
 *  right_rels: the base+OJ Relids syntactically on inner side of join
2024
 *  inner_join_rels: base+OJ Relids participating in inner joins below this one
2025
 *  jointype: what it says (must always be LEFT, FULL, SEMI, or ANTI)
2026
 *  ojrelid: RT index of the join RTE (0 for SEMI, which isn't in the RT list)
2027
 *  clause: the outer join's join condition (in implicit-AND format)
2028
 *
2029
 * The node should eventually be appended to root->join_info_list, but we
2030
 * do not do that here.
2031
 *
2032
 * Note: we assume that this function is invoked bottom-up, so that
2033
 * root->join_info_list already contains entries for all outer joins that are
2034
 * syntactically below this one.
2035
 */
2036
static SpecialJoinInfo *
2037
make_outerjoininfo(PlannerInfo *root,
2038
           Relids left_rels, Relids right_rels,
2039
           Relids inner_join_rels,
2040
           JoinType jointype, Index ojrelid,
2041
           List *clause)
2042
0
{
2043
0
  SpecialJoinInfo *sjinfo = makeNode(SpecialJoinInfo);
2044
0
  Relids    clause_relids;
2045
0
  Relids    strict_relids;
2046
0
  Relids    min_lefthand;
2047
0
  Relids    min_righthand;
2048
0
  Relids    commute_below_l;
2049
0
  Relids    commute_below_r;
2050
0
  ListCell   *l;
2051
2052
  /*
2053
   * We should not see RIGHT JOIN here because left/right were switched
2054
   * earlier
2055
   */
2056
0
  Assert(jointype != JOIN_INNER);
2057
0
  Assert(jointype != JOIN_RIGHT);
2058
2059
  /*
2060
   * Presently the executor cannot support FOR [KEY] UPDATE/SHARE marking of
2061
   * rels appearing on the nullable side of an outer join. (It's somewhat
2062
   * unclear what that would mean, anyway: what should we mark when a result
2063
   * row is generated from no element of the nullable relation?)  So,
2064
   * complain if any nullable rel is FOR [KEY] UPDATE/SHARE.
2065
   *
2066
   * You might be wondering why this test isn't made far upstream in the
2067
   * parser.  It's because the parser hasn't got enough info --- consider
2068
   * FOR UPDATE applied to a view.  Only after rewriting and flattening do
2069
   * we know whether the view contains an outer join.
2070
   *
2071
   * We use the original RowMarkClause list here; the PlanRowMark list would
2072
   * list everything.
2073
   */
2074
0
  foreach(l, root->parse->rowMarks)
2075
0
  {
2076
0
    RowMarkClause *rc = (RowMarkClause *) lfirst(l);
2077
2078
0
    if (bms_is_member(rc->rti, right_rels) ||
2079
0
      (jointype == JOIN_FULL && bms_is_member(rc->rti, left_rels)))
2080
0
      ereport(ERROR,
2081
0
          (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2082
      /*------
2083
       translator: %s is a SQL row locking clause such as FOR UPDATE */
2084
0
           errmsg("%s cannot be applied to the nullable side of an outer join",
2085
0
              LCS_asString(rc->strength))));
2086
0
  }
2087
2088
0
  sjinfo->syn_lefthand = left_rels;
2089
0
  sjinfo->syn_righthand = right_rels;
2090
0
  sjinfo->jointype = jointype;
2091
0
  sjinfo->ojrelid = ojrelid;
2092
  /* these fields may get added to later: */
2093
0
  sjinfo->commute_above_l = NULL;
2094
0
  sjinfo->commute_above_r = NULL;
2095
0
  sjinfo->commute_below_l = NULL;
2096
0
  sjinfo->commute_below_r = NULL;
2097
2098
0
  compute_semijoin_info(root, sjinfo, clause);
2099
2100
  /* If it's a full join, no need to be very smart */
2101
0
  if (jointype == JOIN_FULL)
2102
0
  {
2103
0
    sjinfo->min_lefthand = bms_copy(left_rels);
2104
0
    sjinfo->min_righthand = bms_copy(right_rels);
2105
0
    sjinfo->lhs_strict = false; /* don't care about this */
2106
0
    return sjinfo;
2107
0
  }
2108
2109
  /*
2110
   * Retrieve all relids mentioned within the join clause.
2111
   */
2112
0
  clause_relids = pull_varnos(root, (Node *) clause);
2113
2114
  /*
2115
   * For which relids is the clause strict, ie, it cannot succeed if the
2116
   * rel's columns are all NULL?
2117
   */
2118
0
  strict_relids = find_nonnullable_rels((Node *) clause);
2119
2120
  /* Remember whether the clause is strict for any LHS relations */
2121
0
  sjinfo->lhs_strict = bms_overlap(strict_relids, left_rels);
2122
2123
  /*
2124
   * Required LHS always includes the LHS rels mentioned in the clause. We
2125
   * may have to add more rels based on lower outer joins; see below.
2126
   */
2127
0
  min_lefthand = bms_intersect(clause_relids, left_rels);
2128
2129
  /*
2130
   * Similarly for required RHS.  But here, we must also include any lower
2131
   * inner joins, to ensure we don't try to commute with any of them.
2132
   */
2133
0
  min_righthand = bms_int_members(bms_union(clause_relids, inner_join_rels),
2134
0
                  right_rels);
2135
2136
  /*
2137
   * Now check previous outer joins for ordering restrictions.
2138
   *
2139
   * commute_below_l and commute_below_r accumulate the relids of lower
2140
   * outer joins that we think this one can commute with.  These decisions
2141
   * are just tentative within this loop, since we might find an
2142
   * intermediate outer join that prevents commutation.  Surviving relids
2143
   * will get merged into the SpecialJoinInfo structs afterwards.
2144
   */
2145
0
  commute_below_l = commute_below_r = NULL;
2146
0
  foreach(l, root->join_info_list)
2147
0
  {
2148
0
    SpecialJoinInfo *otherinfo = (SpecialJoinInfo *) lfirst(l);
2149
0
    bool    have_unsafe_phvs;
2150
2151
    /*
2152
     * A full join is an optimization barrier: we can't associate into or
2153
     * out of it.  Hence, if it overlaps either LHS or RHS of the current
2154
     * rel, expand that side's min relset to cover the whole full join.
2155
     */
2156
0
    if (otherinfo->jointype == JOIN_FULL)
2157
0
    {
2158
0
      Assert(otherinfo->ojrelid != 0);
2159
0
      if (bms_overlap(left_rels, otherinfo->syn_lefthand) ||
2160
0
        bms_overlap(left_rels, otherinfo->syn_righthand))
2161
0
      {
2162
0
        min_lefthand = bms_add_members(min_lefthand,
2163
0
                         otherinfo->syn_lefthand);
2164
0
        min_lefthand = bms_add_members(min_lefthand,
2165
0
                         otherinfo->syn_righthand);
2166
0
        min_lefthand = bms_add_member(min_lefthand,
2167
0
                        otherinfo->ojrelid);
2168
0
      }
2169
0
      if (bms_overlap(right_rels, otherinfo->syn_lefthand) ||
2170
0
        bms_overlap(right_rels, otherinfo->syn_righthand))
2171
0
      {
2172
0
        min_righthand = bms_add_members(min_righthand,
2173
0
                        otherinfo->syn_lefthand);
2174
0
        min_righthand = bms_add_members(min_righthand,
2175
0
                        otherinfo->syn_righthand);
2176
0
        min_righthand = bms_add_member(min_righthand,
2177
0
                         otherinfo->ojrelid);
2178
0
      }
2179
      /* Needn't do anything else with the full join */
2180
0
      continue;
2181
0
    }
2182
2183
    /*
2184
     * If our join condition contains any PlaceHolderVars that need to be
2185
     * evaluated above the lower OJ, then we can't commute with it.
2186
     */
2187
0
    if (otherinfo->ojrelid != 0)
2188
0
      have_unsafe_phvs =
2189
0
        contain_placeholder_references_to(root,
2190
0
                          (Node *) clause,
2191
0
                          otherinfo->ojrelid);
2192
0
    else
2193
0
      have_unsafe_phvs = false;
2194
2195
    /*
2196
     * For a lower OJ in our LHS, if our join condition uses the lower
2197
     * join's RHS and is not strict for that rel, we must preserve the
2198
     * ordering of the two OJs, so add lower OJ's full syntactic relset to
2199
     * min_lefthand.  (We must use its full syntactic relset, not just its
2200
     * min_lefthand + min_righthand.  This is because there might be other
2201
     * OJs below this one that this one can commute with, but we cannot
2202
     * commute with them if we don't with this one.)  Also, if we have
2203
     * unsafe PHVs or the current join is a semijoin or antijoin, we must
2204
     * preserve ordering regardless of strictness.
2205
     *
2206
     * Note: I believe we have to insist on being strict for at least one
2207
     * rel in the lower OJ's min_righthand, not its whole syn_righthand.
2208
     *
2209
     * When we don't need to preserve ordering, check to see if outer join
2210
     * identity 3 applies, and if so, remove the lower OJ's ojrelid from
2211
     * our min_lefthand so that commutation is allowed.
2212
     */
2213
0
    if (bms_overlap(left_rels, otherinfo->syn_righthand))
2214
0
    {
2215
0
      if (bms_overlap(clause_relids, otherinfo->syn_righthand) &&
2216
0
        (have_unsafe_phvs ||
2217
0
         jointype == JOIN_SEMI || jointype == JOIN_ANTI ||
2218
0
         !bms_overlap(strict_relids, otherinfo->min_righthand)))
2219
0
      {
2220
        /* Preserve ordering */
2221
0
        min_lefthand = bms_add_members(min_lefthand,
2222
0
                         otherinfo->syn_lefthand);
2223
0
        min_lefthand = bms_add_members(min_lefthand,
2224
0
                         otherinfo->syn_righthand);
2225
0
        if (otherinfo->ojrelid != 0)
2226
0
          min_lefthand = bms_add_member(min_lefthand,
2227
0
                          otherinfo->ojrelid);
2228
0
      }
2229
0
      else if (jointype == JOIN_LEFT &&
2230
0
           otherinfo->jointype == JOIN_LEFT &&
2231
0
           bms_overlap(strict_relids, otherinfo->min_righthand) &&
2232
0
           !bms_overlap(clause_relids, otherinfo->syn_lefthand))
2233
0
      {
2234
        /* Identity 3 applies, so remove the ordering restriction */
2235
0
        min_lefthand = bms_del_member(min_lefthand, otherinfo->ojrelid);
2236
        /* Record the (still tentative) commutability relationship */
2237
0
        commute_below_l =
2238
0
          bms_add_member(commute_below_l, otherinfo->ojrelid);
2239
0
      }
2240
0
    }
2241
2242
    /*
2243
     * For a lower OJ in our RHS, if our join condition does not use the
2244
     * lower join's RHS and the lower OJ's join condition is strict, we
2245
     * can interchange the ordering of the two OJs; otherwise we must add
2246
     * the lower OJ's full syntactic relset to min_righthand.
2247
     *
2248
     * Also, if our join condition does not use the lower join's LHS
2249
     * either, force the ordering to be preserved.  Otherwise we can end
2250
     * up with SpecialJoinInfos with identical min_righthands, which can
2251
     * confuse join_is_legal (see discussion in backend/optimizer/README).
2252
     *
2253
     * Also, we must preserve ordering anyway if we have unsafe PHVs, or
2254
     * if either this join or the lower OJ is a semijoin or antijoin.
2255
     *
2256
     * When we don't need to preserve ordering, check to see if outer join
2257
     * identity 3 applies, and if so, remove the lower OJ's ojrelid from
2258
     * our min_righthand so that commutation is allowed.
2259
     */
2260
0
    if (bms_overlap(right_rels, otherinfo->syn_righthand))
2261
0
    {
2262
0
      if (bms_overlap(clause_relids, otherinfo->syn_righthand) ||
2263
0
        !bms_overlap(clause_relids, otherinfo->min_lefthand) ||
2264
0
        have_unsafe_phvs ||
2265
0
        jointype == JOIN_SEMI ||
2266
0
        jointype == JOIN_ANTI ||
2267
0
        otherinfo->jointype == JOIN_SEMI ||
2268
0
        otherinfo->jointype == JOIN_ANTI ||
2269
0
        !otherinfo->lhs_strict)
2270
0
      {
2271
        /* Preserve ordering */
2272
0
        min_righthand = bms_add_members(min_righthand,
2273
0
                        otherinfo->syn_lefthand);
2274
0
        min_righthand = bms_add_members(min_righthand,
2275
0
                        otherinfo->syn_righthand);
2276
0
        if (otherinfo->ojrelid != 0)
2277
0
          min_righthand = bms_add_member(min_righthand,
2278
0
                           otherinfo->ojrelid);
2279
0
      }
2280
0
      else if (jointype == JOIN_LEFT &&
2281
0
           otherinfo->jointype == JOIN_LEFT &&
2282
0
           otherinfo->lhs_strict)
2283
0
      {
2284
        /* Identity 3 applies, so remove the ordering restriction */
2285
0
        min_righthand = bms_del_member(min_righthand,
2286
0
                         otherinfo->ojrelid);
2287
        /* Record the (still tentative) commutability relationship */
2288
0
        commute_below_r =
2289
0
          bms_add_member(commute_below_r, otherinfo->ojrelid);
2290
0
      }
2291
0
    }
2292
0
  }
2293
2294
  /*
2295
   * Examine PlaceHolderVars.  If a PHV is supposed to be evaluated within
2296
   * this join's nullable side, then ensure that min_righthand contains the
2297
   * full eval_at set of the PHV.  This ensures that the PHV actually can be
2298
   * evaluated within the RHS.  Note that this works only because we should
2299
   * already have determined the final eval_at level for any PHV
2300
   * syntactically within this join.
2301
   */
2302
0
  foreach(l, root->placeholder_list)
2303
0
  {
2304
0
    PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(l);
2305
0
    Relids    ph_syn_level = phinfo->ph_var->phrels;
2306
2307
    /* Ignore placeholder if it didn't syntactically come from RHS */
2308
0
    if (!bms_is_subset(ph_syn_level, right_rels))
2309
0
      continue;
2310
2311
    /* Else, prevent join from being formed before we eval the PHV */
2312
0
    min_righthand = bms_add_members(min_righthand, phinfo->ph_eval_at);
2313
0
  }
2314
2315
  /*
2316
   * If we found nothing to put in min_lefthand, punt and make it the full
2317
   * LHS, to avoid having an empty min_lefthand which will confuse later
2318
   * processing. (We don't try to be smart about such cases, just correct.)
2319
   * Likewise for min_righthand.
2320
   */
2321
0
  if (bms_is_empty(min_lefthand))
2322
0
    min_lefthand = bms_copy(left_rels);
2323
0
  if (bms_is_empty(min_righthand))
2324
0
    min_righthand = bms_copy(right_rels);
2325
2326
  /* Now they'd better be nonempty */
2327
0
  Assert(!bms_is_empty(min_lefthand));
2328
0
  Assert(!bms_is_empty(min_righthand));
2329
  /* Shouldn't overlap either */
2330
0
  Assert(!bms_overlap(min_lefthand, min_righthand));
2331
2332
0
  sjinfo->min_lefthand = min_lefthand;
2333
0
  sjinfo->min_righthand = min_righthand;
2334
2335
  /*
2336
   * Now that we've identified the correct min_lefthand and min_righthand,
2337
   * any commute_below_l or commute_below_r relids that have not gotten
2338
   * added back into those sets (due to intervening outer joins) are indeed
2339
   * commutable with this one.
2340
   *
2341
   * First, delete any subsequently-added-back relids (this is easier than
2342
   * maintaining commute_below_l/r precisely through all the above).
2343
   */
2344
0
  commute_below_l = bms_del_members(commute_below_l, min_lefthand);
2345
0
  commute_below_r = bms_del_members(commute_below_r, min_righthand);
2346
2347
  /* Anything left? */
2348
0
  if (commute_below_l || commute_below_r)
2349
0
  {
2350
    /* Yup, so we must update the derived data in the SpecialJoinInfos */
2351
0
    sjinfo->commute_below_l = commute_below_l;
2352
0
    sjinfo->commute_below_r = commute_below_r;
2353
0
    foreach(l, root->join_info_list)
2354
0
    {
2355
0
      SpecialJoinInfo *otherinfo = (SpecialJoinInfo *) lfirst(l);
2356
2357
0
      if (bms_is_member(otherinfo->ojrelid, commute_below_l))
2358
0
        otherinfo->commute_above_l =
2359
0
          bms_add_member(otherinfo->commute_above_l, ojrelid);
2360
0
      else if (bms_is_member(otherinfo->ojrelid, commute_below_r))
2361
0
        otherinfo->commute_above_r =
2362
0
          bms_add_member(otherinfo->commute_above_r, ojrelid);
2363
0
    }
2364
0
  }
2365
2366
0
  return sjinfo;
2367
0
}
2368
2369
/*
2370
 * compute_semijoin_info
2371
 *    Fill semijoin-related fields of a new SpecialJoinInfo
2372
 *
2373
 * Note: this relies on only the jointype and syn_righthand fields of the
2374
 * SpecialJoinInfo; the rest may not be set yet.
2375
 */
2376
static void
2377
compute_semijoin_info(PlannerInfo *root, SpecialJoinInfo *sjinfo, List *clause)
2378
0
{
2379
0
  List     *semi_operators;
2380
0
  List     *semi_rhs_exprs;
2381
0
  bool    all_btree;
2382
0
  bool    all_hash;
2383
0
  ListCell   *lc;
2384
2385
  /* Initialize semijoin-related fields in case we can't unique-ify */
2386
0
  sjinfo->semi_can_btree = false;
2387
0
  sjinfo->semi_can_hash = false;
2388
0
  sjinfo->semi_operators = NIL;
2389
0
  sjinfo->semi_rhs_exprs = NIL;
2390
2391
  /* Nothing more to do if it's not a semijoin */
2392
0
  if (sjinfo->jointype != JOIN_SEMI)
2393
0
    return;
2394
2395
  /*
2396
   * Look to see whether the semijoin's join quals consist of AND'ed
2397
   * equality operators, with (only) RHS variables on only one side of each
2398
   * one.  If so, we can figure out how to enforce uniqueness for the RHS.
2399
   *
2400
   * Note that the input clause list is the list of quals that are
2401
   * *syntactically* associated with the semijoin, which in practice means
2402
   * the synthesized comparison list for an IN or the WHERE of an EXISTS.
2403
   * Particularly in the latter case, it might contain clauses that aren't
2404
   * *semantically* associated with the join, but refer to just one side or
2405
   * the other.  We can ignore such clauses here, as they will just drop
2406
   * down to be processed within one side or the other.  (It is okay to
2407
   * consider only the syntactically-associated clauses here because for a
2408
   * semijoin, no higher-level quals could refer to the RHS, and so there
2409
   * can be no other quals that are semantically associated with this join.
2410
   * We do things this way because it is useful to have the set of potential
2411
   * unique-ification expressions before we can extract the list of quals
2412
   * that are actually semantically associated with the particular join.)
2413
   *
2414
   * Note that the semi_operators list consists of the joinqual operators
2415
   * themselves (but commuted if needed to put the RHS value on the right).
2416
   * These could be cross-type operators, in which case the operator
2417
   * actually needed for uniqueness is a related single-type operator. We
2418
   * assume here that that operator will be available from the btree or hash
2419
   * opclass when the time comes ... if not, create_unique_plan() will fail.
2420
   */
2421
0
  semi_operators = NIL;
2422
0
  semi_rhs_exprs = NIL;
2423
0
  all_btree = true;
2424
0
  all_hash = enable_hashagg;  /* don't consider hash if not enabled */
2425
0
  foreach(lc, clause)
2426
0
  {
2427
0
    OpExpr     *op = (OpExpr *) lfirst(lc);
2428
0
    Oid     opno;
2429
0
    Node     *left_expr;
2430
0
    Node     *right_expr;
2431
0
    Relids    left_varnos;
2432
0
    Relids    right_varnos;
2433
0
    Relids    all_varnos;
2434
0
    Oid     opinputtype;
2435
2436
    /* Is it a binary opclause? */
2437
0
    if (!IsA(op, OpExpr) ||
2438
0
      list_length(op->args) != 2)
2439
0
    {
2440
      /* No, but does it reference both sides? */
2441
0
      all_varnos = pull_varnos(root, (Node *) op);
2442
0
      if (!bms_overlap(all_varnos, sjinfo->syn_righthand) ||
2443
0
        bms_is_subset(all_varnos, sjinfo->syn_righthand))
2444
0
      {
2445
        /*
2446
         * Clause refers to only one rel, so ignore it --- unless it
2447
         * contains volatile functions, in which case we'd better
2448
         * punt.
2449
         */
2450
0
        if (contain_volatile_functions((Node *) op))
2451
0
          return;
2452
0
        continue;
2453
0
      }
2454
      /* Non-operator clause referencing both sides, must punt */
2455
0
      return;
2456
0
    }
2457
2458
    /* Extract data from binary opclause */
2459
0
    opno = op->opno;
2460
0
    left_expr = linitial(op->args);
2461
0
    right_expr = lsecond(op->args);
2462
0
    left_varnos = pull_varnos(root, left_expr);
2463
0
    right_varnos = pull_varnos(root, right_expr);
2464
0
    all_varnos = bms_union(left_varnos, right_varnos);
2465
0
    opinputtype = exprType(left_expr);
2466
2467
    /* Does it reference both sides? */
2468
0
    if (!bms_overlap(all_varnos, sjinfo->syn_righthand) ||
2469
0
      bms_is_subset(all_varnos, sjinfo->syn_righthand))
2470
0
    {
2471
      /*
2472
       * Clause refers to only one rel, so ignore it --- unless it
2473
       * contains volatile functions, in which case we'd better punt.
2474
       */
2475
0
      if (contain_volatile_functions((Node *) op))
2476
0
        return;
2477
0
      continue;
2478
0
    }
2479
2480
    /* check rel membership of arguments */
2481
0
    if (!bms_is_empty(right_varnos) &&
2482
0
      bms_is_subset(right_varnos, sjinfo->syn_righthand) &&
2483
0
      !bms_overlap(left_varnos, sjinfo->syn_righthand))
2484
0
    {
2485
      /* typical case, right_expr is RHS variable */
2486
0
    }
2487
0
    else if (!bms_is_empty(left_varnos) &&
2488
0
         bms_is_subset(left_varnos, sjinfo->syn_righthand) &&
2489
0
         !bms_overlap(right_varnos, sjinfo->syn_righthand))
2490
0
    {
2491
      /* flipped case, left_expr is RHS variable */
2492
0
      opno = get_commutator(opno);
2493
0
      if (!OidIsValid(opno))
2494
0
        return;
2495
0
      right_expr = left_expr;
2496
0
    }
2497
0
    else
2498
0
    {
2499
      /* mixed membership of args, punt */
2500
0
      return;
2501
0
    }
2502
2503
    /* all operators must be btree equality or hash equality */
2504
0
    if (all_btree)
2505
0
    {
2506
      /* oprcanmerge is considered a hint... */
2507
0
      if (!op_mergejoinable(opno, opinputtype) ||
2508
0
        get_mergejoin_opfamilies(opno) == NIL)
2509
0
        all_btree = false;
2510
0
    }
2511
0
    if (all_hash)
2512
0
    {
2513
      /* ... but oprcanhash had better be correct */
2514
0
      if (!op_hashjoinable(opno, opinputtype))
2515
0
        all_hash = false;
2516
0
    }
2517
0
    if (!(all_btree || all_hash))
2518
0
      return;
2519
2520
    /*
2521
     * Ensure the RHS expression exposes the join's input collation (its
2522
     * type should be OK already); see comments for
2523
     * canonicalize_ec_expression.
2524
     */
2525
0
    right_expr = (Node *) canonicalize_ec_expression((Expr *) copyObject(right_expr),
2526
0
                             exprType(right_expr),
2527
0
                             op->inputcollid);
2528
2529
    /* so far so good, keep building lists */
2530
0
    semi_operators = lappend_oid(semi_operators, opno);
2531
0
    semi_rhs_exprs = lappend(semi_rhs_exprs, right_expr);
2532
0
  }
2533
2534
  /* Punt if we didn't find at least one column to unique-ify */
2535
0
  if (semi_rhs_exprs == NIL)
2536
0
    return;
2537
2538
  /*
2539
   * The expressions we'd need to unique-ify mustn't be volatile.
2540
   */
2541
0
  if (contain_volatile_functions((Node *) semi_rhs_exprs))
2542
0
    return;
2543
2544
  /*
2545
   * If we get here, we can unique-ify the semijoin's RHS using at least one
2546
   * of sorting and hashing.  Save the information about how to do that.
2547
   */
2548
0
  sjinfo->semi_can_btree = all_btree;
2549
0
  sjinfo->semi_can_hash = all_hash;
2550
0
  sjinfo->semi_operators = semi_operators;
2551
0
  sjinfo->semi_rhs_exprs = semi_rhs_exprs;
2552
0
}
2553
2554
/*
2555
 * deconstruct_distribute_oj_quals
2556
 *    Adjust LEFT JOIN quals to be suitable for commuted-left-join cases,
2557
 *    then push them into the joinqual lists and EquivalenceClass structures.
2558
 *
2559
 * This runs immediately after we've completed the deconstruct_distribute scan.
2560
 * jtitems contains all the JoinTreeItems (in depth-first order), and jtitem
2561
 * is one that has postponed oj_joinclauses to deal with.
2562
 */
2563
static void
2564
deconstruct_distribute_oj_quals(PlannerInfo *root,
2565
                List *jtitems,
2566
                JoinTreeItem *jtitem)
2567
0
{
2568
0
  SpecialJoinInfo *sjinfo = jtitem->sjinfo;
2569
0
  Relids    qualscope,
2570
0
        ojscope,
2571
0
        nonnullable_rels;
2572
2573
  /* Recompute syntactic and semantic scopes of this left join */
2574
0
  qualscope = bms_union(sjinfo->syn_lefthand, sjinfo->syn_righthand);
2575
0
  qualscope = bms_add_member(qualscope, sjinfo->ojrelid);
2576
0
  ojscope = bms_union(sjinfo->min_lefthand, sjinfo->min_righthand);
2577
0
  nonnullable_rels = sjinfo->syn_lefthand;
2578
2579
  /*
2580
   * If this join can commute with any other ones per outer-join identity 3,
2581
   * and it is the one providing the join clause with flexible semantics,
2582
   * then we have to generate variants of the join clause with different
2583
   * nullingrels labeling.  Otherwise, just push out the postponed clause
2584
   * as-is.
2585
   */
2586
0
  Assert(sjinfo->lhs_strict); /* else we shouldn't be here */
2587
0
  if (sjinfo->commute_above_r || sjinfo->commute_below_l)
2588
0
  {
2589
0
    Relids    joins_above;
2590
0
    Relids    joins_below;
2591
0
    Relids    incompatible_joins;
2592
0
    Relids    joins_so_far;
2593
0
    List     *quals;
2594
0
    int     save_last_rinfo_serial;
2595
0
    ListCell   *lc;
2596
2597
    /* Identify the outer joins this one commutes with */
2598
0
    joins_above = sjinfo->commute_above_r;
2599
0
    joins_below = sjinfo->commute_below_l;
2600
2601
    /*
2602
     * Generate qual variants with different sets of nullingrels bits.
2603
     *
2604
     * We only need bit-sets that correspond to the successively less
2605
     * deeply syntactically-nested subsets of this join and its
2606
     * commutators.  That's true first because obviously only those forms
2607
     * of the Vars and PHVs could appear elsewhere in the query, and
2608
     * second because the outer join identities do not provide a way to
2609
     * re-order such joins in a way that would require different marking.
2610
     * (That is, while the current join may commute with several others,
2611
     * none of those others can commute with each other.)  To visit the
2612
     * interesting joins in syntactic nesting order, we rely on the
2613
     * jtitems list to be ordered that way.
2614
     *
2615
     * We first strip out all the nullingrels bits corresponding to
2616
     * commuting joins below this one, and then successively put them back
2617
     * as we crawl up the join stack.
2618
     */
2619
0
    quals = jtitem->oj_joinclauses;
2620
0
    if (!bms_is_empty(joins_below))
2621
0
      quals = (List *) remove_nulling_relids((Node *) quals,
2622
0
                           joins_below,
2623
0
                           NULL);
2624
2625
    /*
2626
     * We'll need to mark the lower versions of the quals as not safe to
2627
     * apply above not-yet-processed joins of the stack.  This prevents
2628
     * possibly applying a cloned qual at the wrong join level.
2629
     */
2630
0
    incompatible_joins = bms_union(joins_below, joins_above);
2631
0
    incompatible_joins = bms_add_member(incompatible_joins,
2632
0
                      sjinfo->ojrelid);
2633
2634
    /*
2635
     * Each time we produce RestrictInfo(s) from these quals, reset the
2636
     * last_rinfo_serial counter, so that the RestrictInfos for the "same"
2637
     * qual condition get identical serial numbers.  (This relies on the
2638
     * fact that we're not changing the qual list in any way that'd affect
2639
     * the number of RestrictInfos built from it.) This'll allow us to
2640
     * detect duplicative qual usage later.
2641
     */
2642
0
    save_last_rinfo_serial = root->last_rinfo_serial;
2643
2644
0
    joins_so_far = NULL;
2645
0
    foreach(lc, jtitems)
2646
0
    {
2647
0
      JoinTreeItem *otherjtitem = (JoinTreeItem *) lfirst(lc);
2648
0
      SpecialJoinInfo *othersj = otherjtitem->sjinfo;
2649
0
      bool    below_sjinfo = false;
2650
0
      bool    above_sjinfo = false;
2651
0
      Relids    this_qualscope;
2652
0
      Relids    this_ojscope;
2653
0
      bool    allow_equivalence,
2654
0
            has_clone,
2655
0
            is_clone;
2656
2657
0
      if (othersj == NULL)
2658
0
        continue;   /* not an outer-join item, ignore */
2659
2660
0
      if (bms_is_member(othersj->ojrelid, joins_below))
2661
0
      {
2662
        /* othersj commutes with sjinfo from below left */
2663
0
        below_sjinfo = true;
2664
0
      }
2665
0
      else if (othersj == sjinfo)
2666
0
      {
2667
        /* found our join in syntactic order */
2668
0
        Assert(bms_equal(joins_so_far, joins_below));
2669
0
      }
2670
0
      else if (bms_is_member(othersj->ojrelid, joins_above))
2671
0
      {
2672
        /* othersj commutes with sjinfo from above */
2673
0
        above_sjinfo = true;
2674
0
      }
2675
0
      else
2676
0
      {
2677
        /* othersj is not relevant, ignore */
2678
0
        continue;
2679
0
      }
2680
2681
      /* Reset serial counter for this version of the quals */
2682
0
      root->last_rinfo_serial = save_last_rinfo_serial;
2683
2684
      /*
2685
       * When we are looking at joins above sjinfo, we are envisioning
2686
       * pushing sjinfo to above othersj, so add othersj's nulling bit
2687
       * before distributing the quals.  We should add it to Vars coming
2688
       * from the current join's LHS: we want to transform the second
2689
       * form of OJ identity 3 to the first form, in which Vars of
2690
       * relation B will appear nulled by the syntactically-upper OJ
2691
       * within the Pbc clause, but those of relation C will not.  (In
2692
       * the notation used by optimizer/README, we're converting a qual
2693
       * of the form Pbc to Pb*c.)  Of course, we must also remove that
2694
       * bit from the incompatible_joins value, else we'll make a qual
2695
       * that can't be placed anywhere.
2696
       */
2697
0
      if (above_sjinfo)
2698
0
      {
2699
0
        quals = (List *)
2700
0
          add_nulling_relids((Node *) quals,
2701
0
                     sjinfo->syn_lefthand,
2702
0
                     bms_make_singleton(othersj->ojrelid));
2703
0
        incompatible_joins = bms_del_member(incompatible_joins,
2704
0
                          othersj->ojrelid);
2705
0
      }
2706
2707
      /* Compute qualscope and ojscope for this join level */
2708
0
      this_qualscope = bms_union(qualscope, joins_so_far);
2709
0
      this_ojscope = bms_union(ojscope, joins_so_far);
2710
0
      if (above_sjinfo)
2711
0
      {
2712
        /* othersj is not yet in joins_so_far, but we need it */
2713
0
        this_qualscope = bms_add_member(this_qualscope,
2714
0
                        othersj->ojrelid);
2715
0
        this_ojscope = bms_add_member(this_ojscope,
2716
0
                        othersj->ojrelid);
2717
        /* sjinfo is in joins_so_far, and we don't want it */
2718
0
        this_ojscope = bms_del_member(this_ojscope,
2719
0
                        sjinfo->ojrelid);
2720
0
      }
2721
2722
      /*
2723
       * We generate EquivalenceClasses only from the first form of the
2724
       * quals, with the fewest nullingrels bits set.  An EC made from
2725
       * this version of the quals can be useful below the outer-join
2726
       * nest, whereas versions with some nullingrels bits set would not
2727
       * be.  We cannot generate ECs from more than one version, or
2728
       * we'll make nonsensical conclusions that Vars with nullingrels
2729
       * bits set are equal to their versions without.  Fortunately,
2730
       * such ECs wouldn't be very useful anyway, because they'd equate
2731
       * values not observable outside the join nest.  (See
2732
       * optimizer/README.)
2733
       *
2734
       * The first form of the quals is also the only one marked as
2735
       * has_clone rather than is_clone.
2736
       */
2737
0
      allow_equivalence = (joins_so_far == NULL);
2738
0
      has_clone = allow_equivalence;
2739
0
      is_clone = !has_clone;
2740
2741
0
      distribute_quals_to_rels(root, quals,
2742
0
                   otherjtitem,
2743
0
                   sjinfo,
2744
0
                   root->qual_security_level,
2745
0
                   this_qualscope,
2746
0
                   this_ojscope, nonnullable_rels,
2747
0
                   bms_copy(incompatible_joins),
2748
0
                   allow_equivalence,
2749
0
                   has_clone,
2750
0
                   is_clone,
2751
0
                   NULL); /* no more postponement */
2752
2753
      /*
2754
       * Adjust qual nulling bits for next level up, if needed.  We
2755
       * don't want to put sjinfo's own bit in at all, and if we're
2756
       * above sjinfo then we did it already.  Here, we should mark all
2757
       * Vars coming from the lower join's RHS.  (Again, we are
2758
       * converting a qual of the form Pbc to Pb*c, but now we are
2759
       * putting back bits that were there in the parser output and were
2760
       * temporarily stripped above.)  Update incompatible_joins too.
2761
       */
2762
0
      if (below_sjinfo)
2763
0
      {
2764
0
        quals = (List *)
2765
0
          add_nulling_relids((Node *) quals,
2766
0
                     othersj->syn_righthand,
2767
0
                     bms_make_singleton(othersj->ojrelid));
2768
0
        incompatible_joins = bms_del_member(incompatible_joins,
2769
0
                          othersj->ojrelid);
2770
0
      }
2771
2772
      /* ... and track joins processed so far */
2773
0
      joins_so_far = bms_add_member(joins_so_far, othersj->ojrelid);
2774
0
    }
2775
0
  }
2776
0
  else
2777
0
  {
2778
    /* No commutation possible, just process the postponed clauses */
2779
0
    distribute_quals_to_rels(root, jtitem->oj_joinclauses,
2780
0
                 jtitem,
2781
0
                 sjinfo,
2782
0
                 root->qual_security_level,
2783
0
                 qualscope,
2784
0
                 ojscope, nonnullable_rels,
2785
0
                 NULL, /* incompatible_relids */
2786
0
                 true, /* allow_equivalence */
2787
0
                 false, false,  /* not clones */
2788
0
                 NULL); /* no more postponement */
2789
0
  }
2790
0
}
2791
2792
2793
/*****************************************************************************
2794
 *
2795
 *    QUALIFICATIONS
2796
 *
2797
 *****************************************************************************/
2798
2799
/*
2800
 * distribute_quals_to_rels
2801
 *    Convenience routine to apply distribute_qual_to_rels to each element
2802
 *    of an AND'ed list of clauses.
2803
 */
2804
static void
2805
distribute_quals_to_rels(PlannerInfo *root, List *clauses,
2806
             JoinTreeItem *jtitem,
2807
             SpecialJoinInfo *sjinfo,
2808
             Index security_level,
2809
             Relids qualscope,
2810
             Relids ojscope,
2811
             Relids outerjoin_nonnullable,
2812
             Relids incompatible_relids,
2813
             bool allow_equivalence,
2814
             bool has_clone,
2815
             bool is_clone,
2816
             List **postponed_oj_qual_list)
2817
0
{
2818
0
  ListCell   *lc;
2819
2820
0
  foreach(lc, clauses)
2821
0
  {
2822
0
    Node     *clause = (Node *) lfirst(lc);
2823
2824
0
    distribute_qual_to_rels(root, clause,
2825
0
                jtitem,
2826
0
                sjinfo,
2827
0
                security_level,
2828
0
                qualscope,
2829
0
                ojscope,
2830
0
                outerjoin_nonnullable,
2831
0
                incompatible_relids,
2832
0
                allow_equivalence,
2833
0
                has_clone,
2834
0
                is_clone,
2835
0
                postponed_oj_qual_list);
2836
0
  }
2837
0
}
2838
2839
/*
2840
 * distribute_qual_to_rels
2841
 *    Add clause information to either the baserestrictinfo or joininfo list
2842
 *    (depending on whether the clause is a join) of each base relation
2843
 *    mentioned in the clause.  A RestrictInfo node is created and added to
2844
 *    the appropriate list for each rel.  Alternatively, if the clause uses a
2845
 *    mergejoinable operator, enter its left- and right-side expressions into
2846
 *    the query's EquivalenceClasses.
2847
 *
2848
 * In some cases, quals will be added to parent jtitems' lateral_clauses
2849
 * or to postponed_oj_qual_list instead of being processed right away.
2850
 * These will be dealt with in later calls of deconstruct_distribute.
2851
 *
2852
 * 'clause': the qual clause to be distributed
2853
 * 'jtitem': the JoinTreeItem for the containing jointree node
2854
 * 'sjinfo': join's SpecialJoinInfo (NULL for an inner join or WHERE clause)
2855
 * 'security_level': security_level to assign to the qual
2856
 * 'qualscope': set of base+OJ rels the qual's syntactic scope covers
2857
 * 'ojscope': NULL if not an outer-join qual, else the minimum set of base+OJ
2858
 *    rels needed to form this join
2859
 * 'outerjoin_nonnullable': NULL if not an outer-join qual, else the set of
2860
 *    base+OJ rels appearing on the outer (nonnullable) side of the join
2861
 *    (for FULL JOIN this includes both sides of the join, and must in fact
2862
 *    equal qualscope)
2863
 * 'incompatible_relids': the set of outer-join relid(s) that must not be
2864
 *    computed below this qual.  We only bother to compute this for
2865
 *    "clone" quals, otherwise it can be left NULL.
2866
 * 'allow_equivalence': true if it's okay to convert clause into an
2867
 *    EquivalenceClass
2868
 * 'has_clone': has_clone property to assign to the qual
2869
 * 'is_clone': is_clone property to assign to the qual
2870
 * 'postponed_oj_qual_list': if not NULL, non-degenerate outer join clauses
2871
 *    should be added to this list instead of being processed (list entries
2872
 *    are just the bare clauses)
2873
 *
2874
 * 'qualscope' identifies what level of JOIN the qual came from syntactically.
2875
 * 'ojscope' is needed if we decide to force the qual up to the outer-join
2876
 * level, which will be ojscope not necessarily qualscope.
2877
 */
2878
static void
2879
distribute_qual_to_rels(PlannerInfo *root, Node *clause,
2880
            JoinTreeItem *jtitem,
2881
            SpecialJoinInfo *sjinfo,
2882
            Index security_level,
2883
            Relids qualscope,
2884
            Relids ojscope,
2885
            Relids outerjoin_nonnullable,
2886
            Relids incompatible_relids,
2887
            bool allow_equivalence,
2888
            bool has_clone,
2889
            bool is_clone,
2890
            List **postponed_oj_qual_list)
2891
0
{
2892
0
  Relids    relids;
2893
0
  bool    is_pushed_down;
2894
0
  bool    pseudoconstant = false;
2895
0
  bool    maybe_equivalence;
2896
0
  bool    maybe_outer_join;
2897
0
  RestrictInfo *restrictinfo;
2898
2899
  /*
2900
   * Retrieve all relids mentioned within the clause.
2901
   */
2902
0
  relids = pull_varnos(root, clause);
2903
2904
  /*
2905
   * In ordinary SQL, a WHERE or JOIN/ON clause can't reference any rels
2906
   * that aren't within its syntactic scope; however, if we pulled up a
2907
   * LATERAL subquery then we might find such references in quals that have
2908
   * been pulled up.  We need to treat such quals as belonging to the join
2909
   * level that includes every rel they reference.  Although we could make
2910
   * pull_up_subqueries() place such quals correctly to begin with, it's
2911
   * easier to handle it here.  When we find a clause that contains Vars
2912
   * outside its syntactic scope, locate the nearest parent join level that
2913
   * includes all the required rels and add the clause to that level's
2914
   * lateral_clauses list.  We'll process it when we reach that join level.
2915
   */
2916
0
  if (!bms_is_subset(relids, qualscope))
2917
0
  {
2918
0
    JoinTreeItem *pitem;
2919
2920
0
    Assert(root->hasLateralRTEs); /* shouldn't happen otherwise */
2921
0
    Assert(sjinfo == NULL); /* mustn't postpone past outer join */
2922
0
    for (pitem = jtitem->jti_parent; pitem; pitem = pitem->jti_parent)
2923
0
    {
2924
0
      if (bms_is_subset(relids, pitem->qualscope))
2925
0
      {
2926
0
        pitem->lateral_clauses = lappend(pitem->lateral_clauses,
2927
0
                         clause);
2928
0
        return;
2929
0
      }
2930
2931
      /*
2932
       * We should not be postponing any quals past an outer join.  If
2933
       * this Assert fires, pull_up_subqueries() messed up.
2934
       */
2935
0
      Assert(pitem->sjinfo == NULL);
2936
0
    }
2937
0
    elog(ERROR, "failed to postpone qual containing lateral reference");
2938
0
  }
2939
2940
  /*
2941
   * If it's an outer-join clause, also check that relids is a subset of
2942
   * ojscope.  (This should not fail if the syntactic scope check passed.)
2943
   */
2944
0
  if (ojscope && !bms_is_subset(relids, ojscope))
2945
0
    elog(ERROR, "JOIN qualification cannot refer to other relations");
2946
2947
  /*
2948
   * If the clause is variable-free, our normal heuristic for pushing it
2949
   * down to just the mentioned rels doesn't work, because there are none.
2950
   *
2951
   * If the clause is an outer-join clause, we must force it to the OJ's
2952
   * semantic level to preserve semantics.
2953
   *
2954
   * Otherwise, when the clause contains volatile functions, we force it to
2955
   * be evaluated at its original syntactic level.  This preserves the
2956
   * expected semantics.
2957
   *
2958
   * When the clause contains no volatile functions either, it is actually a
2959
   * pseudoconstant clause that will not change value during any one
2960
   * execution of the plan, and hence can be used as a one-time qual in a
2961
   * gating Result plan node.  We put such a clause into the regular
2962
   * RestrictInfo lists for the moment, but eventually createplan.c will
2963
   * pull it out and make a gating Result node immediately above whatever
2964
   * plan node the pseudoconstant clause is assigned to.  It's usually best
2965
   * to put a gating node as high in the plan tree as possible.
2966
   */
2967
0
  if (bms_is_empty(relids))
2968
0
  {
2969
0
    if (ojscope)
2970
0
    {
2971
      /* clause is attached to outer join, eval it there */
2972
0
      relids = bms_copy(ojscope);
2973
      /* mustn't use as gating qual, so don't mark pseudoconstant */
2974
0
    }
2975
0
    else if (contain_volatile_functions(clause))
2976
0
    {
2977
      /* eval at original syntactic level */
2978
0
      relids = bms_copy(qualscope);
2979
      /* again, can't mark pseudoconstant */
2980
0
    }
2981
0
    else
2982
0
    {
2983
      /*
2984
       * If we are in the top-level join domain, we can push the qual to
2985
       * the top of the plan tree.  Otherwise, be conservative and eval
2986
       * it at original syntactic level.  (Ideally we'd push it to the
2987
       * top of the current join domain in all cases, but that causes
2988
       * problems if we later rearrange outer-join evaluation order.
2989
       * Pseudoconstant quals below the top level are a pretty odd case,
2990
       * so it's not clear that it's worth working hard on.)
2991
       */
2992
0
      if (jtitem->jdomain == (JoinDomain *) linitial(root->join_domains))
2993
0
        relids = bms_copy(jtitem->jdomain->jd_relids);
2994
0
      else
2995
0
        relids = bms_copy(qualscope);
2996
      /* mark as gating qual */
2997
0
      pseudoconstant = true;
2998
      /* tell createplan.c to check for gating quals */
2999
0
      root->hasPseudoConstantQuals = true;
3000
0
    }
3001
0
  }
3002
3003
  /*----------
3004
   * Check to see if clause application must be delayed by outer-join
3005
   * considerations.
3006
   *
3007
   * A word about is_pushed_down: we mark the qual as "pushed down" if
3008
   * it is (potentially) applicable at a level different from its original
3009
   * syntactic level.  This flag is used to distinguish OUTER JOIN ON quals
3010
   * from other quals pushed down to the same joinrel.  The rules are:
3011
   *    WHERE quals and INNER JOIN quals: is_pushed_down = true.
3012
   *    Non-degenerate OUTER JOIN quals: is_pushed_down = false.
3013
   *    Degenerate OUTER JOIN quals: is_pushed_down = true.
3014
   * A "degenerate" OUTER JOIN qual is one that doesn't mention the
3015
   * non-nullable side, and hence can be pushed down into the nullable side
3016
   * without changing the join result.  It is correct to treat it as a
3017
   * regular filter condition at the level where it is evaluated.
3018
   *
3019
   * Note: it is not immediately obvious that a simple boolean is enough
3020
   * for this: if for some reason we were to attach a degenerate qual to
3021
   * its original join level, it would need to be treated as an outer join
3022
   * qual there.  However, this cannot happen, because all the rels the
3023
   * clause mentions must be in the outer join's min_righthand, therefore
3024
   * the join it needs must be formed before the outer join; and we always
3025
   * attach quals to the lowest level where they can be evaluated.  But
3026
   * if we were ever to re-introduce a mechanism for delaying evaluation
3027
   * of "expensive" quals, this area would need work.
3028
   *
3029
   * Note: generally, use of is_pushed_down has to go through the macro
3030
   * RINFO_IS_PUSHED_DOWN, because that flag alone is not always sufficient
3031
   * to tell whether a clause must be treated as pushed-down in context.
3032
   * This seems like another reason why it should perhaps be rethought.
3033
   *----------
3034
   */
3035
0
  if (bms_overlap(relids, outerjoin_nonnullable))
3036
0
  {
3037
    /*
3038
     * The qual is attached to an outer join and mentions (some of the)
3039
     * rels on the nonnullable side, so it's not degenerate.  If the
3040
     * caller wants to postpone handling such clauses, just add it to
3041
     * postponed_oj_qual_list and return.  (The work we've done up to here
3042
     * will have to be redone later, but there's not much of it.)
3043
     */
3044
0
    if (postponed_oj_qual_list != NULL)
3045
0
    {
3046
0
      *postponed_oj_qual_list = lappend(*postponed_oj_qual_list, clause);
3047
0
      return;
3048
0
    }
3049
3050
    /*
3051
     * We can't use such a clause to deduce equivalence (the left and
3052
     * right sides might be unequal above the join because one of them has
3053
     * gone to NULL) ... but we might be able to use it for more limited
3054
     * deductions, if it is mergejoinable.  So consider adding it to the
3055
     * lists of set-aside outer-join clauses.
3056
     */
3057
0
    is_pushed_down = false;
3058
0
    maybe_equivalence = false;
3059
0
    maybe_outer_join = true;
3060
3061
    /*
3062
     * Now force the qual to be evaluated exactly at the level of joining
3063
     * corresponding to the outer join.  We cannot let it get pushed down
3064
     * into the nonnullable side, since then we'd produce no output rows,
3065
     * rather than the intended single null-extended row, for any
3066
     * nonnullable-side rows failing the qual.
3067
     */
3068
0
    Assert(ojscope);
3069
0
    relids = ojscope;
3070
0
    Assert(!pseudoconstant);
3071
0
  }
3072
0
  else
3073
0
  {
3074
    /*
3075
     * Normal qual clause or degenerate outer-join clause.  Either way, we
3076
     * can mark it as pushed-down.
3077
     */
3078
0
    is_pushed_down = true;
3079
3080
    /* Feed qual to the equivalence machinery, if allowed by caller */
3081
0
    maybe_equivalence = allow_equivalence;
3082
3083
    /*
3084
     * Since it doesn't mention the LHS, it's certainly not useful as a
3085
     * set-aside OJ clause, even if it's in an OJ.
3086
     */
3087
0
    maybe_outer_join = false;
3088
0
  }
3089
3090
  /*
3091
   * Build the RestrictInfo node itself.
3092
   */
3093
0
  restrictinfo = make_restrictinfo(root,
3094
0
                   (Expr *) clause,
3095
0
                   is_pushed_down,
3096
0
                   has_clone,
3097
0
                   is_clone,
3098
0
                   pseudoconstant,
3099
0
                   security_level,
3100
0
                   relids,
3101
0
                   incompatible_relids,
3102
0
                   outerjoin_nonnullable);
3103
3104
  /*
3105
   * If it's a join clause, add vars used in the clause to targetlists of
3106
   * their relations, so that they will be emitted by the plan nodes that
3107
   * scan those relations (else they won't be available at the join node!).
3108
   *
3109
   * Normally we mark the vars as needed at the join identified by "relids".
3110
   * However, if this is a clone clause then ignore the outer-join relids in
3111
   * that set.  Otherwise, vars appearing in a cloned clause would end up
3112
   * marked as having to propagate to the highest one of the commuting
3113
   * joins, which would often be an overestimate.  For such clauses, correct
3114
   * var propagation is ensured by making ojscope include input rels from
3115
   * both sides of the join.
3116
   *
3117
   * Note: if the clause gets absorbed into an EquivalenceClass then this
3118
   * may be unnecessary, but for now we have to do it to cover the case
3119
   * where the EC becomes ec_broken and we end up reinserting the original
3120
   * clauses into the plan.
3121
   */
3122
0
  if (bms_membership(relids) == BMS_MULTIPLE)
3123
0
  {
3124
0
    List     *vars = pull_var_clause(clause,
3125
0
                       PVC_RECURSE_AGGREGATES |
3126
0
                       PVC_RECURSE_WINDOWFUNCS |
3127
0
                       PVC_INCLUDE_PLACEHOLDERS);
3128
0
    Relids    where_needed;
3129
3130
0
    if (is_clone)
3131
0
      where_needed = bms_intersect(relids, root->all_baserels);
3132
0
    else
3133
0
      where_needed = relids;
3134
0
    add_vars_to_targetlist(root, vars, where_needed);
3135
0
    list_free(vars);
3136
0
  }
3137
3138
  /*
3139
   * We check "mergejoinability" of every clause, not only join clauses,
3140
   * because we want to know about equivalences between vars of the same
3141
   * relation, or between vars and consts.
3142
   */
3143
0
  check_mergejoinable(restrictinfo);
3144
3145
  /*
3146
   * If it is a true equivalence clause, send it to the EquivalenceClass
3147
   * machinery.  We do *not* attach it directly to any restriction or join
3148
   * lists.  The EC code will propagate it to the appropriate places later.
3149
   *
3150
   * If the clause has a mergejoinable operator, yet isn't an equivalence
3151
   * because it is an outer-join clause, the EC code may still be able to do
3152
   * something with it.  We add it to appropriate lists for further
3153
   * consideration later.  Specifically:
3154
   *
3155
   * If it is a left or right outer-join qualification that relates the two
3156
   * sides of the outer join (no funny business like leftvar1 = leftvar2 +
3157
   * rightvar), we add it to root->left_join_clauses or
3158
   * root->right_join_clauses according to which side the nonnullable
3159
   * variable appears on.
3160
   *
3161
   * If it is a full outer-join qualification, we add it to
3162
   * root->full_join_clauses.  (Ideally we'd discard cases that aren't
3163
   * leftvar = rightvar, as we do for left/right joins, but this routine
3164
   * doesn't have the info needed to do that; and the current usage of the
3165
   * full_join_clauses list doesn't require that, so it's not currently
3166
   * worth complicating this routine's API to make it possible.)
3167
   *
3168
   * If none of the above hold, pass it off to
3169
   * distribute_restrictinfo_to_rels().
3170
   *
3171
   * In all cases, it's important to initialize the left_ec and right_ec
3172
   * fields of a mergejoinable clause, so that all possibly mergejoinable
3173
   * expressions have representations in EquivalenceClasses.  If
3174
   * process_equivalence is successful, it will take care of that;
3175
   * otherwise, we have to call initialize_mergeclause_eclasses to do it.
3176
   */
3177
0
  if (restrictinfo->mergeopfamilies)
3178
0
  {
3179
0
    if (maybe_equivalence)
3180
0
    {
3181
0
      if (process_equivalence(root, &restrictinfo, jtitem->jdomain))
3182
0
        return;
3183
      /* EC rejected it, so set left_ec/right_ec the hard way ... */
3184
0
      if (restrictinfo->mergeopfamilies) /* EC might have changed this */
3185
0
        initialize_mergeclause_eclasses(root, restrictinfo);
3186
      /* ... and fall through to distribute_restrictinfo_to_rels */
3187
0
    }
3188
0
    else if (maybe_outer_join && restrictinfo->can_join)
3189
0
    {
3190
      /* we need to set up left_ec/right_ec the hard way */
3191
0
      initialize_mergeclause_eclasses(root, restrictinfo);
3192
      /* now see if it should go to any outer-join lists */
3193
0
      Assert(sjinfo != NULL);
3194
0
      if (bms_is_subset(restrictinfo->left_relids,
3195
0
                outerjoin_nonnullable) &&
3196
0
        !bms_overlap(restrictinfo->right_relids,
3197
0
               outerjoin_nonnullable))
3198
0
      {
3199
        /* we have outervar = innervar */
3200
0
        OuterJoinClauseInfo *ojcinfo = makeNode(OuterJoinClauseInfo);
3201
3202
0
        ojcinfo->rinfo = restrictinfo;
3203
0
        ojcinfo->sjinfo = sjinfo;
3204
0
        root->left_join_clauses = lappend(root->left_join_clauses,
3205
0
                          ojcinfo);
3206
0
        return;
3207
0
      }
3208
0
      if (bms_is_subset(restrictinfo->right_relids,
3209
0
                outerjoin_nonnullable) &&
3210
0
        !bms_overlap(restrictinfo->left_relids,
3211
0
               outerjoin_nonnullable))
3212
0
      {
3213
        /* we have innervar = outervar */
3214
0
        OuterJoinClauseInfo *ojcinfo = makeNode(OuterJoinClauseInfo);
3215
3216
0
        ojcinfo->rinfo = restrictinfo;
3217
0
        ojcinfo->sjinfo = sjinfo;
3218
0
        root->right_join_clauses = lappend(root->right_join_clauses,
3219
0
                           ojcinfo);
3220
0
        return;
3221
0
      }
3222
0
      if (sjinfo->jointype == JOIN_FULL)
3223
0
      {
3224
        /* FULL JOIN (above tests cannot match in this case) */
3225
0
        OuterJoinClauseInfo *ojcinfo = makeNode(OuterJoinClauseInfo);
3226
3227
0
        ojcinfo->rinfo = restrictinfo;
3228
0
        ojcinfo->sjinfo = sjinfo;
3229
0
        root->full_join_clauses = lappend(root->full_join_clauses,
3230
0
                          ojcinfo);
3231
0
        return;
3232
0
      }
3233
      /* nope, so fall through to distribute_restrictinfo_to_rels */
3234
0
    }
3235
0
    else
3236
0
    {
3237
      /* we still need to set up left_ec/right_ec */
3238
0
      initialize_mergeclause_eclasses(root, restrictinfo);
3239
0
    }
3240
0
  }
3241
3242
  /* No EC special case applies, so push it into the clause lists */
3243
0
  distribute_restrictinfo_to_rels(root, restrictinfo);
3244
0
}
3245
3246
/*
3247
 * add_base_clause_to_rel
3248
 *    Add 'restrictinfo' as a baserestrictinfo to the base relation denoted
3249
 *    by 'relid'.  We offer some simple prechecks to try to determine if the
3250
 *    qual is always true, in which case we ignore it rather than add it.
3251
 *    If we detect the qual is always false, we replace it with
3252
 *    constant-FALSE.
3253
 */
3254
static void
3255
add_base_clause_to_rel(PlannerInfo *root, Index relid,
3256
             RestrictInfo *restrictinfo)
3257
0
{
3258
0
  RelOptInfo *rel = find_base_rel(root, relid);
3259
0
  RangeTblEntry *rte = root->simple_rte_array[relid];
3260
3261
0
  Assert(bms_membership(restrictinfo->required_relids) == BMS_SINGLETON);
3262
3263
  /*
3264
   * For inheritance parent tables, we must always record the RestrictInfo
3265
   * in baserestrictinfo as is.  If we were to transform or skip adding it,
3266
   * then the original wouldn't be available in apply_child_basequals. Since
3267
   * there are two RangeTblEntries for inheritance parents, one with
3268
   * inh==true and the other with inh==false, we're still able to apply this
3269
   * optimization to the inh==false one.  The inh==true one is what
3270
   * apply_child_basequals() sees, whereas the inh==false one is what's used
3271
   * for the scan node in the final plan.
3272
   *
3273
   * We make an exception to this for partitioned tables.  For these, we
3274
   * always apply the constant-TRUE and constant-FALSE transformations.  A
3275
   * qual which is either of these for a partitioned table must also be that
3276
   * for all of its child partitions.
3277
   */
3278
0
  if (!rte->inh || rte->relkind == RELKIND_PARTITIONED_TABLE)
3279
0
  {
3280
    /* Don't add the clause if it is always true */
3281
0
    if (restriction_is_always_true(root, restrictinfo))
3282
0
      return;
3283
3284
    /*
3285
     * Substitute the origin qual with constant-FALSE if it is provably
3286
     * always false.
3287
     *
3288
     * Note that we need to keep the same rinfo_serial, since it is in
3289
     * practice the same condition.  We also need to reset the
3290
     * last_rinfo_serial counter, which is essential to ensure that the
3291
     * RestrictInfos for the "same" qual condition get identical serial
3292
     * numbers (see deconstruct_distribute_oj_quals).
3293
     */
3294
0
    if (restriction_is_always_false(root, restrictinfo))
3295
0
    {
3296
0
      int     save_rinfo_serial = restrictinfo->rinfo_serial;
3297
0
      int     save_last_rinfo_serial = root->last_rinfo_serial;
3298
3299
0
      restrictinfo = make_restrictinfo(root,
3300
0
                       (Expr *) makeBoolConst(false, false),
3301
0
                       restrictinfo->is_pushed_down,
3302
0
                       restrictinfo->has_clone,
3303
0
                       restrictinfo->is_clone,
3304
0
                       restrictinfo->pseudoconstant,
3305
0
                       0, /* security_level */
3306
0
                       restrictinfo->required_relids,
3307
0
                       restrictinfo->incompatible_relids,
3308
0
                       restrictinfo->outer_relids);
3309
0
      restrictinfo->rinfo_serial = save_rinfo_serial;
3310
0
      root->last_rinfo_serial = save_last_rinfo_serial;
3311
0
    }
3312
0
  }
3313
3314
  /* Add clause to rel's restriction list */
3315
0
  rel->baserestrictinfo = lappend(rel->baserestrictinfo, restrictinfo);
3316
3317
  /* Update security level info */
3318
0
  rel->baserestrict_min_security = Min(rel->baserestrict_min_security,
3319
0
                     restrictinfo->security_level);
3320
0
}
3321
3322
/*
3323
 * restriction_is_always_true
3324
 *    Check to see if the RestrictInfo is always true.
3325
 *
3326
 * Currently we only check for NullTest quals and OR clauses that include
3327
 * NullTest quals.  We may extend it in the future.
3328
 */
3329
bool
3330
restriction_is_always_true(PlannerInfo *root,
3331
               RestrictInfo *restrictinfo)
3332
0
{
3333
  /*
3334
   * For a clone clause, we don't have a reliable way to determine if the
3335
   * input expression of a NullTest is non-nullable: nullingrel bits in
3336
   * clone clauses may not reflect reality, so we dare not draw conclusions
3337
   * from clones about whether Vars are guaranteed not-null.
3338
   */
3339
0
  if (restrictinfo->has_clone || restrictinfo->is_clone)
3340
0
    return false;
3341
3342
  /* Check for NullTest qual */
3343
0
  if (IsA(restrictinfo->clause, NullTest))
3344
0
  {
3345
0
    NullTest   *nulltest = (NullTest *) restrictinfo->clause;
3346
3347
    /* is this NullTest an IS_NOT_NULL qual? */
3348
0
    if (nulltest->nulltesttype != IS_NOT_NULL)
3349
0
      return false;
3350
3351
    /*
3352
     * Empty rows can appear NULL in some contexts and NOT NULL in others,
3353
     * so avoid this optimization for row expressions.
3354
     */
3355
0
    if (nulltest->argisrow)
3356
0
      return false;
3357
3358
0
    return expr_is_nonnullable(root, nulltest->arg, NOTNULL_SOURCE_RELOPT);
3359
0
  }
3360
3361
  /* If it's an OR, check its sub-clauses */
3362
0
  if (restriction_is_or_clause(restrictinfo))
3363
0
  {
3364
0
    ListCell   *lc;
3365
3366
0
    Assert(is_orclause(restrictinfo->orclause));
3367
3368
    /*
3369
     * if any of the given OR branches is provably always true then the
3370
     * entire condition is true.
3371
     */
3372
0
    foreach(lc, ((BoolExpr *) restrictinfo->orclause)->args)
3373
0
    {
3374
0
      Node     *orarg = (Node *) lfirst(lc);
3375
3376
0
      if (!IsA(orarg, RestrictInfo))
3377
0
        continue;
3378
3379
0
      if (restriction_is_always_true(root, (RestrictInfo *) orarg))
3380
0
        return true;
3381
0
    }
3382
0
  }
3383
3384
0
  return false;
3385
0
}
3386
3387
/*
3388
 * restriction_is_always_false
3389
 *    Check to see if the RestrictInfo is always false.
3390
 *
3391
 * Currently we only check for NullTest quals and OR clauses that include
3392
 * NullTest quals.  We may extend it in the future.
3393
 */
3394
bool
3395
restriction_is_always_false(PlannerInfo *root,
3396
              RestrictInfo *restrictinfo)
3397
0
{
3398
  /*
3399
   * For a clone clause, we don't have a reliable way to determine if the
3400
   * input expression of a NullTest is non-nullable: nullingrel bits in
3401
   * clone clauses may not reflect reality, so we dare not draw conclusions
3402
   * from clones about whether Vars are guaranteed not-null.
3403
   */
3404
0
  if (restrictinfo->has_clone || restrictinfo->is_clone)
3405
0
    return false;
3406
3407
  /* Check for NullTest qual */
3408
0
  if (IsA(restrictinfo->clause, NullTest))
3409
0
  {
3410
0
    NullTest   *nulltest = (NullTest *) restrictinfo->clause;
3411
3412
    /* is this NullTest an IS_NULL qual? */
3413
0
    if (nulltest->nulltesttype != IS_NULL)
3414
0
      return false;
3415
3416
    /*
3417
     * Empty rows can appear NULL in some contexts and NOT NULL in others,
3418
     * so avoid this optimization for row expressions.
3419
     */
3420
0
    if (nulltest->argisrow)
3421
0
      return false;
3422
3423
0
    return expr_is_nonnullable(root, nulltest->arg, NOTNULL_SOURCE_RELOPT);
3424
0
  }
3425
3426
  /* If it's an OR, check its sub-clauses */
3427
0
  if (restriction_is_or_clause(restrictinfo))
3428
0
  {
3429
0
    ListCell   *lc;
3430
3431
0
    Assert(is_orclause(restrictinfo->orclause));
3432
3433
    /*
3434
     * Currently, when processing OR expressions, we only return true when
3435
     * all of the OR branches are always false.  This could perhaps be
3436
     * expanded to remove OR branches that are provably false.  This may
3437
     * be a useful thing to do as it could result in the OR being left
3438
     * with a single arg.  That's useful as it would allow the OR
3439
     * condition to be replaced with its single argument which may allow
3440
     * use of an index for faster filtering on the remaining condition.
3441
     */
3442
0
    foreach(lc, ((BoolExpr *) restrictinfo->orclause)->args)
3443
0
    {
3444
0
      Node     *orarg = (Node *) lfirst(lc);
3445
3446
0
      if (!IsA(orarg, RestrictInfo) ||
3447
0
        !restriction_is_always_false(root, (RestrictInfo *) orarg))
3448
0
        return false;
3449
0
    }
3450
0
    return true;
3451
0
  }
3452
3453
0
  return false;
3454
0
}
3455
3456
/*
3457
 * distribute_restrictinfo_to_rels
3458
 *    Push a completed RestrictInfo into the proper restriction or join
3459
 *    clause list(s).
3460
 *
3461
 * This is the last step of distribute_qual_to_rels() for ordinary qual
3462
 * clauses.  Clauses that are interesting for equivalence-class processing
3463
 * are diverted to the EC machinery, but may ultimately get fed back here.
3464
 */
3465
void
3466
distribute_restrictinfo_to_rels(PlannerInfo *root,
3467
                RestrictInfo *restrictinfo)
3468
0
{
3469
0
  Relids    relids = restrictinfo->required_relids;
3470
3471
0
  if (!bms_is_empty(relids))
3472
0
  {
3473
0
    int     relid;
3474
3475
0
    if (bms_get_singleton_member(relids, &relid))
3476
0
    {
3477
      /*
3478
       * There is only one relation participating in the clause, so it
3479
       * is a restriction clause for that relation.
3480
       */
3481
0
      add_base_clause_to_rel(root, relid, restrictinfo);
3482
0
    }
3483
0
    else
3484
0
    {
3485
      /*
3486
       * The clause is a join clause, since there is more than one rel
3487
       * in its relid set.
3488
       */
3489
3490
      /*
3491
       * Check for hashjoinable operators.  (We don't bother setting the
3492
       * hashjoin info except in true join clauses.)
3493
       */
3494
0
      check_hashjoinable(restrictinfo);
3495
3496
      /*
3497
       * Likewise, check if the clause is suitable to be used with a
3498
       * Memoize node to cache inner tuples during a parameterized
3499
       * nested loop.
3500
       */
3501
0
      check_memoizable(restrictinfo);
3502
3503
      /*
3504
       * Add clause to the join lists of all the relevant relations.
3505
       */
3506
0
      add_join_clause_to_rels(root, restrictinfo, relids);
3507
0
    }
3508
0
  }
3509
0
  else
3510
0
  {
3511
    /*
3512
     * clause references no rels, and therefore we have no place to attach
3513
     * it.  Shouldn't get here if callers are working properly.
3514
     */
3515
0
    elog(ERROR, "cannot cope with variable-free clause");
3516
0
  }
3517
0
}
3518
3519
/*
3520
 * process_implied_equality
3521
 *    Create a restrictinfo item that says "item1 op item2", and push it
3522
 *    into the appropriate lists.  (In practice opno is always a btree
3523
 *    equality operator.)
3524
 *
3525
 * "qualscope" is the nominal syntactic level to impute to the restrictinfo.
3526
 * This must contain at least all the rels used in the expressions, but it
3527
 * is used only to set the qual application level when both exprs are
3528
 * variable-free.  (Hence, it should usually match the join domain in which
3529
 * the clause applies.)  Otherwise the qual is applied at the lowest join
3530
 * level that provides all its variables.
3531
 *
3532
 * "security_level" is the security level to assign to the new restrictinfo.
3533
 *
3534
 * "both_const" indicates whether both items are known pseudo-constant;
3535
 * in this case it is worth applying eval_const_expressions() in case we
3536
 * can produce constant TRUE or constant FALSE.  (Otherwise it's not,
3537
 * because the expressions went through eval_const_expressions already.)
3538
 *
3539
 * Returns the generated RestrictInfo, if any.  The result will be NULL
3540
 * if both_const is true and we successfully reduced the clause to
3541
 * constant TRUE.
3542
 *
3543
 * Note: this function will copy item1 and item2, but it is caller's
3544
 * responsibility to make sure that the Relids parameters are fresh copies
3545
 * not shared with other uses.
3546
 *
3547
 * Note: we do not do initialize_mergeclause_eclasses() here.  It is
3548
 * caller's responsibility that left_ec/right_ec be set as necessary.
3549
 */
3550
RestrictInfo *
3551
process_implied_equality(PlannerInfo *root,
3552
             Oid opno,
3553
             Oid collation,
3554
             Expr *item1,
3555
             Expr *item2,
3556
             Relids qualscope,
3557
             Index security_level,
3558
             bool both_const)
3559
0
{
3560
0
  RestrictInfo *restrictinfo;
3561
0
  Node     *clause;
3562
0
  Relids    relids;
3563
0
  bool    pseudoconstant = false;
3564
3565
  /*
3566
   * Build the new clause.  Copy to ensure it shares no substructure with
3567
   * original (this is necessary in case there are subselects in there...)
3568
   */
3569
0
  clause = (Node *) make_opclause(opno,
3570
0
                  BOOLOID, /* opresulttype */
3571
0
                  false,  /* opretset */
3572
0
                  copyObject(item1),
3573
0
                  copyObject(item2),
3574
0
                  InvalidOid,
3575
0
                  collation);
3576
3577
  /* If both constant, try to reduce to a boolean constant. */
3578
0
  if (both_const)
3579
0
  {
3580
0
    clause = eval_const_expressions(root, clause);
3581
3582
    /* If we produced const TRUE, just drop the clause */
3583
0
    if (clause && IsA(clause, Const))
3584
0
    {
3585
0
      Const    *cclause = (Const *) clause;
3586
3587
0
      Assert(cclause->consttype == BOOLOID);
3588
0
      if (!cclause->constisnull && DatumGetBool(cclause->constvalue))
3589
0
        return NULL;
3590
0
    }
3591
0
  }
3592
3593
  /*
3594
   * The rest of this is a very cut-down version of distribute_qual_to_rels.
3595
   * We can skip most of the work therein, but there are a couple of special
3596
   * cases we still have to handle.
3597
   *
3598
   * Retrieve all relids mentioned within the possibly-simplified clause.
3599
   */
3600
0
  relids = pull_varnos(root, clause);
3601
0
  Assert(bms_is_subset(relids, qualscope));
3602
3603
  /*
3604
   * If the clause is variable-free, our normal heuristic for pushing it
3605
   * down to just the mentioned rels doesn't work, because there are none.
3606
   * Apply it as a gating qual at the appropriate level (see comments for
3607
   * get_join_domain_min_rels).
3608
   */
3609
0
  if (bms_is_empty(relids))
3610
0
  {
3611
    /* eval at join domain's safe level */
3612
0
    relids = get_join_domain_min_rels(root, qualscope);
3613
    /* mark as gating qual */
3614
0
    pseudoconstant = true;
3615
    /* tell createplan.c to check for gating quals */
3616
0
    root->hasPseudoConstantQuals = true;
3617
0
  }
3618
3619
  /*
3620
   * Build the RestrictInfo node itself.
3621
   */
3622
0
  restrictinfo = make_restrictinfo(root,
3623
0
                   (Expr *) clause,
3624
0
                   true, /* is_pushed_down */
3625
0
                   false, /* !has_clone */
3626
0
                   false, /* !is_clone */
3627
0
                   pseudoconstant,
3628
0
                   security_level,
3629
0
                   relids,
3630
0
                   NULL, /* incompatible_relids */
3631
0
                   NULL); /* outer_relids */
3632
3633
  /*
3634
   * If it's a join clause, add vars used in the clause to targetlists of
3635
   * their relations, so that they will be emitted by the plan nodes that
3636
   * scan those relations (else they won't be available at the join node!).
3637
   *
3638
   * Typically, we'd have already done this when the component expressions
3639
   * were first seen by distribute_qual_to_rels; but it is possible that
3640
   * some of the Vars could have missed having that done because they only
3641
   * appeared in single-relation clauses originally.  So do it here for
3642
   * safety.
3643
   */
3644
0
  if (bms_membership(relids) == BMS_MULTIPLE)
3645
0
  {
3646
0
    List     *vars = pull_var_clause(clause,
3647
0
                       PVC_RECURSE_AGGREGATES |
3648
0
                       PVC_RECURSE_WINDOWFUNCS |
3649
0
                       PVC_INCLUDE_PLACEHOLDERS);
3650
3651
0
    add_vars_to_targetlist(root, vars, relids);
3652
0
    list_free(vars);
3653
0
  }
3654
3655
  /*
3656
   * Check mergejoinability.  This will usually succeed, since the op came
3657
   * from an EquivalenceClass; but we could have reduced the original clause
3658
   * to a constant.
3659
   */
3660
0
  check_mergejoinable(restrictinfo);
3661
3662
  /*
3663
   * Note we don't do initialize_mergeclause_eclasses(); the caller can
3664
   * handle that much more cheaply than we can.  It's okay to call
3665
   * distribute_restrictinfo_to_rels() before that happens.
3666
   */
3667
3668
  /*
3669
   * Push the new clause into all the appropriate restrictinfo lists.
3670
   */
3671
0
  distribute_restrictinfo_to_rels(root, restrictinfo);
3672
3673
0
  return restrictinfo;
3674
0
}
3675
3676
/*
3677
 * build_implied_join_equality --- build a RestrictInfo for a derived equality
3678
 *
3679
 * This overlaps the functionality of process_implied_equality(), but we
3680
 * must not push the RestrictInfo into the joininfo tree.
3681
 *
3682
 * Note: this function will copy item1 and item2, but it is caller's
3683
 * responsibility to make sure that the Relids parameters are fresh copies
3684
 * not shared with other uses.
3685
 *
3686
 * Note: we do not do initialize_mergeclause_eclasses() here.  It is
3687
 * caller's responsibility that left_ec/right_ec be set as necessary.
3688
 */
3689
RestrictInfo *
3690
build_implied_join_equality(PlannerInfo *root,
3691
              Oid opno,
3692
              Oid collation,
3693
              Expr *item1,
3694
              Expr *item2,
3695
              Relids qualscope,
3696
              Index security_level)
3697
0
{
3698
0
  RestrictInfo *restrictinfo;
3699
0
  Expr     *clause;
3700
3701
  /*
3702
   * Build the new clause.  Copy to ensure it shares no substructure with
3703
   * original (this is necessary in case there are subselects in there...)
3704
   */
3705
0
  clause = make_opclause(opno,
3706
0
               BOOLOID, /* opresulttype */
3707
0
               false,  /* opretset */
3708
0
               copyObject(item1),
3709
0
               copyObject(item2),
3710
0
               InvalidOid,
3711
0
               collation);
3712
3713
  /*
3714
   * Build the RestrictInfo node itself.
3715
   */
3716
0
  restrictinfo = make_restrictinfo(root,
3717
0
                   clause,
3718
0
                   true, /* is_pushed_down */
3719
0
                   false, /* !has_clone */
3720
0
                   false, /* !is_clone */
3721
0
                   false, /* pseudoconstant */
3722
0
                   security_level,  /* security_level */
3723
0
                   qualscope, /* required_relids */
3724
0
                   NULL, /* incompatible_relids */
3725
0
                   NULL); /* outer_relids */
3726
3727
  /* Set mergejoinability/hashjoinability flags */
3728
0
  check_mergejoinable(restrictinfo);
3729
0
  check_hashjoinable(restrictinfo);
3730
0
  check_memoizable(restrictinfo);
3731
3732
0
  return restrictinfo;
3733
0
}
3734
3735
/*
3736
 * get_join_domain_min_rels
3737
 *    Identify the appropriate join level for derived quals belonging
3738
 *    to the join domain with the given relids.
3739
 *
3740
 * When we derive a pseudoconstant (Var-free) clause from an EquivalenceClass,
3741
 * we'd ideally apply the clause at the top level of the EC's join domain.
3742
 * However, if there are any outer joins inside that domain that get commuted
3743
 * with joins outside it, that leads to not finding a correct place to apply
3744
 * the clause.  Instead, remove any lower outer joins from the relid set,
3745
 * and apply the clause to just the remaining rels.  This still results in a
3746
 * correct answer, since if the clause produces FALSE then the LHS of these
3747
 * joins will be empty leading to an empty join result.
3748
 *
3749
 * However, there's no need to remove outer joins if this is the top-level
3750
 * join domain of the query, since then there's nothing else to commute with.
3751
 *
3752
 * Note: it's tempting to use this in distribute_qual_to_rels where it's
3753
 * dealing with pseudoconstant quals; but we can't because the necessary
3754
 * SpecialJoinInfos aren't all formed at that point.
3755
 *
3756
 * The result is always freshly palloc'd; we do not modify domain_relids.
3757
 */
3758
static Relids
3759
get_join_domain_min_rels(PlannerInfo *root, Relids domain_relids)
3760
0
{
3761
0
  Relids    result = bms_copy(domain_relids);
3762
0
  ListCell   *lc;
3763
3764
  /* Top-level join domain? */
3765
0
  if (bms_equal(result, root->all_query_rels))
3766
0
    return result;
3767
3768
  /* Nope, look for lower outer joins that could potentially commute out */
3769
0
  foreach(lc, root->join_info_list)
3770
0
  {
3771
0
    SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(lc);
3772
3773
0
    if (sjinfo->jointype == JOIN_LEFT &&
3774
0
      bms_is_member(sjinfo->ojrelid, result))
3775
0
    {
3776
0
      result = bms_del_member(result, sjinfo->ojrelid);
3777
0
      result = bms_del_members(result, sjinfo->syn_righthand);
3778
0
    }
3779
0
  }
3780
0
  return result;
3781
0
}
3782
3783
3784
/*
3785
 * match_foreign_keys_to_quals
3786
 *    Match foreign-key constraints to equivalence classes and join quals
3787
 *
3788
 * The idea here is to see which query join conditions match equality
3789
 * constraints of a foreign-key relationship.  For such join conditions,
3790
 * we can use the FK semantics to make selectivity estimates that are more
3791
 * reliable than estimating from statistics, especially for multiple-column
3792
 * FKs, where the normal assumption of independent conditions tends to fail.
3793
 *
3794
 * In this function we annotate the ForeignKeyOptInfos in root->fkey_list
3795
 * with info about which eclasses and join qual clauses they match, and
3796
 * discard any ForeignKeyOptInfos that are irrelevant for the query.
3797
 */
3798
void
3799
match_foreign_keys_to_quals(PlannerInfo *root)
3800
0
{
3801
0
  List     *newlist = NIL;
3802
0
  ListCell   *lc;
3803
3804
0
  foreach(lc, root->fkey_list)
3805
0
  {
3806
0
    ForeignKeyOptInfo *fkinfo = (ForeignKeyOptInfo *) lfirst(lc);
3807
0
    RelOptInfo *con_rel;
3808
0
    RelOptInfo *ref_rel;
3809
0
    int     colno;
3810
3811
    /*
3812
     * Either relid might identify a rel that is in the query's rtable but
3813
     * isn't referenced by the jointree (typically because it's been
3814
     * removed by join removal), so that it won't have a RelOptInfo. Hence
3815
     * don't use find_base_rel() here.  We can ignore such FKs.
3816
     */
3817
0
    if (fkinfo->con_relid >= root->simple_rel_array_size ||
3818
0
      fkinfo->ref_relid >= root->simple_rel_array_size)
3819
0
      continue;     /* just paranoia */
3820
0
    con_rel = root->simple_rel_array[fkinfo->con_relid];
3821
0
    if (con_rel == NULL)
3822
0
      continue;
3823
0
    ref_rel = root->simple_rel_array[fkinfo->ref_relid];
3824
0
    if (ref_rel == NULL)
3825
0
      continue;
3826
3827
    /*
3828
     * Ignore FK unless both rels are baserels.  This gets rid of FKs that
3829
     * link to inheritance child rels (otherrels).
3830
     */
3831
0
    if (con_rel->reloptkind != RELOPT_BASEREL ||
3832
0
      ref_rel->reloptkind != RELOPT_BASEREL)
3833
0
      continue;
3834
3835
    /*
3836
     * Scan the columns and try to match them to eclasses and quals.
3837
     *
3838
     * Note: for simple inner joins, any match should be in an eclass.
3839
     * "Loose" quals that syntactically match an FK equality must have
3840
     * been rejected for EC status because they are outer-join quals or
3841
     * similar.  We can still consider them to match the FK.
3842
     */
3843
0
    for (colno = 0; colno < fkinfo->nkeys; colno++)
3844
0
    {
3845
0
      EquivalenceClass *ec;
3846
0
      AttrNumber  con_attno,
3847
0
            ref_attno;
3848
0
      Oid     fpeqop;
3849
0
      ListCell   *lc2;
3850
3851
0
      ec = match_eclasses_to_foreign_key_col(root, fkinfo, colno);
3852
      /* Don't bother looking for loose quals if we got an EC match */
3853
0
      if (ec != NULL)
3854
0
      {
3855
0
        fkinfo->nmatched_ec++;
3856
0
        if (ec->ec_has_const)
3857
0
          fkinfo->nconst_ec++;
3858
0
        continue;
3859
0
      }
3860
3861
      /*
3862
       * Scan joininfo list for relevant clauses.  Either rel's joininfo
3863
       * list would do equally well; we use con_rel's.
3864
       */
3865
0
      con_attno = fkinfo->conkey[colno];
3866
0
      ref_attno = fkinfo->confkey[colno];
3867
0
      fpeqop = InvalidOid; /* we'll look this up only if needed */
3868
3869
0
      foreach(lc2, con_rel->joininfo)
3870
0
      {
3871
0
        RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc2);
3872
0
        OpExpr     *clause = (OpExpr *) rinfo->clause;
3873
0
        Var      *leftvar;
3874
0
        Var      *rightvar;
3875
3876
        /* Only binary OpExprs are useful for consideration */
3877
0
        if (!IsA(clause, OpExpr) ||
3878
0
          list_length(clause->args) != 2)
3879
0
          continue;
3880
0
        leftvar = (Var *) get_leftop((Expr *) clause);
3881
0
        rightvar = (Var *) get_rightop((Expr *) clause);
3882
3883
        /* Operands must be Vars, possibly with RelabelType */
3884
0
        while (leftvar && IsA(leftvar, RelabelType))
3885
0
          leftvar = (Var *) ((RelabelType *) leftvar)->arg;
3886
0
        if (!(leftvar && IsA(leftvar, Var)))
3887
0
          continue;
3888
0
        while (rightvar && IsA(rightvar, RelabelType))
3889
0
          rightvar = (Var *) ((RelabelType *) rightvar)->arg;
3890
0
        if (!(rightvar && IsA(rightvar, Var)))
3891
0
          continue;
3892
3893
        /* Now try to match the vars to the current foreign key cols */
3894
0
        if (fkinfo->ref_relid == leftvar->varno &&
3895
0
          ref_attno == leftvar->varattno &&
3896
0
          fkinfo->con_relid == rightvar->varno &&
3897
0
          con_attno == rightvar->varattno)
3898
0
        {
3899
          /* Vars match, but is it the right operator? */
3900
0
          if (clause->opno == fkinfo->conpfeqop[colno])
3901
0
          {
3902
0
            fkinfo->rinfos[colno] = lappend(fkinfo->rinfos[colno],
3903
0
                            rinfo);
3904
0
            fkinfo->nmatched_ri++;
3905
0
          }
3906
0
        }
3907
0
        else if (fkinfo->ref_relid == rightvar->varno &&
3908
0
             ref_attno == rightvar->varattno &&
3909
0
             fkinfo->con_relid == leftvar->varno &&
3910
0
             con_attno == leftvar->varattno)
3911
0
        {
3912
          /*
3913
           * Reverse match, must check commutator operator.  Look it
3914
           * up if we didn't already.  (In the worst case we might
3915
           * do multiple lookups here, but that would require an FK
3916
           * equality operator without commutator, which is
3917
           * unlikely.)
3918
           */
3919
0
          if (!OidIsValid(fpeqop))
3920
0
            fpeqop = get_commutator(fkinfo->conpfeqop[colno]);
3921
0
          if (clause->opno == fpeqop)
3922
0
          {
3923
0
            fkinfo->rinfos[colno] = lappend(fkinfo->rinfos[colno],
3924
0
                            rinfo);
3925
0
            fkinfo->nmatched_ri++;
3926
0
          }
3927
0
        }
3928
0
      }
3929
      /* If we found any matching loose quals, count col as matched */
3930
0
      if (fkinfo->rinfos[colno])
3931
0
        fkinfo->nmatched_rcols++;
3932
0
    }
3933
3934
    /*
3935
     * Currently, we drop multicolumn FKs that aren't fully matched to the
3936
     * query.  Later we might figure out how to derive some sort of
3937
     * estimate from them, in which case this test should be weakened to
3938
     * "if ((fkinfo->nmatched_ec + fkinfo->nmatched_rcols) > 0)".
3939
     */
3940
0
    if ((fkinfo->nmatched_ec + fkinfo->nmatched_rcols) == fkinfo->nkeys)
3941
0
      newlist = lappend(newlist, fkinfo);
3942
0
  }
3943
  /* Replace fkey_list, thereby discarding any useless entries */
3944
0
  root->fkey_list = newlist;
3945
0
}
3946
3947
3948
/*****************************************************************************
3949
 *
3950
 *   CHECKS FOR MERGEJOINABLE AND HASHJOINABLE CLAUSES
3951
 *
3952
 *****************************************************************************/
3953
3954
/*
3955
 * check_mergejoinable
3956
 *    If the restrictinfo's clause is mergejoinable, set the mergejoin
3957
 *    info fields in the restrictinfo.
3958
 *
3959
 *    Currently, we support mergejoin for binary opclauses where
3960
 *    the operator is a mergejoinable operator.  The arguments can be
3961
 *    anything --- as long as there are no volatile functions in them.
3962
 */
3963
static void
3964
check_mergejoinable(RestrictInfo *restrictinfo)
3965
0
{
3966
0
  Expr     *clause = restrictinfo->clause;
3967
0
  Oid     opno;
3968
0
  Node     *leftarg;
3969
3970
0
  if (restrictinfo->pseudoconstant)
3971
0
    return;
3972
0
  if (!is_opclause(clause))
3973
0
    return;
3974
0
  if (list_length(((OpExpr *) clause)->args) != 2)
3975
0
    return;
3976
3977
0
  opno = ((OpExpr *) clause)->opno;
3978
0
  leftarg = linitial(((OpExpr *) clause)->args);
3979
3980
0
  if (op_mergejoinable(opno, exprType(leftarg)) &&
3981
0
    !contain_volatile_functions((Node *) restrictinfo))
3982
0
    restrictinfo->mergeopfamilies = get_mergejoin_opfamilies(opno);
3983
3984
  /*
3985
   * Note: op_mergejoinable is just a hint; if we fail to find the operator
3986
   * in any btree opfamilies, mergeopfamilies remains NIL and so the clause
3987
   * is not treated as mergejoinable.
3988
   */
3989
0
}
3990
3991
/*
3992
 * check_hashjoinable
3993
 *    If the restrictinfo's clause is hashjoinable, set the hashjoin
3994
 *    info fields in the restrictinfo.
3995
 *
3996
 *    Currently, we support hashjoin for binary opclauses where
3997
 *    the operator is a hashjoinable operator.  The arguments can be
3998
 *    anything --- as long as there are no volatile functions in them.
3999
 */
4000
static void
4001
check_hashjoinable(RestrictInfo *restrictinfo)
4002
0
{
4003
0
  Expr     *clause = restrictinfo->clause;
4004
0
  Oid     opno;
4005
0
  Node     *leftarg;
4006
4007
0
  if (restrictinfo->pseudoconstant)
4008
0
    return;
4009
0
  if (!is_opclause(clause))
4010
0
    return;
4011
0
  if (list_length(((OpExpr *) clause)->args) != 2)
4012
0
    return;
4013
4014
0
  opno = ((OpExpr *) clause)->opno;
4015
0
  leftarg = linitial(((OpExpr *) clause)->args);
4016
4017
0
  if (op_hashjoinable(opno, exprType(leftarg)) &&
4018
0
    !contain_volatile_functions((Node *) restrictinfo))
4019
0
    restrictinfo->hashjoinoperator = opno;
4020
0
}
4021
4022
/*
4023
 * check_memoizable
4024
 *    If the restrictinfo's clause is suitable to be used for a Memoize node,
4025
 *    set the left_hasheqoperator and right_hasheqoperator to the hash equality
4026
 *    operator that will be needed during caching.
4027
 */
4028
static void
4029
check_memoizable(RestrictInfo *restrictinfo)
4030
0
{
4031
0
  TypeCacheEntry *typentry;
4032
0
  Expr     *clause = restrictinfo->clause;
4033
0
  Oid     lefttype;
4034
0
  Oid     righttype;
4035
4036
0
  if (restrictinfo->pseudoconstant)
4037
0
    return;
4038
0
  if (!is_opclause(clause))
4039
0
    return;
4040
0
  if (list_length(((OpExpr *) clause)->args) != 2)
4041
0
    return;
4042
4043
0
  lefttype = exprType(linitial(((OpExpr *) clause)->args));
4044
4045
0
  typentry = lookup_type_cache(lefttype, TYPECACHE_HASH_PROC |
4046
0
                 TYPECACHE_EQ_OPR);
4047
4048
0
  if (OidIsValid(typentry->hash_proc) && OidIsValid(typentry->eq_opr))
4049
0
    restrictinfo->left_hasheqoperator = typentry->eq_opr;
4050
4051
0
  righttype = exprType(lsecond(((OpExpr *) clause)->args));
4052
4053
  /*
4054
   * Lookup the right type, unless it's the same as the left type, in which
4055
   * case typentry is already pointing to the required TypeCacheEntry.
4056
   */
4057
0
  if (lefttype != righttype)
4058
0
    typentry = lookup_type_cache(righttype, TYPECACHE_HASH_PROC |
4059
0
                   TYPECACHE_EQ_OPR);
4060
4061
0
  if (OidIsValid(typentry->hash_proc) && OidIsValid(typentry->eq_opr))
4062
0
    restrictinfo->right_hasheqoperator = typentry->eq_opr;
4063
0
}